diff options
993 files changed, 98576 insertions, 16834 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e8a364050a..61bc0ade65 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1 +1,12 @@ +# Following revs are all whitespace changes; use with +# git blame --ignore-revs-file .git-blame-ignore-revs <...> +# or to make it permanent +# git config blame.ignoreRevsFile .git-blame-ignore-revs +701a01920eee5431d2052aad92aefbdf50ac2139 +bf2394f08bdc91a6cbd3784a1bfa3af3247bb06f +0157c327715ca367d13b7f02b2981f3484ccdeeb +787e762445d50ca5b52fafcf8dd6de08ab90916f +ac2914d3261a78cf78eec7a6e20ebbe42bb57150 +ac4d0be5874fafd14212d6007fff7495edc9b152 d62a17aedeb0eebdba98238874bb13d62c48dbf9 +c14777c6bfd0a446c85243d3a9835054a259c276 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 98c7c3d54d..8983b39eb3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,37 +7,91 @@ assignees: '' --- +<!-- + +*** ATTENTION *** + +YOU MUST READ THIS TO HAVE YOUR ISSUE ADDRESSED + +PLEASE READ AND FILL OUT THIS TEMPLATE + +NEGLECTING TO PROVIDE INFORMATION REQUESTED HERE WILL RESULT IN +SIGNIFICANT DELAYS ADDRESSING YOUR ISSUE + +ALWAYS PROVIDE: +- FRR VERSION +- OPERATING SYSTEM VERSION +- KERNEL VERSION + +FAILURE TO PROVIDE THIS MAY RESULT IN YOUR ISSUE BEING IGNORED + +FOLLOW THESE GUIDELINES: + - When reporting a crash, provide a backtrace -- When pasting configs, logs, shell output, backtraces, and other large chunks of text use Markdown code blocks -- Include the FRR version; if you built from Git, please provide the commit hash +- When pasting configs, logs, shell output, backtraces, and other large chunks + of text, surround this text with triple backtics + + ``` + like this + ``` + +- Include the FRR version; if you built from Git, please provide the commit + hash - Write your issue in English +--> + --------------- **Describe the bug** +<!-- A clear and concise description of what the bug is. -(put "x" in "[ ]" if you already tried following) +Put "x" in "[ ]" if you already tried following: +--> + [ ] Did you check if this is a duplicate issue? [ ] Did you test it on the latest FRRouting/frr master branch? **To Reproduce** -Steps to reproduce the behavior: +<!-- +Describe the steps to reproduce the behavior. +Be as descriptive as possible. + +For example: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error +--> **Expected behavior** -A clear and concise description of what you expected to happen. +<!-- +Write here a clear and concise description of what you expected to happen when +using the reproduction steps you provided above +--> **Screenshots** +<!-- If applicable, add screenshots to help explain your problem. +--> **Versions** - - OS Kernel: [e.g. Linux, OpenBSD, etc] [version] - - FRR Version: [version] +<!-- +Include your operating system type and version here + +FAILURE TO PROVIDE THIS MAY RESULT IN YOUR ISSUE BEING IGNORED +--> +<!-- e.g. Fedora 24, Debian 10] --> + - OS Version: +<!-- [e.g. Linux 5.4, OpenBSD 6.6] --> + - Kernel: +<!-- e.g. 6.0, 7.4 --> + - FRR Version: **Additional context** +<!-- Add any other context about the problem here. +--> diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in index 43a77832a9..d6c6c5f0af 100644 --- a/alpine/APKBUILD.in +++ b/alpine/APKBUILD.in @@ -6,7 +6,7 @@ pkgrel=0 pkgdesc="FRRouting is a fork of quagga" url="https://frrouting.org/" license="GPL-2.0" -depends="json-c c-ares ipsec-tools iproute2 python3 py-ipaddr bash" +depends="json-c c-ares iproute2 python3 bash" makedepends="ncurses-dev net-snmp-dev gawk texinfo perl acct autoconf automake bash binutils bison bsd-compat-headers build-base c-ares c-ares-dev ca-certificates cryptsetup-libs curl device-mapper-libs diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c index 28ba8e16a2..731ad1ba8b 100644 --- a/babeld/babel_filter.c +++ b/babeld/babel_filter.c @@ -59,24 +59,16 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen, if (access_list_apply (babel_ifp->list[distribute], &p) == FILTER_DENY) { debugf(BABEL_DEBUG_FILTER, - "%s/%d filtered by distribute %s", - p.family == AF_INET ? - inet_ntoa(p.u.prefix4) : - inet6_ntoa (p.u.prefix6), - p.prefixlen, - output ? "out" : "in"); + "%pFX filtered by distribute %s", + &p, output ? "out" : "in"); return INFINITY; } } if (babel_ifp != NULL && babel_ifp->prefix[distribute]) { if (prefix_list_apply (babel_ifp->prefix[distribute], &p) == PREFIX_DENY) { - debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute %s", - p.family == AF_INET ? - inet_ntoa(p.u.prefix4) : - inet6_ntoa (p.u.prefix6), - p.prefixlen, - output ? "out" : "in"); + debugf(BABEL_DEBUG_FILTER, "%pFX filtered by distribute %s", + &p, output ? "out" : "in"); return INFINITY; } } @@ -91,12 +83,8 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen, if (alist) { if (access_list_apply (alist, &p) == FILTER_DENY) { - debugf(BABEL_DEBUG_FILTER,"%s/%d filtered by distribute %s", - p.family == AF_INET ? - inet_ntoa(p.u.prefix4) : - inet6_ntoa (p.u.prefix6), - p.prefixlen, - output ? "out" : "in"); + debugf(BABEL_DEBUG_FILTER,"%pFX filtered by distribute %s", + &p, output ? "out" : "in"); return INFINITY; } } @@ -105,12 +93,8 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen, plist = prefix_list_lookup (p.family, dist->prefix[distribute]); if (plist) { if (prefix_list_apply (plist, &p) == PREFIX_DENY) { - debugf(BABEL_DEBUG_FILTER,"%s/%d filtered by distribute %s", - p.family == AF_INET ? - inet_ntoa(p.u.prefix4) : - inet6_ntoa (p.u.prefix6), - p.prefixlen, - output ? "out" : "in"); + debugf(BABEL_DEBUG_FILTER,"%pFX filtered by distribute %s", + &p, output ? "out" : "in"); return INFINITY; } } diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 1702d9277c..ae8b161b01 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -1106,6 +1106,7 @@ DEFUN (show_babel_route_addr, { struct in_addr addr; char buf[INET_ADDRSTRLEN + 8]; + char buf1[INET_ADDRSTRLEN + 8]; struct route_stream *routes = NULL; struct xroute_stream *xroutes = NULL; struct prefix prefix; @@ -1118,7 +1119,8 @@ DEFUN (show_babel_route_addr, } /* Quagga has no convenient prefix constructors. */ - snprintf(buf, sizeof(buf), "%s/%d", inet_ntoa(addr), 32); + snprintf(buf, sizeof(buf), "%s/%d", + inet_ntop(AF_INET, &addr, buf1, sizeof(buf1)), 32); ret = str2prefix(buf, &prefix); if (ret == 0) { diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index 86f8bc721e..d10d418572 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -251,7 +251,7 @@ void babelz_zebra_init(void) install_element(CONFIG_NODE, &debug_babel_cmd); install_element(CONFIG_NODE, &no_debug_babel_cmd); - install_element(VIEW_NODE, &show_debugging_babel_cmd); + install_element(ENABLE_NODE, &show_debugging_babel_cmd); } void diff --git a/babeld/babeld.c b/babeld/babeld.c index 09955cfbef..895ede7040 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -317,13 +317,9 @@ babel_clean_routing_process(void) flush_all_routes(); babel_interface_close_all(); - /* cancel threads */ - if (babel_routing_process->t_read != NULL) { - thread_cancel(babel_routing_process->t_read); - } - if (babel_routing_process->t_update != NULL) { - thread_cancel(babel_routing_process->t_update); - } + /* cancel events */ + thread_cancel(&babel_routing_process->t_read); + thread_cancel(&babel_routing_process->t_update); distribute_list_delete(&babel_routing_process->distribute_ctx); XFREE(MTYPE_BABEL, babel_routing_process); @@ -503,9 +499,7 @@ static void babel_set_timer(struct timeval *timeout) { long msecs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; - if (babel_routing_process->t_update != NULL) { - thread_cancel(babel_routing_process->t_update); - } + thread_cancel(&(babel_routing_process->t_update)); thread_add_timer_msec(master, babel_main_loop, NULL, msecs, &babel_routing_process->t_update); } diff --git a/bfdd/control.c b/bfdd/control.c index 3b954c64f8..4929bf1998 100644 --- a/bfdd/control.c +++ b/bfdd/control.c @@ -145,10 +145,7 @@ void control_shutdown(void) { struct bfd_control_socket *bcs; - if (bglobal.bg_csockev) { - thread_cancel(bglobal.bg_csockev); - bglobal.bg_csockev = NULL; - } + thread_cancel(&bglobal.bg_csockev); socket_close(&bglobal.bg_csock); @@ -204,15 +201,8 @@ static void control_free(struct bfd_control_socket *bcs) struct bfd_control_queue *bcq; struct bfd_notify_peer *bnp; - if (bcs->bcs_ev) { - thread_cancel(bcs->bcs_ev); - bcs->bcs_ev = NULL; - } - - if (bcs->bcs_outev) { - thread_cancel(bcs->bcs_outev); - bcs->bcs_outev = NULL; - } + thread_cancel(&(bcs->bcs_ev)); + thread_cancel(&(bcs->bcs_outev)); close(bcs->bcs_sd); @@ -318,10 +308,7 @@ static int control_queue_dequeue(struct bfd_control_socket *bcs) return 1; empty_list: - if (bcs->bcs_outev) { - thread_cancel(bcs->bcs_outev); - bcs->bcs_outev = NULL; - } + thread_cancel(&(bcs->bcs_outev)); bcs->bcs_bout = NULL; return 0; } diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 48e55bce37..3a80d9203b 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -783,17 +783,16 @@ static void bfdd_sessions_enable_address(struct connected *ifc) static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS) { struct connected *ifc; - char buf[64]; ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id); if (ifc == NULL) return 0; if (bglobal.debug_zebra) - zlog_debug("zclient: %s local address %s", + zlog_debug("zclient: %s local address %pFX", cmd == ZEBRA_INTERFACE_ADDRESS_ADD ? "add" : "delete", - prefix2str(ifc->address, buf, sizeof(buf))); + ifc->address); bfdd_sessions_enable_address(ifc); diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 0821a724a6..b94e24e870 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -725,6 +725,8 @@ bool attrhash_cmp(const void *p1, const void *p2) && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t)) && attr1->es_flags == attr2->es_flags && attr1->mm_sync_seqnum == attr2->mm_sync_seqnum + && attr1->df_pref == attr2->df_pref + && attr1->df_alg == attr2->df_alg && attr1->nh_ifindex == attr2->nh_ifindex && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex && attr1->distance == attr2->distance @@ -763,8 +765,7 @@ static void attr_show_all_iterator(struct hash_bucket *bucket, struct vty *vty) struct attr *attr = bucket->data; char sid_str[BUFSIZ]; - vty_out(vty, "attr[%ld] nexthop %s\n", attr->refcnt, - inet_ntoa(attr->nexthop)); + vty_out(vty, "attr[%ld] nexthop %pI4\n", attr->refcnt, &attr->nexthop); sid_str[0] = '\0'; if (attr->srv6_l3vpn) @@ -2248,6 +2249,9 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); + /* Extract DF election preference and mobility sequence number */ + attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg); + /* Extract MAC mobility sequence number, if any. */ attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky); attr->sticky = sticky; diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index e6e953364b..ef0e74344a 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -294,6 +294,10 @@ struct attr { /* SR-TE Color */ uint32_t srte_color; + + /* EVPN DF preference and algorithm for DF election on local ESs */ + uint16_t df_pref; + uint8_t df_alg; }; /* rmap_change_flags definition */ diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index aa0c59f3a7..7cc9ecd79e 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -26,6 +26,7 @@ #include "log.h" #include "memory.h" #include "stream.h" +#include "vxlan.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" @@ -146,6 +147,43 @@ uint8_t bgp_attr_default_gw(struct attr *attr) } /* + * Fetch and return the DF preference and algorithm from + * DF election extended community, if present, else 0. + */ +uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg) +{ + struct ecommunity *ecom; + int i; + uint16_t df_pref = 0; + + *alg = EVPN_MH_DF_ALG_SERVICE_CARVING; + ecom = attr->ecommunity; + if (!ecom || !ecom->size) + return 0; + + for (i = 0; i < ecom->size; i++) { + uint8_t *pnt; + uint8_t type, sub_type; + + pnt = (ecom->val + (i * ECOMMUNITY_SIZE)); + type = *pnt++; + sub_type = *pnt++; + if (!(type == ECOMMUNITY_ENCODE_EVPN + && sub_type == ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION)) + continue; + + *alg = (*pnt++) & ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS; + + pnt += 3; + pnt = ptr_get_be16(pnt, &df_pref); + (void)pnt; /* consume value */ + break; + } + + return df_pref; +} + +/* * Fetch and return the sequence number from MAC Mobility extended * community, if present, else 0. */ diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index 19c028a826..6fdf73fd1e 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -48,6 +48,7 @@ extern uint8_t bgp_attr_default_gw(struct attr *attr); extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag, bool *proxy); +extern uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg); extern bool is_zero_gw_ip(const union gw_addr *gw_ip, afi_t afi); diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 1e1c97c2d9..11e9344d1c 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -385,24 +385,21 @@ static int bgp_bfd_dest_update(ZAPI_CALLBACK_ARGS) if (BGP_DEBUG(zebra, ZEBRA)) { struct vrf *vrf; - char buf[2][PREFIX2STR_BUFFER]; vrf = vrf_lookup_by_id(vrf_id); - prefix2str(&dp, buf[0], sizeof(buf[0])); - if (ifp) { + + if (ifp) zlog_debug( - "Zebra: vrf %s(%u) interface %s bfd destination %s %s %s", - VRF_LOGNAME(vrf), vrf_id, ifp->name, - buf[0], bfd_get_status_str(status), + "Zebra: vrf %s(%u) interface %s bfd destination %pFX %s %s", + VRF_LOGNAME(vrf), vrf_id, ifp->name, &dp, + bfd_get_status_str(status), remote_cbit ? "(cbit on)" : ""); - } else { - prefix2str(&sp, buf[1], sizeof(buf[1])); + else zlog_debug( - "Zebra: vrf %s(%u) source %s bfd destination %s %s %s", - VRF_LOGNAME(vrf), vrf_id, buf[1], buf[0], + "Zebra: vrf %s(%u) source %pFX bfd destination %pFX %s %s", + VRF_LOGNAME(vrf), vrf_id, &sp, &dp, bfd_get_status_str(status), remote_cbit ? "(cbit on)" : ""); - } } /* Bring the peer down if BFD is enabled in BGP */ @@ -601,6 +598,7 @@ static int bgp_bfd_peer_param_type_set(struct peer *peer, return 0; } +#if HAVE_BFDD > 0 /** * Set peer BFD profile configuration. */ @@ -655,6 +653,7 @@ static int bgp_bfd_peer_set_profile(struct peer *peer, const char *profile) return 0; } +#endif /* * bgp_bfd_peer_config_write - Write the peer BFD configuration. diff --git a/bgpd/bgp_bmp.h b/bgpd/bgp_bmp.h index 9032da55bf..d6b22d0cbc 100644 --- a/bgpd/bgp_bmp.h +++ b/bgpd/bgp_bmp.h @@ -156,7 +156,7 @@ struct bmp { * table entry, the sync* fields note down what we sent last */ struct prefix syncpos; - struct bgp_node *syncrdpos; + struct bgp_dest *syncrdpos; uint64_t syncpeerid; afi_t syncafi; safi_t syncsafi; diff --git a/bgpd/bgp_btoa.c b/bgpd/bgp_btoa.c index cbe18e23cb..13c42d95f4 100644 --- a/bgpd/bgp_btoa.c +++ b/bgpd/bgp_btoa.c @@ -108,7 +108,7 @@ static void attr_parse(struct stream *s, uint16_t len) case BGP_ATTR_NEXT_HOP: { struct in_addr nexthop; nexthop.s_addr = stream_get_ipv4(s); - printf("NEXTHOP: %s\n", inet_ntoa(nexthop)); + printf("NEXTHOP: %pI4\n", &nexthop); } break; default: stream_getw_from(s, length); @@ -244,7 +244,7 @@ int main(int argc, char **argv) while (s->getp < len - 16) { p.prefix.s_addr = stream_get_ipv4(s); p.prefixlen = stream_getc(s); - printf("PREFIX: %s/%d\n", inet_ntoa(p.prefix), + printf("PREFIX: %pI4/%d\n", &p.prefix, p.prefixlen); status = stream_getc(s); @@ -252,8 +252,7 @@ int main(int argc, char **argv) peer.s_addr = stream_get_ipv4(s); source_as = stream_getw(s); - printf("FROM: %s AS%d\n", inet_ntoa(peer), - source_as); + printf("FROM: %pI4 AS%d\n", &peer, source_as); printf("ORIGINATED: %s", ctime(&originated)); attrlen = stream_getw(s); @@ -278,8 +277,8 @@ int main(int argc, char **argv) sip.s_addr = stream_get_ipv4(s); dip.s_addr = stream_get_ipv4(s); - printf("saddr: %s\n", inet_ntoa(sip)); - printf("daddr: %s\n", inet_ntoa(dip)); + printf("saddr: %pI4\n", &sip); + printf("daddr: %pI4\n", &dip); printf("\n"); } diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c new file mode 100644 index 0000000000..0731adcb84 --- /dev/null +++ b/bgpd/bgp_conditional_adv.c @@ -0,0 +1,343 @@ +/* + * BGP Conditional advertisement + * Copyright (C) 2020 Samsung R&D Institute India - Bangalore. + * Madhurilatha Kuruganti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "bgpd/bgp_conditional_adv.h" + +const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json); + +static route_map_result_t +bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table, + struct route_map *rmap) +{ + struct attr dummy_attr = {0}; + struct bgp_dest *dest; + struct bgp_path_info *pi; + struct bgp_path_info path = {0}; + struct bgp_path_info_extra path_extra = {0}; + const struct prefix *dest_p; + route_map_result_t ret = RMAP_DENYMATCH; + + for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { + dest_p = bgp_dest_get_prefix(dest); + assert(dest_p); + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + dummy_attr = *pi->attr; + + /* Fill temp path_info */ + prep_for_rmap_apply(&path, &path_extra, dest, pi, + pi->peer, &dummy_attr); + + RESET_FLAG(dummy_attr.rmap_change_flags); + + ret = route_map_apply(rmap, dest_p, RMAP_BGP, &path); + if (ret != RMAP_PERMITMATCH) + bgp_attr_flush(&dummy_attr); + else { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug( + "%s: Condition map routes present in BGP table", + __func__); + + return ret; + } + } + } + + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Condition map routes not present in BGP table", + __func__); + + return ret; +} + +static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, + safi_t safi, struct bgp_table *table, + struct route_map *rmap, + enum update_type update_type) +{ + int addpath_capable; + struct bgp_dest *dest; + struct bgp_path_info *pi; + struct bgp_path_info path; + struct peer_af *paf; + const struct prefix *dest_p; + struct update_subgroup *subgrp; + struct attr dummy_attr = {0}, attr = {0}; + struct bgp_path_info_extra path_extra = {0}; + + paf = peer_af_find(peer, afi, safi); + if (!paf) + return; + + subgrp = PAF_SUBGRP(paf); + /* Ignore if subgroup doesn't exist (implies AF is not negotiated) */ + if (!subgrp) + return; + + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: %s routes to/from %s for %s", __func__, + update_type == ADVERTISE ? "Advertise" : "Withdraw", + peer->host, get_afi_safi_str(afi, safi, false)); + + addpath_capable = bgp_addpath_encode_tx(peer, afi, safi); + + for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { + dest_p = bgp_dest_get_prefix(dest); + assert(dest_p); + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + dummy_attr = *pi->attr; + + /* Fill temp path_info */ + prep_for_rmap_apply(&path, &path_extra, dest, pi, + pi->peer, &dummy_attr); + + RESET_FLAG(dummy_attr.rmap_change_flags); + + if (route_map_apply(rmap, dest_p, RMAP_BGP, &path) + != RMAP_PERMITMATCH) { + bgp_attr_flush(&dummy_attr); + continue; + } + + if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) + || (addpath_capable + && bgp_addpath_tx_path( + peer->addpath_type[afi][safi], + pi))) { + + /* Skip route-map checks in + * subgroup_announce_check while executing from + * the conditional advertise scanner process. + * otherwise when route-map is also configured + * on same peer, routes in advertise-map may not + * be advertised as expected. + */ + if ((update_type == ADVERTISE) + && subgroup_announce_check(dest, pi, subgrp, + dest_p, &attr, + true)) + bgp_adj_out_set_subgroup(dest, subgrp, + &attr, pi); + else { + /* If default originate is enabled for + * the peer, do not send explicit + * withdraw. This will prevent deletion + * of default route advertised through + * default originate. + */ + if (CHECK_FLAG( + peer->af_flags[afi][safi], + PEER_FLAG_DEFAULT_ORIGINATE) + && is_default_prefix(dest_p)) + break; + + bgp_adj_out_unset_subgroup( + dest, subgrp, 1, + bgp_addpath_id_for_peer( + peer, afi, safi, + &pi->tx_addpath)); + } + } + } + } +} + +/* Handler of conditional advertisement timer event. + * Each route in the condition-map is evaluated. + */ +static int bgp_conditional_adv_timer(struct thread *t) +{ + afi_t afi; + safi_t safi; + int pfx_rcd_safi; + struct bgp *bgp = NULL; + struct peer *peer = NULL; + struct peer_af *paf = NULL; + struct bgp_table *table = NULL; + struct bgp_filter *filter = NULL; + struct listnode *node, *nnode = NULL; + struct update_subgroup *subgrp = NULL; + route_map_result_t ret; + + bgp = THREAD_ARG(t); + assert(bgp); + + thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp, + CONDITIONAL_ROUTES_POLL_TIME, &bgp->t_condition_check); + + /* loop through each peer and advertise or withdraw routes if + * advertise-map is configured and prefix(es) in condition-map + * does exist(exist-map)/not exist(non-exist-map) in BGP table + * based on condition(exist-map or non-exist map) + */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + continue; + + if (peer->status != Established) + continue; + + FOREACH_AFI_SAFI (afi, safi) { + if (strmatch(get_afi_safi_str(afi, safi, true), + "Unknown")) + continue; + + if (!peer->afc_nego[afi][safi]) + continue; + + /* labeled-unicast routes are installed in the unicast + * table so in order to display the correct PfxRcd value + * we must look at SAFI_UNICAST + */ + pfx_rcd_safi = (safi == SAFI_LABELED_UNICAST) + ? SAFI_UNICAST + : safi; + + table = bgp->rib[afi][pfx_rcd_safi]; + if (!table) + continue; + + filter = &peer->filter[afi][safi]; + + if (!filter->advmap.aname || !filter->advmap.cname + || !filter->advmap.amap || !filter->advmap.cmap) + continue; + + if (!peer->advmap_config_change[afi][safi] + && !peer->advmap_table_change) + continue; + + if (BGP_DEBUG(update, UPDATE_OUT)) { + if (peer->advmap_table_change) + zlog_debug( + "%s: %s - routes changed in BGP table.", + __func__, peer->host); + if (peer->advmap_config_change[afi][safi]) + zlog_debug( + "%s: %s for %s - advertise/condition map configuration is changed.", + __func__, peer->host, + get_afi_safi_str(afi, safi, + false)); + } + + /* cmap (route-map attached to exist-map or + * non-exist-map) map validation + */ + ret = bgp_check_rmap_prefixes_in_bgp_table( + table, filter->advmap.cmap); + + /* Derive conditional advertisement status from + * condition and return value of condition-map + * validation. + */ + if (filter->advmap.condition == CONDITION_EXIST) + filter->advmap.update_type = + (ret == RMAP_PERMITMATCH) ? ADVERTISE + : WITHDRAW; + else + filter->advmap.update_type = + (ret == RMAP_PERMITMATCH) ? WITHDRAW + : ADVERTISE; + + /* Send regular update as per the existing policy. + * There is a change in route-map, match-rule, ACLs, + * or route-map filter configuration on the same peer. + */ + if (peer->advmap_config_change[afi][safi]) { + + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug( + "%s: Configuration is changed on peer %s for %s, send the normal update first.", + __func__, peer->host, + get_afi_safi_str(afi, safi, + false)); + + paf = peer_af_find(peer, afi, safi); + if (paf) { + update_subgroup_split_peer(paf, NULL); + subgrp = paf->subgroup; + if (subgrp && subgrp->update_group) + subgroup_announce_table( + paf->subgroup, NULL); + } + peer->advmap_config_change[afi][safi] = false; + } + + /* Send update as per the conditional advertisement */ + bgp_conditional_adv_routes(peer, afi, safi, table, + filter->advmap.amap, + filter->advmap.update_type); + } + peer->advmap_table_change = false; + } + return 0; +} + +void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp *bgp = peer->bgp; + + assert(bgp); + + /* This flag is used to monitor conditional routes status in BGP table, + * and advertise/withdraw routes only when there is a change in BGP + * table w.r.t conditional routes + */ + peer->advmap_config_change[afi][safi] = true; + + /* advertise-map is already configured on atleast one of its + * neighbors (AFI/SAFI). So just increment the counter. + */ + if (++bgp->condition_filter_count > 1) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: condition_filter_count %d", __func__, + bgp->condition_filter_count); + + return; + } + + /* Register for conditional routes polling timer */ + thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp, + CONDITIONAL_ROUTES_POLL_TIME, &bgp->t_condition_check); +} + +void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp *bgp = peer->bgp; + + assert(bgp); + + /* advertise-map is not configured on any of its neighbors or + * it is configured on more than one neighbor(AFI/SAFI). + * So there's nothing to do except decrementing the counter. + */ + if (--bgp->condition_filter_count != 0) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: condition_filter_count %d", __func__, + bgp->condition_filter_count); + + return; + } + + /* Last filter removed. So cancel conditional routes polling thread. */ + THREAD_OFF(bgp->t_condition_check); +} diff --git a/bgpd/bgp_conditional_adv.h b/bgpd/bgp_conditional_adv.h new file mode 100644 index 0000000000..7b5053de76 --- /dev/null +++ b/bgpd/bgp_conditional_adv.h @@ -0,0 +1,47 @@ +/* + * BGP Conditional advertisement + * Copyright (C) 2020 Samsung R&D Institute India - Bangalore. + * Madhurilatha Kuruganti + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_BGP_CONDITION_ADV_H +#define _FRR_BGP_CONDITION_ADV_H +#include <zebra.h> +#include "prefix.h" +#include "bgpd/bgp_addpath.h" +#include "bgpd/bgp_attr.h" +#include "bgpd/bgpd.h" +#include "bgpd/bgp_debug.h" +#include "bgpd/bgp_route.h" +#include "bgpd/bgp_updgrp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Polling time for monitoring condition-map routes in route table */ +#define CONDITIONAL_ROUTES_POLL_TIME 60 + +extern void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, + safi_t safi); +extern void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, + safi_t safi); +#ifdef __cplusplus +} +#endif + +#endif /* _FRR_BGP_CONDITION_ADV_H */ diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 9992168182..94a27ead0e 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -467,10 +467,8 @@ int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi) if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) return 0; - /* Cancel reuse thread. */ - if (bdc->t_reuse) - thread_cancel(bdc->t_reuse); - bdc->t_reuse = NULL; + /* Cancel reuse event. */ + thread_cancel(&(bdc->t_reuse)); /* Clean BGP dampening information. */ bgp_damp_info_clean(afi, safi); diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index e9d7c9e8aa..a513bc493d 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -21,6 +21,7 @@ #include <zebra.h> #include <lib/version.h> +#include "lib/printfrr.h" #include "prefix.h" #include "linklist.h" #include "stream.h" @@ -236,7 +237,6 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc, { struct bgp_debug_filter *filter; struct listnode *node, *nnode; - char buf[PREFIX2STR_BUFFER]; vty_out(vty, "%s", desc); @@ -248,10 +248,8 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc, if (filter->p && filter->p->family == AF_EVPN) bgp_debug_print_evpn_prefix(vty, "", filter->p); - else if (filter->p) { - prefix2str(filter->p, buf, sizeof(buf)); - vty_out(vty, " %s", buf); - } + else if (filter->p) + vty_out(vty, " %pFX", filter->p); } } @@ -267,7 +265,6 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc, { struct bgp_debug_filter *filter; struct listnode *node, *nnode; - char buf[PREFIX2STR_BUFFER]; int write = 0; if (list && !list_isempty(list)) { @@ -282,8 +279,7 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc, filter->p); write++; } else if (filter->p) { - prefix2str(filter->p, buf, sizeof(buf)); - vty_out(vty, "%s %s\n", desc, buf); + vty_out(vty, "%s %pFX\n", desc, filter->p); write++; } } @@ -380,7 +376,7 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size) buf[0] = '\0'; if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))) - snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop)); + snprintfrr(buf, size, "nexthop %pI4", &attr->nexthop); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN))) snprintf(buf + strlen(buf), size - strlen(buf), ", origin %s", @@ -400,7 +396,7 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size) BUFSIZ)); if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) - snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop)); + snprintfrr(buf, size, "nexthop %pI4", &attr->nexthop); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) snprintf(buf + strlen(buf), size - strlen(buf), @@ -424,13 +420,13 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size) ", atomic-aggregate"); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) - snprintf(buf + strlen(buf), size - strlen(buf), - ", aggregated by %u %s", attr->aggregator_as, - inet_ntoa(attr->aggregator_addr)); + snprintfrr(buf + strlen(buf), size - strlen(buf), + ", aggregated by %u %pI4", attr->aggregator_as, + &attr->aggregator_addr); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) - snprintf(buf + strlen(buf), size - strlen(buf), - ", originator %s", inet_ntoa(attr->originator_id)); + snprintfrr(buf + strlen(buf), size - strlen(buf), + ", originator %pI4", &attr->originator_id); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { int i; @@ -438,8 +434,8 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size) snprintf(buf + strlen(buf), size - strlen(buf), ", clusterlist"); for (i = 0; i < attr->cluster->length / 4; i++) - snprintf(buf + strlen(buf), size - strlen(buf), " %s", - inet_ntoa(attr->cluster->list[i])); + snprintfrr(buf + strlen(buf), size - strlen(buf), + " %pI4", &attr->cluster->list[i]); } if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) @@ -592,9 +588,9 @@ static void bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc, buf, PREFIX2STR_BUFFER)); } } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IMET_ROUTE) { - snprintf(evpn_desc, sizeof(evpn_desc), - "l2vpn evpn type multicast ip %s", - inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4)); + snprintfrr(evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type multicast ip %pI4", + &p->u.prefix_evpn.imet_addr.ip.ipaddr_v4); } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IP_PREFIX_ROUTE) { uint8_t family = is_evpn_prefix_ipaddr_v4( (struct prefix_evpn *)p) ? AF_INET @@ -616,21 +612,14 @@ static int bgp_debug_parse_evpn_prefix(struct vty *vty, struct cmd_token **argv, struct prefix *argv_p; struct ethaddr mac; struct ipaddr ip; - int evpn_type; - int type_idx = 0; + int evpn_type = 0; int mac_idx = 0; int ip_idx = 0; argv_p = *argv_pp; - if (argv_find(argv, argc, "macip", &type_idx)) - evpn_type = BGP_EVPN_MAC_IP_ROUTE; - else if (argv_find(argv, argc, "multicast", &type_idx)) - evpn_type = BGP_EVPN_IMET_ROUTE; - else if (argv_find(argv, argc, "prefix", &type_idx)) - evpn_type = BGP_EVPN_IP_PREFIX_ROUTE; - else - evpn_type = 0; + if (bgp_evpn_cli_parse_type(&evpn_type, argv, argc) < 0) + return CMD_WARNING; if (evpn_type == BGP_EVPN_MAC_IP_ROUTE) { memset(&ip, 0, sizeof(struct ipaddr)); @@ -1395,31 +1384,33 @@ DEFUN (no_debug_bgp_update_direct_peer, DEFPY (debug_bgp_update_prefix_afi_safi, debug_bgp_update_prefix_afi_safi_cmd, - "debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>", + "debug bgp updates prefix l2vpn$afi evpn$safi type <<macip|2> mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|<multicast|3> ip <A.B.C.D|X:X::X:X>|<prefix|5> ip <A.B.C.D/M|X:X::X:X/M>>", DEBUG_STR BGP_STR "BGP updates\n" "Specify a prefix to debug\n" L2VPN_HELP_STR EVPN_HELP_STR - "Specify EVPN Route type\n" - "MAC-IP (Type-2) route\n" + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR MAC_STR MAC_STR MAC_STR IP_STR "IPv4 address\n" "IPv6 address\n" - "Multicast (Type-3) route\n" + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR IP_STR "IPv4 address\n" "IPv6 address\n" - "Prefix (Type-5) route\n" + EVPN_TYPE_5_HELP_STR + EVPN_TYPE_5_HELP_STR IP_STR "IPv4 prefix\n" "IPv6 prefix\n") { struct prefix *argv_p; int ret = CMD_SUCCESS; - char buf[PREFIX2STR_BUFFER]; argv_p = prefix_new(); @@ -1432,12 +1423,10 @@ DEFPY (debug_bgp_update_prefix_afi_safi, if (!bgp_debug_update_prefixes) bgp_debug_update_prefixes = list_new(); - prefix2str(argv_p, buf, sizeof(buf)); - if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, argv_p)) { vty_out(vty, - "BGP updates debugging is already enabled for %s\n", - buf); + "BGP updates debugging is already enabled for %pFX\n", + argv_p); prefix_free(&argv_p); return CMD_SUCCESS; } @@ -1448,7 +1437,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi, DEBUG_ON(update, UPDATE_PREFIX); } else { TERM_DEBUG_ON(update, UPDATE_PREFIX); - vty_out(vty, "BGP updates debugging is on for %s\n", buf); + vty_out(vty, "BGP updates debugging is on for %pFX\n", argv_p); } prefix_free(&argv_p); @@ -1458,7 +1447,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi, DEFPY (no_debug_bgp_update_prefix_afi_safi, no_debug_bgp_update_prefix_afi_safi_cmd, - "no debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>", + "no debug bgp updates prefix l2vpn$afi evpn$safi type <<macip|2> mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|<multicast|3> ip <A.B.C.D|X:X::X:X>|<prefix|5> ip <A.B.C.D/M|X:X::X:X/M>>", NO_STR DEBUG_STR BGP_STR @@ -1466,17 +1455,20 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi, "Specify a prefix to debug\n" L2VPN_HELP_STR EVPN_HELP_STR - "Specify EVPN Route type\n" - "MAC-IP (Type-2) route\n" + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR MAC_STR MAC_STR MAC_STR IP_STR "IPv4 address\n" "IPv6 address\n" - "Multicast (Type-3) route\n" + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR IP_STR "IPv4 address\n" "IPv6 address\n" - "Prefix (Type-5) route\n" + EVPN_TYPE_5_HELP_STR + EVPN_TYPE_5_HELP_STR IP_STR "IPv4 prefix\n" "IPv6 prefix\n") @@ -1484,7 +1476,6 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi, struct prefix *argv_p; bool found_prefix = false; int ret = CMD_SUCCESS; - char buf[PREFIX2STR_BUFFER]; argv_p = prefix_new(); @@ -1510,13 +1501,11 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi, } } - prefix2str(argv_p, buf, sizeof(buf)); - if (found_prefix) - vty_out(vty, "BGP updates debugging is off for %s\n", buf); + vty_out(vty, "BGP updates debugging is off for %pFX\n", argv_p); else - vty_out(vty, "BGP updates debugging was not enabled for %s\n", - buf); + vty_out(vty, "BGP updates debugging was not enabled for %pFX\n", + argv_p); prefix_free(&argv_p); @@ -2643,7 +2632,6 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, char *str, int size) { char rd_buf[RD_ADDRSTRLEN]; - char pfx_buf[PREFIX_STRLEN]; char tag_buf[30]; /* ' with addpath ID ' 17 * max strlen of uint32 + 10 @@ -2681,10 +2669,9 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, } if (prd) - snprintf(str, size, "RD %s %s%s%s %s %s", - prefix_rd2str(prd, rd_buf, sizeof(rd_buf)), - prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf, - pathid_buf, afi2str(afi), safi2str(safi)); + snprintfrr(str, size, "RD %s %pFX%s%s %s %s", + prefix_rd2str(prd, rd_buf, sizeof(rd_buf)), pu.p, + tag_buf, pathid_buf, afi2str(afi), safi2str(safi)); else if (safi == SAFI_FLOWSPEC) { char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX]; const struct prefix_fs *fs = pu.fs; @@ -2697,9 +2684,8 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, snprintf(str, size, "FS %s Match{%s}", afi2str(afi), return_string); } else - snprintf(str, size, "%s%s%s %s %s", - prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf, - pathid_buf, afi2str(afi), safi2str(safi)); + snprintfrr(str, size, "%pFX%s%s %s %s", pu.p, tag_buf, + pathid_buf, afi2str(afi), safi2str(safi)); return str; } diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index abd349a188..975bba9314 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -677,11 +677,8 @@ static int bgp_dump_unset(struct bgp_dump *bgp_dump) bgp_dump->fp = NULL; } - /* Removing interval thread. */ - if (bgp_dump->t_interval) { - thread_cancel(bgp_dump->t_interval); - bgp_dump->t_interval = NULL; - } + /* Removing interval event. */ + thread_cancel(&bgp_dump->t_interval); bgp_dump->interval = 0; diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 3a0400a4b3..de3757aebb 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -29,6 +29,8 @@ #include "jhash.h" #include "stream.h" +#include "lib/printfrr.h" + #include "bgpd/bgpd.h" #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_lcommunity.h" @@ -819,8 +821,8 @@ static int ecommunity_rt_soo_str_internal(char *buf, size_t bufsz, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - len = snprintf(buf, bufsz, "%s%s:%u", prefix, inet_ntoa(eip.ip), - eip.val); + len = snprintfrr(buf, bufsz, "%s%pI4:%u", prefix, &eip.ip, + eip.val); } /* consume value */ @@ -1036,6 +1038,27 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) (flags & ECOMMUNITY_EVPN_SUBTYPE_ESI_SA_FLAG) ? "SA":"AA"); + } else if (*pnt + == ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION) { + uint8_t alg; + uint16_t pref; + uint16_t bmap; + + alg = *(pnt + 1); + memcpy(&bmap, pnt + 2, 2); + bmap = ntohs(bmap); + memcpy(&pref, pnt + 5, 2); + pref = ntohs(pref); + + if (bmap) + snprintf( + encbuf, sizeof(encbuf), + "DF: (alg: %u, bmap: 0x%x pref: %u)", + alg, bmap, pref); + else + snprintf(encbuf, sizeof(encbuf), + "DF: (alg: %u, pref: %u)", alg, + pref); } else unk_ecom = 1; } else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) { diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index fe90efe1f7..e9c52287f1 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -73,11 +73,15 @@ #define ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL 0x01 #define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02 #define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC 0x03 +#define ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION 0x06 #define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW 0x0d #define ECOMMUNITY_EVPN_SUBTYPE_ND 0x08 #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01 +/* DF alg bits - only lower 5 bits are applicable */ +#define ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS 0x1f + #define ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG 0x01 #define ECOMMUNITY_EVPN_SUBTYPE_ND_OVERRIDE_FLAG 0x02 #define ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG 0x04 diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 0703853354..67d0a95cb6 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -31,6 +31,8 @@ #include "jhash.h" #include "zclient.h" +#include "lib/printfrr.h" + #include "bgpd/bgp_attr_evpn.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -64,9 +66,10 @@ DEFINE_QOBJ_TYPE(bgp_evpn_es) */ static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn); static void bgp_evpn_update_type2_route_entry(struct bgp *bgp, - struct bgpevpn *vpn, - struct bgp_node *rn, struct bgp_path_info *local_pi, - const char *caller); + struct bgpevpn *vpn, + struct bgp_dest *dest, + struct bgp_path_info *local_pi, + const char *caller); static struct in_addr zero_vtep_ip; /* @@ -545,10 +548,10 @@ static void evpn_convert_nexthop_to_ipv6(struct attr *attr) attr->mp_nexthop_len = IPV6_MAX_BYTELEN; } -struct bgp_node *bgp_global_evpn_node_get( - struct bgp_table *table, afi_t afi, - safi_t safi, const struct prefix_evpn *evp, - struct prefix_rd *prd) +struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table, afi_t afi, + safi_t safi, + const struct prefix_evpn *evp, + struct prefix_rd *prd) { struct prefix_evpn global_p; @@ -562,10 +565,10 @@ struct bgp_node *bgp_global_evpn_node_get( return bgp_afi_node_get(table, afi, safi, (struct prefix *)evp, prd); } -struct bgp_node *bgp_global_evpn_node_lookup( - struct bgp_table *table, afi_t afi, - safi_t safi, const struct prefix_evpn *evp, - struct prefix_rd *prd) +struct bgp_dest *bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi, + safi_t safi, + const struct prefix_evpn *evp, + struct prefix_rd *prd) { struct prefix_evpn global_p; @@ -701,9 +704,9 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, stream_putw_at(s, 0, stream_get_endp(s)); if (bgp_debug_zebra(NULL)) - zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s", + zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %pI4", add ? "ADD" : "DEL", vpn->vni, - inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4)); + &p->prefix.imet_addr.ip.ipaddr_v4); return zclient_send_message(zclient); } @@ -1031,18 +1034,17 @@ static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn, safi_t safi = SAFI_EVPN; if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) { - char prefix_buf[PREFIX_STRLEN]; char esi_buf[ESI_STR_LEN]; char esi_buf2[ESI_STR_LEN]; - struct prefix_evpn *evp = (struct prefix_evpn *)&dest->p; + struct prefix_evpn *evp = + (struct prefix_evpn *)bgp_dest_get_prefix(dest); - zlog_debug("local path deleted %s es %s; new-path-es %s", - prefix2str(evp, - prefix_buf, sizeof(prefix_buf)), - esi_to_str(&old_local->attr->esi, - esi_buf, sizeof(esi_buf)), - new_select ? esi_to_str(&new_select->attr->esi, - esi_buf2, sizeof(esi_buf2)) : ""); + zlog_debug("local path deleted %pFX es %s; new-path-es %s", evp, + esi_to_str(&old_local->attr->esi, esi_buf, + sizeof(esi_buf)), + new_select ? esi_to_str(&new_select->attr->esi, + esi_buf2, sizeof(esi_buf2)) + : ""); } /* Locate route node in the global EVPN routing table. Note that @@ -1309,23 +1311,18 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, attr.nexthop = bgp_vrf->evpn_info->pip_ip; attr.mp_nexthop_global_in = bgp_vrf->evpn_info->pip_ip; } else if (bgp_vrf->evpn_info->pip_ip.s_addr == INADDR_ANY) - if (bgp_debug_zebra(NULL)) { - char buf1[PREFIX_STRLEN]; - - zlog_debug("VRF %s evp %s advertise-pip primary ip is not configured", - vrf_id_to_name(bgp_vrf->vrf_id), - prefix2str(evp, buf1, sizeof(buf1))); - } + if (bgp_debug_zebra(NULL)) + zlog_debug( + "VRF %s evp %pFX advertise-pip primary ip is not configured", + vrf_id_to_name(bgp_vrf->vrf_id), evp); } if (bgp_debug_zebra(NULL)) { char buf[ETHER_ADDR_STRLEN]; - char buf1[PREFIX_STRLEN]; char buf2[INET6_ADDRSTRLEN]; - zlog_debug("VRF %s type-5 route evp %s RMAC %s nexthop %s", - vrf_id_to_name(bgp_vrf->vrf_id), - prefix2str(evp, buf1, sizeof(buf1)), + zlog_debug("VRF %s type-5 route evp %pFX RMAC %s nexthop %s", + vrf_id_to_name(bgp_vrf->vrf_id), evp, prefix_mac2str(&attr.rmac, buf, sizeof(buf)), inet_ntop(AF_INET, &attr.nexthop, buf2, INET_ADDRSTRLEN)); @@ -1359,9 +1356,9 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, } static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, - struct bgp_node *rn, uint32_t loc_seq, uint32_t *max_sync_seq, - bool *active_on_peer, bool *peer_router, - bool *proxy_from_peer) + struct bgp_dest *dest, uint32_t loc_seq, + uint32_t *max_sync_seq, bool *active_on_peer, + bool *peer_router, bool *proxy_from_peer) { struct bgp_path_info *tmp_pi; struct bgp_path_info *second_best_path = NULL; @@ -1372,8 +1369,8 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, /* find the best non-local path. a local path can only be present * as best path */ - for (tmp_pi = bgp_dest_get_bgp_path_info(rn); tmp_pi; - tmp_pi = tmp_pi->next) { + for (tmp_pi = bgp_dest_get_bgp_path_info(dest); tmp_pi; + tmp_pi = tmp_pi->next) { if (tmp_pi->sub_type != BGP_ROUTE_IMPORTED || !CHECK_FLAG(tmp_pi->flags, BGP_PATH_VALID)) continue; @@ -1420,11 +1417,13 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, * VPN route table. It will take precedence over all sync paths. */ static void update_evpn_route_entry_sync_info(struct bgp *bgp, - struct bgp_node *rn, struct attr *attr, uint32_t loc_seq, - bool setup_sync) + struct bgp_dest *dest, + struct attr *attr, + uint32_t loc_seq, bool setup_sync) { esi_t *esi; - struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p; + struct prefix_evpn *evp = + (struct prefix_evpn *)bgp_dest_get_prefix(dest); if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE) return; @@ -1437,9 +1436,9 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp, bool peer_router = false; bool proxy_from_peer = false; - bgp_evpn_get_sync_info(bgp, esi, rn, loc_seq, - &max_sync_seq, &active_on_peer, - &peer_router, &proxy_from_peer); + bgp_evpn_get_sync_info(bgp, esi, dest, loc_seq, + &max_sync_seq, &active_on_peer, + &peer_router, &proxy_from_peer); attr->mm_sync_seqnum = max_sync_seq; if (active_on_peer) attr->es_flags |= ATTR_ES_PEER_ACTIVE; @@ -1455,21 +1454,23 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp, attr->es_flags &= ~ATTR_ES_PEER_ROUTER; if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) { - char prefix_buf[PREFIX_STRLEN]; char esi_buf[ESI_STR_LEN]; - zlog_debug("setup sync info for %s es %s max_seq %d %s%s%s", - prefix2str(evp, prefix_buf, - sizeof(prefix_buf)), + zlog_debug( + "setup sync info for %pFX es %s max_seq %d %s%s%s", + evp, esi_to_str(esi, esi_buf, - sizeof(esi_buf)), + sizeof(esi_buf)), max_sync_seq, - (attr->es_flags & ATTR_ES_PEER_ACTIVE) ? - "peer-active " : "", - (attr->es_flags & ATTR_ES_PEER_PROXY) ? - "peer-proxy " : "", - (attr->es_flags & ATTR_ES_PEER_ROUTER) ? - "peer-router " : ""); + (attr->es_flags & ATTR_ES_PEER_ACTIVE) + ? "peer-active " + : "", + (attr->es_flags & ATTR_ES_PEER_PROXY) + ? "peer-proxy " + : "", + (attr->es_flags & ATTR_ES_PEER_ROUTER) + ? "peer-router " + : ""); } } } else { @@ -1660,7 +1661,7 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp, { /* local path was not picked as the winner; kick it out */ if (bgp_debug_zebra(NULL)) - zlog_debug("evicting local evpn prefix %pRN as remote won", + zlog_debug("evicting local evpn prefix %pBD as remote won", dest); evpn_delete_old_local_route(bgp, vpn, dest, local_pi, NULL); @@ -1715,18 +1716,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, if (bgp_debug_zebra(NULL)) { char buf[ETHER_ADDR_STRLEN]; - char buf1[PREFIX_STRLEN]; char buf3[ESI_STR_LEN]; - zlog_debug("VRF %s vni %u type-2 route evp %s RMAC %s nexthop %s esi %s", - vpn->bgp_vrf ? - vrf_id_to_name(vpn->bgp_vrf->vrf_id) : " ", - vpn->vni, - prefix2str(p, buf1, sizeof(buf1)), - prefix_mac2str(&attr.rmac, buf, - sizeof(buf)), - inet_ntoa(attr.mp_nexthop_global_in), - esi_to_str(esi, buf3, sizeof(buf3))); + zlog_debug( + "VRF %s vni %u type-2 route evp %pFX RMAC %s nexthop %pI4 esi %s", + vpn->bgp_vrf ? vrf_id_to_name(vpn->bgp_vrf->vrf_id) + : " ", + vpn->vni, p, + prefix_mac2str(&attr.rmac, buf, sizeof(buf)), + &attr.mp_nexthop_global_in, + esi_to_str(esi, buf3, sizeof(buf3))); } /* router mac is only needed for type-2 routes here. */ if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { @@ -1937,8 +1936,10 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, } static void bgp_evpn_update_type2_route_entry(struct bgp *bgp, - struct bgpevpn *vpn, struct bgp_node *rn, - struct bgp_path_info *local_pi, const char *caller) + struct bgpevpn *vpn, + struct bgp_dest *dest, + struct bgp_path_info *local_pi, + const char *caller) { afi_t afi = AFI_L2VPN; safi_t safi = SAFI_EVPN; @@ -1947,9 +1948,10 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct attr *attr_new; uint32_t seq; int add_l3_ecomm = 0; - struct bgp_node *global_rn; + struct bgp_dest *global_dest; struct bgp_path_info *global_pi; - struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p; + struct prefix_evpn *evp = + (struct prefix_evpn *)bgp_dest_get_prefix(dest); int route_change; bool old_is_sync = false; @@ -1993,24 +1995,23 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp, if (bgp_debug_zebra(NULL)) { char buf[ETHER_ADDR_STRLEN]; - char buf1[PREFIX_STRLEN]; char buf3[ESI_STR_LEN]; - zlog_debug("VRF %s vni %u evp %s RMAC %s nexthop %s esi %s esf 0x%x from %s", - vpn->bgp_vrf ? - vrf_id_to_name(vpn->bgp_vrf->vrf_id) : " ", - vpn->vni, - prefix2str(evp, buf1, sizeof(buf1)), - prefix_mac2str(&attr.rmac, buf, sizeof(buf)), - inet_ntoa(attr.mp_nexthop_global_in), - esi_to_str(&attr.esi, buf3, sizeof(buf3)), - attr.es_flags, caller); + zlog_debug( + "VRF %s vni %u evp %pFX RMAC %s nexthop %pI4 esi %s esf 0x%x from %s", + vpn->bgp_vrf ? vrf_id_to_name(vpn->bgp_vrf->vrf_id) + : " ", + vpn->vni, evp, + prefix_mac2str(&attr.rmac, buf, sizeof(buf)), + &attr.mp_nexthop_global_in, + esi_to_str(&attr.esi, buf3, sizeof(buf3)), + attr.es_flags, caller); } /* Update the route entry. */ - route_change = update_evpn_route_entry(bgp, vpn, afi, safi, - rn, &attr, 0, &pi, 0, seq, - true /* setup_sync */, &old_is_sync); + route_change = update_evpn_route_entry( + bgp, vpn, afi, safi, dest, &attr, 0, &pi, 0, seq, + true /* setup_sync */, &old_is_sync); assert(pi); attr_new = pi->attr; @@ -2026,14 +2027,14 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp, * advertised to peers; otherwise, ensure it is evicted and * (re)install the remote route into zebra. */ - evpn_route_select_install(bgp, vpn, rn); + evpn_route_select_install(bgp, vpn, dest); if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { route_change = 0; } else { if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) { route_change = 0; - evpn_cleanup_local_non_best_route(bgp, vpn, rn, pi); + evpn_cleanup_local_non_best_route(bgp, vpn, dest, pi); } else { bool new_is_sync; @@ -2056,17 +2057,17 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp, if (route_change) { /* Update route in global routing table. */ - global_rn = bgp_global_evpn_node_get(bgp->rib[afi][safi], - afi, safi, evp, &vpn->prd); - assert(global_rn); - update_evpn_route_entry(bgp, vpn, afi, safi, global_rn, - attr_new, 0, &global_pi, 0, - mac_mobility_seqnum(attr_new), - false /* setup_sync */, NULL /* old_is_sync */); + global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, + safi, evp, &vpn->prd); + assert(global_dest); + update_evpn_route_entry( + bgp, vpn, afi, safi, global_dest, attr_new, 0, + &global_pi, 0, mac_mobility_seqnum(attr_new), + false /* setup_sync */, NULL /* old_is_sync */); /* Schedule for processing and unlock node. */ - bgp_process(bgp, global_rn, afi, safi); - bgp_dest_unlock_node(global_rn); + bgp_process(bgp, global_dest, afi, safi); + bgp_dest_unlock_node(global_dest); } /* Unintern temporary. */ @@ -2383,19 +2384,16 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, struct prefix *pp = &p; afi_t afi = 0; safi_t safi = 0; - char buf[PREFIX_STRLEN]; bool new_pi = false; memset(pp, 0, sizeof(struct prefix)); ip_prefix_from_evpn_prefix(evp, pp); - if (bgp_debug_zebra(NULL)) { + if (bgp_debug_zebra(NULL)) zlog_debug( - "vrf %s: import evpn prefix %s parent %p flags 0x%x", - vrf_id_to_name(bgp_vrf->vrf_id), - prefix2str(evp, buf, sizeof(buf)), - parent_pi, parent_pi->flags); - } + "vrf %s: import evpn prefix %pFX parent %p flags 0x%x", + vrf_id_to_name(bgp_vrf->vrf_id), evp, parent_pi, + parent_pi->flags); /* Create (or fetch) route within the VRF. */ /* NOTE: There is no RD here. */ @@ -2474,11 +2472,10 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, bgp_dest_unlock_node(dest); if (bgp_debug_zebra(NULL)) - zlog_debug( - "... %s pi dest %p (l %d) pi %p (l %d, f 0x%x)", - new_pi ? "new" : "update", - dest, bgp_dest_to_rnode(dest)->lock, - pi, pi->lock, pi->flags); + zlog_debug("... %s pi dest %p (l %d) pi %p (l %d, f 0x%x)", + new_pi ? "new" : "update", dest, + bgp_dest_get_lock_count(dest), pi, pi->lock, + pi->flags); return ret; } @@ -2575,18 +2572,15 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, struct prefix *pp = &p; afi_t afi = 0; safi_t safi = 0; - char buf[PREFIX_STRLEN]; memset(pp, 0, sizeof(struct prefix)); ip_prefix_from_evpn_prefix(evp, pp); - if (bgp_debug_zebra(NULL)) { + if (bgp_debug_zebra(NULL)) zlog_debug( - "vrf %s: unimport evpn prefix %s parent %p flags 0x%x", - vrf_id_to_name(bgp_vrf->vrf_id), - prefix2str(evp, buf, sizeof(buf)), - parent_pi, parent_pi->flags); - } + "vrf %s: unimport evpn prefix %pFX parent %p flags 0x%x", + vrf_id_to_name(bgp_vrf->vrf_id), evp, parent_pi, + parent_pi->flags); /* Locate route within the VRF. */ /* NOTE: There is no RD here. */ @@ -2613,10 +2607,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, return 0; if (bgp_debug_zebra(NULL)) - zlog_debug( - "... delete dest %p (l %d) pi %p (l %d, f 0x%x)", - dest, bgp_dest_to_rnode(dest)->lock, - pi, pi->lock, pi->flags); + zlog_debug("... delete dest %p (l %d) pi %p (l %d, f 0x%x)", + dest, bgp_dest_get_lock_count(dest), pi, pi->lock, + pi->flags); /* Process for route leaking. */ vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp_vrf, pi); @@ -2844,15 +2837,13 @@ static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf, */ if (memcmp(&bgp_vrf->rmac, &pi->attr->rmac, ETH_ALEN) == 0) { if (bgp_debug_update(pi->peer, NULL, NULL, 1)) { - char buf1[PREFIX_STRLEN]; char attr_str[BUFSIZ] = {0}; bgp_dump_attr(pi->attr, attr_str, sizeof(attr_str)); - zlog_debug("%s: bgp %u prefix %s with attr %s - DENIED due to self mac", - __func__, bgp_vrf->vrf_id, - prefix2str(evp, buf1, sizeof(buf1)), - attr_str); + zlog_debug( + "%s: bgp %u prefix %pFX with attr %s - DENIED due to self mac", + __func__, bgp_vrf->vrf_id, evp, attr_str); } return 1; @@ -2873,7 +2864,6 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) struct bgp_table *table; struct bgp_path_info *pi; int ret; - char buf[PREFIX_STRLEN]; struct bgp *bgp_evpn = NULL; afi = AFI_L2VPN; @@ -2934,11 +2924,10 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) if (ret) { flog_err( EC_BGP_EVPN_FAIL, - "Failed to %s EVPN %s route in VRF %s", + "Failed to %s EVPN %pFX route in VRF %s", install ? "install" : "uninstall", - prefix2str(evp, buf, - sizeof(buf)), + evp, vrf_id_to_name( bgp_vrf->vrf_id)); return ret; @@ -3107,7 +3096,6 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, struct bgp_path_info *pi, struct list *vrfs, int install) { - char buf[PREFIX2STR_BUFFER]; struct bgp *bgp_vrf; struct listnode *node, *nnode; @@ -3133,10 +3121,9 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, if (ret) { flog_err(EC_BGP_EVPN_FAIL, - "%u: Failed to %s prefix %s in VRF %s", + "%u: Failed to %s prefix %pFX in VRF %s", bgp_def->vrf_id, - install ? "install" : "uninstall", - prefix2str(evp, buf, sizeof(buf)), + install ? "install" : "uninstall", evp, vrf_id_to_name(bgp_vrf->vrf_id)); return ret; } @@ -4094,17 +4081,14 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, const struct prefix *p, { int ret = 0; struct prefix_evpn evp; - char buf[PREFIX_STRLEN]; build_type5_prefix_from_ip_prefix(&evp, p); ret = delete_evpn_type5_route(bgp_vrf, &evp); - if (ret) { + if (ret) flog_err( EC_BGP_EVPN_ROUTE_DELETE, - "%u failed to delete type-5 route for prefix %s in vrf %s", - bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)), - vrf_id_to_name(bgp_vrf->vrf_id)); - } + "%u failed to delete type-5 route for prefix %pFX in vrf %s", + bgp_vrf->vrf_id, p, vrf_id_to_name(bgp_vrf->vrf_id)); } /* withdraw all type-5 routes for an address family */ @@ -4166,14 +4150,13 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, const struct prefix *p, { int ret = 0; struct prefix_evpn evp; - char buf[PREFIX_STRLEN]; build_type5_prefix_from_ip_prefix(&evp, p); ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr); if (ret) flog_err(EC_BGP_EVPN_ROUTE_CREATE, - "%u: Failed to create type-5 route for prefix %s", - bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf))); + "%u: Failed to create type-5 route for prefix %pFX", + bgp_vrf->vrf_id, p); } /* Inject all prefixes of a particular address-family (currently, IPv4 or @@ -4594,81 +4577,6 @@ void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json) } /* - * Function to convert evpn route to string. - * NOTE: We don't use prefix2str as the output here is a bit different. - */ -char *bgp_evpn_route2str(const struct prefix_evpn *p, char *buf, int len) -{ - char buf1[ETHER_ADDR_STRLEN]; - char buf2[PREFIX2STR_BUFFER]; - char buf3[ESI_STR_LEN]; - - if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) { - snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type, - p->prefix.imet_addr.eth_tag, - is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN - : IPV6_MAX_BITLEN, - inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4)); - } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { - if (is_evpn_prefix_ipaddr_none(p)) - snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", - p->prefix.route_type, - p->prefix.macip_addr.eth_tag, - 8 * ETH_ALEN, - prefix_mac2str(&p->prefix.macip_addr.mac, buf1, - sizeof(buf1))); - else { - uint8_t family; - - family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET - : AF_INET6; - snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]", - p->prefix.route_type, - p->prefix.macip_addr.eth_tag, - 8 * ETH_ALEN, - prefix_mac2str(&p->prefix.macip_addr.mac, buf1, - sizeof(buf1)), - family == AF_INET ? IPV4_MAX_BITLEN - : IPV6_MAX_BITLEN, - inet_ntop(family, - &p->prefix.macip_addr.ip.ip.addr, - buf2, - PREFIX2STR_BUFFER)); - } - } else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) { - snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", - p->prefix.route_type, - p->prefix.prefix_addr.eth_tag, - p->prefix.prefix_addr.ip_prefix_length, - is_evpn_prefix_ipaddr_v4(p) - ? inet_ntoa(p->prefix.prefix_addr.ip.ipaddr_v4) - : inet6_ntoa(p->prefix.prefix_addr.ip.ipaddr_v6)); - } else if (p->prefix.route_type == BGP_EVPN_ES_ROUTE) { - snprintf(buf, len, "[%d]:[%s]:[%d]:[%s]", - p->prefix.route_type, - esi_to_str(&p->prefix.es_addr.esi, buf3, sizeof(buf3)), - is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN - : IPV6_MAX_BITLEN, - inet_ntoa(p->prefix.es_addr.ip.ipaddr_v4)); - } else if (p->prefix.route_type == BGP_EVPN_AD_ROUTE) { - snprintf(buf, len, "[%d]:[%u]:[%s]:[%d]:[%s]", - p->prefix.route_type, - p->prefix.ead_addr.eth_tag, - esi_to_str(&p->prefix.ead_addr.esi, - buf3, sizeof(buf3)), - is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN - : IPV6_MAX_BITLEN, - inet_ntoa(p->prefix.ead_addr.ip.ipaddr_v4)); - } else { - /* For EVPN route types not supported yet. */ - snprintf(buf, len, "(unsupported route type %d)", - p->prefix.route_type); - } - - return (buf); -} - -/* * Encode EVPN prefix in Update (MP_REACH) */ void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p, @@ -5035,8 +4943,7 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn) vpn->prd.family = AF_UNSPEC; vpn->prd.prefixlen = 64; - snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id), - vpn->rd_id); + snprintfrr(buf, sizeof(buf), "%pI4:%hu", &bgp->router_id, vpn->rd_id); (void)str2prefix_rd(buf, &vpn->prd); UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD); } @@ -5209,7 +5116,7 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp) sizeof(attr_str)); zlog_debug( - "%u: prefix %pRN with attr %s - DENIED due to martian or self nexthop", + "%u: prefix %pBD with attr %s - DENIED due to martian or self nexthop", bgp->vrf_id, dest, attr_str); } diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 8535f1fa31..ba43191ebf 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -154,8 +154,6 @@ extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf); extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw); extern char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels, char *buf, int len); -extern char *bgp_evpn_route2str(const struct prefix_evpn *p, char *buf, - int len); extern void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json); extern void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p, const struct prefix_rd *prd, diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index 934c22d168..021e811147 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -29,6 +29,8 @@ #include "jhash.h" #include "zclient.h" +#include "lib/printfrr.h" + #include "bgpd/bgp_attr_evpn.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -52,7 +54,10 @@ static void bgp_evpn_local_es_down(struct bgp *bgp, static void bgp_evpn_local_type1_evi_route_del(struct bgp *bgp, struct bgp_evpn_es *es); static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, - struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr); + struct bgp_evpn_es *es, + struct in_addr vtep_ip, + bool esr, uint8_t df_alg, + uint16_t df_pref); static void bgp_evpn_es_vtep_del(struct bgp *bgp, struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr); static void bgp_evpn_es_cons_checks_pend_add(struct bgp_evpn_es *es); @@ -82,8 +87,8 @@ esi_t zero_esi_buf, *zero_esi = &zero_esi_buf; * installed in the ES's routing table. */ static int bgp_evpn_es_route_select_install(struct bgp *bgp, - struct bgp_evpn_es *es, - struct bgp_node *rn) + struct bgp_evpn_es *es, + struct bgp_dest *dest) { int ret = 0; afi_t afi = AFI_L2VPN; @@ -93,8 +98,8 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, struct bgp_path_info_pair old_and_new; /* Compute the best path. */ - bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], - &old_and_new, afi, safi); + bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new, + afi, safi); old_select = old_and_new.old; new_select = old_and_new.new; @@ -103,42 +108,45 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, * updated */ if (old_select && old_select == new_select - && old_select->type == ZEBRA_ROUTE_BGP - && old_select->sub_type == BGP_ROUTE_IMPORTED - && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR) - && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) - && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { + && old_select->type == ZEBRA_ROUTE_BGP + && old_select->sub_type == BGP_ROUTE_IMPORTED + && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR) + && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) + && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { if (bgp_zebra_has_route_changed(old_select)) { - bgp_evpn_es_vtep_add(bgp, es, - old_select->attr->nexthop, - true /*esr*/); + bgp_evpn_es_vtep_add(bgp, es, old_select->attr->nexthop, + true /*esr*/, + old_select->attr->df_alg, + old_select->attr->df_pref); } UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG); - bgp_zebra_clear_route_change_flags(rn); + bgp_zebra_clear_route_change_flags(dest); return ret; } /* If the user did a "clear" this flag will be set */ - UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR); + UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR); /* bestpath has changed; update relevant fields and install or uninstall * into the zebra RIB. */ if (old_select || new_select) - bgp_bump_version(rn); + bgp_bump_version(dest); if (old_select) - bgp_path_info_unset_flag(rn, old_select, BGP_PATH_SELECTED); + bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED); if (new_select) { - bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED); - bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED); + bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED); + bgp_path_info_unset_flag(dest, new_select, + BGP_PATH_ATTR_CHANGED); UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG); } if (new_select && new_select->type == ZEBRA_ROUTE_BGP && new_select->sub_type == BGP_ROUTE_IMPORTED) { - bgp_evpn_es_vtep_add(bgp, es, - new_select->attr->nexthop, true /*esr */); + bgp_evpn_es_vtep_add(bgp, es, new_select->attr->nexthop, + true /*esr */, new_select->attr->df_alg, + new_select->attr->df_pref); } else { if (old_select && old_select->type == ZEBRA_ROUTE_BGP && old_select->sub_type == BGP_ROUTE_IMPORTED) @@ -148,11 +156,11 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, } /* Clear any route change flags. */ - bgp_zebra_clear_route_change_flags(rn); + bgp_zebra_clear_route_change_flags(dest); /* Reap old select bgp_path_info, if it has been removed */ if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED)) - bgp_path_info_reap(rn, old_select); + bgp_path_info_reap(dest, old_select); return ret; } @@ -163,17 +171,17 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, struct bgp_path_info *parent_pi) { int ret = 0; - struct bgp_node *rn = NULL; + struct bgp_dest *dest = NULL; struct bgp_path_info *pi = NULL; struct attr *attr_new = NULL; /* Create (or fetch) route within the VNI. * NOTE: There is no RD here. */ - rn = bgp_node_get(es->route_table, (struct prefix *)p); + dest = bgp_node_get(es->route_table, (struct prefix *)p); /* Check if route entry is already present. */ - for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->extra && (struct bgp_path_info *)pi->extra->parent == parent_pi) @@ -185,16 +193,16 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, /* Create new route with its attribute. */ pi = info_make(parent_pi->type, BGP_ROUTE_IMPORTED, 0, - parent_pi->peer, attr_new, rn); + parent_pi->peer, attr_new, dest); SET_FLAG(pi->flags, BGP_PATH_VALID); bgp_path_info_extra_get(pi); pi->extra->parent = bgp_path_info_lock(parent_pi); - bgp_dest_lock_node((struct bgp_node *)parent_pi->net); - bgp_path_info_add(rn, pi); + bgp_dest_lock_node((struct bgp_dest *)parent_pi->net); + bgp_path_info_add(dest, pi); } else { if (attrhash_cmp(pi->attr, parent_pi->attr) && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { - bgp_dest_unlock_node(rn); + bgp_dest_unlock_node(dest); return 0; } /* The attribute has changed. */ @@ -203,7 +211,7 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, /* Restore route, if needed. */ if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) - bgp_path_info_restore(rn, pi); + bgp_path_info_restore(dest, pi); /* Mark if nexthop has changed. */ if (!IPV4_ADDR_SAME(&pi->attr->nexthop, &attr_new->nexthop)) @@ -216,9 +224,9 @@ static int bgp_evpn_es_route_install(struct bgp *bgp, } /* Perform route selection and update zebra, if required. */ - ret = bgp_evpn_es_route_select_install(bgp, es, rn); + ret = bgp_evpn_es_route_select_install(bgp, es, dest); - bgp_dest_unlock_node(rn); + bgp_dest_unlock_node(dest); return ret; } @@ -228,7 +236,7 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, struct prefix_evpn *p, struct bgp_path_info *parent_pi) { int ret; - struct bgp_node *rn; + struct bgp_dest *dest; struct bgp_path_info *pi; if (!es->route_table) @@ -237,12 +245,12 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, /* Locate route within the ESI. * NOTE: There is no RD here. */ - rn = bgp_node_lookup(es->route_table, (struct prefix *)p); - if (!rn) + dest = bgp_node_lookup(es->route_table, (struct prefix *)p); + if (!dest) return 0; /* Find matching route entry. */ - for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->extra && (struct bgp_path_info *)pi->extra->parent == parent_pi) @@ -252,13 +260,13 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, return 0; /* Mark entry for deletion */ - bgp_path_info_delete(rn, pi); + bgp_path_info_delete(dest, pi); /* Perform route selection and update zebra, if required. */ - ret = bgp_evpn_es_route_select_install(bgp, es, rn); + ret = bgp_evpn_es_route_select_install(bgp, es, dest); /* Unlock route node. */ - bgp_dest_unlock_node(rn); + bgp_dest_unlock_node(dest); return ret; } @@ -293,7 +301,7 @@ int bgp_evpn_es_route_install_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, */ static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es) { - struct bgp_node *rn; + struct bgp_dest *dest; struct bgp_path_info *pi, *nextpi; /* de-activate the ES */ @@ -301,13 +309,12 @@ static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es) bgp_evpn_local_type1_evi_route_del(bgp, es); /* Walk this ES's routing table and delete all routes. */ - for (rn = bgp_table_top(es->route_table); rn; - rn = bgp_route_next(rn)) { - for (pi = bgp_dest_get_bgp_path_info(rn); - (pi != NULL) && (nextpi = pi->next, 1); - pi = nextpi) { - bgp_path_info_delete(rn, pi); - bgp_path_info_reap(rn, pi); + for (dest = bgp_table_top(es->route_table); dest; + dest = bgp_route_next(dest)) { + for (pi = bgp_dest_get_bgp_path_info(dest); + (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) { + bgp_path_info_delete(dest, pi); + bgp_path_info_reap(dest, pi); } } } @@ -327,10 +334,11 @@ static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es) * Note: vpn is applicable only to EAD-EVI routes (NULL for EAD-ES and * ESR). */ -static int bgp_evpn_mh_route_update(struct bgp *bgp, - struct bgp_evpn_es *es, struct bgpevpn *vpn, afi_t afi, - safi_t safi, struct bgp_node *rn, struct attr *attr, - int add, struct bgp_path_info **ri, int *route_changed) +static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, + struct bgpevpn *vpn, afi_t afi, safi_t safi, + struct bgp_dest *dest, struct attr *attr, + int add, struct bgp_path_info **ri, + int *route_changed) { struct bgp_path_info *tmp_pi = NULL; struct bgp_path_info *local_pi = NULL; /* local route entry if any */ @@ -339,11 +347,11 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, struct prefix_evpn *evp; *ri = NULL; - evp = (struct prefix_evpn *)&rn->p; + evp = (struct prefix_evpn *)bgp_dest_get_prefix(dest); *route_changed = 1; /* locate the local and remote entries if any */ - for (tmp_pi = bgp_dest_get_bgp_path_info(rn); tmp_pi; + for (tmp_pi = bgp_dest_get_bgp_path_info(dest); tmp_pi; tmp_pi = tmp_pi->next) { if (tmp_pi->peer == bgp->peer_self && tmp_pi->type == ZEBRA_ROUTE_BGP @@ -361,10 +369,9 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, */ if (remote_pi) { flog_err( - EC_BGP_ES_INVALID, - "%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote", - bgp->vrf_id, es->esi_str, - inet_ntoa(es->originator_ip)); + EC_BGP_ES_INVALID, + "%u ERROR: local es route for ESI: %s Vtep %pI4 also learnt from remote", + bgp->vrf_id, es->esi_str, &es->originator_ip); return -1; } @@ -379,7 +386,7 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, /* Create new route with its attribute. */ tmp_pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, - bgp->peer_self, attr_new, rn); + bgp->peer_self, attr_new, dest); SET_FLAG(tmp_pi->flags, BGP_PATH_VALID); if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE) { @@ -392,7 +399,7 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, } /* add the newly created path to the route-node */ - bgp_path_info_add(rn, tmp_pi); + bgp_path_info_add(dest, tmp_pi); } else { tmp_pi = local_pi; if (attrhash_cmp(tmp_pi->attr, attr) @@ -403,12 +410,12 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, * Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(attr); - bgp_path_info_set_flag(rn, tmp_pi, - BGP_PATH_ATTR_CHANGED); + bgp_path_info_set_flag(dest, tmp_pi, + BGP_PATH_ATTR_CHANGED); /* Restore route, if needed. */ if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED)) - bgp_path_info_restore(rn, tmp_pi); + bgp_path_info_restore(dest, tmp_pi); /* Unintern existing, set to new. */ bgp_attr_unintern(&tmp_pi->attr); @@ -419,13 +426,13 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, if (*route_changed) { if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) - zlog_debug("local ES %s vni %u route-type %s nexthop %s updated", - es->esi_str, - vpn ? vpn->vni : 0, - evp->prefix.route_type == - BGP_EVPN_ES_ROUTE ? "esr" : - (vpn ? "ead-evi" : "ead-es"), - inet_ntoa(attr->mp_nexthop_global_in)); + zlog_debug( + "local ES %s vni %u route-type %s nexthop %pI4 updated", + es->esi_str, vpn ? vpn->vni : 0, + evp->prefix.route_type == BGP_EVPN_ES_ROUTE + ? "esr" + : (vpn ? "ead-evi" : "ead-es"), + &attr->mp_nexthop_global_in); } /* Return back the route entry. */ @@ -444,8 +451,8 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es, afi_t afi = AFI_L2VPN; safi_t safi = SAFI_EVPN; struct bgp_path_info *pi; - struct bgp_node *rn = NULL; /* rn in esi table */ - struct bgp_node *global_rn = NULL; /* rn in global table */ + struct bgp_dest *dest = NULL; /* dest in esi table */ + struct bgp_dest *global_dest = NULL; /* dest in global table */ struct bgp_table *rt_table; struct prefix_rd *prd; @@ -461,51 +468,55 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es, * If it doesn't exist, ther is nothing to do. * Note: there is no RD here. */ - rn = bgp_node_lookup(rt_table, (struct prefix *)p); - if (!rn) + dest = bgp_node_lookup(rt_table, (struct prefix *)p); + if (!dest) return 0; if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) - zlog_debug("local ES %s vni %u route-type %s nexthop %s delete", - es->esi_str, - vpn ? vpn->vni : 0, - p->prefix.route_type == BGP_EVPN_ES_ROUTE ? - "esr" : (vpn ? "ead-evi" : "ead-es"), - inet_ntoa(es->originator_ip)); + zlog_debug( + "local ES %s vni %u route-type %s nexthop %pI4 delete", + es->esi_str, vpn ? vpn->vni : 0, + p->prefix.route_type == BGP_EVPN_ES_ROUTE + ? "esr" + : (vpn ? "ead-evi" : "ead-es"), + &es->originator_ip); /* Next, locate route node in the global EVPN routing table. * Note that this table is a 2-level tree (RD-level + Prefix-level) */ - global_rn = bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi, - (const struct prefix_evpn *)p, prd); - if (global_rn) { + global_dest = + bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi, + (const struct prefix_evpn *)p, prd); + if (global_dest) { /* Delete route entry in the global EVPN table. */ - delete_evpn_route_entry(bgp, afi, safi, global_rn, &pi); + delete_evpn_route_entry(bgp, afi, safi, global_dest, &pi); /* Schedule for processing - withdraws to peers happen from * this table. */ if (pi) - bgp_process(bgp, global_rn, afi, safi); - bgp_dest_unlock_node(global_rn); + bgp_process(bgp, global_dest, afi, safi); + bgp_dest_unlock_node(global_dest); } /* * Delete route entry in the ESI or VNI routing table. * This can just be removed. */ - delete_evpn_route_entry(bgp, afi, safi, rn, &pi); + delete_evpn_route_entry(bgp, afi, safi, dest, &pi); if (pi) - bgp_path_info_reap(rn, pi); - bgp_dest_unlock_node(rn); + bgp_path_info_reap(dest, pi); + bgp_dest_unlock_node(dest); return 0; } /***************************************************************************** * Ethernet Segment (Type-4) Routes - * ESRs are used for BUM handling. XXX - BUM support is planned for phase-2 i.e. - * this code is just a place holder for now + * ESRs are used for DF election. Currently service-carving described in + * RFC 7432 is NOT supported. Instead preference based DF election is + * used by default. + * Reference: draft-ietf-bess-evpn-pref-df */ /* Build extended community for EVPN ES (type-4) route */ static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es, @@ -513,8 +524,10 @@ static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es, { struct ecommunity ecom_encap; struct ecommunity ecom_es_rt; + struct ecommunity ecom_df; struct ecommunity_val eval; struct ecommunity_val eval_es_rt; + struct ecommunity_val eval_df; bgp_encap_types tnl_type; struct ethaddr mac; @@ -538,6 +551,13 @@ static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es, attr->ecommunity = ecommunity_merge(attr->ecommunity, &ecom_es_rt); + /* DF election extended community */ + memset(&ecom_df, 0, sizeof(ecom_df)); + encode_df_elect_extcomm(&eval_df, es->df_pref); + ecom_df.size = 1; + ecom_df.val = (uint8_t *)eval_df.val; + attr->ecommunity = ecommunity_merge(attr->ecommunity, &ecom_df); + attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); } @@ -551,7 +571,7 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp, safi_t safi = SAFI_EVPN; struct attr attr; struct attr *attr_new = NULL; - struct bgp_node *rn = NULL; + struct bgp_dest *dest = NULL; struct bgp_path_info *pi = NULL; memset(&attr, 0, sizeof(struct attr)); @@ -567,17 +587,16 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp, /* First, create (or fetch) route node within the ESI. */ /* NOTE: There is no RD here. */ - rn = bgp_node_get(es->route_table, (struct prefix *)p); + dest = bgp_node_get(es->route_table, (struct prefix *)p); /* Create or update route entry. */ - ret = bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi, - rn, &attr, 1, &pi, &route_changed); - if (ret != 0) { - flog_err(EC_BGP_ES_INVALID, - "%u ERROR: Failed to updated ES route ESI: %s VTEP %s", - bgp->vrf_id, es->esi_str, - inet_ntoa(es->originator_ip)); - } + ret = bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi, dest, &attr, 1, + &pi, &route_changed); + if (ret != 0) + flog_err( + EC_BGP_ES_INVALID, + "%u ERROR: Failed to updated ES route ESI: %s VTEP %pI4", + bgp->vrf_id, es->esi_str, &es->originator_ip); assert(pi); attr_new = pi->attr; @@ -586,8 +605,8 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp, * this is just to set the flags correctly * as local route in the ES always wins. */ - bgp_evpn_es_route_select_install(bgp, es, rn); - bgp_dest_unlock_node(rn); + bgp_evpn_es_route_select_install(bgp, es, dest); + bgp_dest_unlock_node(dest); /* If this is a new route or some attribute has changed, export the * route to the global table. The route will be advertised to peers @@ -597,14 +616,15 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp, if (route_changed) { struct bgp_path_info *global_pi; - rn = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi, - p, &es->prd); - bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi, - rn, attr_new, 1, &global_pi, &route_changed); + dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi, + p, &es->prd); + bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi, dest, + attr_new, 1, &global_pi, + &route_changed); /* Schedule for processing and unlock node. */ - bgp_process(bgp, rn, afi, safi); - bgp_dest_unlock_node(rn); + bgp_process(bgp, dest, afi, safi); + bgp_dest_unlock_node(dest); } /* Unintern temporary. */ @@ -694,8 +714,7 @@ static int bgp_evpn_type4_remote_routes_import(struct bgp *bgp, int ret; afi_t afi; safi_t safi; - char buf[PREFIX_STRLEN]; - struct bgp_node *rd_rn, *rn; + struct bgp_dest *rd_dest, *dest; struct bgp_table *table; struct bgp_path_info *pi; @@ -705,17 +724,19 @@ static int bgp_evpn_type4_remote_routes_import(struct bgp *bgp, /* Walk entire global routing table and evaluate routes which could be * imported into this Ethernet Segment. */ - for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn; - rd_rn = bgp_route_next(rd_rn)) { - table = bgp_dest_get_bgp_table_info(rd_rn); + for (rd_dest = bgp_table_top(bgp->rib[afi][safi]); rd_dest; + rd_dest = bgp_route_next(rd_dest)) { + table = bgp_dest_get_bgp_table_info(rd_dest); if (!table) continue; - for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { - struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p; + for (dest = bgp_table_top(table); dest; + dest = bgp_route_next(dest)) { + struct prefix_evpn *evp = + (struct prefix_evpn *)bgp_dest_get_prefix(dest); - for (pi = bgp_dest_get_bgp_path_info(rn); pi; - pi = pi->next) { + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { /* * Consider "valid" remote routes applicable for * this ES. @@ -737,13 +758,11 @@ static int bgp_evpn_type4_remote_routes_import(struct bgp *bgp, if (ret) { flog_err( - EC_BGP_EVPN_FAIL, - "Failed to %s EVPN %s route in ESI %s", - install ? "install" + EC_BGP_EVPN_FAIL, + "Failed to %s EVPN %pFX route in ESI %s", + install ? "install" : "uninstall", - prefix2str(evp, buf, - sizeof(buf)), - es->esi_str); + evp, es->esi_str); return ret; } } @@ -845,7 +864,7 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, safi_t safi = SAFI_EVPN; struct attr attr; struct attr *attr_new = NULL; - struct bgp_node *rn = NULL; + struct bgp_dest *dest = NULL; struct bgp_path_info *pi = NULL; int route_changed = 0; struct prefix_rd *global_rd; @@ -867,17 +886,17 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, bgp_evpn_type1_evi_route_extcomm_build(es, vpn, &attr); /* First, create (or fetch) route node within the VNI. */ - rn = bgp_node_get(vpn->route_table, (struct prefix *)p); + dest = bgp_node_get(vpn->route_table, (struct prefix *)p); /* Create or update route entry. */ - ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, - rn, &attr, 1, &pi, &route_changed); - if (ret != 0) { - flog_err(EC_BGP_ES_INVALID, - "%u Failed to update EAD-EVI route ESI: %s VNI %u VTEP %s", - bgp->vrf_id, es->esi_str, vpn->vni, - inet_ntoa(es->originator_ip)); - } + ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, dest, + &attr, 1, &pi, &route_changed); + if (ret != 0) + flog_err( + EC_BGP_ES_INVALID, + "%u Failed to update EAD-EVI route ESI: %s VNI %u VTEP %pI4", + bgp->vrf_id, es->esi_str, vpn->vni, + &es->originator_ip); global_rd = &vpn->prd; } else { /* EAD-ES route update */ @@ -889,16 +908,16 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, /* First, create (or fetch) route node within the ES. */ /* NOTE: There is no RD here. */ /* XXX: fragment ID must be included as a part of the prefix. */ - rn = bgp_node_get(es->route_table, (struct prefix *)p); + dest = bgp_node_get(es->route_table, (struct prefix *)p); /* Create or update route entry. */ - ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, - rn, &attr, 1, &pi, &route_changed); + ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, dest, + &attr, 1, &pi, &route_changed); if (ret != 0) { - flog_err(EC_BGP_ES_INVALID, - "%u ERROR: Failed to updated EAD-EVI route ESI: %s VTEP %s", - bgp->vrf_id, es->esi_str, - inet_ntoa(es->originator_ip)); + flog_err( + EC_BGP_ES_INVALID, + "%u ERROR: Failed to updated EAD-EVI route ESI: %s VTEP %pI4", + bgp->vrf_id, es->esi_str, &es->originator_ip); } global_rd = &es->prd; } @@ -911,8 +930,8 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, * this is just to set the flags correctly as local route in * the ES always wins. */ - evpn_route_select_install(bgp, vpn, rn); - bgp_dest_unlock_node(rn); + evpn_route_select_install(bgp, vpn, dest); + bgp_dest_unlock_node(dest); /* If this is a new route or some attribute has changed, export the * route to the global table. The route will be advertised to peers @@ -922,14 +941,15 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, if (route_changed) { struct bgp_path_info *global_pi; - rn = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi, - p, global_rd); - bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, - rn, attr_new, 1, &global_pi, &route_changed); + dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi, + p, global_rd); + bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, dest, + attr_new, 1, &global_pi, + &route_changed); /* Schedule for processing and unlock node. */ - bgp_process(bgp, rn, afi, safi); - bgp_dest_unlock_node(rn); + bgp_process(bgp, dest, afi, safi); + bgp_dest_unlock_node(dest); } /* Unintern temporary. */ @@ -1136,6 +1156,7 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp, { struct bgp_evpn_es *es = es_vtep->es; struct stream *s; + uint32_t flags = 0; /* Check socket. */ if (!zclient || zclient->sock < 0) @@ -1149,6 +1170,9 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp, return 0; } + if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) + flags |= ZAPI_ES_VTEP_FLAG_ESR_RXED; + s = zclient->obuf; stream_reset(s); @@ -1157,19 +1181,24 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp, bgp->vrf_id); stream_put(s, &es->esi, sizeof(esi_t)); stream_put_ipv4(s, es_vtep->vtep_ip.s_addr); + if (add) { + stream_putl(s, flags); + stream_putc(s, es_vtep->df_alg); + stream_putw(s, es_vtep->df_pref); + } stream_putw_at(s, 0, stream_get_endp(s)); if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("Tx %s Remote ESI %s VTEP %s", - add ? "ADD" : "DEL", es->esi_str, - inet_ntoa(es_vtep->vtep_ip)); + zlog_debug("Tx %s Remote ESI %s VTEP %pI4", add ? "ADD" : "DEL", + es->esi_str, &es_vtep->vtep_ip); return zclient_send_message(zclient); } static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, - struct bgp_evpn_es_vtep *es_vtep) + struct bgp_evpn_es_vtep *es_vtep, + bool param_change) { bool old_active; bool new_active; @@ -1185,26 +1214,30 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, new_active = !!CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE); - if (old_active == new_active) - return; + if ((old_active != new_active) || (new_active && param_change)) { - if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("es %s vtep %s %s", - es_vtep->es->esi_str, - inet_ntoa(es_vtep->vtep_ip), - new_active ? "active" : "inactive"); + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("es %s vtep %pI4 %s df %u/%u", + es_vtep->es->esi_str, &es_vtep->vtep_ip, + new_active ? "active" : "inactive", + es_vtep->df_alg, es_vtep->df_pref); - /* send remote ES to zebra */ - bgp_zebra_send_remote_es_vtep(bgp, es_vtep, new_active); + /* send remote ES to zebra */ + bgp_zebra_send_remote_es_vtep(bgp, es_vtep, new_active); - /* queue up the es for background consistency checks */ - bgp_evpn_es_cons_checks_pend_add(es_vtep->es); + /* queue up the es for background consistency checks */ + bgp_evpn_es_cons_checks_pend_add(es_vtep->es); + } } static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, - struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr) + struct bgp_evpn_es *es, + struct in_addr vtep_ip, + bool esr, uint8_t df_alg, + uint16_t df_pref) { struct bgp_evpn_es_vtep *es_vtep; + bool param_change = false; es_vtep = bgp_evpn_es_vtep_find(es, vtep_ip); @@ -1212,17 +1245,23 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, es_vtep = bgp_evpn_es_vtep_new(es, vtep_ip); if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("es %s vtep %s add %s", - es_vtep->es->esi_str, - inet_ntoa(es_vtep->vtep_ip), - esr ? "esr" : "ead"); + zlog_debug("es %s vtep %pI4 add %s df %u/%u", + es_vtep->es->esi_str, &es_vtep->vtep_ip, + esr ? "esr" : "ead", df_alg, df_pref); - if (esr) + if (esr) { SET_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ESR); - else + if ((es_vtep->df_pref != df_pref) + || (es_vtep->df_alg != df_alg)) { + param_change = true; + es_vtep->df_pref = df_pref; + es_vtep->df_alg = df_alg; + } + } else { ++es_vtep->evi_cnt; + } - bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep); + bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change); return es_vtep; } @@ -1230,19 +1269,24 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, static void bgp_evpn_es_vtep_do_del(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, bool esr) { + bool param_change = false; + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("es %s vtep %s del %s", - es_vtep->es->esi_str, - inet_ntoa(es_vtep->vtep_ip), - esr ? "esr" : "ead"); + zlog_debug("es %s vtep %pI4 del %s", es_vtep->es->esi_str, + &es_vtep->vtep_ip, esr ? "esr" : "ead"); if (esr) { UNSET_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ESR); + if (es_vtep->df_pref || es_vtep->df_alg) { + param_change = true; + es_vtep->df_pref = 0; + es_vtep->df_alg = 0; + } } else { if (es_vtep->evi_cnt) --es_vtep->evi_cnt; } - bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep); + bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change); bgp_evpn_es_vtep_free(es_vtep); } @@ -1313,11 +1357,14 @@ static struct bgp_evpn_es *bgp_evpn_es_new(struct bgp *bgp, const esi_t *esi) * This just frees appropriate memory, caller should have taken other * needed actions. */ -static void bgp_evpn_es_free(struct bgp_evpn_es *es) +static void bgp_evpn_es_free(struct bgp_evpn_es *es, const char *caller) { if (es->flags & (BGP_EVPNES_LOCAL | BGP_EVPNES_REMOTE)) return; + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("%s: es %s free", caller, es->esi_str); + /* cleanup resources maintained against the ES */ list_delete(&es->es_evi_list); list_delete(&es->es_vtep_list); @@ -1347,8 +1394,7 @@ static void bgp_evpn_es_local_info_set(struct bgp *bgp, struct bgp_evpn_es *es) bf_assign_index(bm->rd_idspace, es->rd_id); es->prd.family = AF_UNSPEC; es->prd.prefixlen = 64; - snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id), - es->rd_id); + snprintfrr(buf, sizeof(buf), "%pI4:%hu", &bgp->router_id, es->rd_id); (void)str2prefix_rd(buf, &es->prd); } @@ -1365,7 +1411,7 @@ static void bgp_evpn_es_local_info_clear(struct bgp_evpn_es *es) bf_release_index(bm->rd_idspace, es->rd_id); - bgp_evpn_es_free(es); + bgp_evpn_es_free(es, __func__); } /* eval remote info associated with the ES */ @@ -1376,7 +1422,7 @@ static void bgp_evpn_es_remote_info_re_eval(struct bgp_evpn_es *es) } else { if (CHECK_FLAG(es->flags, BGP_EVPNES_REMOTE)) { UNSET_FLAG(es->flags, BGP_EVPNES_REMOTE); - bgp_evpn_es_free(es); + bgp_evpn_es_free(es, __func__); } } } @@ -1422,32 +1468,43 @@ static void bgp_evpn_local_es_down(struct bgp *bgp, } /* Process ES link oper-up by generating ES-EAD and ESR */ -static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es) +static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es, + bool regen_esr) { struct prefix_evpn p; + bool regen_ead = false; - if (CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) - return; - - SET_FLAG(es->flags, BGP_EVPNES_OPER_UP); + if (!CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) { + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("local es %s up", es->esi_str); - if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("local es %s up", es->esi_str); + SET_FLAG(es->flags, BGP_EVPNES_OPER_UP); + regen_esr = true; + regen_ead = true; + } - /* generate ESR */ - build_evpn_type4_prefix(&p, &es->esi, es->originator_ip); - if (bgp_evpn_type4_route_update(bgp, es, &p)) - flog_err(EC_BGP_EVPN_ROUTE_CREATE, - "%u: Type4 route creation failure for ESI %s", - bgp->vrf_id, es->esi_str); + if (regen_esr) { + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("local es %s generate ESR", es->esi_str); + /* generate ESR */ + build_evpn_type4_prefix(&p, &es->esi, es->originator_ip); + if (bgp_evpn_type4_route_update(bgp, es, &p)) + flog_err(EC_BGP_EVPN_ROUTE_CREATE, + "%u: Type4 route creation failure for ESI %s", + bgp->vrf_id, es->esi_str); + } - /* generate EAD-EVI */ - bgp_evpn_local_type1_evi_route_add(bgp, es); + if (regen_ead) { + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("local es %s generate EAD", es->esi_str); + /* generate EAD-EVI */ + bgp_evpn_local_type1_evi_route_add(bgp, es); - /* generate EAD-ES */ - build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG, - &es->esi, es->originator_ip); - bgp_evpn_type1_route_update(bgp, es, NULL, &p); + /* generate EAD-ES */ + build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG, &es->esi, + es->originator_ip); + bgp_evpn_type1_route_update(bgp, es, NULL, &p); + } } static void bgp_evpn_local_es_do_del(struct bgp *bgp, struct bgp_evpn_es *es) @@ -1505,11 +1562,13 @@ int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi) * ES. */ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, - struct in_addr originator_ip, bool oper_up) + struct in_addr originator_ip, bool oper_up, + uint16_t df_pref) { char buf[ESI_STR_LEN]; struct bgp_evpn_es *es; bool new_es = true; + bool regen_esr = false; /* create the new es */ es = bgp_evpn_es_find(esi); @@ -1527,11 +1586,14 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, } if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("add local es %s orig-ip %s", - es->esi_str, - inet_ntoa(originator_ip)); + zlog_debug("add local es %s orig-ip %pI4 df_pref %u", es->esi_str, + &originator_ip, df_pref); es->originator_ip = originator_ip; + if (df_pref != es->df_pref) { + es->df_pref = df_pref; + regen_esr = true; + } bgp_evpn_es_local_info_set(bgp, es); /* import all remote Type-4 routes in the ES table */ @@ -1550,7 +1612,7 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, * can be generated even if the link is inactive. */ if (oper_up) - bgp_evpn_local_es_up(bgp, es); + bgp_evpn_local_es_up(bgp, es, regen_esr); else bgp_evpn_local_es_down(bgp, es); @@ -1564,10 +1626,12 @@ static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es, struct listnode *node; struct bgp_evpn_es_vtep *es_vtep; bool first = true; + char ip_buf[INET6_ADDRSTRLEN]; vtep_str[0] = '\0'; for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { vtep_flag_str[0] = '\0'; + if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) strlcat(vtep_flag_str, "E", sizeof(vtep_flag_str)); if (es_vtep->flags & BGP_EVPNES_VTEP_ACTIVE) @@ -1579,7 +1643,10 @@ static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es, first = false; else strlcat(vtep_str, ",", vtep_str_size); - strlcat(vtep_str, inet_ntoa(es_vtep->vtep_ip), vtep_str_size); + strlcat(vtep_str, + inet_ntop(AF_INET, &es_vtep->vtep_ip, ip_buf, + sizeof(ip_buf)), + vtep_str_size); strlcat(vtep_str, "(", vtep_str_size); strlcat(vtep_str, vtep_flag_str, vtep_str_size); strlcat(vtep_str, ")", vtep_str_size); @@ -1588,21 +1655,18 @@ static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es, return vtep_str; } -static inline void json_array_string_add(json_object *json, const char *str) -{ - json_object_array_add(json, json_object_new_string(str)); -} - static void bgp_evpn_es_json_vtep_fill(json_object *json_vteps, struct bgp_evpn_es_vtep *es_vtep) { json_object *json_vtep_entry; json_object *json_flags; + char ip_buf[INET6_ADDRSTRLEN]; json_vtep_entry = json_object_new_object(); - json_object_string_add(json_vtep_entry, "vtep_ip", - inet_ntoa(es_vtep->vtep_ip)); + json_object_string_add( + json_vtep_entry, "vtep_ip", + inet_ntop(AF_INET, &es_vtep->vtep_ip, ip_buf, sizeof(ip_buf))); if (es_vtep->flags & (BGP_EVPNES_VTEP_ESR | BGP_EVPNES_VTEP_ACTIVE)) { json_flags = json_object_new_array(); @@ -1611,12 +1675,49 @@ static void bgp_evpn_es_json_vtep_fill(json_object *json_vteps, if (es_vtep->flags & BGP_EVPNES_VTEP_ACTIVE) json_array_string_add(json_flags, "active"); json_object_object_add(json_vtep_entry, "flags", json_flags); + if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) { + json_object_int_add(json_vtep_entry, "dfPreference", + es_vtep->df_pref); + json_object_int_add(json_vtep_entry, "dfAlgorithm", + es_vtep->df_pref); + } } json_object_array_add(json_vteps, json_vtep_entry); } +static void bgp_evpn_es_vteps_show_detail(struct vty *vty, + struct bgp_evpn_es *es) +{ + char vtep_flag_str[BGP_EVPN_FLAG_STR_SZ]; + struct listnode *node; + struct bgp_evpn_es_vtep *es_vtep; + char alg_buf[EVPN_DF_ALG_STR_LEN]; + + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { + vtep_flag_str[0] = '\0'; + if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) + strlcat(vtep_flag_str, "E", sizeof(vtep_flag_str)); + if (es_vtep->flags & BGP_EVPNES_VTEP_ACTIVE) + strlcat(vtep_flag_str, "A", sizeof(vtep_flag_str)); + + if (!strlen(vtep_flag_str)) + strlcat(vtep_flag_str, "-", sizeof(vtep_flag_str)); + + vty_out(vty, " %pI4 flags: %s", &es_vtep->vtep_ip, + vtep_flag_str); + + if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) + vty_out(vty, " df_alg: %s df_pref: %u\n", + evpn_es_df_alg2str(es_vtep->df_alg, alg_buf, + sizeof(alg_buf)), + es_vtep->df_pref); + else + vty_out(vty, "\n"); + } +} + static void bgp_evpn_es_show_entry(struct vty *vty, struct bgp_evpn_es *es, json_object *json) { @@ -1680,9 +1781,14 @@ static void bgp_evpn_es_show_entry(struct vty *vty, static void bgp_evpn_es_show_entry_detail(struct vty *vty, struct bgp_evpn_es *es, json_object *json) { + char ip_buf[INET6_ADDRSTRLEN]; + if (json) { json_object *json_flags; json_object *json_incons; + json_object *json_vteps; + struct listnode *node; + struct bgp_evpn_es_vtep *es_vtep; /* Add the "brief" info first */ bgp_evpn_es_show_entry(vty, es, json); @@ -1696,11 +1802,20 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, json_object_object_add(json, "flags", json_flags); } json_object_string_add(json, "originator_ip", - inet_ntoa(es->originator_ip)); + inet_ntop(AF_INET, &es->originator_ip, + ip_buf, sizeof(ip_buf))); json_object_int_add(json, "remoteVniCount", es->remote_es_evi_cnt); json_object_int_add(json, "inconsistentVniVtepCount", es->incons_evi_vtep_cnt); + if (listcount(es->es_vtep_list)) { + json_vteps = json_object_new_array(); + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, + es_vtep)) { + bgp_evpn_es_json_vtep_fill(json_vteps, es_vtep); + } + json_object_object_add(json, "vteps", json_vteps); + } if (es->inconsistencies) { json_incons = json_object_new_array(); if (es->inconsistencies & BGP_EVPNES_INCONS_VTEP_LIST) @@ -1712,7 +1827,6 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, } else { char incons_str[BGP_EVPNES_INCONS_STR_SZ]; char type_str[4]; - char vtep_str[ES_VTEP_LIST_STR_SZ + BGP_EVPN_VTEPS_FLAG_STR_SZ]; char buf1[RD_ADDRSTRLEN]; type_str[0] = '\0'; @@ -1721,10 +1835,6 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, if (es->flags & BGP_EVPNES_REMOTE) strlcat(type_str, "R", sizeof(type_str)); - bgp_evpn_es_vteps_str(vtep_str, es, sizeof(vtep_str)); - if (!strlen(vtep_str)) - strlcpy(buf1, "-", sizeof(buf1)); - if (es->flags & BGP_EVPNES_LOCAL) prefix_rd2str(&es->prd, buf1, sizeof(buf1)); else @@ -1733,8 +1843,10 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, vty_out(vty, "ESI: %s\n", es->esi_str); vty_out(vty, " Type: %s\n", type_str); vty_out(vty, " RD: %s\n", buf1); - vty_out(vty, " Originator-IP: %s\n", - inet_ntoa(es->originator_ip)); + vty_out(vty, " Originator-IP: %pI4\n", &es->originator_ip); + if (es->flags & BGP_EVPNES_LOCAL) + vty_out(vty, " Local ES DF preference: %u\n", + es->df_pref); vty_out(vty, " VNI Count: %d\n", listcount(es->es_evi_list)); vty_out(vty, " Remote VNI Count: %d\n", es->remote_es_evi_cnt); @@ -1750,7 +1862,10 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty, } vty_out(vty, " Inconsistencies: %s\n", incons_str); - vty_out(vty, " VTEPs: %s\n", vtep_str); + if (listcount(es->es_vtep_list)) { + vty_out(vty, " VTEPs:\n"); + bgp_evpn_es_vteps_show_detail(vty, es); + } vty_out(vty, "\n"); } } @@ -1913,18 +2028,18 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, return; if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("es %s evi %u vtep %s %s", - evi_vtep->es_evi->es->esi_str, - evi_vtep->es_evi->vpn->vni, - inet_ntoa(evi_vtep->vtep_ip), - new_active ? "active" : "inactive"); + zlog_debug("es %s evi %u vtep %pI4 %s", + evi_vtep->es_evi->es->esi_str, + evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip, + new_active ? "active" : "inactive"); /* add VTEP to parent es */ if (new_active) { struct bgp_evpn_es_vtep *es_vtep; es_vtep = bgp_evpn_es_vtep_add(bgp, evi_vtep->es_evi->es, - evi_vtep->vtep_ip, false /*esr*/); + evi_vtep->vtep_ip, false /*esr*/, + 0, 0); evi_vtep->es_vtep = es_vtep; } else { if (evi_vtep->es_vtep) { @@ -1949,11 +2064,10 @@ static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp, evi_vtep = bgp_evpn_es_evi_vtep_new(es_evi, vtep_ip); if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("add es %s evi %u vtep %s %s", - evi_vtep->es_evi->es->esi_str, - evi_vtep->es_evi->vpn->vni, - inet_ntoa(evi_vtep->vtep_ip), - ead_es ? "ead_es" : "ead_evi"); + zlog_debug("add es %s evi %u vtep %pI4 %s", + evi_vtep->es_evi->es->esi_str, + evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip, + ead_es ? "ead_es" : "ead_evi"); if (ead_es) SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_ES); @@ -1974,11 +2088,10 @@ static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp, return; if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("del es %s evi %u vtep %s %s", - evi_vtep->es_evi->es->esi_str, - evi_vtep->es_evi->vpn->vni, - inet_ntoa(evi_vtep->vtep_ip), - ead_es ? "ead_es" : "ead_evi"); + zlog_debug("del es %s evi %u vtep %pI4 %s", + evi_vtep->es_evi->es->esi_str, + evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip, + ead_es ? "ead_es" : "ead_evi"); if (ead_es) UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_ES); @@ -2290,13 +2403,10 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, return 0; if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("add remote %s es %s evi %u vtep %s", - p->prefix.ead_addr.eth_tag ? - "ead-es" : "ead-evi", - esi_to_str(esi, buf, - sizeof(buf)), - vpn->vni, - inet_ntoa(p->prefix.ead_addr.ip.ipaddr_v4)); + zlog_debug("add remote %s es %s evi %u vtep %pI4", + p->prefix.ead_addr.eth_tag ? "ead-es" : "ead-evi", + esi_to_str(esi, buf, sizeof(buf)), vpn->vni, + &p->prefix.ead_addr.ip.ipaddr_v4); es = bgp_evpn_es_find(esi); if (!es) { @@ -2313,7 +2423,7 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, if (!es_evi) { es_evi = bgp_evpn_es_evi_new(es, vpn); if (!es_evi) { - bgp_evpn_es_free(es); + bgp_evpn_es_free(es, __func__); return -1; } } @@ -2342,13 +2452,11 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, return 0; if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) - zlog_debug("del remote %s es %s evi %u vtep %s", - p->prefix.ead_addr.eth_tag ? - "ead-es" : "ead-evi", - esi_to_str(&p->prefix.ead_addr.esi, buf, - sizeof(buf)), - vpn->vni, - inet_ntoa(p->prefix.ead_addr.ip.ipaddr_v4)); + zlog_debug( + "del remote %s es %s evi %u vtep %pI4", + p->prefix.ead_addr.eth_tag ? "ead-es" : "ead-evi", + esi_to_str(&p->prefix.ead_addr.esi, buf, sizeof(buf)), + vpn->vni, &p->prefix.ead_addr.ip.ipaddr_v4); es = bgp_evpn_es_find(&p->prefix.ead_addr.esi); if (!es) @@ -2399,6 +2507,7 @@ static char *bgp_evpn_es_evi_vteps_str(char *vtep_str, struct listnode *node; struct bgp_evpn_es_evi_vtep *evi_vtep; bool first = true; + char ip_buf[INET6_ADDRSTRLEN]; vtep_str[0] = '\0'; for (ALL_LIST_ELEMENTS_RO(es_evi->es_evi_vtep_list, node, evi_vtep)) { @@ -2414,7 +2523,10 @@ static char *bgp_evpn_es_evi_vteps_str(char *vtep_str, first = false; else strlcat(vtep_str, ",", vtep_str_size); - strlcat(vtep_str, inet_ntoa(evi_vtep->vtep_ip), vtep_str_size); + strlcat(vtep_str, + inet_ntop(AF_INET, &evi_vtep->vtep_ip, ip_buf, + sizeof(ip_buf)), + vtep_str_size); strlcat(vtep_str, "(", vtep_str_size); strlcat(vtep_str, vtep_flag_str, vtep_str_size); strlcat(vtep_str, ")", vtep_str_size); @@ -2428,12 +2540,13 @@ static void bgp_evpn_es_evi_json_vtep_fill(json_object *json_vteps, { json_object *json_vtep_entry; json_object *json_flags; + char ip_buf[INET6_ADDRSTRLEN]; json_vtep_entry = json_object_new_object(); - json_object_string_add(json_vtep_entry, - "vtep_ip", - inet_ntoa(evi_vtep->vtep_ip)); + json_object_string_add( + json_vtep_entry, "vtep_ip", + inet_ntop(AF_INET, &evi_vtep->vtep_ip, ip_buf, sizeof(ip_buf))); if (evi_vtep->flags & (BGP_EVPN_EVI_VTEP_EAD_PER_ES | BGP_EVPN_EVI_VTEP_EAD_PER_EVI)) { json_flags = json_object_new_array(); @@ -2892,17 +3005,15 @@ void bgp_evpn_mh_finish(void) { struct bgp_evpn_es *es; struct bgp_evpn_es *es_next; - struct bgp *bgp; - bgp = bgp_get_evpn(); - if (bgp) { - RB_FOREACH_SAFE(es, bgp_es_rb_head, - &bgp_mh_info->es_rb_tree, es_next) { - /* XXX - need to force free remote ESs here */ - bgp_evpn_local_es_do_del(bgp, es); - } + if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) + zlog_debug("evpn mh finish"); + + RB_FOREACH_SAFE (es, bgp_es_rb_head, &bgp_mh_info->es_rb_tree, + es_next) { + bgp_evpn_es_local_info_clear(es); } - thread_cancel(bgp_mh_info->t_cons_check); + thread_cancel(&bgp_mh_info->t_cons_check); list_delete(&bgp_mh_info->local_es_list); list_delete(&bgp_mh_info->pend_es_list); diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h index 93355d495a..d719524bdd 100644 --- a/bgpd/bgp_evpn_mh.h +++ b/bgpd/bgp_evpn_mh.h @@ -110,6 +110,9 @@ struct bgp_evpn_es { */ uint32_t incons_evi_vtep_cnt; + /* preference config for BUM-DF election. advertised via the ESR. */ + uint16_t df_pref; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp_evpn_es) @@ -131,6 +134,10 @@ struct bgp_evpn_es_vtep { uint32_t evi_cnt; /* es_evis referencing this vtep as an active path */ + /* Algorithm and preference for DF election. Rxed via the ESR */ + uint8_t df_alg; + uint16_t df_pref; + /* memory used for adding the entry to es->es_vtep_list */ struct listnode es_listnode; }; @@ -264,6 +271,11 @@ static inline bool bgp_evpn_attr_is_local_es(struct attr *attr) return attr ? !!(attr->es_flags & ATTR_ES_IS_LOCAL) : false; } +static inline uint32_t bgp_evpn_attr_get_df_pref(struct attr *attr) +{ + return (attr) ? attr->df_pref : 0; +} + /****************************************************************************/ extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp, struct bgp_evpn_es *es, afi_t afi, safi_t safi, @@ -276,7 +288,8 @@ int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi, struct attr *attr, uint8_t *pfx, int psize, uint32_t addpath_id); extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, - struct in_addr originator_ip, bool oper_up); + struct in_addr originator_ip, bool oper_up, + uint16_t df_pref); extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi); extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni); extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni); diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index ca45b198a7..c47576c00c 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -308,6 +308,17 @@ static inline void encode_es_rt_extcomm(struct ecommunity_val *eval, memcpy(&eval->val[2], mac, ETH_ALEN); } +static inline void encode_df_elect_extcomm(struct ecommunity_val *eval, + uint16_t pref) +{ + memset(eval, 0, sizeof(*eval)); + eval->val[0] = ECOMMUNITY_ENCODE_EVPN; + eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION; + eval->val[2] = EVPN_MH_DF_ALG_PREF; + eval->val[6] = (pref >> 8) & 0xff; + eval->val[7] = pref & 0xff; +} + static inline void encode_esi_label_extcomm(struct ecommunity_val *eval, bool single_active) { @@ -603,11 +614,13 @@ extern void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi, struct bgp_path_info **pi); int vni_list_cmp(void *p1, void *p2); extern int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, - struct bgp_node *rn); -extern struct bgp_node *bgp_global_evpn_node_get( - struct bgp_table *table, afi_t afi, safi_t safi, - const struct prefix_evpn *evp, struct prefix_rd *prd); -extern struct bgp_node *bgp_global_evpn_node_lookup( - struct bgp_table *table, afi_t afi, safi_t safi, - const struct prefix_evpn *evp, struct prefix_rd *prd); + struct bgp_dest *dest); +extern struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table, + afi_t afi, safi_t safi, + const struct prefix_evpn *evp, + struct prefix_rd *prd); +extern struct bgp_dest * +bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi, + const struct prefix_evpn *evp, + struct prefix_rd *prd); #endif /* _BGP_EVPN_PRIVATE_H */ diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 15ecffdc72..e9e2aafebb 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -22,6 +22,8 @@ #include "command.h" #include "prefix.h" #include "lib/json.h" +#include "lib/printfrr.h" +#include "lib/vxlan.h" #include "stream.h" #include "bgpd/bgpd.h" @@ -103,8 +105,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip), - eip.val); + snprintfrr(rt_buf, sizeof(rt_buf), "%pI4:%u", &eip.ip, eip.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -213,8 +214,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip), - eip.val); + snprintfrr(rt_buf, sizeof(rt_buf), "%pI4:%u", &eip.ip, eip.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -314,8 +314,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty, case RD_TYPE_IP: decode_rd_ip(pnt + 2, &rd_ip); - snprintf(rd_str, len, "%s:%d", inet_ntoa(rd_ip.ip), - rd_ip.val); + snprintfrr(rd_str, len, "%pI4:%d", &rd_ip.ip, rd_ip.val); if (json) json_object_string_add(json, "rd", rd_str); else @@ -343,8 +342,9 @@ static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp, if (json) return; - vty_out(vty, "BGP table version is %" PRIu64 ", local router ID is %s\n", - tbl_ver, inet_ntoa(bgp->router_id)); + vty_out(vty, + "BGP table version is %" PRIu64 ", local router ID is %pI4\n", + tbl_ver, &bgp->router_id); vty_out(vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n"); vty_out(vty, "Origin codes: i - IGP, e - EGP, ? - incomplete\n"); @@ -368,6 +368,7 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf, json_object *json_import_rtl = NULL; json_object *json_export_rtl = NULL; char buf2[ETHER_ADDR_STRLEN]; + char originator_ip[BUFSIZ] = {0}; json_import_rtl = json_export_rtl = 0; @@ -380,8 +381,10 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf, json_object_string_add( json, "rd", prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN)); - json_object_string_add(json, "originatorIp", - inet_ntoa(bgp_vrf->originator_ip)); + json_object_string_add( + json, "originatorIp", + inet_ntop(AF_INET, &bgp_vrf->originator_ip, + originator_ip, sizeof(originator_ip))); json_object_string_add(json, "advertiseGatewayMacip", "n/a"); json_object_string_add(json, "advertiseSviMacIp", "n/a"); json_object_to_json_string_ext(json, @@ -409,8 +412,8 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf, vrf_id_to_name(bgp_vrf->vrf_id)); vty_out(vty, " RD: %s\n", prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN)); - vty_out(vty, " Originator IP: %s\n", - inet_ntoa(bgp_vrf->originator_ip)); + vty_out(vty, " Originator IP: %pI4\n", + &bgp_vrf->originator_ip); vty_out(vty, " Advertise-gw-macip : %s\n", "n/a"); vty_out(vty, " Advertise-svi-macip : %s\n", "n/a"); vty_out(vty, " Advertise-pip: %s\n", @@ -473,6 +476,7 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) json_object *json_import_rtl = NULL; json_object *json_export_rtl = NULL; struct bgp *bgp_evpn; + char buf[BUFSIZ] = {0}; bgp_evpn = bgp_get_evpn(); @@ -487,9 +491,11 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) json, "rd", prefix_rd2str(&vpn->prd, buf1, sizeof(buf1))); json_object_string_add(json, "originatorIp", - inet_ntoa(vpn->originator_ip)); - json_object_string_add(json, "mcastGroup", - inet_ntoa(vpn->mcast_grp)); + inet_ntop(AF_INET, &vpn->originator_ip, + buf, sizeof(buf))); + json_object_string_add( + json, "mcastGroup", + inet_ntop(AF_INET, &vpn->mcast_grp, buf, sizeof(buf))); /* per vni knob is enabled -- Enabled * Global knob is enabled -- Active * default -- Disabled @@ -525,10 +531,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json) vrf_id_to_name(vpn->tenant_vrf_id)); vty_out(vty, " RD: %s\n", prefix_rd2str(&vpn->prd, buf1, sizeof(buf1))); - vty_out(vty, " Originator IP: %s\n", - inet_ntoa(vpn->originator_ip)); - vty_out(vty, " Mcast group: %s\n", - inet_ntoa(vpn->mcast_grp)); + vty_out(vty, " Originator IP: %pI4\n", &vpn->originator_ip); + vty_out(vty, " Mcast group: %pI4\n", &vpn->mcast_grp); if (!vpn->advertise_gw_macip && bgp_evpn && bgp_evpn->advertise_gw_macip) vty_out(vty, " Advertise-gw-macip : %s\n", @@ -611,8 +615,8 @@ static void show_esi_routes(struct bgp *bgp, json_object *json_prefix = NULL; const struct prefix *p = bgp_dest_get_prefix(dest); - bgp_evpn_route2str((struct prefix_evpn *)p, prefix_str, - sizeof(prefix_str)); + prefix2str((struct prefix_evpn *)p, prefix_str, + sizeof(prefix_str)); if (json) json_prefix = json_object_new_object(); @@ -706,9 +710,8 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type, json_object *json_prefix = NULL; const struct prefix *p = bgp_dest_get_prefix(dest); - bgp_evpn_route2str( - (struct prefix_evpn *)bgp_dest_get_prefix(dest), - prefix_str, sizeof(prefix_str)); + prefix2str((struct prefix_evpn *)bgp_dest_get_prefix(dest), + prefix_str, sizeof(prefix_str)); if (type && evp->prefix.route_type != type) continue; @@ -826,6 +829,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_object *json_export_rtl = NULL; char buf1[10]; char buf2[INET6_ADDRSTRLEN]; + char buf3[BUFSIZ] = {0}; char rt_buf[25]; char *ecom_str; struct listnode *node, *nnode; @@ -849,7 +853,8 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_object_string_add(json_vni, "type", "L3"); json_object_string_add(json_vni, "inKernel", "True"); json_object_string_add(json_vni, "originatorIp", - inet_ntoa(bgp->originator_ip)); + inet_ntop(AF_INET, &bgp->originator_ip, + buf3, sizeof(buf3))); json_object_string_add( json_vni, "rd", prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN)); @@ -862,7 +867,9 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_vni, "advertisePip", bgp->evpn_info->advertise_pip ? "Enabled" : "Disabled"); json_object_string_add(json_vni, "sysIP", - inet_ntoa(bgp->evpn_info->pip_ip)); + inet_ntop(AF_INET, + &bgp->evpn_info->pip_ip, buf3, + sizeof(buf3))); json_object_string_add(json_vni, "sysMAC", prefix_mac2str(&bgp->evpn_info->pip_rmac, buf2, sizeof(buf2))); @@ -951,6 +958,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; char buf1[10]; char buf2[RD_ADDRSTRLEN]; + char buf3[BUFSIZ] = {0}; char rt_buf[25]; char *ecom_str; struct listnode *node, *nnode; @@ -981,9 +989,11 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) json_vni, "rd", prefix_rd2str(&vpn->prd, buf2, sizeof(buf2))); json_object_string_add(json_vni, "originatorIp", - inet_ntoa(vpn->originator_ip)); + inet_ntop(AF_INET, &vpn->originator_ip, + buf3, sizeof(buf3))); json_object_string_add(json_vni, "mcastGroup", - inet_ntoa(vpn->mcast_grp)); + inet_ntop(AF_INET, &vpn->mcast_grp, buf3, + sizeof(buf3))); /* per vni knob is enabled -- Enabled * Global knob is enabled -- Active * default -- Disabled @@ -1095,6 +1105,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, char rd_str[RD_ADDRSTRLEN]; char buf[BUFSIZ]; int no_display; + char router_id[BUFSIZ] = {0}; unsigned long output_count = 0; unsigned long total_count = 0; @@ -1186,8 +1197,11 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, json_object_string_add( json, "bgpLocalRouterId", - inet_ntoa( - bgp->router_id)); + inet_ntop( + AF_INET, + &bgp->router_id, + router_id, + sizeof(router_id))); json_object_int_add( json, "defaultLocPrf", @@ -1250,9 +1264,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, json_object_string_add( json_prefix_info, "prefix", - bgp_evpn_route2str( - (struct prefix_evpn *)p, buf, - BUFSIZ)); + prefix2str((struct prefix_evpn *)p, buf, + BUFSIZ)); json_object_int_add(json_prefix_info, "prefixLen", p->prefixlen); @@ -2441,7 +2454,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp, return; } - bgp_evpn_route2str(&p, prefix_str, sizeof(prefix_str)); + prefix2str(&p, prefix_str, sizeof(prefix_str)); /* Prefix and num paths displayed once per prefix. */ route_vty_out_detail_header(vty, bgp, dest, prd, afi, safi, json); @@ -2522,8 +2535,8 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp, char prefix_str[BUFSIZ]; int add_prefix_to_json = 0; - bgp_evpn_route2str((struct prefix_evpn *)evp, prefix_str, - sizeof(prefix_str)); + prefix2str((struct prefix_evpn *)evp, prefix_str, + sizeof(prefix_str)); if (type && evp->prefix.route_type != type) continue; @@ -2668,8 +2681,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type, int add_prefix_to_json = 0; const struct prefix *p = bgp_dest_get_prefix(dest); - bgp_evpn_route2str((struct prefix_evpn *)p, prefix_str, - sizeof(prefix_str)); + prefix2str((struct prefix_evpn *)p, prefix_str, + sizeof(prefix_str)); if (type && evp->prefix.route_type != type) continue; @@ -3988,33 +4001,51 @@ DEFUN(show_bgp_l2vpn_evpn_summary, show_established, uj); } +int bgp_evpn_cli_parse_type(int *type, struct cmd_token **argv, int argc) +{ + int type_idx = 0; + + if (argv_find(argv, argc, "type", &type_idx)) { + /* Specific type is requested */ + if ((strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0) + || (strmatch(argv[type_idx + 1]->arg, "2"))) + *type = BGP_EVPN_MAC_IP_ROUTE; + else if ((strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0) + || (strmatch(argv[type_idx + 1]->arg, "3"))) + *type = BGP_EVPN_IMET_ROUTE; + else if ((strncmp(argv[type_idx + 1]->arg, "es", 2) == 0) + || (strmatch(argv[type_idx + 1]->arg, "4"))) + *type = BGP_EVPN_ES_ROUTE; + else if ((strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0) + || (strmatch(argv[type_idx + 1]->arg, "1"))) + *type = BGP_EVPN_AD_ROUTE; + else if ((strncmp(argv[type_idx + 1]->arg, "p", 1) == 0) + || (strmatch(argv[type_idx + 1]->arg, "5"))) + *type = BGP_EVPN_IP_PREFIX_ROUTE; + else + return -1; + } + + return 0; +} + /* * Display global EVPN routing table. */ DEFUN(show_bgp_l2vpn_evpn_route, show_bgp_l2vpn_evpn_route_cmd, - "show bgp l2vpn evpn route [detail] [type <ead|1|macip|2|multicast|3|es|4|prefix|5>] [json]", + "show bgp l2vpn evpn route [detail] [type "EVPN_TYPE_ALL_LIST"] [json]", SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "Display Detailed Information\n" - "Specify Route type\n" - "EAD (Type-1) route\n" - "EAD (Type-1) route\n" - "MAC-IP (Type-2) route\n" - "MAC-IP (Type-2) route\n" - "Multicast (Type-3) route\n" - "Multicast (Type-3) route\n" - "Ethernet Segment (Type-4) route\n" - "Ethernet Segment (Type-4) route\n" - "Prefix (Type-5) route\n" - "Prefix (Type-5) route\n" + EVPN_TYPE_HELP_STR + EVPN_TYPE_ALL_LIST_HELP_STR JSON_STR) { struct bgp *bgp; - int type_idx = 0; int detail = 0; int type = 0; bool uj = false; @@ -4029,27 +4060,8 @@ DEFUN(show_bgp_l2vpn_evpn_route, if (uj) json = json_object_new_object(); - /* get the type */ - if (argv_find(argv, argc, "type", &type_idx)) { - /* Specific type is requested */ - if ((strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0) - || (strmatch(argv[type_idx + 1]->arg, "2"))) - type = BGP_EVPN_MAC_IP_ROUTE; - else if ((strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0) - || (strmatch(argv[type_idx + 1]->arg, "3"))) - type = BGP_EVPN_IMET_ROUTE; - else if ((strncmp(argv[type_idx + 1]->arg, "es", 2) == 0) - || (strmatch(argv[type_idx + 1]->arg, "4"))) - type = BGP_EVPN_ES_ROUTE; - else if ((strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0) - || (strmatch(argv[type_idx + 1]->arg, "1"))) - type = BGP_EVPN_AD_ROUTE; - else if ((strncmp(argv[type_idx + 1]->arg, "p", 1) == 0) - || (strmatch(argv[type_idx + 1]->arg, "5"))) - type = BGP_EVPN_IP_PREFIX_ROUTE; - else - return CMD_WARNING; - } + if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0) + return CMD_WARNING; if (argv_find(argv, argc, "detail", &detail)) detail = 1; @@ -4069,20 +4081,16 @@ DEFUN(show_bgp_l2vpn_evpn_route, */ DEFUN(show_bgp_l2vpn_evpn_route_rd, show_bgp_l2vpn_evpn_route_rd_cmd, - "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <ead|macip|multicast|es|prefix>] [json]", + "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type "EVPN_TYPE_ALL_LIST"] [json]", SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n" - "Specify Route type\n" - "EAD (Type-1) route\n" - "MAC-IP (Type-2) route\n" - "Multicast (Type-3) route\n" - "Ethernet Segment route\n" - "Prefix route\n" + EVPN_RT_HELP_STR + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR + EVPN_TYPE_HELP_STR + EVPN_TYPE_ALL_LIST_HELP_STR JSON_STR) { struct bgp *bgp; @@ -4090,7 +4098,6 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd, struct prefix_rd prd; int type = 0; int rd_idx = 0; - int type_idx = 0; bool uj = false; json_object *json = NULL; @@ -4113,22 +4120,8 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd, } } - /* get the type */ - if (argv_find(argv, argc, "type", &type_idx)) { - /* Specific type is requested */ - if (strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0) - type = BGP_EVPN_MAC_IP_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0) - type = BGP_EVPN_IMET_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "es", 2) == 0) - type = BGP_EVPN_ES_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0) - type = BGP_EVPN_AD_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "pr", 2) == 0) - type = BGP_EVPN_IP_PREFIX_ROUTE; - else - return CMD_WARNING; - } + if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0) + return CMD_WARNING; evpn_show_route_rd(vty, bgp, &prd, type, json); @@ -4151,9 +4144,9 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip, BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n" + EVPN_RT_HELP_STR + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR "MAC\n" "MAC address (e.g., 00:e0:ec:20:12:62)\n" "IP\n" @@ -4227,7 +4220,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi, BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "Ethernet Segment Identifier\n" "ESI ID\n" JSON_STR) @@ -4268,18 +4261,21 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi, * Display per-VNI EVPN routing table. */ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd, - "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <ead|macip|multicast> | vtep A.B.C.D>] [json]", + "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <ead|1|macip|2|multicast|3> | vtep A.B.C.D>] [json]", SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "VNI number\n" - "Specify Route type\n" - "EAD (Type-1) route\n" - "MAC-IP (Type-2) route\n" - "Multicast (Type-3) route\n" + EVPN_TYPE_HELP_STR + EVPN_TYPE_1_HELP_STR + EVPN_TYPE_1_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR "Remote VTEP\n" "Remote VTEP IP address\n" JSON_STR) @@ -4289,6 +4285,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd, struct in_addr vtep_ip; int type = 0; int idx = 0; + int vtep_idx = 0; bool uj = false; json_object *json = NULL; @@ -4308,24 +4305,14 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd, vni = strtoul(argv[idx + 3]->arg, NULL, 10); - if ((!uj && ((argc == (idx + 1 + 5)) && argv[idx + 4]->arg)) - || (uj && ((argc == (idx + 1 + 6)) && argv[idx + 4]->arg))) { - if (strncmp(argv[idx + 4]->arg, "type", 4) == 0) { - if (strncmp(argv[idx + 5]->arg, "ma", 2) == 0) - type = BGP_EVPN_MAC_IP_ROUTE; - else if (strncmp(argv[idx + 5]->arg, "mu", 2) == 0) - type = BGP_EVPN_IMET_ROUTE; - else if (strncmp(argv[idx + 5]->arg, "ea", 2) == 0) - type = BGP_EVPN_AD_ROUTE; - else - return CMD_WARNING; - } else if (strncmp(argv[idx + 4]->arg, "vtep", 4) == 0) { - if (!inet_aton(argv[idx + 5]->arg, &vtep_ip)) { - vty_out(vty, "%% Malformed VTEP IP address\n"); - return CMD_WARNING; - } - } else + if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0) + return CMD_WARNING; + + if (argv_find(argv, argc, "vtep", &vtep_idx)) { + if (!inet_aton(argv[vtep_idx + 1]->arg, &vtep_ip)) { + vty_out(vty, "%% Malformed VTEP IP address\n"); return CMD_WARNING; + } } evpn_show_routes_vni(vty, bgp, vni, type, vtep_ip, json); @@ -4349,7 +4336,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip, BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "VNI number\n" "MAC\n" @@ -4419,10 +4406,10 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast, BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "VNI number\n" - "Multicast (Type-3) route\n" + EVPN_TYPE_3_HELP_STR "Originating Router IP address\n" JSON_STR) { @@ -4477,7 +4464,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all, BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "All VNIs\n" "Print Detailed Output\n" @@ -4602,7 +4589,7 @@ DEFUN(show_bgp_l2vpn_evpn_import_rt, return CMD_SUCCESS; } -DEFPY(test_es_add, +DEFPY_HIDDEN(test_es_add, test_es_add_cmd, "[no$no] test es NAME$esi_str [state NAME$state_str]", NO_STR @@ -4643,7 +4630,8 @@ DEFPY(test_es_add, oper_up = false; vtep_ip = bgp->router_id; - ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up); + ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up, + EVPN_MH_DF_PREF_MIN); if (ret == -1) { vty_out(vty, "%%Failed to add ES\n"); return CMD_WARNING; @@ -4652,7 +4640,7 @@ DEFPY(test_es_add, return CMD_SUCCESS; } -DEFPY(test_es_vni_add, +DEFPY_HIDDEN(test_es_vni_add, test_es_vni_add_cmd, "[no$no] test es NAME$esi_str vni (1-16777215)$vni", NO_STR @@ -4704,32 +4692,36 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary, show_bgp_evpn_summary_cmd, "Summary of BGP neighbor status\n" JSON_STR) ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd, - "show bgp evpn route [detail] [type <macip|multicast>]", + "show bgp evpn route [detail] [type <macip|2|multicast|3>]", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "Display Detailed Information\n" - "Specify Route type\n" - "MAC-IP (Type-2) route\n" - "Multicast (Type-3) route\n") + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR) ALIAS_HIDDEN( show_bgp_l2vpn_evpn_route_rd, show_bgp_evpn_route_rd_cmd, - "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|multicast>]", + "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|2|multicast|3>]", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n" - "Specify Route type\n" - "MAC-IP (Type-2) route\n" - "Multicast (Type-3) route\n") + EVPN_RT_HELP_STR + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR) ALIAS_HIDDEN( show_bgp_l2vpn_evpn_route_rd_macip, show_bgp_evpn_route_rd_macip_cmd, "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD]", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n" + EVPN_RT_HELP_STR + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR "MAC\n" "MAC address (e.g., 00:e0:ec:20:12:62)\n" "IP\n" @@ -4737,14 +4729,16 @@ ALIAS_HIDDEN( ALIAS_HIDDEN( show_bgp_l2vpn_evpn_route_vni, show_bgp_evpn_route_vni_cmd, - "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|multicast> | vtep A.B.C.D>]", + "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|2|multicast|3> | vtep A.B.C.D>]", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "VNI number\n" - "Specify Route type\n" - "MAC-IP (Type-2) route\n" - "Multicast (Type-3) route\n" + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR "Remote VTEP\n" "Remote VTEP IP address\n") @@ -4752,7 +4746,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip, show_bgp_evpn_route_vni_macip_cmd, "show bgp evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD]", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "VNI number\n" "MAC\n" @@ -4764,16 +4758,16 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast, show_bgp_evpn_route_vni_multicast_cmd, "show bgp evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "VNI number\n" - "Multicast (Type-3) route\n" + EVPN_TYPE_3_HELP_STR "Originating Router IP address\n") ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all, show_bgp_evpn_route_vni_all_cmd, "show bgp evpn route vni all [detail] [vtep A.B.C.D]", SHOW_STR BGP_STR EVPN_HELP_STR - "EVPN route information\n" + EVPN_RT_HELP_STR "VXLAN Network Identifier\n" "All VNIs\n" "Print Detailed Output\n" @@ -4854,8 +4848,8 @@ DEFUN_NOSH (exit_vni, DEFUN (bgp_evpn_vrf_rd, bgp_evpn_vrf_rd_cmd, "rd ASN:NN_OR_IP-ADDRESS:NN", - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n") + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR) { int ret; struct prefix_rd prd; @@ -4883,8 +4877,8 @@ DEFUN (no_bgp_evpn_vrf_rd, no_bgp_evpn_vrf_rd_cmd, "no rd ASN:NN_OR_IP-ADDRESS:NN", NO_STR - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n") + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR) { int ret; struct prefix_rd prd; @@ -4919,7 +4913,7 @@ DEFUN (no_bgp_evpn_vrf_rd_without_val, no_bgp_evpn_vrf_rd_without_val_cmd, "no rd", NO_STR - "Route Distinguisher\n") + EVPN_RT_DIST_HELP_STR) { struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); @@ -4939,8 +4933,8 @@ DEFUN (no_bgp_evpn_vrf_rd_without_val, DEFUN (bgp_evpn_vni_rd, bgp_evpn_vni_rd_cmd, "rd ASN:NN_OR_IP-ADDRESS:NN", - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n") + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR) { struct prefix_rd prd; struct bgp *bgp = VTY_GET_CONTEXT(bgp); @@ -4975,8 +4969,8 @@ DEFUN (no_bgp_evpn_vni_rd, no_bgp_evpn_vni_rd_cmd, "no rd ASN:NN_OR_IP-ADDRESS:NN", NO_STR - "Route Distinguisher\n" - "ASN:XX or A.B.C.D:XX\n") + EVPN_RT_DIST_HELP_STR + EVPN_ASN_IP_HELP_STR) { struct prefix_rd prd; struct bgp *bgp = VTY_GET_CONTEXT(bgp); @@ -5018,7 +5012,7 @@ DEFUN (no_bgp_evpn_vni_rd_without_val, no_bgp_evpn_vni_rd_without_val_cmd, "no rd", NO_STR - "Route Distinguisher\n") + EVPN_RT_DIST_HELP_STR) { struct bgp *bgp = VTY_GET_CONTEXT(bgp); VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn); @@ -5073,6 +5067,7 @@ DEFUN (show_bgp_vrf_l3vni_info, { char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; + char originator_ip[BUFSIZ] = {0}; int idx_vrf = 3; const char *name = NULL; struct bgp *bgp = NULL; @@ -5108,7 +5103,7 @@ DEFUN (show_bgp_vrf_l3vni_info, if (!json) { vty_out(vty, "BGP VRF: %s\n", name); - vty_out(vty, " Local-Ip: %s\n", inet_ntoa(bgp->originator_ip)); + vty_out(vty, " Local-Ip: %pI4\n", &bgp->originator_ip); vty_out(vty, " L3-VNI: %u\n", bgp->l3vni); vty_out(vty, " Rmac: %s\n", prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); @@ -5137,7 +5132,9 @@ DEFUN (show_bgp_vrf_l3vni_info, } else { json_object_string_add(json, "vrf", name); json_object_string_add(json, "local-ip", - inet_ntoa(bgp->originator_ip)); + inet_ntop(AF_INET, &bgp->originator_ip, + originator_ip, + sizeof(originator_ip))); json_object_int_add(json, "l3vni", bgp->l3vni); json_object_string_add( json, "rmac", @@ -5249,7 +5246,7 @@ DEFUN (no_bgp_evpn_vrf_rt, "import and export\n" "import\n" "export\n" - "ASN:XX or A.B.C.D:XX\n") + EVPN_ASN_IP_HELP_STR) { struct bgp *bgp = VTY_GET_CONTEXT(bgp); int rt_type, found_ecomdel; @@ -5300,6 +5297,7 @@ DEFUN (no_bgp_evpn_vrf_rt, if (rt_type == RT_TYPE_IMPORT) { if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl, ecomdel)) { + ecommunity_free(&ecomdel); vty_out(vty, "%% RT specified does not match configuration for this VRF\n"); return CMD_WARNING; @@ -5308,6 +5306,7 @@ DEFUN (no_bgp_evpn_vrf_rt, } else if (rt_type == RT_TYPE_EXPORT) { if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl, ecomdel)) { + ecommunity_free(&ecomdel); vty_out(vty, "%% RT specified does not match configuration for this VRF\n"); return CMD_WARNING; @@ -5329,12 +5328,14 @@ DEFUN (no_bgp_evpn_vrf_rt, } if (!found_ecomdel) { + ecommunity_free(&ecomdel); vty_out(vty, "%% RT specified does not match configuration for this VRF\n"); return CMD_WARNING; } } + ecommunity_free(&ecomdel); return CMD_SUCCESS; } @@ -5413,7 +5414,7 @@ DEFUN (no_bgp_evpn_vni_rt, "import and export\n" "import\n" "export\n" - "ASN:XX or A.B.C.D:XX\n") + EVPN_ASN_IP_HELP_STR) { struct bgp *bgp = VTY_GET_CONTEXT(bgp); VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn); diff --git a/bgpd/bgp_evpn_vty.h b/bgpd/bgp_evpn_vty.h index 4d07f7d038..33f6e4f1b6 100644 --- a/bgpd/bgp_evpn_vty.h +++ b/bgpd/bgp_evpn_vty.h @@ -28,4 +28,8 @@ extern void bgp_ethernetvpn_init(void); #define L2VPN_HELP_STR "Layer 2 Virtual Private Network\n" #define EVPN_HELP_STR "Ethernet Virtual Private Network\n" +/* Parse type from "type <ead|1|...>", return -1 on failure */ +extern int bgp_evpn_cli_parse_type(int *type, struct cmd_token **argv, + int argc); + #endif /* _QUAGGA_BGP_EVPN_VTY_H */ diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index 0308a30d54..3162579688 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -507,14 +507,16 @@ DEFUN(no_as_path, no_bgp_as_path_cmd, /* Lookup asfilter. */ asfilter = as_filter_lookup(aslist, regstr, type); - XFREE(MTYPE_TMP, regstr); bgp_regex_free(regex); if (asfilter == NULL) { - vty_out(vty, "\n"); + vty_out(vty, "Regex entered %s does not exist\n", regstr); + XFREE(MTYPE_TMP, regstr); return CMD_WARNING_CONFIG_FAILED; } + XFREE(MTYPE_TMP, regstr); + as_list_filter_delete(aslist, asfilter); return CMD_SUCCESS; diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c index 90e9236385..55e7973f81 100644 --- a/bgpd/bgp_flowspec_util.c +++ b/bgpd/bgp_flowspec_util.c @@ -20,6 +20,8 @@ #include "zebra.h" +#include "lib/printfrr.h" + #include "prefix.h" #include "lib_errors.h" @@ -211,14 +213,11 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type, switch (type) { case BGP_FLOWSPEC_RETURN_STRING: if (prefix_local.family == AF_INET6) { - char str[BGP_FLOWSPEC_STRING_DISPLAY_MAX]; int ret; - prefix2str(&prefix_local, str, - BGP_FLOWSPEC_STRING_DISPLAY_MAX); - ret = snprintf(display, BGP_FLOWSPEC_STRING_DISPLAY_MAX, - "%s/off %u", - str, prefix_offset); + ret = snprintfrr( + display, BGP_FLOWSPEC_STRING_DISPLAY_MAX, + "%pFX/off %u", &prefix_local, prefix_offset); if (ret < 0) { *error = -1; break; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index d7df707a36..4468408415 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -704,8 +704,8 @@ bool bgp_update_delay_configured(struct bgp *bgp) on ending the update delay. */ void bgp_update_delay_end(struct bgp *bgp) { - THREAD_TIMER_OFF(bgp->t_update_delay); - THREAD_TIMER_OFF(bgp->t_establish_wait); + THREAD_OFF(bgp->t_update_delay); + THREAD_OFF(bgp->t_establish_wait); /* Reset update-delay related state */ bgp->update_delay_over = 1; @@ -740,11 +740,12 @@ void bgp_update_delay_end(struct bgp *bgp) bgp->main_zebra_update_hold = 1; bgp->main_peers_update_hold = 1; - /* Resume the queue processing. This should trigger the event that would - take - care of processing any work that was queued during the read-only - mode. */ - work_queue_unplug(bm->process_main_queue); + /* + * Resume the queue processing. This should trigger the event that would + * take care of processing any work that was queued during the read-only + * mode. + */ + work_queue_unplug(bgp->process_queue); } /** @@ -923,7 +924,7 @@ static int bgp_maxmed_onstartup_timer(struct thread *thread) zlog_info("Max med on startup ended - timer expired."); bgp = THREAD_ARG(thread); - THREAD_TIMER_OFF(bgp->t_maxmed_onstartup); + THREAD_OFF(bgp->t_maxmed_onstartup); bgp->maxmed_onstartup_over = 1; bgp_maxmed_update(bgp); @@ -967,7 +968,7 @@ static int bgp_update_delay_timer(struct thread *thread) zlog_info("Update delay ended - timer expired."); bgp = THREAD_ARG(thread); - THREAD_TIMER_OFF(bgp->t_update_delay); + THREAD_OFF(bgp->t_update_delay); bgp_update_delay_end(bgp); return 0; @@ -981,7 +982,7 @@ static int bgp_establish_wait_timer(struct thread *thread) zlog_info("Establish wait - timer expired."); bgp = THREAD_ARG(thread); - THREAD_TIMER_OFF(bgp->t_establish_wait); + THREAD_OFF(bgp->t_establish_wait); bgp_check_update_delay(bgp); return 0; @@ -997,7 +998,7 @@ static void bgp_update_delay_begin(struct bgp *bgp) struct peer *peer; /* Stop the processing of queued work. Enqueue shall continue */ - work_queue_plug(bm->process_main_queue); + work_queue_plug(bgp->process_queue); for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) peer->update_delay_over = 0; diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 85c0eccc26..b9156df617 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -31,8 +31,7 @@ #define BGP_TIMER_OFF(T) \ do { \ - if (T) \ - THREAD_TIMER_OFF(T); \ + THREAD_OFF(T); \ } while (0) #define BGP_EVENT_ADD(P, E) \ diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index 412c8e3e5e..38455b5e02 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -31,7 +31,7 @@ #include "network.h" // for ERRNO_IO_RETRY #include "stream.h" // for stream_get_endp, stream_getw_from, str... #include "ringbuf.h" // for ringbuf_remain, ringbuf_peek, ringbuf_... -#include "thread.h" // for THREAD_OFF, THREAD_ARG, thread, thread... +#include "thread.h" // for THREAD_OFF, THREAD_ARG, thread... #include "zassert.h" // for assert #include "bgpd/bgp_io.h" @@ -39,6 +39,7 @@ #include "bgpd/bgp_errors.h" // for expanded error reference information #include "bgpd/bgp_fsm.h" // for BGP_EVENT_ADD, bgp_event #include "bgpd/bgp_packet.h" // for bgp_notify_send_with_data, bgp_notify... +#include "bgpd/bgp_trace.h" // for frrtraces #include "bgpd/bgpd.h" // for peer, BGP_MARKER_SIZE, bgp_master, bm /* clang-format on */ @@ -234,6 +235,7 @@ static int bgp_process_reads(struct thread *thread) assert(ringbuf_get(ibw, pkt->data, pktsize) == pktsize); stream_set_endp(pkt, pktsize); + frrtrace(2, frr_bgp, packet_read, peer, pkt); frr_with_mutex(&peer->io_mtx) { stream_fifo_push(peer->ibuf, pkt); } diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index fba954c432..4f440cd1f8 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -215,7 +215,6 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi, int command; uint16_t flags = 0; size_t flags_pos = 0; - char addr[PREFIX_STRLEN]; p = bgp_dest_get_prefix(dest); local_label = &(dest->local_label); @@ -242,11 +241,11 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi, * always takes precedence over auto-assigned labels. */ if (!have_label_to_reg) { - if (BGP_DEBUG(labelpool, LABELPOOL)) { - prefix2str(p, addr, PREFIX_STRLEN); - zlog_debug("%s: Requesting label from LP for %s", - __func__, addr); - } + if (BGP_DEBUG(labelpool, LABELPOOL)) + zlog_debug( + "%s: Requesting label from LP for %pFX", + __func__, p); + /* bgp_reg_for_label_callback() will call back * __func__ when it gets a label from the pool. * This means we'll never register FECs without @@ -422,8 +421,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, */ flog_err( EC_BGP_UPDATE_RCV, - "%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring", - peer->host, inet_ntoa(p.u.prefix4)); + "%s: IPv4 labeled-unicast NLRI is multicast address %pI4, ignoring", + peer->host, &p.u.prefix4); continue; } } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index b082aa9c6a..21c880e95b 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -60,6 +60,9 @@ #include "bgpd/bgp_keepalives.h" #include "bgpd/bgp_network.h" #include "bgpd/bgp_errors.h" +#include "lib/routing_nb.h" +#include "bgpd/bgp_nb.h" +#include "bgpd/bgp_evpn_mh.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -205,6 +208,8 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) if (bgp_default) bgp_delete(bgp_default); + bgp_evpn_mh_finish(); + /* reverse bgp_dump_init */ bgp_dump_finish(); @@ -370,9 +375,11 @@ static void bgp_vrf_terminate(void) } static const struct frr_yang_module_info *const bgpd_yang_modules[] = { + &frr_bgp_info, &frr_filter_info, &frr_interface_info, &frr_route_map_info, + &frr_routing_info, &frr_vrf_info, }; @@ -497,6 +504,10 @@ int main(int argc, char **argv) /* Initializations. */ bgp_vrf_init(); + hook_register(routing_conf_event, + routing_control_plane_protocols_name_validate); + + /* BGP related initialization. */ bgp_init((unsigned short)instance); diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index b7f516eaf7..ff5cfe05fb 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -412,8 +412,9 @@ static void bgp_path_info_mpath_lb_update(struct bgp_path_info *path, bool set, struct bgp_path_info_mpath *mpath; if ((mpath = path->mpath) == NULL) { - if (!set) + if (!set || (cum_bw == 0 && !all_paths_lb)) return; + mpath = bgp_path_info_mpath_get(path); if (!mpath) return; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 5ef3cf736d..0c527efb8c 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -506,7 +506,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ if (debug) zlog_debug( - "%s: entry: leak-to=%s, p=%pRN, type=%d, sub_type=%d", + "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d", __func__, bgp->name_pretty, bn, source_bpi->type, source_bpi->sub_type); @@ -547,7 +547,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ bgp_attr_unintern(&new_attr); if (debug) zlog_debug( - "%s: ->%s: %pRN: Found route, no change", + "%s: ->%s: %pBD: Found route, no change", __func__, bgp->name_pretty, bn); return NULL; } @@ -608,7 +608,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ bgp_dest_unlock_node(bn); if (debug) - zlog_debug("%s: ->%s: %pRN Found route, changed attr", + zlog_debug("%s: ->%s: %pBD Found route, changed attr", __func__, bgp->name_pretty, bn); return bpi; @@ -674,7 +674,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ bgp_process(bgp, bn, afi, safi); if (debug) - zlog_debug("%s: ->%s: %pRN: Added new route", __func__, + zlog_debug("%s: ->%s: %pBD: Added new route", __func__, bgp->name_pretty, bn); return new; @@ -929,7 +929,7 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */ if (debug) { zlog_debug( - "%s: entry: leak-from=%s, p=%pRN, type=%d, sub_type=%d", + "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d", __func__, bgp_vrf->name_pretty, path_vrf->net, path_vrf->type, path_vrf->sub_type); } @@ -1009,7 +1009,7 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */ for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) { bpi = bgp_dest_get_bgp_path_info(bn); if (debug && bpi) { - zlog_debug("%s: looking at prefix %pRN", + zlog_debug("%s: looking at prefix %pBD", __func__, bn); } @@ -1106,13 +1106,9 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ return; } - if (debug) { - char buf_prefix[PREFIX_STRLEN]; - - prefix2str(p, buf_prefix, sizeof(buf_prefix)); - zlog_debug("%s: updating %s to vrf %s", __func__, - buf_prefix, bgp_vrf->name_pretty); - } + if (debug) + zlog_debug("%s: updating %pFX to vrf %s", __func__, p, + bgp_vrf->name_pretty); /* shallow copy */ static_attr = *path_vpn->attr; @@ -1262,7 +1258,7 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ } if (debug) - zlog_debug("%s: pfx %pRN: num_labels %d", __func__, + zlog_debug("%s: pfx %pBD: num_labels %d", __func__, path_vpn->net, num_labels); /* @@ -1315,7 +1311,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */ int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF); if (debug) - zlog_debug("%s: entry: p=%pRN, type=%d, sub_type=%d", __func__, + zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__, path_vpn->net, path_vpn->type, path_vpn->sub_type); if (debug) @@ -2581,7 +2577,7 @@ void vpn_leak_postchange_all(void) * also VRF Y should unimport its routes from VRF X table. * This will ensure VPN table is cleaned up appropriately. */ -int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty) +void bgp_vpn_leak_unimport(struct bgp *from_bgp) { struct bgp *to_bgp; const char *tmp_name; @@ -2593,7 +2589,7 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty) int debug; if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF) - return 0; + return; debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF)); @@ -2662,7 +2658,7 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty) } } } - return 0; + return; } /* When a router bgp is configured, there could be a bgp vrf @@ -2691,8 +2687,7 @@ void bgp_vpn_leak_export(struct bgp *from_bgp) idir = BGP_VPN_POLICY_DIR_FROMVPN; edir = BGP_VPN_POLICY_DIR_TOVPN; - export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name) - : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME)); + export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME; for (afi = 0; afi < AFI_MAX; ++afi) { /* vrf leak is for IPv4 and IPv6 Unicast only */ diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index ccd0d96169..df2544d608 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -266,7 +266,7 @@ extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); extern void vpn_leak_postchange_all(void); extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, bool is_config); -extern int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty); +extern void bgp_vpn_leak_unimport(struct bgp *from_bgp); extern void bgp_vpn_leak_export(struct bgp *from_bgp); #endif /* _QUAGGA_BGP_MPLSVPN_H */ diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c new file mode 100644 index 0000000000..333ca3cce9 --- /dev/null +++ b/bgpd/bgp_nb.c @@ -0,0 +1,7889 @@ +/* + * Bgp northbound callbacks registery + * Copyright (C) 2020 Nvidia + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "northbound.h" +#include "libfrr.h" +#include "bgpd/bgp_nb.h" + +/* clang-format off */ +const struct frr_yang_module_info frr_bgp_info = { + .name = "frr-bgp", + .nodes = { + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp", + .cbs = { + .cli_show = cli_show_router_bgp, + .create = bgp_router_create, + .destroy = bgp_router_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-as", + .cbs = { + .modify = bgp_global_local_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/router-id", + .cbs = { + .cli_show = cli_show_router_bgp_router_id, + .modify = bgp_global_router_id_modify, + .destroy = bgp_global_router_id_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/identifier", + .cbs = { + .cli_show = cli_show_router_bgp_confederation_identifier, + .modify = bgp_global_confederation_identifier_modify, + .destroy = bgp_global_confederation_identifier_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/member-as", + .cbs = { + .cli_show = cli_show_router_bgp_confederation_member_as, + .create = bgp_global_confederation_member_as_create, + .destroy = bgp_global_confederation_member_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config", + .cbs = { + .cli_show = cli_show_router_bgp_med_config, + .apply_finish = bgp_global_med_config_apply_finish, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/enable-med-admin", + .cbs = { + .modify = bgp_global_med_config_enable_med_admin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-admin", + .cbs = { + .modify = bgp_global_med_config_max_med_admin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-time", + .cbs = { + .modify = bgp_global_med_config_max_med_onstart_up_time_modify, + .destroy = bgp_global_med_config_max_med_onstart_up_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-value", + .cbs = { + .modify = bgp_global_med_config_max_med_onstart_up_value_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector", + .cbs = { + .cli_show = cli_show_router_bgp_route_reflector, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/route-reflector-cluster-id", + .cbs = { + .modify = bgp_global_route_reflector_route_reflector_cluster_id_modify, + .destroy = bgp_global_route_reflector_route_reflector_cluster_id_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/no-client-reflect", + .cbs = { + .modify = bgp_global_route_reflector_no_client_reflect_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/allow-outbound-policy", + .cbs = { + .modify = bgp_global_route_reflector_allow_outbound_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options", + .cbs = { + .apply_finish = bgp_global_route_selection_options_apply_finish, + .cli_show = cli_show_router_bgp_route_selection, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/always-compare-med", + .cbs = { + .modify = bgp_global_route_selection_options_always_compare_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/deterministic-med", + .cbs = { + .modify = bgp_global_route_selection_options_deterministic_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/confed-med", + .cbs = { + .modify = bgp_global_route_selection_options_confed_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/missing-as-worst-med", + .cbs = { + .modify = bgp_global_route_selection_options_missing_as_worst_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/aspath-confed", + .cbs = { + .modify = bgp_global_route_selection_options_aspath_confed_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/ignore-as-path-length", + .cbs = { + .modify = bgp_global_route_selection_options_ignore_as_path_length_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/external-compare-router-id", + .cbs = { + .modify = bgp_global_route_selection_options_external_compare_router_id_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/allow-multiple-as", + .cbs = { + .modify = bgp_global_route_selection_options_allow_multiple_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/multi-path-as-set", + .cbs = { + .modify = bgp_global_route_selection_options_multi_path_as_set_modify, + .destroy = bgp_global_route_selection_options_multi_path_as_set_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config", + .cbs = { + .cli_show = cli_show_router_global_neighbor_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/dynamic-neighbors-limit", + .cbs = { + .modify = bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify, + .destroy = bgp_global_global_neighbor_config_dynamic_neighbors_limit_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/log-neighbor-changes", + .cbs = { + .modify = bgp_global_global_neighbor_config_log_neighbor_changes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/wpkt-quanta", + .cbs = { + .modify = bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/rpkt-quanta", + .cbs = { + .modify = bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/enabled", + .cbs = { + .modify = bgp_global_graceful_restart_enabled_modify, + .destroy = bgp_global_graceful_restart_enabled_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/graceful-restart-disable", + .cbs = { + .modify = bgp_global_graceful_restart_graceful_restart_disable_modify, + .destroy = bgp_global_graceful_restart_graceful_restart_disable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/preserve-fw-entry", + .cbs = { + .modify = bgp_global_graceful_restart_preserve_fw_entry_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/restart-time", + .cbs = { + .modify = bgp_global_graceful_restart_restart_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/stale-routes-time", + .cbs = { + .modify = bgp_global_graceful_restart_stale_routes_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/selection-deferral-time", + .cbs = { + .modify = bgp_global_graceful_restart_selection_deferral_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/rib-stale-time", + .cbs = { + .modify = bgp_global_graceful_restart_rib_stale_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/subgroup-pkt-queue-size", + .cbs = { + .cli_show = cli_show_router_global_update_group_config_subgroup_pkt_queue_size, + .modify = bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/coalesce-time", + .cbs = { + .cli_show = cli_show_router_global_update_group_config_coalesce_time, + .modify = bgp_global_global_update_group_config_coalesce_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/rmap-delay-time", + .cbs = { + .modify = bgp_global_global_config_timers_rmap_delay_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/update-delay-time", + .cbs = { + .modify = bgp_global_global_config_timers_update_delay_time_modify, + .destroy = bgp_global_global_config_timers_update_delay_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/establish-wait-time", + .cbs = { + .modify = bgp_global_global_config_timers_establish_wait_time_modify, + .destroy = bgp_global_global_config_timers_establish_wait_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/connect-retry-interval", + .cbs = { + .modify = bgp_global_global_config_timers_connect_retry_interval_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/hold-time", + .cbs = { + .modify = bgp_global_global_config_timers_hold_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/keepalive", + .cbs = { + .modify = bgp_global_global_config_timers_keepalive_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/instance-type-view", + .cbs = { + .modify = bgp_global_instance_type_view_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-multihop-connected-route-check", + .cbs = { + .cli_show = cli_show_router_global_ebgp_multihop_connected_route_check, + .modify = bgp_global_ebgp_multihop_connected_route_check_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/fast-external-failover", + .cbs = { + .cli_show = cli_show_router_bgp_fast_external_failover, + .modify = bgp_global_fast_external_failover_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-pref", + .cbs = { + .cli_show = cli_show_router_bgp_local_pref, + .modify = bgp_global_local_pref_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/default-shutdown", + .cbs = { + .cli_show = cli_show_router_bgp_default_shutdown, + .modify = bgp_global_default_shutdown_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-requires-policy", + .cbs = { + .cli_show = cli_show_router_bgp_ebgp_requires_policy, + .modify = bgp_global_ebgp_requires_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-hostname", + .cbs = { + .cli_show = cli_show_router_bgp_show_hostname, + .modify = bgp_global_show_hostname_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-nexthop-hostname", + .cbs = { + .cli_show = cli_show_router_bgp_show_nexthop_hostname, + .modify = bgp_global_show_nexthop_hostname_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/import-check", + .cbs = { + .cli_show = cli_show_router_bgp_import_check, + .modify = bgp_global_import_check_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-shutdown/enable", + .cbs = { + .cli_show = cli_show_router_bgp_graceful_shutdown, + .modify = bgp_global_graceful_shutdown_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list", + .cbs = { + .create = bgp_global_bmp_config_target_list_create, + .destroy = bgp_global_bmp_config_target_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/incoming-session/session-list", + .cbs = { + .create = bgp_global_bmp_config_target_list_incoming_session_session_list_create, + .destroy = bgp_global_bmp_config_target_list_incoming_session_session_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list", + .cbs = { + .create = bgp_global_bmp_config_target_list_outgoing_session_session_list_create, + .destroy = bgp_global_bmp_config_target_list_outgoing_session_session_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/min-retry-time", + .cbs = { + .modify = bgp_global_bmp_config_target_list_outgoing_session_session_list_min_retry_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/max-retry-time", + .cbs = { + .modify = bgp_global_bmp_config_target_list_outgoing_session_session_list_max_retry_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/mirror", + .cbs = { + .modify = bgp_global_bmp_config_target_list_mirror_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/stats-time", + .cbs = { + .modify = bgp_global_bmp_config_target_list_stats_time_modify, + .destroy = bgp_global_bmp_config_target_list_stats_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv4-access-list", + .cbs = { + .modify = bgp_global_bmp_config_target_list_ipv4_access_list_modify, + .destroy = bgp_global_bmp_config_target_list_ipv4_access_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv6-access-list", + .cbs = { + .modify = bgp_global_bmp_config_target_list_ipv6_access_list_modify, + .destroy = bgp_global_bmp_config_target_list_ipv6_access_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi", + .cbs = { + .create = bgp_global_bmp_config_target_list_afi_safis_afi_safi_create, + .destroy = bgp_global_bmp_config_target_list_afi_safis_afi_safi_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/mirror-buffer-limit", + .cbs = { + .modify = bgp_global_bmp_config_mirror_buffer_limit_modify, + .destroy = bgp_global_bmp_config_mirror_buffer_limit_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_create, + .destroy = bgp_global_afi_safis_afi_safi_destroy, + .cli_show = cli_show_bgp_global_afi_safi_header, + .cli_show_end = cli_show_bgp_global_afi_safi_header_end, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor", + .cbs = { + .create = bgp_neighbors_neighbor_create, + .destroy = bgp_neighbors_neighbor_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-interface", + .cbs = { + .modify = bgp_neighbors_neighbor_local_interface_modify, + .destroy = bgp_neighbors_neighbor_local_interface_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-port", + .cbs = { + .modify = bgp_neighbors_neighbor_local_port_modify, + .destroy = bgp_neighbors_neighbor_local_port_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/peer-group", + .cbs = { + .modify = bgp_neighbors_neighbor_peer_group_modify, + .destroy = bgp_neighbors_neighbor_peer_group_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/password", + .cbs = { + .modify = bgp_neighbors_neighbor_password_modify, + .destroy = bgp_neighbors_neighbor_password_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ttl-security", + .cbs = { + .modify = bgp_neighbors_neighbor_ttl_security_modify, + .destroy = bgp_neighbors_neighbor_ttl_security_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/solo", + .cbs = { + .modify = bgp_neighbors_neighbor_solo_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/enforce-first-as", + .cbs = { + .modify = bgp_neighbors_neighbor_enforce_first_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/description", + .cbs = { + .modify = bgp_neighbors_neighbor_description_modify, + .destroy = bgp_neighbors_neighbor_description_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/passive-mode", + .cbs = { + .modify = bgp_neighbors_neighbor_passive_mode_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/dynamic-capability", + .cbs = { + .modify = bgp_neighbors_neighbor_capability_options_dynamic_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/strict-capability", + .cbs = { + .modify = bgp_neighbors_neighbor_capability_options_strict_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/extended-nexthop-capability", + .cbs = { + .modify = bgp_neighbors_neighbor_capability_options_extended_nexthop_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/capability-negotiate", + .cbs = { + .modify = bgp_neighbors_neighbor_capability_options_capability_negotiate_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/override-capability", + .cbs = { + .modify = bgp_neighbors_neighbor_capability_options_override_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/ip", + .cbs = { + .modify = bgp_neighbors_neighbor_update_source_ip_modify, + .destroy = bgp_neighbors_neighbor_update_source_ip_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/interface", + .cbs = { + .modify = bgp_neighbors_neighbor_update_source_interface_modify, + .destroy = bgp_neighbors_neighbor_update_source_interface_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as-type", + .cbs = { + .modify = bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as", + .cbs = { + .modify = bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify, + .destroy = bgp_neighbors_neighbor_neighbor_remote_as_remote_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/enabled", + .cbs = { + .modify = bgp_neighbors_neighbor_ebgp_multihop_enabled_modify, + .destroy = bgp_neighbors_neighbor_ebgp_multihop_enabled_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/multihop-ttl", + .cbs = { + .modify = bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_modify, + .destroy = bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/disable-connected-check", + .cbs = { + .modify = bgp_neighbors_neighbor_ebgp_multihop_disable_connected_check_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/local-as", + .cbs = { + .modify = bgp_neighbors_neighbor_local_as_local_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-prepend", + .cbs = { + .modify = bgp_neighbors_neighbor_local_as_no_prepend_modify, + .destroy = bgp_neighbors_neighbor_local_as_no_prepend_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-replace-as", + .cbs = { + .modify = bgp_neighbors_neighbor_local_as_no_replace_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/enable", + .cbs = { + .modify = bgp_neighbors_neighbor_bfd_options_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/detect-multiplier", + .cbs = { + .modify = bgp_neighbors_neighbor_bfd_options_detect_multiplier_modify, + .destroy = bgp_neighbors_neighbor_bfd_options_detect_multiplier_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/required-min-rx", + .cbs = { + .modify = bgp_neighbors_neighbor_bfd_options_required_min_rx_modify, + .destroy = bgp_neighbors_neighbor_bfd_options_required_min_rx_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/desired-min-tx", + .cbs = { + .modify = bgp_neighbors_neighbor_bfd_options_desired_min_tx_modify, + .destroy = bgp_neighbors_neighbor_bfd_options_desired_min_tx_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/session-type", + .cbs = { + .modify = bgp_neighbors_neighbor_bfd_options_session_type_modify, + .destroy = bgp_neighbors_neighbor_bfd_options_session_type_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/check-cp-failure", + .cbs = { + .modify = bgp_neighbors_neighbor_bfd_options_check_cp_failure_modify, + .destroy = bgp_neighbors_neighbor_bfd_options_check_cp_failure_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/enable", + .cbs = { + .modify = bgp_neighbors_neighbor_admin_shutdown_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/message", + .cbs = { + .modify = bgp_neighbors_neighbor_admin_shutdown_message_modify, + .destroy = bgp_neighbors_neighbor_admin_shutdown_message_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/enable", + .cbs = { + .modify = bgp_neighbors_neighbor_graceful_restart_enable_modify, + .destroy = bgp_neighbors_neighbor_graceful_restart_enable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-helper", + .cbs = { + .modify = bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_modify, + .destroy = bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-disable", + .cbs = { + .modify = bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_modify, + .destroy = bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/advertise-interval", + .cbs = { + .modify = bgp_neighbors_neighbor_timers_advertise_interval_modify, + .destroy = bgp_neighbors_neighbor_timers_advertise_interval_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/connect-time", + .cbs = { + .modify = bgp_neighbors_neighbor_timers_connect_time_modify, + .destroy = bgp_neighbors_neighbor_timers_connect_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/hold-time", + .cbs = { + .modify = bgp_neighbors_neighbor_timers_hold_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/keepalive", + .cbs = { + .modify = bgp_neighbors_neighbor_timers_keepalive_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/enabled", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_enabled_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_create, + .destroy = bgp_neighbors_unnumbered_neighbor_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/v6only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_v6only_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/peer-group", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_peer_group_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_peer_group_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/password", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_password_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_password_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ttl-security", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_ttl_security_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_ttl_security_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/solo", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_solo_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/enforce-first-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_enforce_first_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/description", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_description_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_description_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/passive-mode", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_passive_mode_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/dynamic-capability", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_capability_options_dynamic_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/strict-capability", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_capability_options_strict_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/extended-nexthop-capability", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_capability_options_extended_nexthop_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/capability-negotiate", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_capability_options_capability_negotiate_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/override-capability", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_capability_options_override_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/ip", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_update_source_ip_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_update_source_ip_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/interface", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_update_source_interface_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_update_source_interface_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/enabled", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/multihop-ttl", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/disable-connected-check", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_disable_connected_check_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/local-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_local_as_local_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-prepend", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-replace-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/enable", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/detect-multiplier", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/required-min-rx", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/desired-min-tx", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/session-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/check-cp-failure", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/enable", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_admin_shutdown_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/message", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/enable", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-helper", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-disable", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/advertise-interval", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/connect-time", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_timers_connect_time_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_timers_connect_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/hold-time", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_timers_hold_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/keepalive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_timers_keepalive_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/enabled", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_enabled_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group", + .cbs = { + .create = bgp_peer_groups_peer_group_create, + .destroy = bgp_peer_groups_peer_group_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv4-listen-range", + .cbs = { + .create = bgp_peer_groups_peer_group_ipv4_listen_range_create, + .destroy = bgp_peer_groups_peer_group_ipv4_listen_range_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv6-listen-range", + .cbs = { + .create = bgp_peer_groups_peer_group_ipv6_listen_range_create, + .destroy = bgp_peer_groups_peer_group_ipv6_listen_range_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/password", + .cbs = { + .modify = bgp_peer_groups_peer_group_password_modify, + .destroy = bgp_peer_groups_peer_group_password_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ttl-security", + .cbs = { + .modify = bgp_peer_groups_peer_group_ttl_security_modify, + .destroy = bgp_peer_groups_peer_group_ttl_security_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/solo", + .cbs = { + .modify = bgp_peer_groups_peer_group_solo_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/enforce-first-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_enforce_first_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/description", + .cbs = { + .modify = bgp_peer_groups_peer_group_description_modify, + .destroy = bgp_peer_groups_peer_group_description_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/passive-mode", + .cbs = { + .modify = bgp_peer_groups_peer_group_passive_mode_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/dynamic-capability", + .cbs = { + .modify = bgp_peer_groups_peer_group_capability_options_dynamic_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/strict-capability", + .cbs = { + .modify = bgp_peer_groups_peer_group_capability_options_strict_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/extended-nexthop-capability", + .cbs = { + .modify = bgp_peer_groups_peer_group_capability_options_extended_nexthop_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/capability-negotiate", + .cbs = { + .modify = bgp_peer_groups_peer_group_capability_options_capability_negotiate_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/override-capability", + .cbs = { + .modify = bgp_peer_groups_peer_group_capability_options_override_capability_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/ip", + .cbs = { + .modify = bgp_peer_groups_peer_group_update_source_ip_modify, + .destroy = bgp_peer_groups_peer_group_update_source_ip_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/interface", + .cbs = { + .modify = bgp_peer_groups_peer_group_update_source_interface_modify, + .destroy = bgp_peer_groups_peer_group_update_source_interface_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_modify, + .destroy = bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/enabled", + .cbs = { + .modify = bgp_peer_groups_peer_group_ebgp_multihop_enabled_modify, + .destroy = bgp_peer_groups_peer_group_ebgp_multihop_enabled_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/multihop-ttl", + .cbs = { + .modify = bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_modify, + .destroy = bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/disable-connected-check", + .cbs = { + .modify = bgp_peer_groups_peer_group_ebgp_multihop_disable_connected_check_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/local-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_local_as_local_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-prepend", + .cbs = { + .modify = bgp_peer_groups_peer_group_local_as_no_prepend_modify, + .destroy = bgp_peer_groups_peer_group_local_as_no_prepend_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_local_as_no_replace_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/enable", + .cbs = { + .modify = bgp_peer_groups_peer_group_bfd_options_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/detect-multiplier", + .cbs = { + .modify = bgp_peer_groups_peer_group_bfd_options_detect_multiplier_modify, + .destroy = bgp_peer_groups_peer_group_bfd_options_detect_multiplier_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/required-min-rx", + .cbs = { + .modify = bgp_peer_groups_peer_group_bfd_options_required_min_rx_modify, + .destroy = bgp_peer_groups_peer_group_bfd_options_required_min_rx_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/desired-min-tx", + .cbs = { + .modify = bgp_peer_groups_peer_group_bfd_options_desired_min_tx_modify, + .destroy = bgp_peer_groups_peer_group_bfd_options_desired_min_tx_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/session-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_bfd_options_session_type_modify, + .destroy = bgp_peer_groups_peer_group_bfd_options_session_type_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/check-cp-failure", + .cbs = { + .modify = bgp_peer_groups_peer_group_bfd_options_check_cp_failure_modify, + .destroy = bgp_peer_groups_peer_group_bfd_options_check_cp_failure_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/enable", + .cbs = { + .modify = bgp_peer_groups_peer_group_admin_shutdown_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/message", + .cbs = { + .modify = bgp_peer_groups_peer_group_admin_shutdown_message_modify, + .destroy = bgp_peer_groups_peer_group_admin_shutdown_message_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/enable", + .cbs = { + .modify = bgp_peer_groups_peer_group_graceful_restart_enable_modify, + .destroy = bgp_peer_groups_peer_group_graceful_restart_enable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-helper", + .cbs = { + .modify = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_modify, + .destroy = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-disable", + .cbs = { + .modify = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_modify, + .destroy = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/advertise-interval", + .cbs = { + .modify = bgp_peer_groups_peer_group_timers_advertise_interval_modify, + .destroy = bgp_peer_groups_peer_group_timers_advertise_interval_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/connect-time", + .cbs = { + .modify = bgp_peer_groups_peer_group_timers_connect_time_modify, + .destroy = bgp_peer_groups_peer_group_timers_connect_time_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/hold-time", + .cbs = { + .modify = bgp_peer_groups_peer_group_timers_hold_time_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/keepalive", + .cbs = { + .modify = bgp_peer_groups_peer_group_timers_keepalive_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/enabled", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/backdoor", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/label-index", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_aggregate_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/distance", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_distance_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/access-list-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ebgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/cluster-length-list", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/metric", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/rmap-policy-import", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_admin_distance_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rd", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label-auto", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/nexthop", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-vpn", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vrf-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-import", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/redirect-rt", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-rt-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-rt-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rt-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/label-index", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_aggregate_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/distance", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/access-list-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/cluster-length-list", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/rmap-policy-import", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_admin_distance_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rd", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label-auto", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/nexthop", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vpn", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-vpn", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vrf-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-import", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/redirect-rt", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-rt-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-rt-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rt-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ebgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify, + .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp", + .cbs = { + .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/maximum-paths", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/backdoor", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/label-index", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/as-set", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/summary-only", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/distance", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/access-list-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/backdoor", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_backdoor_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/label-index", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/as-set", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_as_set_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/summary-only", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_summary_only_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/origin", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/match-med", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/suppress-map", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route", + .cbs = { + .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish, + .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy, + .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/distance", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/access-list-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish, + .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/enable", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reuse-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/suppress-above", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/unreach-decay", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-flowspec/flow-spec-config/interface", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify, + .destroy = bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config", + .cbs = { + .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish, + .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create, + .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy, + .cli_show = cli_show_bgp_global_afi_safi_network_config, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_create, + .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/label-index", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_label_index_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_create, + .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list", + .cbs = { + .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_create, + .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/label-index", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_label_index_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/rmap-policy-export", + .cbs = { + .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_modify, + .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/pre-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_pre_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/post-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_post_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/pre-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_pre_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/post-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_post_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/pre-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_pre_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/post-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_post_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/pre-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_pre_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/post-policy", + .cbs = { + .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_post_policy_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list", + .cbs = { + .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify, + } + }, + { + .xpath = NULL, + }, + } +}; diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h new file mode 100644 index 0000000000..532021425f --- /dev/null +++ b/bgpd/bgp_nb.h @@ -0,0 +1,3596 @@ +/* + * Bgp northbound callbacks api interfaces + * Copyright (C) 2020 Nvidia + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_BGP_NB_H_ +#define _FRR_BGP_NB_H_ + +#include "northbound.h" + +extern const struct frr_yang_module_info frr_bgp_info; + +/* prototypes */ +int bgp_router_create(struct nb_cb_create_args *args); +int bgp_router_destroy(struct nb_cb_destroy_args *args); +int bgp_global_local_as_modify(struct nb_cb_modify_args *args); +int bgp_global_router_id_modify(struct nb_cb_modify_args *args); +int bgp_global_router_id_destroy(struct nb_cb_destroy_args *args); +int bgp_global_confederation_identifier_modify(struct nb_cb_modify_args *args); +int bgp_global_confederation_identifier_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_confederation_member_as_create(struct nb_cb_create_args *args); +int bgp_global_confederation_member_as_destroy(struct nb_cb_destroy_args *args); +int bgp_global_med_config_enable_med_admin_modify( + struct nb_cb_modify_args *args); +int bgp_global_med_config_max_med_admin_modify(struct nb_cb_modify_args *args); +int bgp_global_med_config_max_med_onstart_up_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_med_config_max_med_onstart_up_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_med_config_max_med_onstart_up_value_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_reflector_route_reflector_cluster_id_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_reflector_route_reflector_cluster_id_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_route_reflector_no_client_reflect_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_reflector_allow_outbound_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_always_compare_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_deterministic_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_confed_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_missing_as_worst_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_aspath_confed_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_ignore_as_path_length_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_external_compare_router_id_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_allow_multiple_as_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_multi_path_as_set_modify( + struct nb_cb_modify_args *args); +int bgp_global_route_selection_options_multi_path_as_set_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_neighbor_config_dynamic_neighbors_limit_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_global_neighbor_config_log_neighbor_changes_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_modify( + struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_enabled_modify(struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_enabled_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_graceful_restart_preserve_fw_entry_modify( + struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_restart_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_stale_routes_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_selection_deferral_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_graceful_restart_rib_stale_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_update_group_config_coalesce_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_config_timers_rmap_delay_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_config_timers_update_delay_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_config_timers_update_delay_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_global_config_timers_establish_wait_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_config_timers_establish_wait_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_global_config_timers_connect_retry_interval_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_config_timers_hold_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_global_config_timers_keepalive_modify( + struct nb_cb_modify_args *args); +int bgp_global_instance_type_view_modify(struct nb_cb_modify_args *args); +int bgp_global_ebgp_multihop_connected_route_check_modify( + struct nb_cb_modify_args *args); +int bgp_global_fast_external_failover_modify(struct nb_cb_modify_args *args); +int bgp_global_local_pref_modify(struct nb_cb_modify_args *args); +int bgp_global_default_shutdown_modify(struct nb_cb_modify_args *args); +int bgp_global_ebgp_requires_policy_modify(struct nb_cb_modify_args *args); +int bgp_global_show_hostname_modify(struct nb_cb_modify_args *args); +int bgp_global_show_nexthop_hostname_modify(struct nb_cb_modify_args *args); +int bgp_global_import_check_modify(struct nb_cb_modify_args *args); +int bgp_global_graceful_shutdown_enable_modify(struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_create(struct nb_cb_create_args *args); +int bgp_global_bmp_config_target_list_destroy(struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_incoming_session_session_list_create( + struct nb_cb_create_args *args); +int bgp_global_bmp_config_target_list_incoming_session_session_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_outgoing_session_session_list_create( + struct nb_cb_create_args *args); +int bgp_global_bmp_config_target_list_outgoing_session_session_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_outgoing_session_session_list_min_retry_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_outgoing_session_session_list_max_retry_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_mirror_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_stats_time_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_stats_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_ipv4_access_list_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_ipv4_access_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_ipv6_access_list_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_ipv6_access_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_create( + struct nb_cb_create_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_mirror_buffer_limit_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_mirror_buffer_limit_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_create(struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_create(struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_local_interface_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_local_interface_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_local_port_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_local_port_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_peer_group_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_peer_group_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_password_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_password_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_ttl_security_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_ttl_security_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_solo_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_enforce_first_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_description_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_description_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_passive_mode_modify(struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_capability_options_dynamic_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_capability_options_strict_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_capability_options_extended_nexthop_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_capability_options_capability_negotiate_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_capability_options_override_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_update_source_ip_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_update_source_ip_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_update_source_interface_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_update_source_interface_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_ebgp_multihop_enabled_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_ebgp_multihop_enabled_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_ebgp_multihop_disable_connected_check_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_local_as_local_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_local_as_no_prepend_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_local_as_no_prepend_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_local_as_no_replace_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_enable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_detect_multiplier_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_detect_multiplier_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_bfd_options_required_min_rx_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_required_min_rx_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_bfd_options_desired_min_tx_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_desired_min_tx_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_bfd_options_session_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_session_type_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_bfd_options_check_cp_failure_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_bfd_options_check_cp_failure_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_admin_shutdown_enable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_admin_shutdown_message_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_admin_shutdown_message_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_graceful_restart_enable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_graceful_restart_enable_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_timers_advertise_interval_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_timers_advertise_interval_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_timers_connect_time_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_timers_connect_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_timers_hold_time_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_timers_keepalive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_enabled_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_create(struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_destroy(struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_v6only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_peer_group_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_peer_group_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_password_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_password_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_ttl_security_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_ttl_security_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_solo_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_enforce_first_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_description_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_description_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_passive_mode_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_capability_options_dynamic_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_capability_options_strict_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_capability_options_extended_nexthop_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_capability_options_capability_negotiate_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_capability_options_override_capability_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_update_source_ip_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_update_source_ip_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_update_source_interface_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_update_source_interface_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_disable_connected_check_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_local_as_local_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_admin_shutdown_enable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_timers_connect_time_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_timers_connect_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_timers_hold_time_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_timers_keepalive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_enabled_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_create(struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_destroy(struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_ipv4_listen_range_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_ipv4_listen_range_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_ipv6_listen_range_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_ipv6_listen_range_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_password_modify(struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_password_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_ttl_security_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_ttl_security_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_solo_modify(struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_enforce_first_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_description_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_description_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_passive_mode_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_capability_options_dynamic_capability_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_capability_options_strict_capability_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_capability_options_extended_nexthop_capability_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_capability_options_capability_negotiate_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_capability_options_override_capability_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_update_source_ip_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_update_source_ip_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_update_source_interface_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_update_source_interface_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_ebgp_multihop_enabled_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_ebgp_multihop_enabled_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_ebgp_multihop_disable_connected_check_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_local_as_local_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_local_as_no_prepend_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_local_as_no_prepend_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_local_as_no_replace_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_enable_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_bfd_options_required_min_rx_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_required_min_rx_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_bfd_options_session_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_session_type_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_admin_shutdown_enable_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_admin_shutdown_message_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_admin_shutdown_message_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_graceful_restart_enable_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_graceful_restart_enable_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_timers_advertise_interval_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_timers_advertise_interval_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_timers_connect_time_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_timers_connect_time_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_timers_hold_time_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_timers_keepalive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_label_index_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_create( + struct nb_cb_create_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_label_index_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args); +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args); + +/* + * Callback registered with routing_nb lib to validate only + * one instance of bgp instance is allowed + */ +int routing_control_plane_protocols_name_validate( + struct nb_cb_create_args *args); + +/* Optional 'cli_show' callbacks. */ +void cli_show_router_bgp(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_router_id(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_route_selection(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_ebgp_requires_policy(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_default_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_import_check(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_show_nexthop_hostname(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_fast_external_failover(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_global_neighbor_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_global_update_group_config_subgroup_pkt_queue_size( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_router_global_update_group_config_coalesce_time( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_router_global_ebgp_multihop_connected_route_check( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_router_bgp_local_pref(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_route_reflector(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_confederation_identifier(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_confederation_member_as(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_graceful_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_header(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_header_end(struct vty *vty, + struct lyd_node *dnode); +void cli_show_bgp_global_afi_safi_network_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_unicast_aggregate_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +void cli_show_bgp_global_afi_safi_unicast_admin_distance_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export( + struct vty *vty, struct lyd_node *dnode, bool show_defaults); + +void bgp_global_route_selection_options_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_network_config_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_aggregate_route_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_admin_distance_route_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish( + struct nb_cb_apply_finish_args *args); +void bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish( + struct nb_cb_apply_finish_args *args); + +/* xpath macros */ +/* route-list */ +#define FRR_BGP_GLOBAL_XPATH \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ + "frr-bgp:bgp" + +#define FRR_BGP_GLOBAL_AS_XPATH \ + "/frr-routing:routing/control-plane-protocols/" \ + "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ + "frr-bgp:bgp/local-as" +#define FRR_BGP_AFI_SAFI_REDIST_XPATH \ + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/" \ + "redistribution-list[route-type='%s'][route-instance='%s']" + +#endif diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c new file mode 100644 index 0000000000..66dfa2aea7 --- /dev/null +++ b/bgpd/bgp_nb_config.c @@ -0,0 +1,32481 @@ +/* + * Bgp northbound config callbacks + * Copyright (C) 2020 Nvidia + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "northbound.h" +#include "libfrr.h" +#include "log.h" +#include "bgpd/bgp_nb.h" +#include "bgpd/bgp_nb.h" +#include "bgpd/bgpd.h" +#include "bgpd/bgp_vty.h" +#include "bgpd/bgp_mplsvpn.h" +#include "bgpd/bgp_fsm.h" +#include "bgpd/bgp_addpath.h" +#include "bgpd/bgp_updgrp.h" +#include "bgpd/bgp_io.h" +#include "bgpd/bgp_damp.h" + +FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, + { .val_ulong = 10, .match_profile = "datacenter", }, + { .val_ulong = 120 }, +) +FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME, + { .val_ulong = 9, .match_profile = "datacenter", }, + { .val_ulong = 180 }, +) +FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE, + { .val_ulong = 3, .match_profile = "datacenter", }, + { .val_ulong = 60 }, +) + +int routing_control_plane_protocols_name_validate( + struct nb_cb_create_args *args) +{ + const char *name; + + name = yang_dnode_get_string(args->dnode, "./name"); + if (!strmatch(name, "bgp")) { + snprintf(args->errmsg, args->errmsg_len, + "per vrf only one bgp instance is supported."); + return NB_ERR_VALIDATION; + } + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp + */ +int bgp_router_create(struct nb_cb_create_args *args) +{ + const struct lyd_node *vrf_dnode; + struct bgp *bgp; + struct vrf *vrf; + const char *name = NULL; + as_t as; + enum bgp_instance_type inst_type; + bool is_view_inst = false; + int ret; + int is_new_bgp = 0; + + inst_type = BGP_INSTANCE_TYPE_DEFAULT; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf = nb_running_get_entry(vrf_dnode, NULL, true); + + if (strmatch(vrf->name, VRF_DEFAULT_NAME)) { + name = NULL; + } else { + name = vrf->name; + inst_type = BGP_INSTANCE_TYPE_VRF; + } + + as = yang_dnode_get_uint32(args->dnode, "./global/local-as"); + + is_view_inst = yang_dnode_get_bool( + args->dnode, "./global/instance-type-view"); + if (is_view_inst) + inst_type = BGP_INSTANCE_TYPE_VIEW; + + if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) + is_new_bgp = (bgp_lookup(as, name) == NULL); + + ret = bgp_get_vty(&bgp, &as, name, inst_type); + if (ret == BGP_ERR_INSTANCE_MISMATCH) { + snprintf( + args->errmsg, args->errmsg_len, + "BGP instance name and AS number mismatch\nBGP instance is already running; AS is %u, input-as %u", + bgp->as, as); + + return NB_ERR_INCONSISTENCY; + } + /* + * If we just instantiated the default instance, complete + * any pending VRF-VPN leaking that was configured via + * earlier "router bgp X vrf FOO" blocks. + */ + if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) + vpn_leak_postchange_all(); + + if (inst_type == BGP_INSTANCE_TYPE_VRF) + bgp_vpn_leak_export(bgp); + + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + + nb_running_set_entry(args->dnode, bgp); + break; + } + + return NB_OK; +} + +int bgp_router_destroy(struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + + if (!bgp) + return NB_OK; + + if (bgp->l3vni) { + snprintf(args->errmsg, args->errmsg_len, + "Please unconfigure l3vni %u", bgp->l3vni); + return NB_ERR_VALIDATION; + } + + /* Cannot delete default instance if vrf instances exist */ + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) { + struct listnode *node; + struct bgp *tmp_bgp; + + for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) { + if (tmp_bgp->inst_type + == BGP_INSTANCE_TYPE_VRF) { + snprintf( + args->errmsg, args->errmsg_len, + "Cannot delete default BGP instance. Dependent VRF instances exist\n"); + return NB_ERR_VALIDATION; + } + } + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_unset_entry(args->dnode); + + bgp_vpn_leak_unimport(bgp); + bgp_delete(bgp); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-as + */ +int bgp_global_local_as_modify(struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + as_t as; + const struct lyd_node *vrf_dnode; + const char *vrf_name; + const char *name = NULL; + enum bgp_instance_type inst_type; + int ret; + bool is_view_inst = false; + + switch (args->event) { + case NB_EV_VALIDATE: + as = yang_dnode_get_uint32(args->dnode, NULL); + + inst_type = BGP_INSTANCE_TYPE_DEFAULT; + + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + + if (strmatch(vrf_name, VRF_DEFAULT_NAME)) { + name = NULL; + } else { + name = vrf_name; + inst_type = BGP_INSTANCE_TYPE_VRF; + } + + is_view_inst = yang_dnode_get_bool(args->dnode, + "../instance-type-view"); + if (is_view_inst) + inst_type = BGP_INSTANCE_TYPE_VIEW; + + ret = bgp_lookup_by_as_name_type(&bgp, &as, name, inst_type); + if (ret == BGP_ERR_INSTANCE_MISMATCH) { + snprintf( + args->errmsg, args->errmsg_len, + "BGP instance name and AS number mismatch\nBGP instance is already running; input-as %u", + as); + + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTE: handled in bgp_global_create callback, the as change + * will be rejected in validate phase. + */ + as = yang_dnode_get_uint32(args->dnode, NULL); + bgp = nb_running_get_entry(args->dnode, NULL, true); + if (bgp->as != as) { + snprintf(args->errmsg, args->errmsg_len, + "BGP instance is already running; AS is %u", + bgp->as); + return NB_ERR_INCONSISTENCY; + } + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/router-id + */ +int bgp_global_router_id_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + struct in_addr router_id; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4(&router_id, args->dnode, NULL); + bgp_router_id_static_set(bgp, router_id); + + return NB_OK; +} + +int bgp_global_router_id_destroy(struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + struct in_addr router_id; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + router_id.s_addr = 0; + bgp_router_id_static_set(bgp, router_id); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/identifier + */ +int bgp_global_confederation_identifier_modify(struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + as_t as; + + switch (args->event) { + case NB_EV_VALIDATE: + as = yang_dnode_get_uint32(args->dnode, NULL); + if (!as) { + snprintf(args->errmsg, args->errmsg_len, "Invalid AS."); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + as = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_confederation_id_set(bgp, as); + + break; + } + + return NB_OK; +} + +int bgp_global_confederation_identifier_destroy(struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_confederation_id_unset(bgp); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/member-as + */ +int bgp_global_confederation_member_as_create(struct nb_cb_create_args *args) +{ + as_t my_as, as; + struct bgp *bgp; + int ret; + + switch (args->event) { + case NB_EV_VALIDATE: + my_as = yang_dnode_get_uint32(args->dnode, + "../../../global/local-as"); + as = yang_dnode_get_uint32(args->dnode, NULL); + if (my_as == as) { + snprintf( + args->errmsg, args->errmsg_len, + "Local member-AS %u not allowed in confed peer list", + my_as); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + as = yang_dnode_get_uint32(args->dnode, NULL); + + ret = bgp_confederation_peers_add(bgp, as); + if (ret == BGP_ERR_INVALID_AS) { + snprintf( + args->errmsg, args->errmsg_len, + "Local member-AS not alloed in confed peer list"); + return NB_ERR_INCONSISTENCY; + } + + break; + } + + return NB_OK; +} + +int bgp_global_confederation_member_as_destroy(struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + as_t as; + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + as = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_confederation_peers_remove(bgp, as); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config + */ +void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args) +{ + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_maxmed_update(bgp); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/enable-med-admin + */ +int bgp_global_med_config_enable_med_admin_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp->v_maxmed_admin = yang_dnode_get_bool(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-admin + */ +int bgp_global_med_config_max_med_admin_modify(struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + uint32_t med_admin_val; + + switch (args->event) { + case NB_EV_VALIDATE: + med_admin_val = yang_dnode_get_uint32(args->dnode, NULL); + + /* enable_med_admin is required to be enabled for max-med-admin + * non default value. + */ + if (med_admin_val != BGP_MAXMED_VALUE_DEFAULT + && !yang_dnode_get_bool(args->dnode, + "../enable-med-admin")) { + snprintf(args->errmsg, args->errmsg_len, + "enable med admin is not set"); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + med_admin_val = yang_dnode_get_uint32(args->dnode, NULL); + + bgp->maxmed_admin_value = med_admin_val; + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-time + */ +int bgp_global_med_config_max_med_onstart_up_time_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp->v_maxmed_onstartup = + yang_dnode_get_uint32(args->dnode, NULL); + + break; + } + + return NB_OK; +} + +int bgp_global_med_config_max_med_onstart_up_time_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + /* Cancel max-med onstartup if its on */ + if (bgp->t_maxmed_onstartup) { + THREAD_OFF(bgp->t_maxmed_onstartup); + bgp->maxmed_onstartup_over = 1; + } + + bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED; + /* Resetting onstartup value as part of dependent node is + * detroyed. + */ + bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-value + */ +int bgp_global_med_config_max_med_onstart_up_value_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + uint32_t onstartup_val; + + switch (args->event) { + case NB_EV_VALIDATE: + onstartup_val = yang_dnode_get_uint32(args->dnode, NULL); + + if (!yang_dnode_exists(args->dnode, + "../max-med-onstart-up-time") + && onstartup_val != BGP_MAXMED_VALUE_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "max-med-onstart-up-time is not set."); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp->maxmed_onstartup_value = + yang_dnode_get_uint32(args->dnode, NULL); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/route-reflector-cluster-id + */ +int bgp_global_route_reflector_route_reflector_cluster_id_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + struct in_addr cluster_id; + const struct lyd_node_leaf_list *dleaf; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + dleaf = (const struct lyd_node_leaf_list *)args->dnode; + if (dleaf->value_type == LY_TYPE_STRING) + yang_dnode_get_ipv4(&cluster_id, args->dnode, NULL); + else + (void)inet_aton(dleaf->value_str, &cluster_id); + + bgp_cluster_id_set(bgp, &cluster_id); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +int bgp_global_route_reflector_route_reflector_cluster_id_destroy( + struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_cluster_id_unset(bgp); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/no-client-reflect + */ +int bgp_global_route_reflector_no_client_reflect_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/allow-outbound-policy + */ +int bgp_global_route_reflector_allow_outbound_policy_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); + + update_group_announce_rrclients(bgp); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options + */ +void bgp_global_route_selection_options_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_recalculate_all_bestpaths(bgp); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/always-compare-med + */ +int bgp_global_route_selection_options_always_compare_med_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); + + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/deterministic-med + */ +int bgp_global_route_selection_options_deterministic_med_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + int bestpath_per_as_used; + afi_t afi; + safi_t safi; + struct peer *peer; + struct listnode *node; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + + if (!bgp) + return NB_OK; + + /* for deconfiguring deterministic-med case */ + if (!yang_dnode_get_bool(args->dnode, NULL) + && CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { + bestpath_per_as_used = 0; + + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + FOREACH_AFI_SAFI (afi, safi) + if (bgp_addpath_dmed_required( + peer->addpath_type[afi] + [safi])) { + bestpath_per_as_used = 1; + break; + } + + if (bestpath_per_as_used) + break; + } + + if (bestpath_per_as_used) { + snprintf( + args->errmsg, args->errmsg_len, + "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use"); + return NB_ERR_VALIDATION; + } + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/confed-med + */ +int bgp_global_route_selection_options_confed_med_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/missing-as-worst-med + */ +int bgp_global_route_selection_options_missing_as_worst_med_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/aspath-confed + */ +int bgp_global_route_selection_options_aspath_confed_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/ignore-as-path-length + */ +int bgp_global_route_selection_options_ignore_as_path_length_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/external-compare-router-id + */ +int bgp_global_route_selection_options_external_compare_router_id_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/allow-multiple-as + */ +int bgp_global_route_selection_options_allow_multiple_as_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) { + SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); + if (yang_dnode_get_bool(args->dnode, + "../multi-path-as-set")) { + SET_FLAG(bgp->flags, + BGP_FLAG_MULTIPATH_RELAX_AS_SET); + } + } else { + UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); + /* unset as-set */ + UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + } + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/multi-path-as-set + */ +int bgp_global_route_selection_options_multi_path_as_set_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (!CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) { + SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + + } else + zlog_debug( + "%s multi-path-as-set as part of allow-multiple-as modify cb.", + __func__); + + break; + } + + return NB_OK; +} + +int bgp_global_route_selection_options_multi_path_as_set_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + /* Only unset if it set, it is possible allow_multiple_as_modify + * unset this. + */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) { + UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + + bgp_recalculate_all_bestpaths(bgp); + } + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/dynamic-neighbors-limit + */ +int bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t listen_limit; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + listen_limit = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_listen_limit_set(bgp, listen_limit); + + return NB_OK; +} + +int bgp_global_global_neighbor_config_dynamic_neighbors_limit_destroy( + struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + bgp_listen_limit_unset(bgp); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/log-neighbor-changes + */ +int bgp_global_global_neighbor_config_log_neighbor_changes_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/wpkt-quanta + */ +int bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t quanta; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + quanta = yang_dnode_get_uint32(args->dnode, NULL); + + if (atomic_load_explicit(&bgp->wpkt_quanta, memory_order_relaxed) + == BGP_WRITE_PACKET_MAX) + bgp_wpkt_quanta_config_vty(bgp, quanta, true); + else + bgp_wpkt_quanta_config_vty(bgp, quanta, false); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/rpkt-quanta + */ +int bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t quanta; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + quanta = yang_dnode_get_uint32(args->dnode, NULL); + + if (atomic_load_explicit(&bgp->rpkt_quanta, memory_order_relaxed) + == BGP_READ_PACKET_MAX) + bgp_rpkt_quanta_config_vty(bgp, quanta, true); + else + bgp_rpkt_quanta_config_vty(bgp, quanta, false); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/enabled + */ +int bgp_global_graceful_restart_enabled_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_graceful_restart_enabled_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/graceful-restart-disable + */ +int bgp_global_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/preserve-fw-entry + */ +int bgp_global_graceful_restart_preserve_fw_entry_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/restart-time + */ +int bgp_global_graceful_restart_restart_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/stale-routes-time + */ +int bgp_global_graceful_restart_stale_routes_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/selection-deferral-time + */ +int bgp_global_graceful_restart_selection_deferral_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/rib-stale-time + */ +int bgp_global_graceful_restart_rib_stale_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/subgroup-pkt-queue-size + */ +int bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t max_size; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + max_size = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_default_subgroup_pkt_queue_max_set(bgp, max_size); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/coalesce-time + */ +int bgp_global_global_update_group_config_coalesce_time_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + uint32_t coalesce_time; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + coalesce_time = yang_dnode_get_uint32(args->dnode, NULL); + + if (coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME) { + bgp->heuristic_coalesce = false; + bgp->coalesce_time = coalesce_time; + } else { + bgp->heuristic_coalesce = true; + bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/rmap-delay-time + */ +int bgp_global_global_config_timers_rmap_delay_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/update-delay-time + */ +int bgp_global_global_config_timers_update_delay_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_global_config_timers_update_delay_time_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/establish-wait-time + */ +int bgp_global_global_config_timers_establish_wait_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_global_config_timers_establish_wait_time_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/connect-retry-interval + */ +int bgp_global_global_config_timers_connect_retry_interval_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/hold-time + */ +int bgp_global_global_config_timers_hold_time_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + unsigned long keepalive = 0; + unsigned long holdtime = 0; + + switch (args->event) { + case NB_EV_VALIDATE: + holdtime = yang_dnode_get_uint16(args->dnode, NULL); + /* Holdtime value check. */ + if (holdtime < 3 && holdtime != 0) { + snprintf( + args->errmsg, args->errmsg_len, + "hold time value must be either 0 or greater than 3"); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + keepalive = yang_dnode_get_uint16(args->dnode, "../keepalive"); + holdtime = yang_dnode_get_uint16(args->dnode, NULL); + + bgp_timers_set(bgp, keepalive, holdtime, + DFLT_BGP_CONNECT_RETRY); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/keepalive + */ +int bgp_global_global_config_timers_keepalive_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + unsigned long keepalive = 0; + unsigned long holdtime = 0; + + switch (args->event) { + case NB_EV_VALIDATE: + holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time"); + /* Holdtime value check. */ + if (holdtime < 3 && holdtime != 0) { + snprintf( + args->errmsg, args->errmsg_len, + "hold time value must be either 0 or greater than 3"); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + keepalive = yang_dnode_get_uint16(args->dnode, NULL); + holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time"); + + bgp_timers_set(bgp, keepalive, holdtime, + DFLT_BGP_CONNECT_RETRY); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/instance-type-view + */ +int bgp_global_instance_type_view_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-multihop-connected-route-check + */ +int bgp_global_ebgp_multihop_connected_route_check_modify( + struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); + + if (bgp_clear_star_soft_in(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/fast-external-failover + */ +int bgp_global_fast_external_failover_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + if (!yang_dnode_get_bool(args->dnode, NULL)) { + SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); + } else + UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-pref + */ +int bgp_global_local_pref_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + struct bgp *bgp; + uint32_t local_pref; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + local_pref = yang_dnode_get_uint32(args->dnode, NULL); + + bgp_default_local_preference_set(bgp, local_pref); + + if (bgp_clear_star_soft_in(bgp->name, args->errmsg, args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/default-shutdown + */ +int bgp_global_default_shutdown_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + bgp->autoshutdown = yang_dnode_get_bool(args->dnode, NULL); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-requires-policy + */ +int bgp_global_ebgp_requires_policy_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-hostname + */ +int bgp_global_show_hostname_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-nexthop-hostname + */ +int bgp_global_show_nexthop_hostname_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/import-check + */ +int bgp_global_import_check_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct bgp *bgp; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); + + bgp_static_redo_import_check(bgp); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-shutdown/enable + */ +int bgp_global_graceful_shutdown_enable_modify(struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) { + snprintf( + args->errmsg, args->errmsg_len, + "%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown"); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + bgp = nb_running_get_entry(args->dnode, NULL, true); + + if (yang_dnode_get_bool(args->dnode, NULL)) + SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); + + bgp_static_redo_import_check(bgp); + bgp_redistribute_redo(bgp); + + if (bgp_clear_star_soft_out(bgp->name, args->errmsg, + args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + if (bgp_clear_star_soft_in(bgp->name, args->errmsg, + args->errmsg_len)) + return NB_ERR_INCONSISTENCY; + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list + */ +int bgp_global_bmp_config_target_list_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/incoming-session/session-list + */ +int bgp_global_bmp_config_target_list_incoming_session_session_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_incoming_session_session_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list + */ +int bgp_global_bmp_config_target_list_outgoing_session_session_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_outgoing_session_session_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/min-retry-time + */ +int bgp_global_bmp_config_target_list_outgoing_session_session_list_min_retry_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/max-retry-time + */ +int bgp_global_bmp_config_target_list_outgoing_session_session_list_max_retry_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/mirror + */ +int bgp_global_bmp_config_target_list_mirror_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/stats-time + */ +int bgp_global_bmp_config_target_list_stats_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_stats_time_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv4-access-list + */ +int bgp_global_bmp_config_target_list_ipv4_access_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_ipv4_access_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv6-access-list + */ +int bgp_global_bmp_config_target_list_ipv6_access_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_ipv6_access_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/mirror-buffer-limit + */ +int bgp_global_bmp_config_mirror_buffer_limit_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_bmp_config_mirror_buffer_limit_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi + */ +int bgp_global_afi_safis_afi_safi_create(struct nb_cb_create_args *args) +{ + const struct lyd_node *vrf_dnode; + const char *vrf_name; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + af_name = yang_dnode_get_string(args->dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if ((!strmatch(vrf_name, VRF_DEFAULT_NAME)) + && safi != SAFI_UNICAST && safi != SAFI_MULTICAST + && safi != SAFI_EVPN) { + snprintf( + args->errmsg, args->errmsg_len, + "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances."); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor + */ +int bgp_neighbors_neighbor_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-interface + */ +int bgp_neighbors_neighbor_local_interface_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_local_interface_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-port + */ +int bgp_neighbors_neighbor_local_port_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_local_port_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/peer-group + */ +int bgp_neighbors_neighbor_peer_group_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_peer_group_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/password + */ +int bgp_neighbors_neighbor_password_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_password_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ttl-security + */ +int bgp_neighbors_neighbor_ttl_security_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_ttl_security_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/solo + */ +int bgp_neighbors_neighbor_solo_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/enforce-first-as + */ +int bgp_neighbors_neighbor_enforce_first_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/description + */ +int bgp_neighbors_neighbor_description_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_description_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/passive-mode + */ +int bgp_neighbors_neighbor_passive_mode_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/dynamic-capability + */ +int bgp_neighbors_neighbor_capability_options_dynamic_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/strict-capability + */ +int bgp_neighbors_neighbor_capability_options_strict_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/extended-nexthop-capability + */ +int bgp_neighbors_neighbor_capability_options_extended_nexthop_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/capability-negotiate + */ +int bgp_neighbors_neighbor_capability_options_capability_negotiate_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/override-capability + */ +int bgp_neighbors_neighbor_capability_options_override_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/ip + */ +int bgp_neighbors_neighbor_update_source_ip_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_update_source_ip_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/interface + */ +int bgp_neighbors_neighbor_update_source_interface_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_update_source_interface_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as-type + */ +int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as + */ +int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/enabled + */ +int bgp_neighbors_neighbor_ebgp_multihop_enabled_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_ebgp_multihop_enabled_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/multihop-ttl + */ +int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/disable-connected-check + */ +int bgp_neighbors_neighbor_ebgp_multihop_disable_connected_check_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/local-as + */ +int bgp_neighbors_neighbor_local_as_local_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-prepend + */ +int bgp_neighbors_neighbor_local_as_no_prepend_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_local_as_no_prepend_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-replace-as + */ +int bgp_neighbors_neighbor_local_as_no_replace_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/enable + */ +int bgp_neighbors_neighbor_bfd_options_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/detect-multiplier + */ +int bgp_neighbors_neighbor_bfd_options_detect_multiplier_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_bfd_options_detect_multiplier_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/required-min-rx + */ +int bgp_neighbors_neighbor_bfd_options_required_min_rx_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_bfd_options_required_min_rx_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/desired-min-tx + */ +int bgp_neighbors_neighbor_bfd_options_desired_min_tx_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_bfd_options_desired_min_tx_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/session-type + */ +int bgp_neighbors_neighbor_bfd_options_session_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_bfd_options_session_type_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/check-cp-failure + */ +int bgp_neighbors_neighbor_bfd_options_check_cp_failure_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_bfd_options_check_cp_failure_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/enable + */ +int bgp_neighbors_neighbor_admin_shutdown_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/message + */ +int bgp_neighbors_neighbor_admin_shutdown_message_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_admin_shutdown_message_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/enable + */ +int bgp_neighbors_neighbor_graceful_restart_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_graceful_restart_enable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-helper + */ +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-disable + */ +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/advertise-interval + */ +int bgp_neighbors_neighbor_timers_advertise_interval_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_timers_advertise_interval_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/connect-time + */ +int bgp_neighbors_neighbor_timers_connect_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_timers_connect_time_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/hold-time + */ +int bgp_neighbors_neighbor_timers_hold_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/keepalive + */ +int bgp_neighbors_neighbor_timers_keepalive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/enabled + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_enabled_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor + */ +int bgp_neighbors_unnumbered_neighbor_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/v6only + */ +int bgp_neighbors_unnumbered_neighbor_v6only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/peer-group + */ +int bgp_neighbors_unnumbered_neighbor_peer_group_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_peer_group_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/password + */ +int bgp_neighbors_unnumbered_neighbor_password_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_password_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ttl-security + */ +int bgp_neighbors_unnumbered_neighbor_ttl_security_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_ttl_security_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/solo + */ +int bgp_neighbors_unnumbered_neighbor_solo_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/enforce-first-as + */ +int bgp_neighbors_unnumbered_neighbor_enforce_first_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/description + */ +int bgp_neighbors_unnumbered_neighbor_description_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_description_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/passive-mode + */ +int bgp_neighbors_unnumbered_neighbor_passive_mode_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/dynamic-capability + */ +int bgp_neighbors_unnumbered_neighbor_capability_options_dynamic_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/strict-capability + */ +int bgp_neighbors_unnumbered_neighbor_capability_options_strict_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/extended-nexthop-capability + */ +int bgp_neighbors_unnumbered_neighbor_capability_options_extended_nexthop_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/capability-negotiate + */ +int bgp_neighbors_unnumbered_neighbor_capability_options_capability_negotiate_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/override-capability + */ +int bgp_neighbors_unnumbered_neighbor_capability_options_override_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/ip + */ +int bgp_neighbors_unnumbered_neighbor_update_source_ip_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_update_source_ip_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/interface + */ +int bgp_neighbors_unnumbered_neighbor_update_source_interface_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_update_source_interface_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as-type + */ +int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as + */ +int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/enabled + */ +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/multihop-ttl + */ +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/disable-connected-check + */ +int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_disable_connected_check_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/local-as + */ +int bgp_neighbors_unnumbered_neighbor_local_as_local_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-prepend + */ +int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-replace-as + */ +int bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/enable + */ +int bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/detect-multiplier + */ +int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/required-min-rx + */ +int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/desired-min-tx + */ +int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/session-type + */ +int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/check-cp-failure + */ +int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/enable + */ +int bgp_neighbors_unnumbered_neighbor_admin_shutdown_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/message + */ +int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/enable + */ +int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-helper + */ +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-disable + */ +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/advertise-interval + */ +int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/connect-time + */ +int bgp_neighbors_unnumbered_neighbor_timers_connect_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_timers_connect_time_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/hold-time + */ +int bgp_neighbors_unnumbered_neighbor_timers_hold_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/keepalive + */ +int bgp_neighbors_unnumbered_neighbor_timers_keepalive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/enabled + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_enabled_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group + */ +int bgp_peer_groups_peer_group_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv4-listen-range + */ +int bgp_peer_groups_peer_group_ipv4_listen_range_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_ipv4_listen_range_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv6-listen-range + */ +int bgp_peer_groups_peer_group_ipv6_listen_range_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_ipv6_listen_range_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/password + */ +int bgp_peer_groups_peer_group_password_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_password_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ttl-security + */ +int bgp_peer_groups_peer_group_ttl_security_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_ttl_security_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/solo + */ +int bgp_peer_groups_peer_group_solo_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/enforce-first-as + */ +int bgp_peer_groups_peer_group_enforce_first_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/description + */ +int bgp_peer_groups_peer_group_description_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_description_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/passive-mode + */ +int bgp_peer_groups_peer_group_passive_mode_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/dynamic-capability + */ +int bgp_peer_groups_peer_group_capability_options_dynamic_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/strict-capability + */ +int bgp_peer_groups_peer_group_capability_options_strict_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/extended-nexthop-capability + */ +int bgp_peer_groups_peer_group_capability_options_extended_nexthop_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/capability-negotiate + */ +int bgp_peer_groups_peer_group_capability_options_capability_negotiate_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/override-capability + */ +int bgp_peer_groups_peer_group_capability_options_override_capability_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/ip + */ +int bgp_peer_groups_peer_group_update_source_ip_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_update_source_ip_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/interface + */ +int bgp_peer_groups_peer_group_update_source_interface_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_update_source_interface_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as-type + */ +int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as + */ +int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/enabled + */ +int bgp_peer_groups_peer_group_ebgp_multihop_enabled_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_ebgp_multihop_enabled_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/multihop-ttl + */ +int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/disable-connected-check + */ +int bgp_peer_groups_peer_group_ebgp_multihop_disable_connected_check_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/local-as + */ +int bgp_peer_groups_peer_group_local_as_local_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-prepend + */ +int bgp_peer_groups_peer_group_local_as_no_prepend_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_local_as_no_prepend_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as + */ +int bgp_peer_groups_peer_group_local_as_no_replace_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/enable + */ +int bgp_peer_groups_peer_group_bfd_options_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/detect-multiplier + */ +int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/required-min-rx + */ +int bgp_peer_groups_peer_group_bfd_options_required_min_rx_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_bfd_options_required_min_rx_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/desired-min-tx + */ +int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/session-type + */ +int bgp_peer_groups_peer_group_bfd_options_session_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_bfd_options_session_type_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/check-cp-failure + */ +int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/enable + */ +int bgp_peer_groups_peer_group_admin_shutdown_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/message + */ +int bgp_peer_groups_peer_group_admin_shutdown_message_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_admin_shutdown_message_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/enable + */ +int bgp_peer_groups_peer_group_graceful_restart_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_graceful_restart_enable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-helper + */ +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-disable + */ +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/advertise-interval + */ +int bgp_peer_groups_peer_group_timers_advertise_interval_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_timers_advertise_interval_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/connect-time + */ +int bgp_peer_groups_peer_group_timers_connect_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_timers_connect_time_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/hold-time + */ +int bgp_peer_groups_peer_group_timers_hold_time_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/keepalive + */ +int bgp_peer_groups_peer_group_timers_keepalive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/enabled + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +void bgp_global_afi_safis_afi_safi_network_config_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + bool is_backdoor = false; + uint32_t label_index = BGP_INVALID_LABEL_INDEX; + const char *rmap_name = NULL; + afi_t afi; + safi_t safi; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + is_backdoor = yang_dnode_get_bool(args->dnode, "./backdoor"); + + if (yang_dnode_exists(args->dnode, "./label-index")) + label_index = + yang_dnode_get_uint32(args->dnode, "./label-index"); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-export")) + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-export"); + + bgp_static_set(bgp, NULL, &prefix, afi, safi, rmap_name, is_backdoor, + label_index, args->errmsg, args->errmsg_len); +} + +static int bgp_global_afi_safis_afi_safi_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + uint32_t label_index = BGP_INVALID_LABEL_INDEX; + const char *rmap_name = NULL; + bool is_backdoor = false; + afi_t afi; + safi_t safi; + int ret; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-export")) + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-export"); + + if (yang_dnode_exists(args->dnode, "./label-index")) + label_index = + yang_dnode_get_uint32(args->dnode, "./label-index"); + + if (yang_dnode_exists(args->dnode, "./backdoor")) + is_backdoor = yang_dnode_get_bool(args->dnode, "./backdoor"); + + ret = bgp_static_set(bgp, "no", &prefix, afi, safi, rmap_name, + is_backdoor, label_index, args->errmsg, + args->errmsg_len); + if (ret < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create( + struct nb_cb_create_args *args) +{ + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/backdoor + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/label-index + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify( + struct nb_cb_modify_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + uint32_t label_index; + afi_t afi; + safi_t safi; + struct bgp_dest *dest; + struct bgp_static *bgp_static; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + yang_dnode_get_prefix(&prefix, args->dnode, "../prefix"); + apply_mask(&prefix); + + label_index = yang_dnode_get_uint32(args->dnode, NULL); + + dest = bgp_node_get(bgp->route[afi][safi], &prefix); + bgp_static = bgp_dest_get_bgp_static_info(dest); + if (bgp_static) { + if (bgp_static->label_index != label_index) { + snprintf( + args->errmsg, args->errmsg_len, + "Cannot change label-index: curr %u input %u\n", + bgp_static->label_index, label_index); + return NB_ERR_VALIDATION; + } + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + /* rmap destory alone is not supported by backend, the entire network + * config needs to be destroyed. + */ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +void bgp_global_afi_safi_aggregate_route_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + const char *rmap_name = NULL; + afi_t afi; + safi_t safi; + uint8_t as_set = 0; + int summary_only = 0; + uint8_t origin = BGP_ORIGIN_UNSPECIFIED; + bool match_med = false; + const char *suppress_map = NULL; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + if (yang_dnode_exists(args->dnode, "./as-set")) + as_set = yang_dnode_get_bool(args->dnode, "./as-set"); + + summary_only = yang_dnode_get_bool(args->dnode, "./summary-only"); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-export")) + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-export"); + + origin = yang_dnode_get_enum(args->dnode, "./origin"); + match_med = yang_dnode_get_bool(args->dnode, "./match-med"); + if (yang_dnode_exists(args->dnode, "./suppress-map")) + suppress_map = + yang_dnode_get_string(args->dnode, "./suppress-map"); + + bgp_aggregate_set(bgp, &prefix, afi, safi, rmap_name, summary_only, + as_set, origin, match_med, suppress_map, args->errmsg, + args->errmsg_len); +} + +static int +bgp_global_afi_safi_aggregate_route_destroy(struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + struct prefix prefix; + afi_t afi; + safi_t safi; + int ret; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&prefix, args->dnode, "./prefix"); + + ret = bgp_aggregate_unset(bgp, &prefix, afi, safi, args->errmsg, + args->errmsg_len); + + if (ret < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_aggregate_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/origin + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/match-med + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/suppress-map + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +void bgp_global_afi_safi_admin_distance_route_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + const char *af_name; + const char *prefix_str = NULL; + const char *access_list_str = NULL; + uint8_t distance; + afi_t afi; + safi_t safi; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + prefix_str = yang_dnode_get_string(args->dnode, "./prefix"); + distance = yang_dnode_get_uint8(args->dnode, "./distance"); + if (yang_dnode_exists(args->dnode, "./access-list-policy-export")) + access_list_str = yang_dnode_get_string( + args->dnode, "./access-list-policy-export"); + + bgp_distance_set(distance, prefix_str, access_list_str, afi, safi, + args->errmsg, args->errmsg_len); +} + +static int bgp_global_afi_safi_admin_distance_route_destroy( + struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + const char *af_name; + const char *prefix_str = NULL; + const char *access_list_str = NULL; + uint8_t distance; + afi_t afi; + safi_t safi; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + prefix_str = yang_dnode_get_string(args->dnode, "./prefix"); + distance = yang_dnode_get_uint8(args->dnode, "./distance"); + if (yang_dnode_exists(args->dnode, "./access-list-policy-export")) + access_list_str = yang_dnode_get_string( + args->dnode, "./access-list-policy-export"); + + if (bgp_distance_unset(distance, prefix_str, access_list_str, afi, safi, + args->errmsg, args->errmsg_len) + != CMD_SUCCESS) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_admin_distance_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/distance + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/access-list-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +void bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int half = DEFAULT_HALF_LIFE * 60; + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + int max; + char ab_xpath[XPATH_MAXLEN]; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!yang_dnode_get_bool(args->dnode, "./enable")) { + bgp_damp_disable(bgp, afi, safi); + } else { + half = yang_dnode_get_uint8(args->dnode, "./reach-decay"); + half *= 60; + reuse = yang_dnode_get_uint16(args->dnode, "./reuse-above"); + + suppress = + yang_dnode_get_uint16(args->dnode, "./suppress-above"); + + max = yang_dnode_get_uint8(args->dnode, "./unreach-decay"); + yang_dnode_get_path(args->dnode, ab_xpath, sizeof(ab_xpath)); + strlcat(ab_xpath, "/unreach-decay", sizeof(ab_xpath)); + if (yang_get_default_uint8(ab_xpath) == max) + max = half * 4; + else + max *= 60; + + bgp_damp_enable(bgp, afi, safi, half, reuse, suppress, max); + } +} + +static int +bgp_global_afi_safi_route_flap_validation(struct nb_cb_modify_args *args) +{ + int reuse; + int suppress; + + if (yang_dnode_exists(args->dnode, "../supress-above") + && yang_dnode_exists(args->dnode, "../reuse-above")) { + suppress = + yang_dnode_get_uint16(args->dnode, "../suppress-above"); + reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above"); + if (suppress < reuse) { + snprintf( + args->errmsg, args->errmsg_len, + "Suppress value cannot be less than reuse value \n"); + return NB_ERR_VALIDATION; + } + } + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/enable + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../suppress-above")) + suppress = yang_dnode_get_uint16(args->dnode, + "../suppress-above"); + reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above"); + if (suppress < reuse) { + snprintf( + args->errmsg, args->errmsg_len, + "Suppress value cannot be less than reuse value \n"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +static int +bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + uint16_t maxpaths, default_maxpaths; + int ret; + char xpath[XPATH_MAXLEN]; + char afi_xpath[XPATH_MAXLEN]; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + + snprintf(xpath, sizeof(xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp", + "bgp", bgp->name ? bgp->name : VRF_DEFAULT_NAME); + snprintf( + afi_xpath, sizeof(afi_xpath), + "/global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + strlcat(xpath, afi_xpath, sizeof(xpath)); + default_maxpaths = yang_get_default_uint16(xpath); + + ret = bgp_maxpaths_config_vty(bgp, afi, safi, BGP_PEER_EBGP, maxpaths, + 0, maxpaths != default_maxpaths ? 1 : 0, + args->errmsg, args->errmsg_len); + if (ret != CMD_SUCCESS) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ebgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp + */ +void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + uint16_t maxpaths, default_maxpaths; + char xpath[XPATH_MAXLEN]; + char afi_xpath[XPATH_MAXLEN]; + uint16_t options = 0; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + maxpaths = yang_dnode_get_uint16(args->dnode, "./maximum-paths"); + if (yang_dnode_get_bool(args->dnode, "./cluster-length-list")) + options = BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN; + + snprintf(xpath, sizeof(xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp", + "bgp", bgp->name ? bgp->name : VRF_DEFAULT_NAME); + snprintf( + afi_xpath, sizeof(afi_xpath), + "/global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + strlcat(xpath, afi_xpath, sizeof(xpath)); + default_maxpaths = yang_get_default_uint16(xpath); + + bgp_maxpaths_config_vty(bgp, afi, safi, BGP_PEER_IBGP, maxpaths, + options, maxpaths != default_maxpaths ? 1 : 0, + args->errmsg, args->errmsg_len); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/cluster-length-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +void bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int route_type; + int route_instance; + struct bgp_redist *red; + bool changed = false; + struct route_map *route_map = NULL; + const char *rmap_name = NULL; + uint32_t metric = 0; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + route_type = yang_dnode_get_enum(args->dnode, "./route-type"); + route_instance = yang_dnode_get_uint16(args->dnode, "./route-instance"); + + red = bgp_redist_add(bgp, afi, route_type, route_instance); + + if (yang_dnode_exists(args->dnode, "./rmap-policy-import")) { + rmap_name = yang_dnode_get_string(args->dnode, + "./rmap-policy-import"); + route_map = route_map_lookup_by_name(rmap_name); + + changed = bgp_redistribute_rmap_set(red, rmap_name, route_map); + } + + if (yang_dnode_exists(args->dnode, "./metric")) { + metric = yang_dnode_get_uint32(args->dnode, "./metric"); + changed |= bgp_redistribute_metric_set(bgp, red, afi, + route_type, metric); + } + + bgp_redistribute_set(bgp, afi, route_type, route_instance, changed); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy( + struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int route_type; + int route_instance; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + route_type = yang_dnode_get_enum(args->dnode, "./route-type"); + route_instance = + yang_dnode_get_uint16(args->dnode, "./route-instance"); + + bgp_redistribute_unset(bgp, afi, route_type, route_instance); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/metric + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/rmap-policy-import + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +static int +bgp_global_afi_safis_admin_distance_modify(struct nb_cb_apply_finish_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + uint8_t distance_ebgp, distance_ibgp, distance_local; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + distance_ebgp = yang_dnode_get_uint8(args->dnode, "./external"); + distance_ibgp = yang_dnode_get_uint8(args->dnode, "./internal"); + distance_local = yang_dnode_get_uint8(args->dnode, "./local"); + + bgp->distance_ebgp[afi][safi] = distance_ebgp; + bgp->distance_ibgp[afi][safi] = distance_ibgp; + bgp->distance_local[afi][safi] = distance_local; + + bgp_announce_routes_distance_update(bgp, afi, safi); + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance + */ +void bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *rd_str = NULL; + struct prefix_rd prd; + + bgp = nb_running_get_entry(args->dnode, NULL, true); + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + rd_str = yang_dnode_get_string(args->dnode, NULL); + if (!str2prefix_rd(rd_str, &prd)) { + snprintf(args->errmsg, args->errmsg_len, "Malformed rd %s\n", + rd_str); + return NB_ERR_INCONSISTENCY; + } + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + bgp->vpn_policy[afi].tovpn_rd = prd; + SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *rd_str = NULL; + struct prefix_rd prd; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + rd_str = yang_dnode_get_string(args->dnode, NULL); + if (str2prefix_rd(rd_str, &prd)) { + snprintf(args->errmsg, args->errmsg_len, "Malformed rd %s \n", + rd_str); + return NB_ERR_INCONSISTENCY; + } + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rd + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify( + args); + + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label-auto + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + struct prefix p; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&p, args->dnode, NULL); + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + bgp->vpn_policy[afi].tovpn_nexthop = p; + SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + struct prefix p; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + yang_dnode_get_prefix(&p, args->dnode, NULL); + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/nexthop + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify( + args); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy( + args); + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify( + struct nb_cb_modify_args *args, const char *direction_str, + bool is_enable) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int previous_state; + int flag; + vpn_policy_direction_t dir; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!strcmp(direction_str, "import")) { + flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT; + dir = BGP_VPN_POLICY_DIR_FROMVPN; + } else if (!strcmp(direction_str, "export")) { + flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT; + dir = BGP_VPN_POLICY_DIR_TOVPN; + } else { + snprintf(args->errmsg, args->errmsg_len, + "unknown direction %s\n", direction_str); + return NB_ERR_INCONSISTENCY; + } + + previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag); + + if (is_enable) { + SET_FLAG(bgp->af_flags[afi][safi], flag); + if (!previous_state) { + /* trigger export current vrf */ + vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); + } + } else { + if (previous_state) { + /* trigger un-export current vrf */ + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + } + UNSET_FLAG(bgp->af_flags[afi][safi], flag); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify( + struct nb_cb_modify_args *args) +{ + bool is_enable = false; + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type + && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { + snprintf( + args->errmsg, args->errmsg_len, + "import|export vpn valid only for bgp vrf or default instance"); + return NB_ERR_VALIDATION; + } + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + if (yang_dnode_get_bool(args->dnode, NULL)) + is_enable = true; + + return bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify( + args, "import", is_enable); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-vpn + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify( + struct nb_cb_modify_args *args) +{ + bool is_enable = false; + struct bgp *bgp; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type + && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { + snprintf( + args->errmsg, args->errmsg_len, + "import|export vpn valid only for bgp vrf or default instance"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + if (yang_dnode_get_bool(args->dnode, NULL)) + is_enable = true; + + return bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify( + args, "export", is_enable); + } + + return NB_OK; +} + + +static int bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create( + struct nb_cb_create_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret = 0; + as_t as; + struct bgp *vrf_bgp, *bgp_default; + const char *import_name; + char *vname; + enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF; + struct listnode *node; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + as = bgp->as; + import_name = yang_dnode_get_string(args->dnode, "./vrf"); + + if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type) + && (strcmp(import_name, VRF_DEFAULT_NAME) == 0)) + || (bgp->name && (strcmp(import_name, bgp->name) == 0))) { + snprintf(args->errmsg, args->errmsg_len, + "Cannot %s vrf %s into itself\n", "import", + import_name); + return NB_ERR_INCONSISTENCY; + } + + bgp_default = bgp_get_default(); + if (!bgp_default) { + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&bgp_default, &as, NULL, + BGP_INSTANCE_TYPE_DEFAULT); + + if (ret) { + snprintf( + args->errmsg, args->errmsg_len, + "VRF default is not configured as a bgp instance"); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_bgp = bgp_lookup_by_name(import_name); + if (!vrf_bgp) { + if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) + vrf_bgp = bgp_default; + else + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); + + if (ret) { + snprintf(args->errmsg, args->errmsg_len, + "VRF %s is not configured as a bgp instance\n", + import_name); + return NB_ERR_INCONSISTENCY; + } + } + + /* Already importing from "import_vrf"? */ + for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node, + vname)) { + if (strcmp(vname, import_name) == 0) { + snprintf(args->errmsg, args->errmsg_len, + "already importing from vrf %s", import_name); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_import_from_vrf(bgp, vrf_bgp, afi, safi); + + return NB_OK; +} + + +static int bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret = 0; + as_t as; + struct bgp *vrf_bgp, *bgp_default; + const char *import_name; + enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + as = bgp->as; + import_name = yang_dnode_get_string(args->dnode, "./vrf"); + + if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type) + && (strcmp(import_name, VRF_DEFAULT_NAME) == 0)) + || (bgp->name && (strcmp(import_name, bgp->name) == 0))) { + snprintf(args->errmsg, args->errmsg_len, + "Cannot %s vrf %s into itself\n", "unimport", + import_name); + return NB_ERR_INCONSISTENCY; + } + + bgp_default = bgp_get_default(); + if (!bgp_default) { + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&bgp_default, &as, NULL, + BGP_INSTANCE_TYPE_DEFAULT); + + if (ret) { + snprintf( + args->errmsg, args->errmsg_len, "%s", + "VRF default is not configured as a bgp instance"); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_bgp = bgp_lookup_by_name(import_name); + if (!vrf_bgp) { + if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) + vrf_bgp = bgp_default; + else + /* Auto-create assuming the same AS */ + ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); + + if (ret) { + snprintf(args->errmsg, args->errmsg_len, + "VRF %s is not configured as a bgp instance\n", + import_name); + return NB_ERR_INCONSISTENCY; + } + } + + vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi); + + return NB_OK; +} + + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vrf-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create( + struct nb_cb_create_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, true, args->errmsg, + args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create( + args); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy( + args); + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + struct nb_cb_modify_args *args, const char *dstr) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *rmap_str = NULL; + int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; + vpn_policy_direction_t dir; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!strcmp(dstr, "import")) { + rmap_str = yang_dnode_get_string(args->dnode, NULL); + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + } else if (!strcmp(dstr, "export")) { + rmap_str = yang_dnode_get_string(args->dnode, NULL); + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } else if (!strcmp(dstr, "both")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } + + for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { + if (!dodir[dir]) + continue; + + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + + if (bgp->vpn_policy[afi].rmap_name[dir]) + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp->vpn_policy[afi].rmap_name[dir]); + bgp->vpn_policy[afi].rmap_name[dir] = + XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str); + bgp->vpn_policy[afi].rmap[dir] = + route_map_lookup_by_name(rmap_str); + if (!bgp->vpn_policy[afi].rmap[dir]) + return NB_OK; + + + vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); + } + + return NB_OK; +} + +static int bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + struct nb_cb_destroy_args *args, const char *dstr) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; + vpn_policy_direction_t dir; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + if (!strcmp(dstr, "import")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + } else if (!strcmp(dstr, "export")) { + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } else if (!strcmp(dstr, "both")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } + + for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { + if (!dodir[dir]) + continue; + + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + + if (bgp->vpn_policy[afi].rmap_name[dir]) + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp->vpn_policy[afi].rmap_name[dir]); + bgp->vpn_policy[afi].rmap_name[dir] = NULL; + bgp->vpn_policy[afi].rmap[dir] = NULL; + + vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-import + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "import"); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "import"); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "export"); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "export"); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/redirect-rt + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-rt-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-rt-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rt-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create( + struct nb_cb_create_args *args) +{ + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/label-index + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in unicast_network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_aggregate_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/origin + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/match-med + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/suppress-map + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_admin_distance_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/distance + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/access-list-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/enable + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + int reuse = DEFAULT_REUSE; + int suppress = DEFAULT_SUPPRESS; + + switch (args->event) { + case NB_EV_VALIDATE: + if (yang_dnode_exists(args->dnode, "../suppress-above")) + suppress = yang_dnode_get_uint16(args->dnode, + "../suppress-above"); + reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above"); + if (suppress < reuse) { + snprintf( + args->errmsg, args->errmsg_len, + "Suppress value cannot be less than reuse value \n"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/cluster-length-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy( + struct nb_cb_destroy_args *args) +{ + const struct lyd_node *af_dnode; + struct bgp *bgp; + const char *af_name; + afi_t afi; + safi_t safi; + int route_type; + int route_instance; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + bgp = nb_running_get_entry(af_dnode, NULL, true); + + route_type = yang_dnode_get_enum(args->dnode, "./route-type"); + route_instance = + yang_dnode_get_uint16(args->dnode, "./route-instance"); + + bgp_redistribute_unset(bgp, afi, route_type, route_instance); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/rmap-policy-import + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance + */ +void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rd + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify( + args); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label-auto + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/nexthop + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify( + struct nb_cb_modify_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, false, + args->errmsg, args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify( + args); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vpn + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-vpn + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vrf-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create( + struct nb_cb_create_args *args) +{ + struct bgp *bgp; + const struct lyd_node *af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + switch (args->event) { + case NB_EV_VALIDATE: + bgp = nb_running_get_entry(args->dnode, NULL, false); + if (!bgp) + return NB_OK; + af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + if (!vpn_policy_check_import(bgp, afi, safi, true, args->errmsg, + args->errmsg_len)) + return NB_ERR_VALIDATION; + + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create( + args); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-import + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "import"); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "import"); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify( + args, "export"); + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy( + args, "export"); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/redirect-rt + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-rt-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-rt-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rt-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ebgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/enable + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify( + args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/maximum-paths + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify( + struct nb_cb_modify_args *args) +{ + uint16_t maxpaths; + + switch (args->event) { + case NB_EV_VALIDATE: + maxpaths = yang_dnode_get_uint16(args->dnode, NULL); + if (maxpaths > MULTIPATH_NUM) { + snprintf(args->errmsg, args->errmsg_len, + "maxpaths %u is out of range %u", maxpaths, + MULTIPATH_NUM); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/enable + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create( + struct nb_cb_create_args *args) +{ + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/backdoor + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/label-index + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/as-set + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/summary-only + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/origin + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/match-med + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/suppress-map + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_admin_distance_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/distance + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/access-list-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/distance + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/access-list-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/enable + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance + */ +void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/enable + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + return bgp_global_afi_safi_route_flap_validation(args); + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reuse-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/suppress-above + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/unreach-decay + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export + */ +int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create( + struct nb_cb_create_args *args) +{ + /* Handled in network_config_apply_finish callback */ + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safis_afi_safi_network_config_destroy( + args); + + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/backdoor + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_backdoor_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/label-index + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/as-set + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_as_set_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/summary-only + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_summary_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/origin + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/match-med + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/suppress-map + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_global_afi_safi_admin_distance_route_destroy(args); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance + */ +void bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish( + struct nb_cb_apply_finish_args *args) +{ + bgp_global_afi_safis_admin_distance_modify(args); +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local + */ +int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify( + struct nb_cb_modify_args *args) +{ + /* Handled in admin_distance_apply_finish callback */ + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-flowspec/flow-spec-config/interface + */ +int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/label-index + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_label_index_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/label-index + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_label_index_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/rmap-policy-export + */ +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/pre-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/post-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/pre-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/post-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/pre-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/post-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/pre-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_pre_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/post-policy + */ +int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_post_policy_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create( + struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 0d8214e4d6..29cca99fd7 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -757,10 +757,10 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp, if (dest->pdest) { prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest), buf1, sizeof(buf1)); - vty_out(vty, " %d/%d %pRN RD %s %s flags 0x%x\n", + vty_out(vty, " %d/%d %pBD RD %s %s flags 0x%x\n", afi, safi, dest, buf1, bgp_path->name_pretty, path->flags); } else - vty_out(vty, " %d/%d %pRN %s flags 0x%x\n", + vty_out(vty, " %d/%d %pBD %s flags 0x%x\n", afi, safi, dest, bgp_path->name_pretty, path->flags); } } diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index e97c34bb5e..64b10c0252 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -315,15 +315,12 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc, bnc->change_flags = 0; /* debug print the input */ - if (BGP_DEBUG(nht, NHT)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&nhr->prefix, buf, sizeof(buf)); + if (BGP_DEBUG(nht, NHT)) zlog_debug( - "%s(%u): Rcvd NH update %s(%u) - metric %d/%d #nhops %d/%d flags 0x%x", - bnc->bgp->name_pretty, bnc->bgp->vrf_id, buf, + "%s(%u): Rcvd NH update %pFX(%u) - metric %d/%d #nhops %d/%d flags 0x%x", + bnc->bgp->name_pretty, bnc->bgp->vrf_id, &nhr->prefix, bnc->srte_color, nhr->metric, bnc->metric, nhr->nexthop_num, bnc->nexthop_num, bnc->flags); - } if (nhr->metric != bnc->metric) bnc->change_flags |= BGP_NEXTHOP_METRIC_CHANGED; @@ -454,14 +451,10 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) bnc = bnc_find(tree, &nhr.prefix, nhr.srte_color); if (!bnc) { - if (BGP_DEBUG(nht, NHT)) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&nhr.prefix, buf, sizeof(buf)); + if (BGP_DEBUG(nht, NHT)) zlog_debug( - "parse nexthop update(%s(%u)(%s)): bnc info not found", - buf, nhr.srte_color, bgp->name_pretty); - } + "parse nexthop update(%pFX(%u)(%s)): bnc info not found", + &nhr.prefix, nhr.srte_color, bgp->name_pretty); return; } @@ -757,7 +750,7 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc) path->sub_type, path->attr, dest)) { if (BGP_DEBUG(nht, NHT)) zlog_debug( - "%s: prefix %pRN (vrf %s), ignoring path due to martian or self-next-hop", + "%s: prefix %pBD (vrf %s), ignoring path due to martian or self-next-hop", __func__, dest, bgp_path->name); } else bnc_is_valid_nexthop = @@ -771,12 +764,12 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc) prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest), buf1, sizeof(buf1)); zlog_debug( - "... eval path %d/%d %pRN RD %s %s flags 0x%x", + "... eval path %d/%d %pBD RD %s %s flags 0x%x", afi, safi, dest, buf1, bgp_path->name_pretty, path->flags); } else zlog_debug( - "... eval path %d/%d %pRN %s flags 0x%x", + "... eval path %d/%d %pBD %s flags 0x%x", afi, safi, dest, bgp_path->name_pretty, path->flags); } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 6c077878b5..a23acda0a8 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -63,6 +63,7 @@ #include "bgpd/bgp_io.h" #include "bgpd/bgp_keepalives.h" #include "bgpd/bgp_flowspec.h" +#include "bgpd/bgp_trace.h" DEFINE_HOOK(bgp_packet_dump, (struct peer *peer, uint8_t type, bgp_size_t size, @@ -402,12 +403,13 @@ int bgp_generate_updgrp_packets(struct thread *thread) /* * The code beyond this part deals with update packets, proceed only * if peer is Established and updates are not on hold (as part of - * update-delay post processing). + * update-delay processing). */ if (peer->status != Established) return 0; - if (peer->bgp->main_peers_update_hold) + if ((peer->bgp->main_peers_update_hold) + || bgp_update_delay_active(peer->bgp)) return 0; if (peer->t_routeadv) @@ -566,9 +568,9 @@ void bgp_open_send(struct peer *peer) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending OPEN, version %d, my as %u, holdtime %d, id %s", + "%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4", peer->host, BGP_VERSION_4, local_as, send_holdtime, - inet_ntoa(peer->local_id)); + &peer->local_id); /* Dump packet if debug option is set. */ /* bgp_packet_dump (s); */ @@ -1022,8 +1024,8 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id) && peer->local_as == peer->as) flog_err( EC_BGP_ROUTER_ID_SAME, - "Peer's router-id %s is the same as ours", - inet_ntoa(remote_id)); + "Peer's router-id %pI4 is the same as ours", + &remote_id); /* 3. Otherwise, the local system closes newly created @@ -1115,9 +1117,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) /* Receive OPEN message log */ if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s rcv OPEN, version %d, remote-as (in open) %u, holdtime %d, id %s", - peer->host, version, remote_as, holdtime, - inet_ntoa(remote_id)); + "%s rcv OPEN, version %d, remote-as (in open) %u, holdtime %d, id %pI4", + peer->host, version, remote_as, holdtime, &remote_id); /* BEGIN to read the capability here, but dont do it yet */ mp_capability = 0; @@ -1219,8 +1220,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) || (peer->sort == BGP_PEER_IBGP && ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr))) { if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s bad OPEN, wrong router identifier %s", - peer->host, inet_ntoa(remote_id)); + zlog_debug("%s bad OPEN, wrong router identifier %pI4", + peer->host, &remote_id); bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_BAD_BGP_IDENT, notify_data_remote_id, 4); @@ -1782,6 +1783,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) peer->update_time = bgp_clock(); + /* Notify BGP Conditional advertisement scanner process */ + peer->advmap_table_change = true; + return Receive_UPDATE_message; } @@ -2367,6 +2371,7 @@ int bgp_process_packet(struct thread *thread) */ switch (type) { case BGP_MSG_OPEN: + frrtrace(2, frr_bgp, open_process, peer, size); atomic_fetch_add_explicit(&peer->open_in, 1, memory_order_relaxed); mprc = bgp_open_receive(peer, size); @@ -2377,6 +2382,7 @@ int bgp_process_packet(struct thread *thread) __func__, peer->host); break; case BGP_MSG_UPDATE: + frrtrace(2, frr_bgp, update_process, peer, size); atomic_fetch_add_explicit(&peer->update_in, 1, memory_order_relaxed); peer->readtime = monotime(NULL); @@ -2388,6 +2394,7 @@ int bgp_process_packet(struct thread *thread) __func__, peer->host); break; case BGP_MSG_NOTIFY: + frrtrace(2, frr_bgp, notification_process, peer, size); atomic_fetch_add_explicit(&peer->notify_in, 1, memory_order_relaxed); mprc = bgp_notify_receive(peer, size); @@ -2398,6 +2405,7 @@ int bgp_process_packet(struct thread *thread) __func__, peer->host); break; case BGP_MSG_KEEPALIVE: + frrtrace(2, frr_bgp, keepalive_process, peer, size); peer->readtime = monotime(NULL); atomic_fetch_add_explicit(&peer->keepalive_in, 1, memory_order_relaxed); @@ -2410,6 +2418,7 @@ int bgp_process_packet(struct thread *thread) break; case BGP_MSG_ROUTE_REFRESH_NEW: case BGP_MSG_ROUTE_REFRESH_OLD: + frrtrace(2, frr_bgp, refresh_process, peer, size); atomic_fetch_add_explicit(&peer->refresh_in, 1, memory_order_relaxed); mprc = bgp_route_refresh_receive(peer, size); @@ -2420,6 +2429,7 @@ int bgp_process_packet(struct thread *thread) __func__, peer->host); break; case BGP_MSG_CAPABILITY: + frrtrace(2, frr_bgp, capability_process, peer, size); atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1, memory_order_relaxed); mprc = bgp_capability_receive(peer, size); diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index f6e5c196ca..f7dd08443f 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -23,6 +23,8 @@ #include "jhash.h" #include "pbr.h" +#include "lib/printfrr.h" + #include "bgpd/bgpd.h" #include "bgpd/bgp_pbr.h" #include "bgpd/bgp_debug.h" @@ -1438,7 +1440,6 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api) int i = 0; char return_string[512]; char *ptr = return_string; - char buff[64]; int nb_items = 0; int delta, len = sizeof(return_string); @@ -1449,12 +1450,10 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api) struct prefix *p = &(api->src_prefix); if (api->src_prefix_offset) - delta = snprintf(ptr, len, "@src %s/off%u", - prefix2str(p, buff, 64), - api->src_prefix_offset); + delta = snprintfrr(ptr, len, "@src %pFX/off%u", p, + api->src_prefix_offset); else - delta = snprintf(ptr, len, "@src %s", - prefix2str(p, buff, 64)); + delta = snprintfrr(ptr, len, "@src %pFX", p); len -= delta; ptr += delta; INCREMENT_DISPLAY(ptr, nb_items, len); @@ -1464,12 +1463,10 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api) INCREMENT_DISPLAY(ptr, nb_items, len); if (api->dst_prefix_offset) - delta = snprintf(ptr, len, "@dst %s/off%u", - prefix2str(p, buff, 64), - api->dst_prefix_offset); + delta = snprintfrr(ptr, len, "@dst %pFX/off%u", p, + api->dst_prefix_offset); else - delta = snprintf(ptr, len, "@dst %s", - prefix2str(p, buff, 64)); + delta = snprintfrr(ptr, len, "@dst %pFX", p); len -= delta; ptr += delta; } diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c index 6ba56c7011..097ab9254e 100644 --- a/bgpd/bgp_rd.c +++ b/bgpd/bgp_rd.c @@ -29,6 +29,8 @@ #include "filter.h" #include "frrstr.h" +#include "lib/printfrr.h" + #include "bgpd/bgpd.h" #include "bgpd/bgp_rd.h" #include "bgpd/bgp_attr.h" @@ -182,8 +184,7 @@ char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size) return buf; } else if (type == RD_TYPE_IP) { decode_rd_ip(pnt + 2, &rd_ip); - snprintf(buf, size, "%s:%hu", inet_ntoa(rd_ip.ip), - rd_ip.val); + snprintfrr(buf, size, "%pI4:%hu", &rd_ip.ip, rd_ip.val); return buf; } #ifdef ENABLE_BGP_VNC @@ -210,6 +211,6 @@ void form_auto_rd(struct in_addr router_id, prd->family = AF_UNSPEC; prd->prefixlen = 64; - snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(router_id), rd_id); + snprintfrr(buf, sizeof(buf), "%pI4:%hu", &router_id, rd_id); (void)str2prefix_rd(buf, prd); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 15c1df8473..8a237e329e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -70,6 +70,7 @@ #include "bgpd/bgp_addpath.h" #include "bgpd/bgp_mac.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_trace.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -84,6 +85,9 @@ #include "bgpd/bgp_flowspec.h" #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_pbr.h" +#include "northbound.h" +#include "northbound_cli.h" +#include "bgpd/bgp_nb.h" #ifndef VTYSH_EXTRACT_PL #include "bgpd/bgp_route_clippy.c" @@ -115,6 +119,14 @@ DEFINE_HOOK(bgp_process, struct peer *peer, bool withdraw), (bgp, afi, safi, bn, peer, withdraw)) +/** Test if path is suppressed. */ +static bool bgp_path_suppressed(struct bgp_path_info *pi) +{ + if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL) + return false; + + return listcount(pi->extra->aggr_suppressors) > 0; +} struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi, safi_t safi, const struct prefix *p, @@ -216,7 +228,7 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) unsigned refcount; bpi = bgp_path_info_lock(bpi); - refcount = bpi->net->lock - 1; + refcount = bgp_dest_get_lock_count(bpi->net) - 1; bgp_dest_unlock_node((struct bgp_dest *)bpi->net); if (!refcount) bpi->net = NULL; @@ -314,8 +326,8 @@ static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete) if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) { if (BGP_DEBUG(update, UPDATE_OUT)) zlog_debug( - "Route %pRN is in workqueue and being processed, not deferred.", - bgp_dest_to_rnode(dest)); + "Route %pBD is in workqueue and being processed, not deferred.", + dest); return 0; } @@ -359,14 +371,12 @@ static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete) */ if (set_flag && table) { if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) { + if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) + bgp->gr_info[afi][safi].gr_deferred++; SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); - if (dest->rt_node == NULL) - dest->rt_node = listnode_add( - bgp->gr_info[afi][safi].route_list, - dest); if (BGP_DEBUG(update, UPDATE_OUT)) - zlog_debug("DEFER route %pRN, dest %p, node %p", - dest, dest, dest->rt_node); + zlog_debug("DEFER route %pBD, dest %p", dest, + dest); return 0; } } @@ -550,6 +560,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, bool same_esi; bool old_proxy; bool new_proxy; + bool new_origin, exist_origin; *paths_eq = 0; @@ -723,18 +734,18 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, *reason = bgp_path_selection_evpn_lower_ip; if (debug) zlog_debug( - "%s: %s wins over %s due to same MM seq %u and lower IP %s", + "%s: %s wins over %s due to same MM seq %u and lower IP %pI4", pfx_buf, new_buf, exist_buf, new_mm_seq, - inet_ntoa(new->attr->nexthop)); + &new->attr->nexthop); return 1; } if (nh_cmp > 0) { *reason = bgp_path_selection_evpn_lower_ip; if (debug) zlog_debug( - "%s: %s loses to %s due to same MM seq %u and higher IP %s", + "%s: %s loses to %s due to same MM seq %u and higher IP %pI4", pfx_buf, new_buf, exist_buf, new_mm_seq, - inet_ntoa(new->attr->nexthop)); + &new->attr->nexthop); return 0; } } @@ -794,8 +805,12 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, * - BGP_ROUTE_AGGREGATE * - BGP_ROUTE_REDISTRIBUTE */ - if (!(new->sub_type == BGP_ROUTE_NORMAL || - new->sub_type == BGP_ROUTE_IMPORTED)) { + new_origin = !(new->sub_type == BGP_ROUTE_NORMAL || + new->sub_type == BGP_ROUTE_IMPORTED); + exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL || + exist->sub_type == BGP_ROUTE_IMPORTED); + + if (new_origin && !exist_origin) { *reason = bgp_path_selection_local_route; if (debug) zlog_debug( @@ -804,8 +819,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, return 1; } - if (!(exist->sub_type == BGP_ROUTE_NORMAL || - exist->sub_type == BGP_ROUTE_IMPORTED)) { + if (!new_origin && exist_origin) { *reason = bgp_path_selection_local_route; if (debug) zlog_debug( @@ -1288,6 +1302,7 @@ static enum filter_type bgp_input_filter(struct peer *peer, safi_t safi) { struct bgp_filter *filter; + enum filter_type ret = FILTER_PERMIT; filter = &peer->filter[afi][safi]; @@ -1299,26 +1314,43 @@ static enum filter_type bgp_input_filter(struct peer *peer, if (DISTRIBUTE_IN_NAME(filter)) { FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter); - if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY) - return FILTER_DENY; + if (access_list_apply(DISTRIBUTE_IN(filter), p) + == FILTER_DENY) { + ret = FILTER_DENY; + goto done; + } } if (PREFIX_LIST_IN_NAME(filter)) { FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter); - if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY) - return FILTER_DENY; + if (prefix_list_apply(PREFIX_LIST_IN(filter), p) + == PREFIX_DENY) { + ret = FILTER_DENY; + goto done; + } } if (FILTER_LIST_IN_NAME(filter)) { FILTER_EXIST_WARN(FILTER_LIST, as, filter); if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath) - == AS_FILTER_DENY) - return FILTER_DENY; + == AS_FILTER_DENY) { + ret = FILTER_DENY; + goto done; + } } - return FILTER_PERMIT; +done: + if (frrtrace_enabled(frr_bgp, input_filter)) { + char pfxprint[PREFIX2STR_BUFFER]; + + prefix2str(p, pfxprint, sizeof(pfxprint)); + frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi, + ret == FILTER_PERMIT ? "permit" : "deny"); + } + + return ret; #undef FILTER_EXIST_WARN } @@ -1328,6 +1360,7 @@ static enum filter_type bgp_output_filter(struct peer *peer, safi_t safi) { struct bgp_filter *filter; + enum filter_type ret = FILTER_PERMIT; filter = &peer->filter[afi][safi]; @@ -1339,27 +1372,43 @@ static enum filter_type bgp_output_filter(struct peer *peer, if (DISTRIBUTE_OUT_NAME(filter)) { FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter); - if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY) - return FILTER_DENY; + if (access_list_apply(DISTRIBUTE_OUT(filter), p) + == FILTER_DENY) { + ret = FILTER_DENY; + goto done; + } } if (PREFIX_LIST_OUT_NAME(filter)) { FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter); if (prefix_list_apply(PREFIX_LIST_OUT(filter), p) - == PREFIX_DENY) - return FILTER_DENY; + == PREFIX_DENY) { + ret = FILTER_DENY; + goto done; + } } if (FILTER_LIST_OUT_NAME(filter)) { FILTER_EXIST_WARN(FILTER_LIST, as, filter); if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath) - == AS_FILTER_DENY) - return FILTER_DENY; + == AS_FILTER_DENY) { + ret = FILTER_DENY; + goto done; + } } - return FILTER_PERMIT; + if (frrtrace_enabled(frr_bgp, output_filter)) { + char pfxprint[PREFIX2STR_BUFFER]; + + prefix2str(p, pfxprint, sizeof(pfxprint)); + frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi, + ret == FILTER_PERMIT ? "permit" : "deny"); + } + +done: + return ret; #undef FILTER_EXIST_WARN } @@ -1613,7 +1662,34 @@ void bgp_attr_add_gshut_community(struct attr *attr) } -static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) +/* Notify BGP Conditional advertisement scanner process. */ +void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp) +{ + struct peer *temp_peer; + struct peer *peer = SUBGRP_PEER(subgrp); + struct listnode *temp_node, *temp_nnode = NULL; + afi_t afi = SUBGRP_AFI(subgrp); + safi_t safi = SUBGRP_SAFI(subgrp); + struct bgp *bgp = SUBGRP_INST(subgrp); + struct bgp_filter *filter = &peer->filter[afi][safi]; + + if (!ADVERTISE_MAP_NAME(filter)) + return; + + for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) { + if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + continue; + + if (peer != temp_peer) + continue; + + temp_peer->advmap_table_change = true; + break; + } +} + + +void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) { if (family == AF_INET) { attr->nexthop.s_addr = INADDR_ANY; @@ -1627,7 +1703,8 @@ static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr) bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct update_subgroup *subgrp, - const struct prefix *p, struct attr *attr) + const struct prefix *p, struct attr *attr, + bool skip_rmap_check) { struct bgp_filter *filter; struct peer *from; @@ -1635,7 +1712,6 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct peer *onlypeer; struct bgp *bgp; struct attr *piattr; - char buf[PREFIX_STRLEN]; route_map_result_t ret; int transparent; int reflect; @@ -1671,9 +1747,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, * though they can have peer pointers that reference other * systems */ - prefix2str(p, buf, PREFIX_STRLEN); - zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", - __func__, buf); + zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe", + __func__, p); samepeer_safe = 1; } #endif @@ -1706,10 +1781,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, } /* Aggregate-address suppress check. */ - if (pi->extra && pi->extra->suppress) - if (!UNSUPPRESS_MAP_NAME(filter)) { - return false; - } + if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter)) + return false; /* * If we are doing VRF 2 VRF leaking via the import @@ -1726,11 +1799,10 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi); if (!bgp_is_valid_label(&label)) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) - zlog_debug("u%" PRIu64 ":s%" PRIu64" %s/%d is filtered - no label (%p)", + zlog_debug("u%" PRIu64 ":s%" PRIu64 + " %pFX is filtered - no label (%p)", subgrp->update_group->id, subgrp->id, - inet_ntop(p->family, &p->u.prefix, - buf, SU_ADDRSTRLEN), - p->prefixlen, &label); + p, &label); return false; } } @@ -1771,9 +1843,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) zlog_debug( - "%s [Update:SEND] %s originator-id is same as remote router-id", - onlypeer->host, - prefix2str(p, buf, sizeof(buf))); + "%s [Update:SEND] %pFX originator-id is same as remote router-id", + onlypeer->host, p); return false; } @@ -1788,10 +1859,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) zlog_debug( - "%s [Update:SEND] %s is filtered via ORF", - peer->host, - prefix2str(p, buf, - sizeof(buf))); + "%s [Update:SEND] %pFX is filtered via ORF", + peer->host, p); return false; } } @@ -1799,8 +1868,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, /* Output filter check. */ if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) - zlog_debug("%s [Update:SEND] %s is filtered", - peer->host, prefix2str(p, buf, sizeof(buf))); + zlog_debug("%s [Update:SEND] %pFX is filtered", + peer->host, p); return false; } @@ -1950,7 +2019,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_peer_as_override(bgp, afi, safi, peer, attr); /* Route map & unsuppress-map apply. */ - if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) { + if (!skip_rmap_check + && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) { struct bgp_path_info rmap_path = {0}; struct bgp_path_info_extra dummy_rmap_path_extra = {0}; struct attr dummy_attr = {0}; @@ -1975,7 +2045,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT); - if (pi->extra && pi->extra->suppress) + if (bgp_path_suppressed(pi)) ret = route_map_apply(UNSUPPRESS_MAP(filter), p, RMAP_BGP, &rmap_path); else @@ -1986,8 +2056,9 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if (ret == RMAP_DENYMATCH) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) - zlog_debug("%s [Update:SEND] %s is filtered by route-map", - peer->host, prefix2str(p, buf, sizeof(buf))); + zlog_debug( + "%s [Update:SEND] %pFX is filtered by route-map", + peer->host, p); bgp_attr_flush(attr); return false; @@ -2268,10 +2339,11 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (debug) { bgp_path_info_path_with_addpath_rx_str( new_select, path_buf); - zlog_debug("%s: %s is the bestpath from AS %u", - pfx_buf, path_buf, - aspath_get_first_as( - new_select->attr->aspath)); + zlog_debug( + "%pBD: %s is the bestpath from AS %u", + dest, path_buf, + aspath_get_first_as( + new_select->attr->aspath)); } } } @@ -2345,8 +2417,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, else snprintf(path_buf, sizeof(path_buf), "NONE"); zlog_debug( - "%s: After path selection, newbest is %s oldbest was %s", - pfx_buf, path_buf, + "%pBD: After path selection, newbest is %s oldbest was %s", + dest, path_buf, old_select ? old_select->peer->host : "NONE"); } @@ -2361,8 +2433,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (pi == new_select) { if (debug) zlog_debug( - "%s: %s is the bestpath, add to the multipath list", - pfx_buf, path_buf); + "%pBD: %s is the bestpath, add to the multipath list", + dest, path_buf); bgp_mp_list_add(&mp_list, pi); continue; } @@ -2379,8 +2451,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (!bgp_path_info_nexthop_cmp(pi, new_select)) { if (debug) zlog_debug( - "%s: %s has the same nexthop as the bestpath, skip it", - pfx_buf, path_buf); + "%pBD: %s has the same nexthop as the bestpath, skip it", + dest, path_buf); continue; } @@ -2391,8 +2463,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (paths_eq) { if (debug) zlog_debug( - "%s: %s is equivalent to the bestpath, add to the multipath list", - pfx_buf, path_buf); + "%pBD: %s is equivalent to the bestpath, add to the multipath list", + dest, path_buf); bgp_mp_list_add(&mp_list, pi); } } @@ -2432,12 +2504,8 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer : NULL); - if (BGP_DEBUG(update, UPDATE_OUT)) { - char buf_prefix[PREFIX_STRLEN]; - prefix2str(p, buf_prefix, sizeof(buf_prefix)); - zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix, - selected); - } + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected); /* First update is deferred until ORF or ROUTE-REFRESH is received */ if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi], @@ -2450,7 +2518,8 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, /* Announcement to the subgroup. If the route is filtered withdraw it. */ if (selected) { - if (subgroup_announce_check(dest, selected, subgrp, p, &attr)) + if (subgroup_announce_check(dest, selected, subgrp, p, &attr, + false)) bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected); else bgp_adj_out_unset_subgroup(dest, subgrp, 1, @@ -2601,7 +2670,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, debug = bgp_debug_bestpath(dest); if (debug) zlog_debug( - "%s: bgp delete in progress, ignoring event, p=%pRN", + "%s: bgp delete in progress, ignoring event, p=%pBD", __func__, dest); return; } @@ -2625,7 +2694,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, debug = bgp_debug_bestpath(dest); if (debug) - zlog_debug("%s: p=%pRN afi=%s, safi=%s start", __func__, dest, + zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest, afi2str(afi), safi2str(safi)); /* The best path calculation for the route is deferred if @@ -2633,7 +2702,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) { if (BGP_DEBUG(update, UPDATE_OUT)) - zlog_debug("SELECT_DEFER falg set for route %p", dest); + zlog_debug("SELECT_DEFER flag set for route %p", dest); return; } @@ -2686,7 +2755,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, if (debug) zlog_debug( - "%s: p=%pRN afi=%s, safi=%s, old_select=%p, new_select=%p", + "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p", __func__, dest, afi2str(afi), safi2str(safi), old_select, new_select); @@ -2849,37 +2918,39 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi) struct bgp_dest *dest; int cnt = 0; struct afi_safi_info *thread_info; - struct listnode *node = NULL, *nnode = NULL; - if (bgp->gr_info[afi][safi].t_route_select) + if (bgp->gr_info[afi][safi].t_route_select) { + struct thread *t = bgp->gr_info[afi][safi].t_route_select; + + thread_info = THREAD_ARG(t); + XFREE(MTYPE_TMP, thread_info); BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select); + } if (BGP_DEBUG(update, UPDATE_OUT)) { zlog_debug("%s: processing route for %s : cnt %d", __func__, get_afi_safi_str(afi, safi, false), - listcount(bgp->gr_info[afi][safi].route_list)); + bgp->gr_info[afi][safi].gr_deferred); } /* Process the route list */ - node = listhead(bgp->gr_info[afi][safi].route_list); - while (node) { - dest = listgetdata(node); - nnode = node->next; - list_delete_node(bgp->gr_info[afi][safi].route_list, node); - dest->rt_node = NULL; - - if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) { - UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); - bgp_process_main_one(bgp, dest, afi, safi); - cnt++; - if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) - break; + for (dest = bgp_table_top(bgp->rib[afi][safi]); dest; + dest = bgp_route_next(dest)) { + if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) + continue; + + UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); + bgp->gr_info[afi][safi].gr_deferred--; + bgp_process_main_one(bgp, dest, afi, safi); + cnt++; + if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) { + bgp_dest_unlock_node(dest); + break; } - node = nnode; } /* Send EOR message when all routes are processed */ - if (list_isempty(bgp->gr_info[afi][safi].route_list)) { + if (bgp->gr_info[afi][safi].gr_deferred) { bgp_send_delayed_eor(bgp); /* Send route processing complete message to RIB */ bgp_zebra_update(afi, safi, bgp->vrf_id, @@ -2941,18 +3012,21 @@ static void bgp_processq_del(struct work_queue *wq, void *data) XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode); } -void bgp_process_queue_init(void) +void bgp_process_queue_init(struct bgp *bgp) { - if (!bm->process_main_queue) - bm->process_main_queue = - work_queue_new(bm->master, "process_main_queue"); + if (!bgp->process_queue) { + char name[BUFSIZ]; + + snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty); + bgp->process_queue = work_queue_new(bm->master, name); + } - bm->process_main_queue->spec.workfunc = &bgp_process_wq; - bm->process_main_queue->spec.del_item_data = &bgp_processq_del; - bm->process_main_queue->spec.max_retries = 0; - bm->process_main_queue->spec.hold = 50; + bgp->process_queue->spec.workfunc = &bgp_process_wq; + bgp->process_queue->spec.del_item_data = &bgp_processq_del; + bgp->process_queue->spec.max_retries = 0; + bgp->process_queue->spec.hold = 50; /* Use a higher yield value of 50ms for main queue processing */ - bm->process_main_queue->spec.yield = 50 * 1000L; + bgp->process_queue->spec.yield = 50 * 1000L; } static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) @@ -2972,7 +3046,7 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi) { #define ARBITRARY_PROCESS_QLEN 10000 - struct work_queue *wq = bm->process_main_queue; + struct work_queue *wq = bgp->process_queue; struct bgp_process_queue *pqnode; int pqnode_reuse = 0; @@ -3029,13 +3103,13 @@ void bgp_add_eoiu_mark(struct bgp *bgp) { struct bgp_process_queue *pqnode; - if (bm->process_main_queue == NULL) + if (bgp->process_queue == NULL) return; pqnode = bgp_processq_alloc(bgp); SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER); - work_queue_add(bm->process_main_queue, pqnode); + work_queue_add(bgp->process_queue, pqnode); } static int bgp_maximum_prefix_restart_timer(struct thread *thread) @@ -3167,7 +3241,8 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi, UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT); - if (pcount > (pcount * peer->pmax_threshold[afi][safi] / 100)) { + if (pcount + > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) { if (CHECK_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD) && !always) @@ -3212,13 +3287,7 @@ void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi, if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) { UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER); bgp = pi->peer->bgp; - if ((dest->rt_node) - && (bgp->gr_info[afi][safi].route_list)) { - list_delete_node(bgp->gr_info[afi][safi] - .route_list, - dest->rt_node); - dest->rt_node = NULL; - } + bgp->gr_info[afi][safi].gr_deferred--; } } } @@ -3430,6 +3499,14 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, uint8_t pi_type = 0; uint8_t pi_sub_type = 0; + if (frrtrace_enabled(frr_bgp, process_update)) { + char pfxprint[PREFIX2STR_BUFFER]; + + prefix2str(p, pfxprint, sizeof(pfxprint)); + frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id, + afi, safi, attr); + } + #ifdef ENABLE_BGP_VNC int vnc_implicit_withdraw = 0; #endif @@ -4287,7 +4364,7 @@ void bgp_stop_announce_route_timer(struct peer_af *paf) if (!paf->t_announce_route) return; - THREAD_TIMER_OFF(paf->t_announce_route); + thread_cancel(&paf->t_announce_route); } /* @@ -4311,6 +4388,10 @@ static int bgp_announce_route_timer_expired(struct thread *t) return 0; peer_af_announce_route(paf, 1); + + /* Notify BGP conditional advertisement scanner percess */ + peer->advmap_config_change[paf->afi][paf->safi] = true; + return 0; } @@ -4546,7 +4627,7 @@ static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi, struct bgp_table *table) { struct bgp_dest *dest; - int force = bm->process_main_queue ? 0 : 1; + int force = peer->bgp->process_queue ? 0 : 1; if (!table) table = peer->bgp->rib[afi][safi]; @@ -4983,8 +5064,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, */ flog_err( EC_BGP_UPDATE_RCV, - "%s: IPv4 unicast NLRI is multicast address %s, ignoring", - peer->host, inet_ntoa(p.u.prefix4)); + "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring", + peer->host, &p.u.prefix4); continue; } } @@ -5538,28 +5619,16 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p, /* Configure static BGP network. When user don't run zebra, static route should be installed as valid. */ -static int bgp_static_set(struct vty *vty, const char *negate, - const char *ip_str, afi_t afi, safi_t safi, - const char *rmap, int backdoor, uint32_t label_index) +int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx, + afi_t afi, safi_t safi, const char *rmap, int backdoor, + uint32_t label_index, char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; struct prefix p; struct bgp_static *bgp_static; struct bgp_dest *dest; uint8_t need_update = 0; - /* Convert IP prefix string to struct prefix. */ - ret = str2prefix(ip_str, &p); - if (!ret) { - vty_out(vty, "%% Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) { - vty_out(vty, "%% Malformed prefix (link-local address)\n"); - return CMD_WARNING_CONFIG_FAILED; - } - + prefix_copy(&p, pfx); apply_mask(&p); if (negate) { @@ -5568,24 +5637,25 @@ static int bgp_static_set(struct vty *vty, const char *negate, dest = bgp_node_lookup(bgp->route[afi][safi], &p); if (!dest) { - vty_out(vty, "%% Can't find static route specified\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "Can't find static route specified\n"); + return -1; } bgp_static = bgp_dest_get_bgp_static_info(dest); if ((label_index != BGP_INVALID_LABEL_INDEX) && (label_index != bgp_static->label_index)) { - vty_out(vty, - "%% label-index doesn't match static route\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "label-index doesn't match static route\n"); + return -1; } if ((rmap && bgp_static->rmap.name) && strcmp(rmap, bgp_static->rmap.name)) { - vty_out(vty, - "%% route-map name doesn't match static route\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "route-map name doesn't match static route\n"); + return -1; } /* Update BGP RIB. */ @@ -5606,8 +5676,9 @@ static int bgp_static_set(struct vty *vty, const char *negate, /* Configuration change. */ /* Label index cannot be changed. */ if (bgp_static->label_index != label_index) { - vty_out(vty, "%% cannot change label-index\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "cannot change label-index\n"); + return -1; } /* Check previous routes are installed into BGP. */ @@ -5669,7 +5740,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, bgp_static_update(bgp, &p, bgp_static, afi, safi); } - return CMD_SUCCESS; + return 0; } void bgp_static_add(struct bgp *bgp) @@ -5745,9 +5816,9 @@ void bgp_static_delete(struct bgp *bgp) bgp_dest_get_prefix( dest)); bgp_static_free(bgp_static); - bgp_dest_set_bgp_static_info(dest, + bgp_dest_set_bgp_static_info(rm, NULL); - bgp_dest_unlock_node(dest); + bgp_dest_unlock_node(rm); } } else { bgp_static = bgp_dest_get_bgp_static_info(dest); @@ -6119,25 +6190,27 @@ DEFUN (no_bgp_table_map, argv[idx_word]->arg); } -DEFPY(bgp_network, - bgp_network_cmd, - "[no] network \ - <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \ - [{route-map WORD$map_name|label-index (0-1048560)$label_index| \ - backdoor$backdoor}]", - NO_STR - "Specify a network to announce via BGP\n" - "IPv4 prefix\n" - "Network number\n" - "Network mask\n" - "Network mask\n" - "Route-map to modify the attributes\n" - "Name of the route map\n" - "Label index to associate with the prefix\n" - "Label index value\n" - "Specify a BGP backdoor route\n") -{ - char addr_prefix_str[BUFSIZ]; +DEFPY_YANG (bgp_network, bgp_network_cmd, + "[no] network \ + <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \ + [{route-map WORD$map_name|label-index (0-1048560)$label_index| \ + backdoor$backdoor}]", + NO_STR + "Specify a network to announce via BGP\n" + "IPv4 prefix\n" + "Network number\n" + "Network mask\n" + "Network mask\n" + "Route-map to modify the attributes\n" + "Name of the route map\n" + "Label index to associate with the prefix\n" + "Label index value\n" + "Specify a BGP backdoor route\n") +{ + char addr_prefix_str[PREFIX_STRLEN]; + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; if (address_str) { int ret; @@ -6150,27 +6223,102 @@ DEFPY(bgp_network, } } - return bgp_static_set( - vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP, - bgp_node_safi(vty), map_name, backdoor ? 1 : 0, - label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + if (no) { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + if (map_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_CREATE, map_name); + else + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_DESTROY, NULL); + + if (label_index_str) + nb_cli_enqueue_change(vty, "./label-index", + NB_OP_MODIFY, label_index_str); + + nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY, + backdoor ? "true" : "false"); + } + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), + address_str ? addr_prefix_str : prefix_str); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFPY(ipv6_bgp_network, - ipv6_bgp_network_cmd, - "[no] network X:X::X:X/M$prefix \ - [{route-map WORD$map_name|label-index (0-1048560)$label_index}]", - NO_STR - "Specify a network to announce via BGP\n" - "IPv6 prefix\n" - "Route-map to modify the attributes\n" - "Name of the route map\n" - "Label index to associate with the prefix\n" - "Label index value\n") +DEFPY_YANG (ipv6_bgp_network, + ipv6_bgp_network_cmd, + "[no] network X:X::X:X/M$prefix \ + [{route-map WORD$map_name|label-index (0-1048560)$label_index}]", + NO_STR + "Specify a network to announce via BGP\n" + "IPv6 prefix\n" + "Route-map to modify the attributes\n" + "Name of the route map\n" + "Label index to associate with the prefix\n" + "Label index value\n") { - return bgp_static_set( - vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0, - label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + if (no) { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + if (map_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_MODIFY, map_name); + else + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_DESTROY, NULL); + + if (label_index_str) + nb_cli_enqueue_change(vty, "./label-index", + NB_OP_MODIFY, label_index_str); + } + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), prefix_str); + + return nb_cli_apply_changes(vty, base_xpath); +} + +void cli_show_bgp_global_afi_safi_network_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " network %s", yang_dnode_get_string(dnode, "./prefix")); + + if (yang_dnode_exists(dnode, "./label-index")) + vty_out(vty, " label-index %s", + yang_dnode_get_string(dnode, "./label-index")); + + if (yang_dnode_exists(dnode, "./rmap-policy-export")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./rmap-policy-export")); + + if (yang_dnode_get_bool(dnode, "./backdoor")) + vty_out(vty, " backdoor"); + + vty_out(vty, "\n"); } static struct bgp_aggregate *bgp_aggregate_new(void) @@ -6180,11 +6328,119 @@ static struct bgp_aggregate *bgp_aggregate_new(void) static void bgp_aggregate_free(struct bgp_aggregate *aggregate) { + XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name); + route_map_counter_decrement(aggregate->suppress_map); XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name); route_map_counter_decrement(aggregate->rmap.map); XFREE(MTYPE_BGP_AGGREGATE, aggregate); } +/** + * Helper function to avoid repeated code: prepare variables for a + * `route_map_apply` call. + * + * \returns `true` on route map match, otherwise `false`. + */ +static bool aggr_suppress_map_test(struct bgp *bgp, + struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + const struct prefix *p = bgp_dest_get_prefix(pi->net); + route_map_result_t rmr = RMAP_DENYMATCH; + struct bgp_path_info rmap_path = {}; + struct attr attr = {}; + + /* No route map entries created, just don't match. */ + if (aggregate->suppress_map == NULL) + return false; + + /* Call route map matching and return result. */ + attr.aspath = aspath_empty(); + rmap_path.peer = bgp->peer_self; + rmap_path.attr = &attr; + + SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE); + rmr = route_map_apply(aggregate->suppress_map, p, RMAP_BGP, &rmap_path); + bgp->peer_self->rmap_type = 0; + + bgp_attr_flush(&attr); + + return rmr == RMAP_PERMITMATCH; +} + +/** Test whether the aggregation has suppressed this path or not. */ +static bool aggr_suppress_exists(struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL) + return false; + + return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL; +} + +/** + * Suppress this path and keep the reference. + * + * \returns `true` if needs processing otherwise `false`. + */ +static bool aggr_suppress_path(struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + struct bgp_path_info_extra *pie; + + /* Path is already suppressed by this aggregation. */ + if (aggr_suppress_exists(aggregate, pi)) + return false; + + pie = bgp_path_info_extra_get(pi); + + /* This is the first suppression, allocate memory and list it. */ + if (pie->aggr_suppressors == NULL) + pie->aggr_suppressors = list_new(); + + listnode_add(pie->aggr_suppressors, aggregate); + + /* Only mark for processing if suppressed. */ + if (listcount(pie->aggr_suppressors) == 1) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("aggregate-address suppressing: %pFX", + bgp_dest_get_prefix(pi->net)); + + bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED); + return true; + } + + return false; +} + +/** + * Unsuppress this path and remove the reference. + * + * \returns `true` if needs processing otherwise `false`. + */ +static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + /* Path wasn't suppressed. */ + if (!aggr_suppress_exists(aggregate, pi)) + return false; + + listnode_delete(pi->extra->aggr_suppressors, aggregate); + + /* Unsuppress and free extra memory if last item. */ + if (listcount(pi->extra->aggr_suppressors) == 0) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("aggregate-address unsuppressing: %pFX", + bgp_dest_get_prefix(pi->net)); + + list_delete(&pi->extra->aggr_suppressors); + bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED); + return true; + } + + return false; +} + static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin, struct aspath *aspath, struct community *comm, @@ -6240,6 +6496,13 @@ static void bgp_aggregate_install( && pi->sub_type == BGP_ROUTE_AGGREGATE) break; + /* + * If we have paths with different MEDs, then don't install + * (or uninstall) the aggregate route. + */ + if (aggregate->match_med && aggregate->med_mismatched) + goto uninstall_aggregate_route; + if (aggregate->count > 0) { /* * If the aggregate information has not changed @@ -6284,6 +6547,7 @@ static void bgp_aggregate_install( bgp_path_info_add(dest, new); bgp_process(bgp, dest, afi, safi); } else { + uninstall_aggregate_route: for (pi = orig; pi; pi = pi->next) if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP @@ -6300,6 +6564,172 @@ static void bgp_aggregate_install( bgp_dest_unlock_node(dest); } +/** + * Check if the current path has different MED than other known paths. + * + * \returns `true` if the MED matched the others else `false`. + */ +static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate, + struct bgp *bgp, struct bgp_path_info *pi) +{ + uint32_t cur_med = bgp_med_value(pi->attr, bgp); + + /* This is the first route being analyzed. */ + if (!aggregate->med_initialized) { + aggregate->med_initialized = true; + aggregate->med_mismatched = false; + aggregate->med_matched_value = cur_med; + } else { + /* Check if routes with different MED showed up. */ + if (cur_med != aggregate->med_matched_value) + aggregate->med_mismatched = true; + } + + return !aggregate->med_mismatched; +} + +/** + * Initializes and tests all routes in the aggregate address path for MED + * values. + * + * \returns `true` if all MEDs are the same otherwise `false`. + */ +static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate, + struct bgp *bgp, const struct prefix *p, + afi_t afi, safi_t safi) +{ + struct bgp_table *table = bgp->rib[afi][safi]; + const struct prefix *dest_p; + struct bgp_dest *dest, *top; + struct bgp_path_info *pi; + bool med_matched = true; + + aggregate->med_initialized = false; + + top = bgp_node_get(table, p); + for (dest = bgp_node_get(table, p); dest; + dest = bgp_route_next_until(dest, top)) { + dest_p = bgp_dest_get_prefix(dest); + if (dest_p->prefixlen <= p->prefixlen) + continue; + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + if (BGP_PATH_HOLDDOWN(pi)) + continue; + if (pi->sub_type == BGP_ROUTE_AGGREGATE) + continue; + if (!bgp_aggregate_med_match(aggregate, bgp, pi)) { + med_matched = false; + break; + } + } + if (!med_matched) + break; + } + bgp_dest_unlock_node(top); + + return med_matched; +} + +/** + * Toggles the route suppression status for this aggregate address + * configuration. + */ +void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, + struct bgp *bgp, const struct prefix *p, + afi_t afi, safi_t safi, bool suppress) +{ + struct bgp_table *table = bgp->rib[afi][safi]; + const struct prefix *dest_p; + struct bgp_dest *dest, *top; + struct bgp_path_info *pi; + bool toggle_suppression; + + /* We've found a different MED we must revert any suppressed routes. */ + top = bgp_node_get(table, p); + for (dest = bgp_node_get(table, p); dest; + dest = bgp_route_next_until(dest, top)) { + dest_p = bgp_dest_get_prefix(dest); + if (dest_p->prefixlen <= p->prefixlen) + continue; + + toggle_suppression = false; + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + if (BGP_PATH_HOLDDOWN(pi)) + continue; + if (pi->sub_type == BGP_ROUTE_AGGREGATE) + continue; + + /* We are toggling suppression back. */ + if (suppress) { + /* Suppress route if not suppressed already. */ + if (aggr_suppress_path(aggregate, pi)) + toggle_suppression = true; + continue; + } + + /* Install route if there is no more suppression. */ + if (aggr_unsuppress_path(aggregate, pi)) + toggle_suppression = true; + } + + if (toggle_suppression) + bgp_process(bgp, dest, afi, safi); + } + bgp_dest_unlock_node(top); +} + +/** + * Aggregate address MED matching incremental test: this function is called + * when the initial aggregation occurred and we are only testing a single + * new path. + * + * In addition to testing and setting the MED validity it also installs back + * suppressed routes (if summary is configured). + * + * Must not be called in `bgp_aggregate_route`. + */ +static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate, + struct bgp *bgp, const struct prefix *p, + afi_t afi, safi_t safi, + struct bgp_path_info *pi, bool is_adding) +{ + /* MED matching disabled. */ + if (!aggregate->match_med) + return; + + /* Aggregation with different MED, nothing to do. */ + if (aggregate->med_mismatched) + return; + + /* + * Test the current entry: + * + * is_adding == true: if the new entry doesn't match then we must + * install all suppressed routes. + * + * is_adding == false: if the entry being removed was the last + * unmatching entry then we can suppress all routes. + */ + if (!is_adding) { + if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) + && aggregate->summary_only) + bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, + safi, true); + } else + bgp_aggregate_med_match(aggregate, bgp, pi); + + /* No mismatches, just quit. */ + if (!aggregate->med_mismatched) + return; + + /* Route summarization is disabled. */ + if (!aggregate->summary_only) + return; + + bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false); +} + /* Update an aggregate as routes are added/removed from the BGP table */ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, safi_t safi, struct bgp_aggregate *aggregate) @@ -6323,6 +6753,21 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, || (bgp->peer_self == NULL)) return; + /* Initialize and test routes for MED difference. */ + if (aggregate->match_med) + bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi); + + /* + * Reset aggregate count: we might've been called from route map + * update so in that case we must retest all more specific routes. + * + * \see `bgp_route_map_process_update`. + */ + aggregate->count = 0; + aggregate->incomplete_origin_count = 0; + aggregate->incomplete_origin_count = 0; + aggregate->egp_origin_count = 0; + /* ORIGIN attribute: If at least one route among routes that are aggregated has ORIGIN with the value INCOMPLETE, then the aggregated route must have the ORIGIN attribute with the value @@ -6359,12 +6804,32 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, /* * summary-only aggregate route suppress * aggregated route announcements. + * + * MED matching: + * Don't create summaries if MED didn't match + * otherwise neither the specific routes and the + * aggregation will be announced. */ - if (aggregate->summary_only) { - (bgp_path_info_extra_get(pi))->suppress++; - bgp_path_info_set_flag(dest, pi, - BGP_PATH_ATTR_CHANGED); - match++; + if (aggregate->summary_only + && AGGREGATE_MED_VALID(aggregate)) { + if (aggr_suppress_path(aggregate, pi)) + match++; + } + + /* + * Suppress more specific routes that match the route + * map results. + * + * MED matching: + * Don't suppress routes if MED matching is enabled and + * it mismatched otherwise we might end up with no + * routes for this path. + */ + if (aggregate->suppress_map_name + && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pi)) { + if (aggr_suppress_path(aggregate, pi)) + match++; } aggregate->count++; @@ -6502,16 +6967,19 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, if (pi->sub_type == BGP_ROUTE_AGGREGATE) continue; - if (aggregate->summary_only && pi->extra) { - pi->extra->suppress--; + if (aggregate->summary_only && pi->extra + && AGGREGATE_MED_VALID(aggregate)) { + if (aggr_unsuppress_path(aggregate, pi)) + match++; + } - if (pi->extra->suppress == 0) { - bgp_path_info_set_flag( - dest, pi, - BGP_PATH_ATTR_CHANGED); + if (aggregate->suppress_map_name + && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pi)) { + if (aggr_unsuppress_path(aggregate, pi)) match++; - } } + aggregate->count--; if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE) @@ -6593,8 +7061,20 @@ static void bgp_add_route_to_aggregate(struct bgp *bgp, aggregate->count++; - if (aggregate->summary_only) - (bgp_path_info_extra_get(pinew))->suppress++; + /* + * This must be called before `summary` check to avoid + * "suppressing" twice. + */ + if (aggregate->match_med) + bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, + pinew, true); + + if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) + aggr_suppress_path(aggregate, pinew); + + if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pinew)) + aggr_suppress_path(aggregate, pinew); switch (pinew->attr->origin) { case BGP_ORIGIN_INCOMPLETE: @@ -6690,17 +7170,22 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi, if (pi->sub_type == BGP_ROUTE_AGGREGATE) return; - if (aggregate->summary_only - && pi->extra - && pi->extra->suppress > 0) { - pi->extra->suppress--; + if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) + if (aggr_unsuppress_path(aggregate, pi)) + match++; - if (pi->extra->suppress == 0) { - bgp_path_info_set_flag(pi->net, pi, - BGP_PATH_ATTR_CHANGED); + if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pi)) + if (aggr_unsuppress_path(aggregate, pi)) match++; - } - } + + /* + * This must be called after `summary`, `suppress-map` check to avoid + * "unsuppressing" twice. + */ + if (aggregate->match_med) + bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi, + true); if (aggregate->count > 0) aggregate->count--; @@ -6863,35 +7348,25 @@ static const char *bgp_origin2str(uint8_t origin) return "n/a"; } -static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str, - afi_t afi, safi_t safi) +int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi, + safi_t safi, char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - struct prefix p; struct bgp_dest *dest; struct bgp_aggregate *aggregate; - /* Convert string to prefix structure. */ - ret = str2prefix(prefix_str, &p); - if (!ret) { - vty_out(vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - apply_mask(&p); - + apply_mask(prefix); /* Old configuration check. */ - dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p); + dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix); if (!dest) { - vty_out(vty, - "%% There is no aggregate-address configuration.\n"); - return CMD_WARNING_CONFIG_FAILED; + snprintf(errmsg, errmsg_len, + "There is no aggregate-address configuration.\n"); + return -1; } aggregate = bgp_dest_get_bgp_aggregate_info(dest); - bgp_aggregate_delete(bgp, &p, afi, safi, aggregate); - bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, - NULL, NULL, 0, aggregate); + bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate); + bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL, + 0, aggregate); /* Unlock aggregate address configuration. */ bgp_dest_set_bgp_aggregate_info(dest, NULL); @@ -6952,54 +7427,60 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str, bgp_dest_unlock_node(dest); bgp_dest_unlock_node(dest); - return CMD_SUCCESS; + return 0; } -static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, - safi_t safi, const char *rmap, - uint8_t summary_only, uint8_t as_set, - uint8_t origin) +int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi, + safi_t safi, const char *rmap, uint8_t summary_only, + uint8_t as_set, uint8_t origin, bool match_med, + const char *suppress_map, + char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int ret; - struct prefix p; struct bgp_dest *dest; struct bgp_aggregate *aggregate; uint8_t as_set_new = as_set; + char buf[PREFIX2STR_BUFFER]; - /* Convert string to prefix structure. */ - ret = str2prefix(prefix_str, &p); - if (!ret) { - vty_out(vty, "Malformed prefix\n"); - return CMD_WARNING_CONFIG_FAILED; + if (suppress_map && summary_only) { + snprintf(errmsg, errmsg_len, + "'summary-only' and 'suppress-map' can't be used at the same time\n"); + return -1; } - apply_mask(&p); - if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) || - (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) { - vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n", - prefix_str); - return CMD_WARNING_CONFIG_FAILED; + apply_mask(prefix); + + if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN) + || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) { + snprintf( + errmsg, errmsg_len, + "Specified prefix: %s will not result in any useful aggregation, disallowing\n", + prefix2str(prefix, buf, PREFIX_STRLEN)); + return -1; } /* Old configuration check. */ - dest = bgp_node_get(bgp->aggregate[afi][safi], &p); + dest = bgp_node_get(bgp->aggregate[afi][safi], prefix); aggregate = bgp_dest_get_bgp_aggregate_info(dest); if (aggregate) { - vty_out(vty, "There is already same aggregate network.\n"); + snprintf(errmsg, errmsg_len, + "There is already same aggregate network.\n"); /* try to remove the old entry */ - ret = bgp_aggregate_unset(vty, prefix_str, afi, safi); + ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg, + errmsg_len); if (ret) { - vty_out(vty, "Error deleting aggregate.\n"); + snprintf(errmsg, errmsg_len, + "Error deleting aggregate.\n"); bgp_dest_unlock_node(dest); - return CMD_WARNING_CONFIG_FAILED; + return -1; } } /* Make aggregate address structure. */ aggregate = bgp_aggregate_new(); aggregate->summary_only = summary_only; + aggregate->match_med = match_med; /* Network operators MUST NOT locally generate any new * announcements containing AS_SET or AS_CONFED_SET. If they have @@ -7015,7 +7496,8 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, zlog_warn( "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.", __func__); - vty_out(vty, + snprintf( + errmsg, errmsg_len, "Ignoring as-set because `bgp reject-as-sets` is enabled.\n"); } } @@ -7037,244 +7519,215 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, aggregate->rmap.map = route_map_lookup_by_name(rmap); route_map_counter_increment(aggregate->rmap.map); } + + if (suppress_map) { + XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name); + route_map_counter_decrement(aggregate->suppress_map); + + aggregate->suppress_map_name = + XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map); + aggregate->suppress_map = + route_map_lookup_by_name(aggregate->suppress_map_name); + route_map_counter_increment(aggregate->suppress_map); + } + bgp_dest_set_bgp_aggregate_info(dest, aggregate); /* Aggregate address insert into BGP routing table. */ - bgp_aggregate_route(bgp, &p, afi, safi, aggregate); + bgp_aggregate_route(bgp, prefix, afi, safi, aggregate); - return CMD_SUCCESS; + return 0; } -DEFUN (aggregate_address, - aggregate_address_cmd, - "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]", - "Configure BGP aggregate entries\n" - "Aggregate prefix\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Filter more specific routes from updates\n" - "Generate AS set path information\n" - "Apply route map to aggregate network\n" - "Name of route map\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n") -{ - int idx = 0; - argv_find(argv, argc, "A.B.C.D/M", &idx); - char *prefix = argv[idx]->arg; - char *rmap = NULL; - uint8_t origin = BGP_ORIGIN_UNSPECIFIED; - int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET - : AGGREGATE_AS_UNSET; - idx = 0; - int summary_only = argv_find(argv, argc, "summary-only", &idx) - ? AGGREGATE_SUMMARY_ONLY - : 0; - - idx = 0; - argv_find(argv, argc, "WORD", &idx); - if (idx) - rmap = argv[idx]->arg; - - idx = 0; - if (argv_find(argv, argc, "origin", &idx)) { - if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0) - origin = BGP_ORIGIN_IGP; - if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0) - origin = BGP_ORIGIN_EGP; - if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0) - origin = BGP_ORIGIN_INCOMPLETE; - } - - return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty), rmap, - summary_only, as_set, origin); -} - -DEFUN (aggregate_address_mask, - aggregate_address_mask_cmd, - "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]", - "Configure BGP aggregate entries\n" - "Aggregate address\n" - "Aggregate mask\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Filter more specific routes from updates\n" - "Generate AS set path information\n" - "Apply route map to aggregate network\n" - "Name of route map\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n") -{ - int idx = 0; - argv_find(argv, argc, "A.B.C.D", &idx); - char *prefix = argv[idx]->arg; - char *mask = argv[idx + 1]->arg; - bool rmap_found; - char *rmap = NULL; - uint8_t origin = BGP_ORIGIN_UNSPECIFIED; - int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET - : AGGREGATE_AS_UNSET; - idx = 0; - int summary_only = argv_find(argv, argc, "summary-only", &idx) - ? AGGREGATE_SUMMARY_ONLY - : 0; - - rmap_found = argv_find(argv, argc, "WORD", &idx); - if (rmap_found) - rmap = argv[idx]->arg; +DEFPY_YANG( + aggregate_addressv4, aggregate_addressv4_cmd, + "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {" + "as-set$as_set_s" + "|summary-only$summary_only" + "|route-map WORD$rmap_name" + "|origin <egp|igp|incomplete>$origin_s" + "|matching-MED-only$match_med" + "|suppress-map WORD$suppress_map" + "}", + NO_STR + "Configure BGP aggregate entries\n" + "Aggregate prefix\n" + "Aggregate address\n" + "Aggregate mask\n" + "Generate AS set path information\n" + "Filter more specific routes from updates\n" + "Apply route map to aggregate network\n" + "Route map name\n" + "BGP origin code\n" + "Remote EGP\n" + "Local IGP\n" + "Unknown heritage\n" + "Only aggregate routes with matching MED\n" + "Suppress the selected more specific routes\n" + "Route map with the route selectors\n") +{ + char base_xpath[XPATH_MAXLEN]; + safi_t safi = bgp_node_safi(vty); + char prefix_buf[PREFIX2STR_BUFFER]; + + if (addr_str) { + if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf) + == 0) { + vty_out(vty, "%% Inconsistent address and mask\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } else { + strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf)); + } - char prefix_str[BUFSIZ]; - int ret = netmask_str2prefix_str(prefix, mask, prefix_str); + if (!no && origin_s) + nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s); - if (!ret) { - vty_out(vty, "%% Inconsistent address and mask\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!no && as_set_s) + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false"); - idx = 0; - if (argv_find(argv, argc, "origin", &idx)) { - if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0) - origin = BGP_ORIGIN_IGP; - if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0) - origin = BGP_ORIGIN_EGP; - if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0) - origin = BGP_ORIGIN_INCOMPLETE; - } + if (!no && summary_only) + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "true"); + else + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "false"); - return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty), - rmap, summary_only, as_set, origin); -} + if (!no && match_med) + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, + "false"); -DEFUN (no_aggregate_address, - no_aggregate_address_cmd, - "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]", - NO_STR - "Configure BGP aggregate entries\n" - "Aggregate prefix\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Filter more specific routes from updates\n" - "Generate AS set path information\n" - "Apply route map to aggregate network\n" - "Name of route map\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n") -{ - int idx = 0; - argv_find(argv, argc, "A.B.C.D/M", &idx); - char *prefix = argv[idx]->arg; - return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty)); -} + if (rmap_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY, + rmap_name); + else + nb_cli_enqueue_change(vty, "./rmap-policy-export", + NB_OP_DESTROY, NULL); -DEFUN (no_aggregate_address_mask, - no_aggregate_address_mask_cmd, - "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]", - NO_STR - "Configure BGP aggregate entries\n" - "Aggregate address\n" - "Aggregate mask\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Filter more specific routes from updates\n" - "Generate AS set path information\n" - "Apply route map to aggregate network\n" - "Name of route map\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n") -{ - int idx = 0; - argv_find(argv, argc, "A.B.C.D", &idx); - char *prefix = argv[idx]->arg; - char *mask = argv[idx + 1]->arg; + if (suppress_map) + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY, + suppress_map); + else + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY, + NULL); - char prefix_str[BUFSIZ]; - int ret = netmask_str2prefix_str(prefix, mask, prefix_str); + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']", + yang_afi_safi_value2identity(AFI_IP, safi), + bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf); - if (!ret) { - vty_out(vty, "%% Inconsistent address and mask\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, base_xpath); +} + +DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd, + "[no] aggregate-address X:X::X:X/M$prefix {" + "as-set$as_set_s" + "|summary-only$summary_only" + "|route-map WORD$rmap_name" + "|origin <egp|igp|incomplete>$origin_s" + "|matching-MED-only$match_med" + "|suppress-map WORD$suppress_map" + "}", + NO_STR + "Configure BGP aggregate entries\n" + "Aggregate prefix\n" + "Generate AS set path information\n" + "Filter more specific routes from updates\n" + "Apply route map to aggregate network\n" + "Route map name\n" + "BGP origin code\n" + "Remote EGP\n" + "Local IGP\n" + "Unknown heritage\n" + "Only aggregate routes with matching MED\n" + "Suppress the selected more specific routes\n" + "Route map with the route selectors\n") +{ + char base_xpath[XPATH_MAXLEN]; + safi_t safi = bgp_node_safi(vty); + + if (!no && origin_s) + nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s); + + if (!no && as_set_s) + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false"); + + if (!no && summary_only) + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "true"); + else + nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY, + "false"); + + if (!no && match_med) + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, + "false"); + + if (rmap_name) + nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY, + rmap_name); + + if (suppress_map) + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY, + suppress_map); + else + nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY, + NULL); - return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty)); + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']", + yang_afi_safi_value2identity(AFI_IP6, safi), + bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str); + + if (no) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (ipv6_aggregate_address, - ipv6_aggregate_address_cmd, - "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]", - "Configure BGP aggregate entries\n" - "Aggregate prefix\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Filter more specific routes from updates\n" - "Generate AS set path information\n" - "Apply route map to aggregate network\n" - "Name of route map\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n") +void cli_show_bgp_global_afi_safi_unicast_aggregate_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - int idx = 0; - argv_find(argv, argc, "X:X::X:X/M", &idx); - char *prefix = argv[idx]->arg; - char *rmap = NULL; - bool rmap_found; - uint8_t origin = BGP_ORIGIN_UNSPECIFIED; - int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET - : AGGREGATE_AS_UNSET; - - idx = 0; - int sum_only = argv_find(argv, argc, "summary-only", &idx) - ? AGGREGATE_SUMMARY_ONLY - : 0; - - rmap_found = argv_find(argv, argc, "WORD", &idx); - if (rmap_found) - rmap = argv[idx]->arg; - - idx = 0; - if (argv_find(argv, argc, "origin", &idx)) { - if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0) - origin = BGP_ORIGIN_IGP; - if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0) - origin = BGP_ORIGIN_EGP; - if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0) - origin = BGP_ORIGIN_INCOMPLETE; - } - - return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap, - sum_only, as_set, origin); -} - -DEFUN (no_ipv6_aggregate_address, - no_ipv6_aggregate_address_cmd, - "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]", - NO_STR - "Configure BGP aggregate entries\n" - "Aggregate prefix\n" - "Generate AS set path information\n" - "Filter more specific routes from updates\n" - "Filter more specific routes from updates\n" - "Generate AS set path information\n" - "Apply route map to aggregate network\n" - "Name of route map\n" - "BGP origin code\n" - "Remote EGP\n" - "Local IGP\n" - "Unknown heritage\n") -{ - int idx = 0; - argv_find(argv, argc, "X:X::X:X/M", &idx); - char *prefix = argv[idx]->arg; - return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST); + uint8_t origin; + + vty_out(vty, " aggregate-address %s", + yang_dnode_get_string(dnode, "./prefix")); + + if (yang_dnode_get_bool(dnode, "./as-set")) + vty_out(vty, " as-set"); + + if (yang_dnode_get_bool(dnode, "./summary-only")) + vty_out(vty, " summary-only"); + + if (yang_dnode_exists(dnode, "./rmap-policy-export")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./rmap-policy-export")); + + origin = yang_dnode_get_enum(dnode, "./origin"); + if (origin != BGP_ORIGIN_UNSPECIFIED) + vty_out(vty, " origin %s", bgp_origin2str(origin)); + + if (yang_dnode_get_bool(dnode, "./match-med")) + vty_out(vty, " matching-MED-only"); + + vty_out(vty, "\n"); } /* Redistribute route treatment. */ @@ -7519,10 +7972,7 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty, if (p->family == AF_INET) { if (!json) { - len = vty_out( - vty, "%s/%d", - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), - p->prefixlen); + len = vty_out(vty, "%pFX", p); } else { json_object_string_add(json, "prefix", inet_ntop(p->family, @@ -7533,14 +7983,10 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty, json_object_string_add(json, "network", buf2); } } else if (p->family == AF_ETHERNET) { - prefix2str(p, buf, PREFIX_STRLEN); - len = vty_out(vty, "%s", buf); + len = vty_out(vty, "%pFX", p); } else if (p->family == AF_EVPN) { if (!json) - len = vty_out( - vty, "%s", - bgp_evpn_route2str((struct prefix_evpn *)p, buf, - BUFSIZ)); + len = vty_out(vty, "%pFX", (struct prefix_evpn *)p); else bgp_evpn_route2json((struct prefix_evpn *)p, json); } else if (p->family == AF_FLOWSPEC) { @@ -7550,10 +7996,7 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty, NLRI_STRING_FORMAT_MIN, json); } else { if (!json) - len = vty_out( - vty, "%s/%d", - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), - p->prefixlen); + len = vty_out(vty, "%pFX", p); else { json_object_string_add(json, "prefix", inet_ntop(p->family, @@ -7592,7 +8035,7 @@ static void route_vty_short_status_out(struct vty *vty, if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) json_object_boolean_true_add(json_path, "stale"); - if (path->extra && path->extra->suppress) + if (path->extra && bgp_path_suppressed(path)) json_object_boolean_true_add(json_path, "suppressed"); if (CHECK_FLAG(path->flags, BGP_PATH_VALID) @@ -7629,7 +8072,7 @@ static void route_vty_short_status_out(struct vty *vty, vty_out(vty, "R"); else if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) vty_out(vty, "S"); - else if (path->extra && path->extra->suppress) + else if (bgp_path_suppressed(path)) vty_out(vty, "s"); else if (CHECK_FLAG(path->flags, BGP_PATH_VALID) && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) @@ -7799,10 +8242,14 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } } else if (safi == SAFI_EVPN) { if (json_paths) { + char buf[BUFSIZ] = {0}; + json_nexthop_global = json_object_new_object(); json_object_string_add(json_nexthop_global, "ip", - inet_ntoa(attr->nexthop)); + inet_ntop(AF_INET, + &attr->nexthop, buf, + sizeof(buf))); if (path->peer->hostname) json_object_string_add(json_nexthop_global, @@ -7830,13 +8277,16 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } else if (safi == SAFI_FLOWSPEC) { if (attr->nexthop.s_addr != INADDR_ANY) { if (json_paths) { + char buf[BUFSIZ] = {0}; + json_nexthop_global = json_object_new_object(); json_object_string_add(json_nexthop_global, "afi", "ipv4"); json_object_string_add( json_nexthop_global, "ip", - inet_ntoa(attr->nexthop)); + inet_ntop(AF_INET, &attr->nexthop, buf, + sizeof(buf))); if (path->peer->hostname) json_object_string_add( @@ -7866,10 +8316,14 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { if (json_paths) { + char buf[BUFSIZ] = {0}; + json_nexthop_global = json_object_new_object(); json_object_string_add(json_nexthop_global, "ip", - inet_ntoa(attr->nexthop)); + inet_ntop(AF_INET, + &attr->nexthop, buf, + sizeof(buf))); if (path->peer->hostname) json_object_string_add(json_nexthop_global, @@ -8177,18 +8631,24 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p, /* Print attribute */ if (attr) { if (use_json) { + char buf[BUFSIZ] = {0}; + if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) json_object_string_add( json_net, "nextHop", - inet_ntoa( - attr->mp_nexthop_global_in)); + inet_ntop( + AF_INET, + &attr->mp_nexthop_global_in, + buf, sizeof(buf))); else json_object_string_add( json_net, "nextHop", - inet_ntoa(attr->nexthop)); + inet_ntop(AF_INET, + &attr->nexthop, buf, + sizeof(buf))); } else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { char buf[BUFSIZ]; @@ -8198,11 +8658,16 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p, inet_ntop(AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ)); - } else if (p->family == AF_EVPN && - !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) - json_object_string_add(json_net, - "nextHop", inet_ntoa( - attr->mp_nexthop_global_in)); + } else if (p->family == AF_EVPN + && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + char buf[BUFSIZ] = {0}; + + json_object_string_add( + json_net, "nextHop", + inet_ntop(AF_INET, + &attr->mp_nexthop_global_in, + buf, sizeof(buf))); + } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) @@ -8230,15 +8695,12 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p, || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) - vty_out(vty, "%-16s", - inet_ntoa( - attr->mp_nexthop_global_in)); + vty_out(vty, "%-16pI4", + &attr->mp_nexthop_global_in); else if (wide) - vty_out(vty, "%-41s", - inet_ntoa(attr->nexthop)); + vty_out(vty, "%-41pI4", &attr->nexthop); else - vty_out(vty, "%-16s", - inet_ntoa(attr->nexthop)); + vty_out(vty, "%-16pI4", &attr->nexthop); } else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { char buf[BUFSIZ]; @@ -8323,22 +8785,27 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { + char buf[BUFSIZ] = {0}; + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { if (json) json_object_string_add( json_out, "mpNexthopGlobalIn", - inet_ntoa(attr->mp_nexthop_global_in)); + inet_ntop(AF_INET, + &attr->mp_nexthop_global_in, + buf, sizeof(buf))); else - vty_out(vty, "%-16s", - inet_ntoa(attr->mp_nexthop_global_in)); + vty_out(vty, "%-16pI4", + &attr->mp_nexthop_global_in); } else { if (json) json_object_string_add( json_out, "nexthop", - inet_ntoa(attr->nexthop)); + inet_ntop(AF_INET, &attr->nexthop, buf, + sizeof(buf))); else - vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); + vty_out(vty, "%-16pI4", &attr->nexthop); } } else if (((p->family == AF_INET6) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) @@ -8847,7 +9314,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, { char buf[INET6_ADDRSTRLEN]; char buf1[BUFSIZ]; - char buf2[EVPN_ROUTE_STRLEN]; struct attr *attr = path->attr; int sockunion_vty_out(struct vty *, union sockunion *); time_t tbuf; @@ -8885,7 +9351,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, if (path->extra) { char tag_buf[30]; - buf2[0] = '\0'; tag_buf[0] = '\0'; if (path->extra && path->extra->num_labels) { bgp_evpn_label2str(path->extra->label, @@ -8894,11 +9359,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } if (safi == SAFI_EVPN) { if (!json_paths) { - bgp_evpn_route2str( + vty_out(vty, " Route %pFX", (struct prefix_evpn *) - bgp_dest_get_prefix(bn), - buf2, sizeof(buf2)); - vty_out(vty, " Route %s", buf2); + bgp_dest_get_prefix(bn)); if (tag_buf[0] != '\0') vty_out(vty, " VNI %s", tag_buf); vty_out(vty, "\n"); @@ -8922,14 +9385,20 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, pdest), buf1, sizeof(buf1)); if (is_pi_family_evpn(parent_ri)) { - bgp_evpn_route2str( + vty_out(vty, + " Imported from %s:%pFX, VNI %s\n", + buf1, (struct prefix_evpn *) bgp_dest_get_prefix( dest), - buf2, sizeof(buf2)); - vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf); + tag_buf); } else - vty_out(vty, " Imported from %s:%s\n", buf1, buf2); + vty_out(vty, + " Imported from %s:%pFX\n", + buf1, + (struct prefix_evpn *) + bgp_dest_get_prefix( + dest)); } } } @@ -8966,11 +9435,14 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) { if (json_paths) { + char buf[BUFSIZ] = {0}; + json_object_int_add(json_path, "aggregatorAs", attr->aggregator_as); - json_object_string_add( - json_path, "aggregatorId", - inet_ntoa(attr->aggregator_addr)); + json_object_string_add(json_path, "aggregatorId", + inet_ntop(AF_INET, + &attr->aggregator_addr, + buf, sizeof(buf))); if (attr->aggregator_as == BGP_AS_ZERO) json_object_boolean_true_add( json_path, "aggregatorAsMalformed"); @@ -8980,13 +9452,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } else { if (attr->aggregator_as == BGP_AS_ZERO) vty_out(vty, - ", (aggregated by %u(malformed) %s)", + ", (aggregated by %u(malformed) %pI4)", attr->aggregator_as, - inet_ntoa(attr->aggregator_addr)); + &attr->aggregator_addr); else - vty_out(vty, ", (aggregated by %u %s)", + vty_out(vty, ", (aggregated by %u %pI4)", attr->aggregator_as, - inet_ntoa(attr->aggregator_addr)); + &attr->aggregator_addr); } } @@ -9033,12 +9505,16 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, || bn_p->family == AF_EVPN) && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { + char buf[BUFSIZ] = {0}; + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { if (json_paths) { json_object_string_add( json_nexthop_global, "ip", - inet_ntoa(attr->mp_nexthop_global_in)); + inet_ntop(AF_INET, + &attr->mp_nexthop_global_in, + buf, sizeof(buf))); if (path->peer->hostname) json_object_string_add( @@ -9057,7 +9533,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, if (json_paths) { json_object_string_add( json_nexthop_global, "ip", - inet_ntoa(attr->nexthop)); + inet_ntop(AF_INET, &attr->nexthop, buf, + sizeof(buf))); if (path->peer->hostname) json_object_string_add( @@ -9154,11 +9631,16 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, vty_out(vty, " from :: "); } - if (json_paths) + if (json_paths) { + char buf[BUFSIZ] = {0}; + json_object_string_add(json_peer, "routerId", - inet_ntoa(bgp->router_id)); - else - vty_out(vty, "(%s)", inet_ntoa(bgp->router_id)); + inet_ntop(AF_INET, + &bgp->router_id, buf, + sizeof(buf))); + } else { + vty_out(vty, "(%pI4)", &bgp->router_id); + } } /* We RXed this path from one of our peers */ @@ -9211,8 +9693,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) - vty_out(vty, " (%s)", - inet_ntoa(attr->originator_id)); + vty_out(vty, " (%pI4)", &attr->originator_id); else vty_out(vty, " (%s)", inet_ntop(AF_INET, @@ -9522,14 +10003,17 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, /* Line 7 display Originator, Cluster-id */ if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) { + char buf[BUFSIZ] = {0}; + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) { if (json_paths) json_object_string_add( json_path, "originatorId", - inet_ntoa(attr->originator_id)); + inet_ntop(AF_INET, &attr->originator_id, + buf, sizeof(buf))); else - vty_out(vty, " Originator: %s", - inet_ntoa(attr->originator_id)); + vty_out(vty, " Originator: %pI4", + &attr->originator_id); } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) { @@ -9543,8 +10027,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, for (i = 0; i < attr->cluster->length / 4; i++) { json_string = json_object_new_string( - inet_ntoa(attr->cluster - ->list[i])); + inet_ntop( + AF_INET, + &attr->cluster->list[i], + buf, sizeof(buf))); json_object_array_add( json_cluster_list_list, json_string); @@ -9568,9 +10054,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, for (i = 0; i < attr->cluster->length / 4; i++) { - vty_out(vty, "%s ", - inet_ntoa(attr->cluster - ->list[i])); + vty_out(vty, "%pI4 ", + &attr->cluster->list[i]); } } } @@ -9794,13 +10279,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, } vty_out(vty, - " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n" + " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 + ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n" " \"localAS\": %u,\n \"routes\": { ", bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - ? VRF_DEFAULT_NAME - : bgp->name, - table->version, inet_ntoa(bgp->router_id), + ? VRF_DEFAULT_NAME + : bgp->name, + table->version, &bgp->router_id, bgp->default_local_pref, bgp->as); if (rd) { vty_out(vty, " \"routeDistinguishers\" : {"); @@ -9978,9 +10464,10 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, } if (!use_json && header) { - vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ", - table->version, - inet_ntoa(bgp->router_id)); + vty_out(vty, + "BGP table version is %" PRIu64 + ", local router ID is %pI4, vrf id ", + table->version, &bgp->router_id); if (bgp->vrf_id == VRF_UNKNOWN) vty_out(vty, "%s", VRFID_NONE_STR); else @@ -10243,8 +10730,6 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, struct peer *peer; struct listnode *node, *nnode; char buf1[RD_ADDRSTRLEN]; - char buf2[INET6_ADDRSTRLEN]; - char buf3[EVPN_ROUTE_STRLEN]; char prefix_str[BUFSIZ]; int count = 0; int best = 0; @@ -10276,11 +10761,10 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, if (safi == SAFI_EVPN) { if (!json) { - vty_out(vty, "BGP routing table entry for %s%s%s\n", + vty_out(vty, "BGP routing table entry for %s%s%pFX\n", prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) - : "", prd ? ":" : "", - bgp_evpn_route2str((struct prefix_evpn *)p, - buf3, sizeof(buf3))); + : "", + prd ? ":" : "", (struct prefix_evpn *)p); } else { json_object_string_add(json, "rd", prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) : @@ -10289,15 +10773,12 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, } } else { if (!json) { - vty_out(vty, "BGP routing table entry for %s%s%s/%d\n", + vty_out(vty, "BGP routing table entry for %s%s%pFX\n", ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) - ? prefix_rd2str(prd, buf1, - sizeof(buf1)) - : ""), - safi == SAFI_MPLS_VPN ? ":" : "", - inet_ntop(p->family, &p->u.prefix, buf2, - INET6_ADDRSTRLEN), - p->prefixlen); + ? prefix_rd2str(prd, buf1, + sizeof(buf1)) + : ""), + safi == SAFI_MPLS_VPN ? ":" : "", p); } else json_object_string_add(json, "prefix", @@ -10319,7 +10800,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, count++; if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) { best = count; - if (pi->extra && pi->extra->suppress) + if (bgp_path_suppressed(pi)) suppress = 1; if (pi->attr->community == NULL) @@ -11623,9 +12104,6 @@ static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top, struct bgp_path_info *pi; const struct prefix *rn_p; - if (dest == top) - return; - if (!bgp_dest_has_bgp_path_info_data(dest)) return; @@ -12315,12 +12793,15 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp, json_object *json_ocode, bool wide) { uint64_t version = table ? table->version : 0; + char buf[BUFSIZ] = {0}; if (*header1) { if (json) { json_object_int_add(json, "bgpTableVersion", version); json_object_string_add(json, "bgpLocalRouterId", - inet_ntoa(bgp->router_id)); + inet_ntop(AF_INET, + &bgp->router_id, buf, + sizeof(buf))); json_object_int_add(json, "defaultLocPrf", bgp->default_local_pref); json_object_int_add(json, "localAS", bgp->as); @@ -12330,8 +12811,9 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp, json_ocode); } else { vty_out(vty, - "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ", - version, inet_ntoa(bgp->router_id)); + "BGP table version is %" PRIu64 + ", local router ID is %pI4, vrf id ", + version, &bgp->router_id); if (bgp->vrf_id == VRF_UNKNOWN) vty_out(vty, "%s", VRFID_NONE_STR); else @@ -12423,11 +12905,15 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, if (type == bgp_show_adj_route_advertised && subgrp && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) { + char buf[BUFSIZ] = {0}; + if (use_json) { json_object_int_add(json, "bgpTableVersion", table->version); json_object_string_add(json, "bgpLocalRouterId", - inet_ntoa(bgp->router_id)); + inet_ntop(AF_INET, + &bgp->router_id, buf, + sizeof(buf))); json_object_int_add(json, "defaultLocPrf", bgp->default_local_pref); json_object_int_add(json, "localAS", bgp->as); @@ -12439,8 +12925,10 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, json, "bgpOriginatingDefaultNetwork", (afi == AFI_IP) ? "0.0.0.0/0" : "::/0"); } else { - vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ", - table->version, inet_ntoa(bgp->router_id)); + vty_out(vty, + "BGP table version is %" PRIu64 + ", local router ID is %pI4, vrf id ", + table->version, &bgp->router_id); if (bgp->vrf_id == VRF_UNKNOWN) vty_out(vty, "%s", VRFID_NONE_STR); else @@ -12905,10 +13393,6 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer, if (use_json) SET_FLAG(show_flags, BGP_SHOW_OPT_JSON); - /* labeled-unicast routes live in the unicast table */ - if (safi == SAFI_LABELED_UNICAST) - safi = SAFI_UNICAST; - if (!peer || !peer->afc[afi][safi]) { if (use_json) { json_object *json_no = NULL; @@ -12924,6 +13408,10 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer, return CMD_WARNING; } + /* labeled-unicast routes live in the unicast table */ + if (safi == SAFI_LABELED_UNICAST) + safi = SAFI_UNICAST; + return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags); } @@ -13066,28 +13554,21 @@ static void bgp_distance_free(struct bgp_distance *bdistance) XFREE(MTYPE_BGP_DISTANCE, bdistance); } -static int bgp_distance_set(struct vty *vty, const char *distance_str, - const char *ip_str, const char *access_list_str) +int bgp_distance_set(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, safi_t safi, + char *errmsg, size_t errmsg_len) { int ret; - afi_t afi; - safi_t safi; struct prefix p; - uint8_t distance; struct bgp_dest *dest; struct bgp_distance *bdistance; - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); - ret = str2prefix(ip_str, &p); if (ret == 0) { - vty_out(vty, "Malformed prefix\n"); + snprintf(errmsg, errmsg_len, "Malformed prefix\n"); return CMD_WARNING_CONFIG_FAILED; } - distance = atoi(distance_str); - /* Get BGP distance node. */ dest = bgp_node_get(bgp_distance_table[afi][safi], &p); bdistance = bgp_dest_get_bgp_distance_info(dest); @@ -13110,37 +13591,32 @@ static int bgp_distance_set(struct vty *vty, const char *distance_str, return CMD_SUCCESS; } -static int bgp_distance_unset(struct vty *vty, const char *distance_str, - const char *ip_str, const char *access_list_str) +int bgp_distance_unset(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, safi_t safi, + char *errmsg, size_t errmsg_len) { int ret; - afi_t afi; - safi_t safi; struct prefix p; - int distance; struct bgp_dest *dest; struct bgp_distance *bdistance; - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); - ret = str2prefix(ip_str, &p); if (ret == 0) { - vty_out(vty, "Malformed prefix\n"); + snprintf(errmsg, errmsg_len, "Malformed prefix\n"); return CMD_WARNING_CONFIG_FAILED; } dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p); if (!dest) { - vty_out(vty, "Can't find specified prefix\n"); + snprintf(errmsg, errmsg_len, "Can't find specified prefix\n"); return CMD_WARNING_CONFIG_FAILED; } bdistance = bgp_dest_get_bgp_distance_info(dest); - distance = atoi(distance_str); if (bdistance->distance != distance) { - vty_out(vty, "Distance does not match configured\n"); + snprintf(errmsg, errmsg_len, + "Distance does not match configured\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -13218,9 +13694,8 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo, * we should tell ZEBRA update the routes for a specific * AFI/SAFI to reflect changes in RIB. */ -static void bgp_announce_routes_distance_update(struct bgp *bgp, - afi_t update_afi, - safi_t update_safi) +void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi, + safi_t update_safi) { afi_t afi; safi_t safi; @@ -13240,237 +13715,228 @@ static void bgp_announce_routes_distance_update(struct bgp *bgp, } } -DEFUN (bgp_distance, - bgp_distance_cmd, - "distance bgp (1-255) (1-255) (1-255)", - "Define an administrative distance\n" - "BGP distance\n" - "Distance for routes external to the AS\n" - "Distance for routes internal to the AS\n" - "Distance for local routes\n") +DEFUN_YANG(bgp_distance, bgp_distance_cmd, + "distance bgp (1-255) (1-255) (1-255)", + "Define an administrative distance\n" + "BGP distance\n" + "Distance for routes external to the AS\n" + "Distance for routes internal to the AS\n" + "Distance for local routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 2; int idx_number_2 = 3; int idx_number_3 = 4; - int distance_ebgp = atoi(argv[idx_number]->arg); - int distance_ibgp = atoi(argv[idx_number_2]->arg); - int distance_local = atoi(argv[idx_number_3]->arg); afi_t afi; safi_t safi; + char xpath[XPATH_MAXLEN]; afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if (bgp->distance_ebgp[afi][safi] != distance_ebgp - || bgp->distance_ibgp[afi][safi] != distance_ibgp - || bgp->distance_local[afi][safi] != distance_local) { - bgp->distance_ebgp[afi][safi] = distance_ebgp; - bgp->distance_ibgp[afi][safi] = distance_ibgp; - bgp->distance_local[afi][safi] = distance_local; - bgp_announce_routes_distance_update(bgp, afi, safi); - } - return CMD_SUCCESS; -} + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, + argv[idx_number_2]->arg); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, + argv[idx_number_3]->arg); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG(no_bgp_distance, no_bgp_distance_cmd, + "no distance bgp [(1-255) (1-255) (1-255)]", + NO_STR + "Define an administrative distance\n" + "BGP distance\n" + "Distance for routes external to the AS\n" + "Distance for routes internal to the AS\n" + "Distance for local routes\n") +{ + afi_t afi; + safi_t safi; + char xpath[XPATH_MAXLEN]; -DEFUN (no_bgp_distance, - no_bgp_distance_cmd, - "no distance bgp [(1-255) (1-255) (1-255)]", - NO_STR - "Define an administrative distance\n" - "BGP distance\n" - "Distance for routes external to the AS\n" - "Distance for routes internal to the AS\n" - "Distance for local routes\n") + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL); + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + uint8_t distance_ebgp, distance_ibgp, distance_local; + + distance_ebgp = yang_dnode_get_uint8(dnode, "./external"); + distance_ibgp = yang_dnode_get_uint8(dnode, "./internal"); + distance_local = yang_dnode_get_uint8(dnode, "./local"); + + vty_out(vty, " distance bgp %d %d %d\n", distance_ebgp, distance_ibgp, + distance_local); +} + +DEFPY_YANG(bgp_distance_source, + bgp_distance_source_cmd, + "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]", + NO_STR + "Define an administrative distance\n" + "Distance value\n" + "IPv4 source prefix\n" + "IPv6 source prefix\n" + "Access list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); afi_t afi; safi_t safi; + char xpath[XPATH_MAXLEN]; afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if (bgp->distance_ebgp[afi][safi] != 0 - || bgp->distance_ibgp[afi][safi] != 0 - || bgp->distance_local[afi][safi] != 0) { - bgp->distance_ebgp[afi][safi] = 0; - bgp->distance_ibgp[afi][safi] = 0; - bgp->distance_local[afi][safi] = 0; - bgp_announce_routes_distance_update(bgp, afi, safi); + if (!no) { + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY, + distance_str); + if (acl) + nb_cli_enqueue_change(vty, + "./access-list-policy-export", + NB_OP_CREATE, acl); + else + nb_cli_enqueue_change(vty, + "./access-list-policy-export", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); } - return CMD_SUCCESS; -} + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), prefix_str); -DEFUN (bgp_distance_source, - bgp_distance_source_cmd, - "distance (1-255) A.B.C.D/M", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") -{ - int idx_number = 1; - int idx_ipv4_prefixlen = 2; - bgp_distance_set(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, xpath); } -DEFUN (no_bgp_distance_source, - no_bgp_distance_source_cmd, - "no distance (1-255) A.B.C.D/M", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") +void cli_show_bgp_global_afi_safi_unicast_admin_distance_route( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - int idx_number = 2; - int idx_ipv4_prefixlen = 3; - bgp_distance_unset(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, NULL); - return CMD_SUCCESS; + vty_out(vty, " distance %d %s %s\n", + yang_dnode_get_uint8(dnode, "./distance"), + yang_dnode_get_string(dnode, "./prefix"), + (yang_dnode_exists(dnode, "./access-list-policy-export")) + ? yang_dnode_get_string(dnode, + "./access-list-policy-export") + : ""); } -DEFUN (bgp_distance_source_access_list, - bgp_distance_source_access_list_cmd, - "distance (1-255) A.B.C.D/M WORD", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") +DEFPY_YANG(bgp_dampening, + bgp_dampening_cmd, + "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_supress]]", + NO_STR + "BGP Specific commands\n" + "Enable route-flap dampening\n" + "Half-life time for the penalty\n" + "Value to start reusing a route\n" + "Value to start suppressing a route\n" + "Maximum duration to suppress a stable route\n") { - int idx_number = 1; - int idx_ipv4_prefixlen = 2; - int idx_word = 3; - bgp_distance_set(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); - return CMD_SUCCESS; -} + afi_t afi; + safi_t safi; + char xpath[XPATH_MAXLEN]; -DEFUN (no_bgp_distance_source_access_list, - no_bgp_distance_source_access_list_cmd, - "no distance (1-255) A.B.C.D/M WORD", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") -{ - int idx_number = 2; - int idx_ipv4_prefixlen = 3; - int idx_word = 4; - bgp_distance_unset(vty, argv[idx_number]->arg, - argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); - return CMD_SUCCESS; -} + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); -DEFUN (ipv6_bgp_distance_source, - ipv6_bgp_distance_source_cmd, - "distance (1-255) X:X::X:X/M", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") -{ - bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL); - return CMD_SUCCESS; -} + if (!no) { + nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true"); + if (argc == 6) { + nb_cli_enqueue_change(vty, "./reach-decay", + NB_OP_MODIFY, halflife_str); + nb_cli_enqueue_change(vty, "./reuse-above", + NB_OP_MODIFY, reuse_str); + nb_cli_enqueue_change(vty, "./suppress-above", + NB_OP_MODIFY, suppress_str); + nb_cli_enqueue_change(vty, "./unreach-decay", + NB_OP_MODIFY, max_supress_str); + } if (argc == 3) { + nb_cli_enqueue_change(vty, "./reach-decay", + NB_OP_MODIFY, halflife_str); + } + } else { + nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false"); + } -DEFUN (no_ipv6_bgp_distance_source, - no_ipv6_bgp_distance_source_cmd, - "no distance (1-255) X:X::X:X/M", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n") -{ - bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL); - return CMD_SUCCESS; -} + snprintf( + xpath, sizeof(xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); -DEFUN (ipv6_bgp_distance_source_access_list, - ipv6_bgp_distance_source_access_list_cmd, - "distance (1-255) X:X::X:X/M WORD", - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") -{ - bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, xpath); } -DEFUN (no_ipv6_bgp_distance_source_access_list, - no_ipv6_bgp_distance_source_access_list_cmd, - "no distance (1-255) X:X::X:X/M WORD", - NO_STR - "Define an administrative distance\n" - "Administrative distance\n" - "IP source prefix\n" - "Access list name\n") +void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg); - return CMD_SUCCESS; -} + if (!yang_dnode_get_bool(dnode, "./enable")) + return; -DEFUN (bgp_damp_set, - bgp_damp_set_cmd, - "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]", - "BGP Specific commands\n" - "Enable route-flap dampening\n" - "Half-life time for the penalty\n" - "Value to start reusing a route\n" - "Value to start suppressing a route\n" - "Maximum duration to suppress a stable route\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_half_life = 2; - int idx_reuse = 3; - int idx_suppress = 4; - int idx_max_suppress = 5; int half = DEFAULT_HALF_LIFE * 60; int reuse = DEFAULT_REUSE; int suppress = DEFAULT_SUPPRESS; - int max = 4 * half; - - if (argc == 6) { - half = atoi(argv[idx_half_life]->arg) * 60; - reuse = atoi(argv[idx_reuse]->arg); - suppress = atoi(argv[idx_suppress]->arg); - max = atoi(argv[idx_max_suppress]->arg) * 60; - } else if (argc == 3) { - half = atoi(argv[idx_half_life]->arg) * 60; - max = 4 * half; - } - - /* - * These can't be 0 but our SA doesn't understand the - * way our cli is constructed - */ - assert(reuse); - assert(half); - if (suppress < reuse) { - vty_out(vty, - "Suppress value cannot be less than reuse value \n"); - return 0; - } - - return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half, - reuse, suppress, max); -} - -DEFUN (bgp_damp_unset, - bgp_damp_unset_cmd, - "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]", - NO_STR - "BGP Specific commands\n" - "Enable route-flap dampening\n" - "Half-life time for the penalty\n" - "Value to start reusing a route\n" - "Value to start suppressing a route\n" - "Maximum duration to suppress a stable route\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty)); + int max; + + half = yang_dnode_get_uint8(dnode, "../reach-decay"); + reuse = yang_dnode_get_uint16(dnode, "../reuse-above"); + suppress = yang_dnode_get_uint16(dnode, "../suppress-above"); + max = yang_dnode_get_uint8(dnode, "../unreach-decay"); + + if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE + && suppress == DEFAULT_SUPPRESS && max == half * 4) + vty_out(vty, " bgp dampening\n"); + else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE + && suppress == DEFAULT_SUPPRESS && max == half * 4) + vty_out(vty, " bgp dampening %u\n", half); + else + vty_out(vty, " bgp dampening %u %d %d %d\n", half, reuse, + suppress, max); } /* Display specified route of BGP table. */ @@ -13691,7 +14157,6 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp, const struct prefix_rd *prd; struct bgp_static *bgp_static; mpls_label_t label; - char buf[SU_ADDRSTRLEN]; char rdbuf[RD_ADDRSTRLEN]; /* Network configuration. */ @@ -13715,10 +14180,7 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp, prefix_rd2str(prd, rdbuf, sizeof(rdbuf)); label = decode_label(&bgp_static->label); - vty_out(vty, " network %s/%d rd %s", - inet_ntop(p->family, &p->u.prefix, buf, - SU_ADDRSTRLEN), - p->prefixlen, rdbuf); + vty_out(vty, " network %pFX rd %s", p, rdbuf); if (safi == SAFI_MPLS_VPN) vty_out(vty, " label %u", label); @@ -13816,7 +14278,6 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi, const struct prefix *p; struct bgp_static *bgp_static; struct bgp_aggregate *bgp_aggregate; - char buf[SU_ADDRSTRLEN]; if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) { bgp_config_write_network_vpn(vty, bgp, afi, safi); @@ -13837,9 +14298,7 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi, p = bgp_dest_get_prefix(dest); - vty_out(vty, " network %s/%d", - inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), - p->prefixlen); + vty_out(vty, " network %pFX", p); if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) vty_out(vty, " label-index %u", @@ -13863,9 +14322,7 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi, p = bgp_dest_get_prefix(dest); - vty_out(vty, " aggregate-address %s/%d", - inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), - p->prefixlen); + vty_out(vty, " aggregate-address %pFX", p); if (bgp_aggregate->as_set) vty_out(vty, " as-set"); @@ -13880,6 +14337,13 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi, vty_out(vty, " origin %s", bgp_origin2str(bgp_aggregate->origin)); + if (bgp_aggregate->match_med) + vty_out(vty, " matching-MED-only"); + + if (bgp_aggregate->suppress_map_name) + vty_out(vty, " suppress-map %s", + bgp_aggregate->suppress_map_name); + vty_out(vty, "\n"); } } @@ -13907,7 +14371,7 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi, dest = bgp_route_next(dest)) { bdistance = bgp_dest_get_bgp_distance_info(dest); if (bdistance != NULL) - vty_out(vty, " distance %d %pRN %s\n", + vty_out(vty, " distance %d %pBD %s\n", bdistance->distance, dest, bdistance->access_list ? bdistance->access_list : ""); @@ -13929,36 +14393,24 @@ void bgp_route_init(void) install_element(BGP_NODE, &bgp_network_cmd); install_element(BGP_NODE, &no_bgp_table_map_cmd); - install_element(BGP_NODE, &aggregate_address_cmd); - install_element(BGP_NODE, &aggregate_address_mask_cmd); - install_element(BGP_NODE, &no_aggregate_address_cmd); - install_element(BGP_NODE, &no_aggregate_address_mask_cmd); + install_element(BGP_NODE, &aggregate_addressv4_cmd); /* IPv4 unicast configuration. */ install_element(BGP_IPV4_NODE, &bgp_table_map_cmd); install_element(BGP_IPV4_NODE, &bgp_network_cmd); install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd); - install_element(BGP_IPV4_NODE, &aggregate_address_cmd); - install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd); - install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd); - install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd); + install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd); /* IPv4 multicast configuration. */ install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd); install_element(BGP_IPV4M_NODE, &bgp_network_cmd); install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd); - install_element(BGP_IPV4M_NODE, &aggregate_address_cmd); - install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd); - install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd); - install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd); + install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd); /* IPv4 labeled-unicast configuration. */ install_element(BGP_IPV4L_NODE, &bgp_network_cmd); - install_element(BGP_IPV4L_NODE, &aggregate_address_cmd); - install_element(BGP_IPV4L_NODE, &aggregate_address_mask_cmd); - install_element(BGP_IPV4L_NODE, &no_aggregate_address_cmd); - install_element(BGP_IPV4L_NODE, &no_aggregate_address_mask_cmd); + install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd); install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd); install_element(VIEW_NODE, &show_ip_bgp_cmd); @@ -14003,67 +14455,38 @@ void bgp_route_init(void) install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd); install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd); - install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd); - install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd); + install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd); install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd); /* IPv6 labeled unicast address family. */ install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd); - install_element(BGP_IPV6L_NODE, &ipv6_aggregate_address_cmd); - install_element(BGP_IPV6L_NODE, &no_ipv6_aggregate_address_cmd); + install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd); install_element(BGP_NODE, &bgp_distance_cmd); install_element(BGP_NODE, &no_bgp_distance_cmd); install_element(BGP_NODE, &bgp_distance_source_cmd); - install_element(BGP_NODE, &no_bgp_distance_source_cmd); - install_element(BGP_NODE, &bgp_distance_source_access_list_cmd); - install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd); install_element(BGP_IPV4_NODE, &bgp_distance_cmd); install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd); install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd); - install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd); - install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd); - install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd); install_element(BGP_IPV4M_NODE, &bgp_distance_cmd); install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd); install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd); - install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd); - install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd); - install_element(BGP_IPV4M_NODE, - &no_bgp_distance_source_access_list_cmd); install_element(BGP_IPV6_NODE, &bgp_distance_cmd); install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd); - install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6_NODE, - &ipv6_bgp_distance_source_access_list_cmd); - install_element(BGP_IPV6_NODE, - &no_ipv6_bgp_distance_source_access_list_cmd); + install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd); install_element(BGP_IPV6M_NODE, &bgp_distance_cmd); install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd); - install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd); - install_element(BGP_IPV6M_NODE, - &ipv6_bgp_distance_source_access_list_cmd); - install_element(BGP_IPV6M_NODE, - &no_ipv6_bgp_distance_source_access_list_cmd); + install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd); /* BGP dampening */ - install_element(BGP_NODE, &bgp_damp_set_cmd); - install_element(BGP_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd); - install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd); - install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd); + install_element(BGP_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV4_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV6_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd); + install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd); /* Large Communities */ install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 3407884897..e4c6f9a0e2 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -110,8 +110,8 @@ struct bgp_path_info_extra { /* Pointer to dampening structure. */ struct bgp_damp_info *damp_info; - /* This route is suppressed with aggregation. */ - int suppress; + /** List of aggregations that suppress this path. */ + struct list *aggr_suppressors; /* Nexthop reachability check. */ uint32_t igpmetric; @@ -379,6 +379,30 @@ struct bgp_aggregate { /* SAFI configuration. */ safi_t safi; + + /** Match only equal MED. */ + bool match_med; + /* MED matching state. */ + /** Did we get the first MED value? */ + bool med_initialized; + /** Are there MED mismatches? */ + bool med_mismatched; + /** MED value found in current group. */ + uint32_t med_matched_value; + + /** + * Test if aggregated address MED of all route match, otherwise + * returns `false`. This macro will also return `true` if MED + * matching is disabled. + */ +#define AGGREGATE_MED_VALID(aggregate) \ + (((aggregate)->match_med && !(aggregate)->med_mismatched) \ + || !(aggregate)->match_med) + + /** Suppress map route map name (`NULL` when disabled). */ + char *suppress_map_name; + /** Suppress map route map pointer. */ + struct route_map *suppress_map; }; #define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \ @@ -430,6 +454,14 @@ struct bgp_aggregate { #define UNSUPPRESS_MAP_NAME(F) ((F)->usmap.name) #define UNSUPPRESS_MAP(F) ((F)->usmap.map) +#define ADVERTISE_MAP_NAME(F) ((F)->advmap.aname) +#define ADVERTISE_MAP(F) ((F)->advmap.amap) + +#define ADVERTISE_CONDITION(F) ((F)->advmap.condition) + +#define CONDITION_MAP_NAME(F) ((F)->advmap.cname) +#define CONDITION_MAP(F) ((F)->advmap.cmap) + /* path PREFIX (addpath rxid NUMBER) */ #define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32 @@ -508,7 +540,7 @@ DECLARE_HOOK(bgp_process, /* Prototypes. */ extern void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi, struct peer *peer, afi_t afi, safi_t safi); -extern void bgp_process_queue_init(void); +extern void bgp_process_queue_init(struct bgp *bgp); extern void bgp_route_init(void); extern void bgp_route_finish(void); extern void bgp_cleanup_routes(struct bgp *); @@ -639,6 +671,8 @@ extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p, struct bgp_path_info *path, int display, json_object *json); +extern void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp); + extern void subgroup_process_announce_selected(struct update_subgroup *subgrp, struct bgp_path_info *selected, struct bgp_dest *dest, @@ -647,7 +681,8 @@ extern void subgroup_process_announce_selected(struct update_subgroup *subgrp, extern bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, struct update_subgroup *subgrp, - const struct prefix *p, struct attr *attr); + const struct prefix *p, struct attr *attr, + bool skip_rmap_check); extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer); extern void bgp_process_queues_drain_immediate(void); @@ -691,4 +726,36 @@ extern bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, struct attr *attr, struct bgp_dest *dest); extern int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, struct bgp_path_info *exist, int *paths_eq); +extern void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, + struct bgp *bgp, + const struct prefix *p, afi_t afi, + safi_t safi, bool suppress); +extern int bgp_static_set(struct bgp *bgp, const char *negate, + struct prefix *pfx, afi_t afi, safi_t safi, + const char *rmap, int backdoor, uint32_t label_index, + char *errmsg, size_t errmsg_len); + +extern int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi, + safi_t safi, const char *rmap, + uint8_t summary_only, uint8_t as_set, + uint8_t origin, bool match_med, + const char *suppress_map, char *errmsg, + size_t errmsg_len); + +extern int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, + afi_t afi, safi_t safi, char *errmsg, + size_t errmsg_len); + +extern void bgp_announce_routes_distance_update(struct bgp *bgp, + afi_t update_afi, + safi_t update_safi); + +extern int bgp_distance_set(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, safi_t safi, + char *errmsg, size_t errmsg_len); + +extern int bgp_distance_unset(uint8_t distance, const char *ip_str, + const char *access_list_str, afi_t afi, + safi_t safi, char *errmsg, size_t errmsg_len); +extern void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr); #endif /* _QUAGGA_BGP_ROUTE_H */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 09cc775d47..e4a9c29000 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3695,9 +3695,22 @@ static void bgp_route_map_process_peer(const char *rmap_name, if (filter->usmap.name && (strcmp(rmap_name, filter->usmap.name) == 0)) filter->usmap.map = map; + if (filter->advmap.aname + && (strcmp(rmap_name, filter->advmap.aname) == 0)) { + filter->advmap.amap = map; + } + + if (filter->advmap.cname + && (strcmp(rmap_name, filter->advmap.cname) == 0)) { + filter->advmap.cmap = map; + } + if (peer->default_rmap[afi][safi].name && (strcmp(rmap_name, peer->default_rmap[afi][safi].name) == 0)) peer->default_rmap[afi][safi].map = map; + + /* Notify BGP conditional advertisement scanner percess */ + peer->advmap_config_change[afi][safi] = true; } static void bgp_route_map_update_peer_group(const char *rmap_name, @@ -3746,6 +3759,7 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name, int route_update) { int i; + bool matched; afi_t afi; safi_t safi; struct peer *peer; @@ -3845,16 +3859,35 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name, if (!aggregate) continue; - if (!aggregate->rmap.name - || (strcmp(rmap_name, aggregate->rmap.name) != 0)) - continue; + matched = false; - if (!aggregate->rmap.map) - route_map_counter_increment(map); + /* Update suppress map pointer. */ + if (aggregate->suppress_map_name + && strmatch(aggregate->suppress_map_name, + rmap_name)) { + if (aggregate->rmap.map == NULL) + route_map_counter_increment(map); + + aggregate->suppress_map = map; + + bgp_aggregate_toggle_suppressed( + aggregate, bgp, bgp_dest_get_prefix(bn), + afi, safi, false); + + matched = true; + } + + if (aggregate->rmap.name + && strmatch(rmap_name, aggregate->rmap.name)) { + if (aggregate->rmap.map == NULL) + route_map_counter_increment(map); + + aggregate->rmap.map = map; - aggregate->rmap.map = map; + matched = true; + } - if (route_update) { + if (matched && route_update) { const struct prefix *bn_p = bgp_dest_get_prefix(bn); @@ -3960,8 +3993,7 @@ static void bgp_route_map_mark_update(const char *rmap_name) /* If new update is received before the current timer timed out, * turn it off and start a new timer. */ - if (bm->t_rmap_update != NULL) - THREAD_OFF(bm->t_rmap_update); + THREAD_OFF(bm->t_rmap_update); /* rmap_update_timer of 0 means don't do route updates */ if (bm->rmap_update_timer) { @@ -4034,32 +4066,64 @@ DEFUN (no_match_mac_address, RMAP_EVENT_FILTER_DELETED); } +/* + * Helper to handle the case of the user passing in a number or type string + */ +static const char *parse_evpn_rt_type(const char *num_rt_type) +{ + switch (num_rt_type[0]) { + case '1': + return "ead"; + case '2': + return "macip"; + case '3': + return "multicast"; + case '4': + return "es"; + case '5': + return "prefix"; + default: + break; + } + + /* Was already full type string */ + return num_rt_type; +} + DEFUN (match_evpn_route_type, match_evpn_route_type_cmd, - "match evpn route-type <macip | multicast | prefix>", + "match evpn route-type <macip|2|multicast|3|prefix|5>", MATCH_STR EVPN_HELP_STR - "Match route-type\n" - "mac-ip route\n" - "IMET route\n" - "prefix route\n") -{ - return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg, + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_5_HELP_STR + EVPN_TYPE_5_HELP_STR) +{ + return bgp_route_match_add(vty, "evpn route-type", + parse_evpn_rt_type(argv[3]->arg), RMAP_EVENT_MATCH_ADDED); } DEFUN (no_match_evpn_route_type, no_match_evpn_route_type_cmd, - "no match evpn route-type <macip | multicast | prefix>", + "no match evpn route-type <macip|2|multicast|3|prefix|5>", NO_STR MATCH_STR EVPN_HELP_STR - "Match route-type\n" - "mac-ip route\n" - "IMET route\n" - "prefix route\n") -{ - return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg, + EVPN_TYPE_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_2_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_3_HELP_STR + EVPN_TYPE_5_HELP_STR + EVPN_TYPE_5_HELP_STR) +{ + return bgp_route_match_delete(vty, "evpn route-type", + parse_evpn_rt_type(argv[4]->arg), RMAP_EVENT_MATCH_DELETED); } diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index ca47fb316a..0f0aff7eaa 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -702,8 +702,6 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr, as_t as_number = 0; struct lrtr_ip_addr ip_addr_prefix; enum pfxv_state result; - char buf[BUFSIZ]; - const char *prefix_string; if (!is_synchronized()) return 0; @@ -754,27 +752,26 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr, prefix->prefixlen, &result); // Print Debug output - prefix_string = prefix2str(prefix, buf, sizeof(buf)); switch (result) { case BGP_PFXV_STATE_VALID: RPKI_DEBUG( - "Validating Prefix %s from asn %u Result: VALID", - prefix_string, as_number); + "Validating Prefix %pFX from asn %u Result: VALID", + prefix, as_number); return RPKI_VALID; case BGP_PFXV_STATE_NOT_FOUND: RPKI_DEBUG( - "Validating Prefix %s from asn %u Result: NOT FOUND", - prefix_string, as_number); + "Validating Prefix %pFX from asn %u Result: NOT FOUND", + prefix, as_number); return RPKI_NOTFOUND; case BGP_PFXV_STATE_INVALID: RPKI_DEBUG( - "Validating Prefix %s from asn %u Result: INVALID", - prefix_string, as_number); + "Validating Prefix %pFX from asn %u Result: INVALID", + prefix, as_number); return RPKI_INVALID; default: RPKI_DEBUG( - "Validating Prefix %s from asn %u Result: CANNOT VALIDATE", - prefix_string, as_number); + "Validating Prefix %pFX from asn %u Result: CANNOT VALIDATE", + prefix, as_number); break; } return 0; diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index 185cb251c7..022a6413e2 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -26,6 +26,7 @@ #include "queue.h" #include "filter.h" #include "command.h" +#include "printfrr.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -153,13 +154,8 @@ void bgp_delete_listnode(struct bgp_node *node) if (bgp && rn && rn->lock == 1) { /* Delete the route from the selection pending list */ - if ((node->rt_node) - && (bgp->gr_info[afi][safi].route_list)) { - list_delete_node( - bgp->gr_info[afi][safi].route_list, - node->rt_node); - node->rt_node = NULL; - } + bgp->gr_info[afi][safi].gr_deferred--; + UNSET_FLAG(node->flags, BGP_NODE_SELECT_DEFER); } } } @@ -203,3 +199,14 @@ struct bgp_node *bgp_table_subtree_lookup(const struct bgp_table *table, bgp_dest_lock_node(matched); return matched; } + +printfrr_ext_autoreg_p("BD", printfrr_bd) +static ssize_t printfrr_bd(char *buf, size_t bsz, const char *fmt, + int prec, const void *ptr) +{ + const struct bgp_dest *dest = ptr; + const struct prefix *p = bgp_dest_get_prefix(dest); + + prefix2str(p, buf, bsz); + return 2; +} diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index cf0086b52e..4e9abf863d 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -102,8 +102,7 @@ struct bgp_node { #define BGP_NODE_LABEL_CHANGED (1 << 2) #define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3) #define BGP_NODE_SELECT_DEFER (1 << 4) - /* list node pointer */ - struct listnode *rt_node; + struct bgp_addpath_node_data tx_addpath; enum bgp_path_selection_reason reason; @@ -469,8 +468,14 @@ static inline const struct prefix *bgp_dest_get_prefix(const struct bgp_dest *de return &dest->p; } +static inline unsigned int bgp_dest_get_lock_count(const struct bgp_dest *dest) +{ + return dest->lock; +} + #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pRN" (struct bgp_node *) +#pragma FRR printfrr_ext "%pBD" (struct bgp_dest *) #endif #endif /* _QUAGGA_BGP_TABLE_H */ diff --git a/bgpd/bgp_trace.c b/bgpd/bgp_trace.c new file mode 100644 index 0000000000..2ebc63b6b5 --- /dev/null +++ b/bgpd/bgp_trace.c @@ -0,0 +1,4 @@ +#define TRACEPOINT_CREATE_PROBES +#define TRACEPOINT_DEFINE + +#include "bgp_trace.h" diff --git a/bgpd/bgp_trace.h b/bgpd/bgp_trace.h new file mode 100644 index 0000000000..2566ffb928 --- /dev/null +++ b/bgpd/bgp_trace.h @@ -0,0 +1,131 @@ +/* Tracing for BGP + * + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(_BGP_TRACE_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define _BGP_TRACE_H + +#include "lib/trace.h" + +#ifdef HAVE_LTTNG + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER frr_bgp + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "bgpd/bgp_trace.h" + +#include <lttng/tracepoint.h> + +#include "bgpd/bgpd.h" +#include "lib/stream.h" + +/* clang-format off */ + +TRACEPOINT_EVENT_CLASS( + frr_bgp, + packet_process, + TP_ARGS(struct peer *, peer, bgp_size_t, size), + TP_FIELDS( + ctf_string(peer, peer->host ? peer->host : "(unknown peer)") + ) +) + +#define PKT_PROCESS_TRACEPOINT_INSTANCE(name) \ + TRACEPOINT_EVENT_INSTANCE( \ + frr_bgp, packet_process, name, \ + TP_ARGS(struct peer *, peer, bgp_size_t, size)) \ + TRACEPOINT_LOGLEVEL(frr_bgp, name, TRACE_INFO) + +PKT_PROCESS_TRACEPOINT_INSTANCE(open_process) +PKT_PROCESS_TRACEPOINT_INSTANCE(keepalive_process) +PKT_PROCESS_TRACEPOINT_INSTANCE(update_process) +PKT_PROCESS_TRACEPOINT_INSTANCE(notification_process) +PKT_PROCESS_TRACEPOINT_INSTANCE(capability_process) +PKT_PROCESS_TRACEPOINT_INSTANCE(refresh_process) + +TRACEPOINT_EVENT( + frr_bgp, + packet_read, + TP_ARGS(struct peer *, peer, struct stream *, pkt), + TP_FIELDS( + ctf_string(peer, peer->host ? peer->host : "(unknown peer)") + ctf_sequence_hex(uint8_t, packet, pkt->data, size_t, + STREAM_READABLE(pkt)) + ) +) + +TRACEPOINT_LOGLEVEL(frr_bgp, packet_read, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + process_update, + TP_ARGS(struct peer *, peer, char *, pfx, uint32_t, addpath_id, afi_t, + afi, safi_t, safi, struct attr *, attr), + TP_FIELDS( + ctf_string(peer, peer->host ? peer->host : "(unknown peer)") + ctf_string(prefix, pfx) + ctf_integer(uint32_t, addpath_id, addpath_id) + ctf_integer(afi_t, afi, afi) + ctf_integer(safi_t, safi, safi) + ctf_integer_hex(intptr_t, attribute_ptr, attr) + ) +) + +TRACEPOINT_LOGLEVEL(frr_bgp, process_update, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + input_filter, + TP_ARGS(struct peer *, peer, char *, pfx, afi_t, afi, safi_t, safi, + const char *, result), + TP_FIELDS( + ctf_string(peer, peer->host ? peer->host : "(unknown peer)") + ctf_string(prefix, pfx) + ctf_integer(afi_t, afi, afi) + ctf_integer(safi_t, safi, safi) + ctf_string(action, result) + ) +) + +TRACEPOINT_LOGLEVEL(frr_bgp, input_filter, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_bgp, + output_filter, + TP_ARGS(struct peer *, peer, char *, pfx, afi_t, afi, safi_t, safi, + const char *, result), + TP_FIELDS( + ctf_string(peer, peer->host ? peer->host : "(unknown peer)") + ctf_string(prefix, pfx) + ctf_integer(afi_t, afi, afi) + ctf_integer(safi_t, safi, safi) + ctf_string(action, result) + ) +) + +TRACEPOINT_LOGLEVEL(frr_bgp, output_filter, TRACE_INFO) + +/* clang-format on */ + +#include <lttng/tracepoint-event.h> + +#endif /* HAVE_LTTNG */ + +#endif /* _BGP_TRACE_H */ diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index d2e563b237..2788a8ea4f 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -195,6 +195,19 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi, MTYPE_BGP_FILTER_NAME, UNSUPPRESS_MAP_NAME(srcfilter)); UNSUPPRESS_MAP(dstfilter) = UNSUPPRESS_MAP(srcfilter); } + + if (ADVERTISE_MAP_NAME(srcfilter)) { + ADVERTISE_MAP_NAME(dstfilter) = XSTRDUP( + MTYPE_BGP_FILTER_NAME, ADVERTISE_MAP_NAME(srcfilter)); + ADVERTISE_MAP(dstfilter) = ADVERTISE_MAP(srcfilter); + ADVERTISE_CONDITION(dstfilter) = ADVERTISE_CONDITION(srcfilter); + } + + if (CONDITION_MAP_NAME(srcfilter)) { + CONDITION_MAP_NAME(dstfilter) = XSTRDUP( + MTYPE_BGP_FILTER_NAME, CONDITION_MAP_NAME(srcfilter)); + CONDITION_MAP(dstfilter) = CONDITION_MAP(srcfilter); + } } /** @@ -218,6 +231,10 @@ static void conf_release(struct peer *src, afi_t afi, safi_t safi) XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->usmap.name); + XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.aname); + + XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.cname); + XFREE(MTYPE_BGP_PEER_HOST, src->host); } @@ -353,6 +370,11 @@ static unsigned int updgrp_hash_key_make(const void *p) strlen(filter->usmap.name), SEED1), key); + if (filter->advmap.aname) + key = jhash_1word(jhash(filter->advmap.aname, + strlen(filter->advmap.aname), SEED1), + key); + if (peer->default_rmap[afi][safi].name) key = jhash_1word( jhash(peer->default_rmap[afi][safi].name, @@ -481,6 +503,12 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2) && strcmp(fl1->usmap.name, fl2->usmap.name))) return false; + if ((fl1->advmap.aname && !fl2->advmap.aname) + || (!fl1->advmap.aname && fl2->advmap.aname) + || (fl1->advmap.aname && fl2->advmap.aname + && strcmp(fl1->advmap.aname, fl2->advmap.aname))) + return false; + if ((pe1->default_rmap[afi][safi].name && !pe2->default_rmap[afi][safi].name) || (!pe1->default_rmap[afi][safi].name @@ -795,17 +823,12 @@ static void update_subgroup_delete(struct update_subgroup *subgrp) if (subgrp->update_group) UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted); - if (subgrp->t_merge_check) - THREAD_OFF(subgrp->t_merge_check); - - if (subgrp->t_coalesce) - THREAD_TIMER_OFF(subgrp->t_coalesce); + THREAD_OFF(subgrp->t_merge_check); + THREAD_OFF(subgrp->t_coalesce); bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp)); subgroup_clear_table(subgrp); - if (subgrp->t_coalesce) - THREAD_TIMER_OFF(subgrp->t_coalesce); sync_delete(subgrp); if (BGP_DEBUG(update_groups, UPDATE_GROUPS) && subgrp->update_group) @@ -1771,7 +1794,7 @@ int update_group_refresh_default_originate_route_map(struct thread *thread) bgp = THREAD_ARG(thread); update_group_walk(bgp, update_group_default_originate_route_map_walkcb, reason); - THREAD_TIMER_OFF(bgp->t_rmap_def_originate_eval); + thread_cancel(&bgp->t_rmap_def_originate_eval); bgp_unlock(bgp); return 0; diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 67fa9a3ea3..3cfb73d8a8 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -215,6 +215,9 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg) } } } + + /* Notify BGP Conditional advertisement */ + bgp_notify_conditional_adv_scanner(subgrp); } return UPDWALK_CONTINUE; @@ -246,9 +249,10 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp, if (adj->subgroup == subgrp) { if (header1) { vty_out(vty, - "BGP table version is %" PRIu64", local router ID is %s\n", + "BGP table version is %" PRIu64 + ", local router ID is %pI4\n", table->version, - inet_ntoa(bgp->router_id)); + &bgp->router_id); vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER); header1 = 0; @@ -641,7 +645,8 @@ void subgroup_announce_table(struct update_subgroup *subgrp, peer->addpath_type[afi][safi], ri))) { if (subgroup_announce_check(dest, ri, subgrp, - dest_p, &attr)) + dest_p, &attr, + false)) bgp_adj_out_set_subgroup(dest, subgrp, &attr, ri); else { @@ -726,7 +731,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) struct bgp *bgp; struct attr attr; struct attr *new_attr = &attr; - struct aspath *aspath; struct prefix p; struct peer *from; struct bgp_dest *dest; @@ -751,7 +755,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) from = bgp->peer_self; bgp_attr_default_set(&attr, BGP_ORIGIN_IGP); - aspath = attr.aspath; attr.local_pref = bgp->default_local_pref; @@ -767,12 +770,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) } if (peer->default_rmap[afi][safi].name) { - struct attr attr_tmp = attr; - struct bgp_path_info bpi_rmap = {0}; - - bpi_rmap.peer = bgp->peer_self; - bpi_rmap.attr = &attr_tmp; - SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT); /* Iterate over the RIB to see if we can announce @@ -784,20 +781,45 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if (!bgp_dest_has_bgp_path_info_data(dest)) continue; - ret = route_map_apply(peer->default_rmap[afi][safi].map, - bgp_dest_get_prefix(dest), - RMAP_BGP, &bpi_rmap); + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { + struct attr tmp_attr; + struct bgp_path_info tmp_pi; + struct bgp_path_info_extra tmp_pie; + + tmp_attr = *pi->attr; + + prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, + pi->peer, &tmp_attr); + + ret = route_map_apply( + peer->default_rmap[afi][safi].map, + bgp_dest_get_prefix(dest), RMAP_BGP, + &tmp_pi); - if (ret != RMAP_DENYMATCH) + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&tmp_attr); + continue; + } else { + new_attr = bgp_attr_intern(&tmp_attr); + new_attr->aspath = attr.aspath; + + subgroup_announce_reset_nhop( + (peer_cap_enhe(peer, afi, safi) + ? AF_INET6 + : AF_INET), + new_attr); + + break; + } + } + if (ret == RMAP_PERMITMATCH) break; } bgp->peer_self->rmap_type = 0; - new_attr = bgp_attr_intern(&attr_tmp); - if (ret == RMAP_DENYMATCH) { - bgp_attr_flush(&attr_tmp); + if (ret == RMAP_DENYMATCH) withdraw = 1; - } } /* Check if the default route is in local BGP RIB which is @@ -826,7 +848,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) if (subgroup_announce_check( dest, pi, subgrp, bgp_dest_get_prefix(dest), - &attr)) + &attr, false)) bgp_adj_out_set_subgroup( dest, subgrp, &attr, pi); @@ -876,8 +898,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) subgroup_default_update_packet(subgrp, new_attr, from); } } - - aspath_unintern(&aspath); } /* diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index f706b834fe..c3edb9e9a4 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -488,10 +488,10 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, stream_put_in_addr_at(s, offset_nh, mod_v4nh); if (bgp_debug_update(peer, NULL, NULL, 0)) - zlog_debug("u%" PRIu64 ":s%" PRIu64" %s send UPDATE w/ nexthop %s%s", + zlog_debug("u%" PRIu64 ":s%" PRIu64 + " %s send UPDATE w/ nexthop %pI4%s", PAF_SUBGRP(paf)->update_group->id, - PAF_SUBGRP(paf)->id, peer->host, - inet_ntoa(*mod_v4nh), + PAF_SUBGRP(paf)->id, peer->host, mod_v4nh, (nhlen == BGP_ATTR_NHLEN_VPNV4 ? " and RD" : "")); } else if (nhafi == AFI_IP6) { @@ -642,10 +642,10 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, stream_put_in_addr_at(s, vec->offset + 1, mod_v4nh); if (bgp_debug_update(peer, NULL, NULL, 0)) - zlog_debug("u%" PRIu64 ":s%" PRIu64" %s send UPDATE w/ nexthop %s", + zlog_debug("u%" PRIu64 ":s%" PRIu64 + " %s send UPDATE w/ nexthop %pI4", PAF_SUBGRP(paf)->update_group->id, - PAF_SUBGRP(paf)->id, peer->host, - inet_ntoa(*mod_v4nh)); + PAF_SUBGRP(paf)->id, peer->host, mod_v4nh); } return s; @@ -1137,7 +1137,6 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp, /* Logging the attribute. */ if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) { char attrstr[BUFSIZ]; - char buf[PREFIX_STRLEN]; /* ' with addpath ID ' 17 * max strlen of uint32 + 10 * +/- (just in case) + 1 @@ -1156,10 +1155,9 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp, else tx_id_buf[0] = '\0'; - zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s", - (SUBGRP_UPDGRP(subgrp))->id, subgrp->id, - prefix2str(&p, buf, sizeof(buf)), tx_id_buf, - attrstr); + zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %pFX%s %s", + (SUBGRP_UPDGRP(subgrp))->id, subgrp->id, &p, + tx_id_buf, attrstr); } s = stream_new(BGP_MAX_PACKET_SIZE); @@ -1222,7 +1220,6 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp) p.prefixlen = 0; if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) { - char buf[PREFIX_STRLEN]; /* ' with addpath ID ' 17 * max strlen of uint32 + 10 * +/- (just in case) + 1 @@ -1235,9 +1232,10 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp) " with addpath ID %u", BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); - zlog_debug("u%" PRIu64 ":s%" PRIu64" send UPDATE %s%s -- unreachable", - (SUBGRP_UPDGRP(subgrp))->id, subgrp->id, - prefix2str(&p, buf, sizeof(buf)), tx_id_buf); + zlog_debug("u%" PRIu64 ":s%" PRIu64 + " send UPDATE %pFX%s -- unreachable", + (SUBGRP_UPDGRP(subgrp))->id, subgrp->id, &p, + tx_id_buf); } s = stream_new(BGP_MAX_PACKET_SIZE); diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index 0b5d156e6d..cb459ae13c 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -22,6 +22,7 @@ #include "command.h" #include "prefix.h" #include "lib/json.h" +#include "lib/printfrr.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_route.h" @@ -117,11 +118,15 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, if (header) { if (use_json) { + char buf[BUFSIZ] = {0}; + json_object_int_add( json, "bgpTableVersion", 0); json_object_string_add( json, "bgpLocalRouterId", - inet_ntoa(bgp->router_id)); + inet_ntop(AF_INET, + &bgp->router_id, buf, + sizeof(buf))); json_object_int_add( json, "defaultLocPrf", @@ -137,8 +142,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, json_ocode); } else { vty_out(vty, - "BGP table version is 0, local router ID is %s\n", - inet_ntoa(bgp->router_id)); + "BGP table version is 0, local router ID is %pI4\n", + &bgp->router_id); vty_out(vty, "Default local pref %u, ", bgp->default_local_pref); vty_out(vty, "local AS %u\n", bgp->as); @@ -184,10 +189,10 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, "%u:%d", rd_as.as, rd_as.val); else if (type == RD_TYPE_IP) - snprintf(rd_str, sizeof(rd_str), - "%s:%d", - inet_ntoa(rd_ip.ip), - rd_ip.val); + snprintfrr(rd_str, + sizeof(rd_str), + "%pI4:%d", &rd_ip.ip, + rd_ip.val); json_object_string_add( json_routes, "rd", rd_str); @@ -199,9 +204,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, vty_out(vty, "%u:%d", rd_as.as, rd_as.val); else if (type == RD_TYPE_IP) - vty_out(vty, "%s:%d", - inet_ntoa(rd_ip.ip), - rd_ip.val); + vty_out(vty, "%pI4:%d", + &rd_ip.ip, rd_ip.val); #ifdef ENABLE_BGP_VNC else if (type == RD_TYPE_VNC_ETH) vty_out(vty, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 795a4adfc7..00e781d804 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -73,6 +73,11 @@ #include "bgpd/rfapi/bgp_rfapi_cfg.h" #endif +#include "northbound.h" +#include "northbound_cli.h" +#include "bgpd/bgp_nb.h" + + FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK, { .val_bool = false, @@ -268,6 +273,37 @@ static const char *get_afi_safi_json_str(afi_t afi, safi_t safi) return "Unknown"; } +/* return string maps to afi-safi specific container names + * defined in bgp yang file. + */ +const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi) +{ + if (afi == AFI_IP && safi == SAFI_UNICAST) + return "ipv4-unicast"; + else if (afi == AFI_IP && safi == SAFI_MULTICAST) + return "ipv4-multicast"; + else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST) + return "ipv4-labeled-unicast"; + else if (afi == AFI_IP && safi == SAFI_MPLS_VPN) + return "l3vpn-ipv4-unicast"; + else if (afi == AFI_IP && safi == SAFI_FLOWSPEC) + return "ipv4-flowspec"; + else if (afi == AFI_IP6 && safi == SAFI_UNICAST) + return "ipv6-unicast"; + else if (afi == AFI_IP6 && safi == SAFI_MULTICAST) + return "ipv6-multicast"; + else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST) + return "ipv6-labeled-unicast"; + else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN) + return "l3vpn-ipv6-unicast"; + else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC) + return "ipv6-flowspec"; + else if (afi == AFI_L2VPN && safi == SAFI_EVPN) + return "l2vpn-evpn"; + else + return "Unknown"; +} + /* Utility function to get address family from current node. */ afi_t bgp_node_afi(struct vty *vty) { @@ -751,18 +787,19 @@ enum clear_sort { clear_as }; -static void bgp_clear_vty_error(struct vty *vty, struct peer *peer, afi_t afi, - safi_t safi, int error) +static void bgp_clear_vty_error(struct peer *peer, afi_t afi, safi_t safi, + int error, char *errmsg, size_t errmsg_len) { switch (error) { case BGP_ERR_AF_UNCONFIGURED: - vty_out(vty, - "%%BGP: Enable %s address family for the neighbor %s\n", - get_afi_safi_str(afi, safi, false), peer->host); + snprintf(errmsg, errmsg_len, + "%%BGP: Enable %s address family for the neighbor %s", + get_afi_safi_str(afi, safi, false), peer->host); break; case BGP_ERR_SOFT_RECONFIG_UNCONFIGURED: - vty_out(vty, - "%%BGP: Inbound soft reconfig for %s not possible as it\n has neither refresh capability, nor inbound soft reconfig\n", + snprintf( + errmsg, errmsg_len, + "%%BGP: Inbound soft reconfig for %s not possible as it\n has neither refresh capability, nor inbound soft reconfig", peer->host); break; default: @@ -820,9 +857,9 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi, } /* `clear ip bgp' functions. */ -static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, +static int bgp_clear(struct bgp *bgp, afi_t afi, safi_t safi, enum clear_sort sort, enum bgp_clear_type stype, - const char *arg) + const char *arg, char *errmsg, size_t errmsg_len) { int ret = 0; bool found = false; @@ -848,7 +885,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); } if (gr_router_detected @@ -877,8 +915,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, if (!peer) { peer = peer_lookup_by_hostname(bgp, arg); if (!peer) { - vty_out(vty, - "Malformed address or name: %s\n", + snprintf( + errmsg, errmsg_len, + "Malformed address or name: %s", arg); return CMD_WARNING; } @@ -886,9 +925,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } else { peer = peer_lookup(bgp, &su); if (!peer) { - vty_out(vty, - "%%BGP: Unknown neighbor - \"%s\"\n", - arg); + snprintf(errmsg, errmsg_len, + "%%BGP: Unknown neighbor - \"%s\"", + arg); return CMD_WARNING; } } @@ -903,7 +942,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = BGP_ERR_AF_UNCONFIGURED; if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, errmsg, + errmsg_len); return CMD_SUCCESS; } @@ -914,7 +954,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, group = peer_group_lookup(bgp, arg); if (!group) { - vty_out(vty, "%%BGP: No such peer-group %s\n", arg); + snprintf(errmsg, errmsg_len, + "%%BGP: No such peer-group %s", arg); return CMD_WARNING; } @@ -922,14 +963,16 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = bgp_peer_clear(peer, afi, safi, &nnode, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); else found = true; } if (!found) - vty_out(vty, - "%%BGP: No %s peer belonging to peer-group %s is configured\n", + snprintf( + errmsg, errmsg_len, + "%%BGP: No %s peer belonging to peer-group %s is configured", get_afi_safi_str(afi, safi, false), arg); return CMD_SUCCESS; @@ -949,7 +992,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = bgp_peer_clear(peer, afi, safi, &nnode, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); else found = true; } @@ -963,9 +1007,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } if (!found) - vty_out(vty, - "%%BGP: No external %s peer is configured\n", - get_afi_safi_str(afi, safi, false)); + snprintf(errmsg, errmsg_len, + "%%BGP: No external %s peer is configured", + get_afi_safi_str(afi, safi, false)); return CMD_SUCCESS; } @@ -986,7 +1030,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, ret = bgp_peer_clear(peer, afi, safi, &nnode, stype); if (ret < 0) - bgp_clear_vty_error(vty, peer, afi, safi, ret); + bgp_clear_vty_error(peer, afi, safi, ret, + errmsg, errmsg_len); else found = true; } @@ -1000,9 +1045,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } if (!found) - vty_out(vty, - "%%BGP: No %s peer is configured with AS %s\n", - get_afi_safi_str(afi, safi, false), arg); + snprintf(errmsg, errmsg_len, + "%%BGP: No %s peer is configured with AS %s", + get_afi_safi_str(afi, safi, false), arg); return CMD_SUCCESS; } @@ -1010,9 +1055,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, return CMD_SUCCESS; } -static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi, - safi_t safi, enum clear_sort sort, - enum bgp_clear_type stype, const char *arg) +static int bgp_clear_vty(const char *name, afi_t afi, safi_t safi, + enum clear_sort sort, enum bgp_clear_type stype, + const char *arg, char *errmsg, size_t errmsg_len) { struct bgp *bgp; @@ -1020,40 +1065,56 @@ static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi, if (name) { bgp = bgp_lookup_by_name(name); if (bgp == NULL) { - vty_out(vty, "Can't find BGP instance %s\n", name); + snprintf(errmsg, errmsg_len, + "Can't find BGP instance %s", name); return CMD_WARNING; } } else { bgp = bgp_get_default(); if (bgp == NULL) { - vty_out(vty, "No BGP process is configured\n"); + snprintf(errmsg, errmsg_len, + "No BGP process is configured"); return CMD_WARNING; } } - return bgp_clear(vty, bgp, afi, safi, sort, stype, arg); + return bgp_clear(bgp, afi, safi, sort, stype, arg, errmsg, errmsg_len); } /* clear soft inbound */ -static void bgp_clear_star_soft_in(struct vty *vty, const char *name) +int bgp_clear_star_soft_in(const char *name, char *errmsg, size_t errmsg_len) { afi_t afi; safi_t safi; + int ret; - FOREACH_AFI_SAFI (afi, safi) - bgp_clear_vty(vty, name, afi, safi, clear_all, - BGP_CLEAR_SOFT_IN, NULL); + FOREACH_AFI_SAFI (afi, safi) { + ret = bgp_clear_vty(name, afi, safi, clear_all, + BGP_CLEAR_SOFT_IN, NULL, errmsg, + errmsg_len); + if (ret != CMD_SUCCESS) + return -1; + } + + return 0; } /* clear soft outbound */ -static void bgp_clear_star_soft_out(struct vty *vty, const char *name) +int bgp_clear_star_soft_out(const char *name, char *errmsg, size_t errmsg_len) { afi_t afi; safi_t safi; + int ret; - FOREACH_AFI_SAFI (afi, safi) - bgp_clear_vty(vty, name, afi, safi, clear_all, - BGP_CLEAR_SOFT_OUT, NULL); + FOREACH_AFI_SAFI (afi, safi) { + ret = bgp_clear_vty(name, afi, safi, clear_all, + BGP_CLEAR_SOFT_OUT, NULL, errmsg, + errmsg_len); + if (ret != CMD_SUCCESS) + return -1; + } + + return 0; } @@ -1162,23 +1223,21 @@ DEFUN (no_auto_summary, } /* "router bgp" commands. */ -DEFUN_NOSH (router_bgp, - router_bgp_cmd, - "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", - ROUTER_STR - BGP_STR - AS_STR - BGP_INSTANCE_HELP_STR) +DEFUN_YANG_NOSH(router_bgp, + router_bgp_cmd, + "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", + ROUTER_STR BGP_STR AS_STR BGP_INSTANCE_HELP_STR) { int idx_asn = 2; int idx_view_vrf = 3; int idx_vrf = 4; - int is_new_bgp = 0; - int ret; + int ret = CMD_SUCCESS; as_t as; struct bgp *bgp; const char *name = NULL; + char as_str[12] = {'\0'}; enum bgp_instance_type inst_type; + char base_xpath[XPATH_MAXLEN]; // "router bgp" without an ASN if (argc == 2) { @@ -1194,12 +1253,38 @@ DEFUN_NOSH (router_bgp, vty_out(vty, "%% Please specify ASN and VRF\n"); return CMD_WARNING_CONFIG_FAILED; } + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", VRF_DEFAULT_NAME); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + snprintf(as_str, 12, "%d", bgp->as); + nb_cli_enqueue_change(vty, "./global/local-as", NB_OP_MODIFY, + as_str); + if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) { + nb_cli_enqueue_change(vty, + "./global/instance-type-view", + NB_OP_MODIFY, "true"); + } + + nb_cli_pending_commit_check(vty); + ret = nb_cli_apply_changes(vty, base_xpath); + if (ret == CMD_SUCCESS) { + VTY_PUSH_XPATH(BGP_NODE, base_xpath); + + /* + * For backward compatibility with old commands we still + * need to use the qobj infrastructure. + */ + VTY_PUSH_CONTEXT(BGP_NODE, bgp); + } + return ret; } // "router bgp X" else { - as = strtoul(argv[idx_asn]->arg, NULL, 10); + as = strtoul(argv[idx_asn]->arg, NULL, 10); inst_type = BGP_INSTANCE_TYPE_DEFAULT; if (argc > 3) { name = argv[idx_vrf]->arg; @@ -1209,70 +1294,63 @@ DEFUN_NOSH (router_bgp, name = NULL; else inst_type = BGP_INSTANCE_TYPE_VRF; - } else if (!strcmp(argv[idx_view_vrf]->text, "view")) + } else if (!strcmp(argv[idx_view_vrf]->text, "view")) { inst_type = BGP_INSTANCE_TYPE_VIEW; + } } - - if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) - is_new_bgp = (bgp_lookup(as, name) == NULL); - - ret = bgp_get_vty(&bgp, &as, name, inst_type); - switch (ret) { - case BGP_ERR_AS_MISMATCH: - vty_out(vty, "BGP is already running; AS is %u\n", as); - return CMD_WARNING_CONFIG_FAILED; - case BGP_ERR_INSTANCE_MISMATCH: - vty_out(vty, - "BGP instance name and AS number mismatch\n"); - vty_out(vty, - "BGP instance is already running; AS is %u\n", - as); - return CMD_WARNING_CONFIG_FAILED; + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", name ? name : VRF_DEFAULT_NAME); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./global/local-as", NB_OP_MODIFY, + argv[idx_asn]->arg); + if (inst_type == BGP_INSTANCE_TYPE_VIEW) { + nb_cli_enqueue_change(vty, + "./global/instance-type-view", + NB_OP_MODIFY, "true"); } - /* - * If we just instantiated the default instance, complete - * any pending VRF-VPN leaking that was configured via - * earlier "router bgp X vrf FOO" blocks. - */ - if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) - vpn_leak_postchange_all(); + nb_cli_pending_commit_check(vty); + ret = nb_cli_apply_changes(vty, base_xpath); + if (ret == CMD_SUCCESS) { + VTY_PUSH_XPATH(BGP_NODE, base_xpath); - if (inst_type == BGP_INSTANCE_TYPE_VRF) - bgp_vpn_leak_export(bgp); - /* Pending: handle when user tries to change a view to vrf n vv. - */ + /* + * For backward compatibility with old commands we still + * need to use the qobj infrastructure. + */ + bgp = bgp_lookup(as, name); + if (bgp) + VTY_PUSH_CONTEXT(BGP_NODE, bgp); + } } - /* unset the auto created flag as the user config is now present */ - UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); - VTY_PUSH_CONTEXT(BGP_NODE, bgp); - - return CMD_SUCCESS; + return ret; } /* "no router bgp" commands. */ -DEFUN (no_router_bgp, - no_router_bgp_cmd, - "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", - NO_STR - ROUTER_STR - BGP_STR - AS_STR - BGP_INSTANCE_HELP_STR) +DEFUN_YANG(no_router_bgp, + no_router_bgp_cmd, + "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]", + NO_STR ROUTER_STR BGP_STR AS_STR BGP_INSTANCE_HELP_STR) { int idx_asn = 3; int idx_vrf = 5; - as_t as; + as_t as = 0; struct bgp *bgp; const char *name = NULL; + char base_xpath[XPATH_MAXLEN]; + const struct lyd_node *bgp_glb_dnode; // "no router bgp" without an ASN if (argc == 3) { // Pending: Make VRF option available for ASN less config - bgp = bgp_get_default(); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", VRF_DEFAULT_NAME); - if (bgp == NULL) { + bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode, + base_xpath); + if (!bgp_glb_dnode) { vty_out(vty, "%% No BGP process is configured\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -1282,6 +1360,11 @@ DEFUN (no_router_bgp, return CMD_WARNING_CONFIG_FAILED; } + /* tcli mode bgp would not be set until apply stage. */ + bgp = nb_running_get_entry(bgp_glb_dnode, NULL, false); + if (!bgp) + return CMD_SUCCESS; + if (bgp->l3vni) { vty_out(vty, "%% Please unconfigure l3vni %u", bgp->l3vni); @@ -1321,94 +1404,94 @@ DEFUN (no_router_bgp, } } } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH, + "frr-bgp:bgp", "bgp", + bgp->name ? bgp->name : VRF_DEFAULT_NAME); - if (bgp_vpn_leak_unimport(bgp, vty)) - return CMD_WARNING_CONFIG_FAILED; - - bgp_delete(bgp); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, base_xpath); } +void cli_show_router_bgp(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + const struct lyd_node *vrf_dnode; + const char *vrf_name; + as_t as; -/* BGP router-id. */ + vrf_dnode = yang_dnode_get_parent(dnode, "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + as = yang_dnode_get_uint32(dnode, "./global/local-as"); -DEFPY (bgp_router_id, - bgp_router_id_cmd, - "bgp router-id A.B.C.D", - BGP_STR - "Override configured router identifier\n" - "Manually configured router identifier\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_router_id_static_set(bgp, router_id); - return CMD_SUCCESS; + vty_out(vty, "!\n"); + vty_out(vty, "router bgp %u", as); + if (!strmatch(vrf_name, VRF_DEFAULT_NAME)) + vty_out(vty, " vrf %s", vrf_name); + vty_out(vty, "\n"); } -DEFPY (no_bgp_router_id, - no_bgp_router_id_cmd, - "no bgp router-id [A.B.C.D]", - NO_STR - BGP_STR - "Override configured router identifier\n" - "Manually configured router identifier\n") +/* BGP router-id. */ + +DEFPY_YANG(bgp_router_id, bgp_router_id_cmd, "bgp router-id A.B.C.D", + BGP_STR + "Override configured router identifier\n" + "Manually configured router identifier\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, "./global/router-id", NB_OP_MODIFY, + router_id_str); - if (router_id_str) { - if (!IPV4_ADDR_SAME(&bgp->router_id_static, &router_id)) { - vty_out(vty, "%% BGP router-id doesn't match\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } + return nb_cli_apply_changes(vty, NULL); +} - router_id.s_addr = 0; - bgp_router_id_static_set(bgp, router_id); +DEFPY_YANG(no_bgp_router_id, no_bgp_router_id_cmd, "no bgp router-id [A.B.C.D]", + NO_STR BGP_STR + "Override configured router identifier\n" + "Manually configured router identifier\n") +{ + nb_cli_enqueue_change(vty, "./global/router-id", NB_OP_DESTROY, + router_id_str ? router_id_str : NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_bgp_router_id(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp router-id %s\n", yang_dnode_get_string(dnode, NULL)); +} /* BGP Cluster ID. */ -DEFUN (bgp_cluster_id, - bgp_cluster_id_cmd, - "bgp cluster-id <A.B.C.D|(1-4294967295)>", - BGP_STR - "Configure Route-Reflector Cluster-id\n" - "Route-Reflector Cluster-id in IP address format\n" - "Route-Reflector Cluster-id as 32 bit quantity\n") +DEFUN_YANG(bgp_cluster_id, + bgp_cluster_id_cmd, + "bgp cluster-id <A.B.C.D|(1-4294967295)>", + BGP_STR + "Configure Route-Reflector Cluster-id\n" + "Route-Reflector Cluster-id in IP address format\n" + "Route-Reflector Cluster-id as 32 bit quantity\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_ipv4 = 2; - int ret; - struct in_addr cluster; - - ret = inet_aton(argv[idx_ipv4]->arg, &cluster); - if (!ret) { - vty_out(vty, "%% Malformed bgp cluster identifier\n"); - return CMD_WARNING_CONFIG_FAILED; - } - bgp_cluster_id_set(bgp, &cluster); - bgp_clear_star_soft_out(vty, bgp->name); + nb_cli_enqueue_change( + vty, "./global/route-reflector/route-reflector-cluster-id", + NB_OP_MODIFY, argv[idx_ipv4]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_cluster_id, - no_bgp_cluster_id_cmd, - "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]", - NO_STR - BGP_STR - "Configure Route-Reflector Cluster-id\n" - "Route-Reflector Cluster-id in IP address format\n" - "Route-Reflector Cluster-id as 32 bit quantity\n") +DEFUN_YANG(no_bgp_cluster_id, + no_bgp_cluster_id_cmd, + "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]", + NO_STR BGP_STR + "Configure Route-Reflector Cluster-id\n" + "Route-Reflector Cluster-id in IP address format\n" + "Route-Reflector Cluster-id as 32 bit quantity\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_cluster_id_unset(bgp); - bgp_clear_star_soft_out(vty, bgp->name); + nb_cli_enqueue_change( + vty, "./global/route-reflector/route-reflector-cluster-id", + NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } DEFPY (bgp_norib, @@ -1446,87 +1529,86 @@ DEFPY (no_bgp_norib, return CMD_SUCCESS; } -DEFUN (bgp_confederation_identifier, - bgp_confederation_identifier_cmd, - "bgp confederation identifier (1-4294967295)", - "BGP specific commands\n" - "AS confederation parameters\n" - "AS number\n" - "Set routing domain confederation AS\n") +DEFUN_YANG(bgp_confederation_identifier, + bgp_confederation_identifier_cmd, + "bgp confederation identifier (1-4294967295)", + "BGP specific commands\n" + "AS confederation parameters\n" + "AS number\n" + "Set routing domain confederation AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - as_t as; - as = strtoul(argv[idx_number]->arg, NULL, 10); - - bgp_confederation_id_set(bgp, as); + nb_cli_enqueue_change(vty, "./global/confederation/identifier", + NB_OP_MODIFY, argv[idx_number]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_confederation_identifier, - no_bgp_confederation_identifier_cmd, - "no bgp confederation identifier [(1-4294967295)]", - NO_STR - "BGP specific commands\n" - "AS confederation parameters\n" - "AS number\n" - "Set routing domain confederation AS\n") +DEFUN_YANG(no_bgp_confederation_identifier, + no_bgp_confederation_identifier_cmd, + "no bgp confederation identifier [(1-4294967295)]", + NO_STR + "BGP specific commands\n" + "AS confederation parameters\n" + "AS number\n" + "Set routing domain confederation AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_confederation_id_unset(bgp); + nb_cli_enqueue_change(vty, "./global/confederation/identifier", + NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (bgp_confederation_peers, - bgp_confederation_peers_cmd, - "bgp confederation peers (1-4294967295)...", - "BGP specific commands\n" - "AS confederation parameters\n" - "Peer ASs in BGP confederation\n" - AS_STR) +void cli_show_router_bgp_confederation_identifier(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp confederation identifier %u\n", + yang_dnode_get_uint32(dnode, NULL)); +} + +DEFUN_YANG(bgp_confederation_peers, + bgp_confederation_peers_cmd, + "bgp confederation peers (1-4294967295)...", + "BGP specific commands\n" + "AS confederation parameters\n" + "Peer ASs in BGP confederation\n" AS_STR) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_asn = 3; - as_t as; int i; - for (i = idx_asn; i < argc; i++) { - as = strtoul(argv[i]->arg, NULL, 10); - - if (bgp->as == as) { - vty_out(vty, - "%% Local member-AS not allowed in confed peer list\n"); - continue; - } + for (i = idx_asn; i < argc; i++) + nb_cli_enqueue_change(vty, "./global/confederation/member-as", + NB_OP_CREATE, argv[i]->arg); - bgp_confederation_peers_add(bgp, as); - } - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_confederation_peers, - no_bgp_confederation_peers_cmd, - "no bgp confederation peers (1-4294967295)...", - NO_STR - "BGP specific commands\n" - "AS confederation parameters\n" - "Peer ASs in BGP confederation\n" - AS_STR) +DEFUN_YANG(no_bgp_confederation_peers, + no_bgp_confederation_peers_cmd, + "no bgp confederation peers (1-4294967295)...", + NO_STR + "BGP specific commands\n" + "AS confederation parameters\n" + "Peer ASs in BGP confederation\n" AS_STR) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_asn = 4; - as_t as; int i; - for (i = idx_asn; i < argc; i++) { - as = strtoul(argv[i]->arg, NULL, 10); + for (i = idx_asn; i < argc; i++) + nb_cli_enqueue_change(vty, "./global/confederation/member-as", + NB_OP_DESTROY, argv[i]->arg); - bgp_confederation_peers_remove(bgp, as); - } - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_confederation_member_as(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp confederation peers %u \n", + yang_dnode_get_uint32(dnode, NULL)); } /** @@ -1534,23 +1616,16 @@ DEFUN (no_bgp_confederation_peers, * @peer_type: BGP_PEER_EBGP or BGP_PEER_IBGP * @set: 1 for setting values, 0 for removing the max-paths config. */ -static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type, - const char *mpaths, uint16_t options, - int set) +int bgp_maxpaths_config_vty(struct bgp *bgp, afi_t afi, safi_t safi, + int peer_type, uint16_t maxpaths, uint16_t options, + int set, char *errmsg, size_t errmsg_len) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - uint16_t maxpaths = 0; int ret; - afi_t afi; - safi_t safi; - - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); if (set) { - maxpaths = strtol(mpaths, NULL, 10); if (maxpaths > multipath_num) { - vty_out(vty, + snprintf( + errmsg, errmsg_len, "%% Maxpaths Specified: %d is > than multipath num specified on bgp command line %d", maxpaths, multipath_num); return CMD_WARNING_CONFIG_FAILED; @@ -1561,7 +1636,8 @@ static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type, ret = bgp_maximum_paths_unset(bgp, afi, safi, peer_type); if (ret < 0) { - vty_out(vty, + snprintf( + errmsg, errmsg_len, "%% Failed to %sset maximum-paths %s %u for afi %u, safi %u\n", (set == 1) ? "" : "un", (peer_type == BGP_PEER_EBGP) ? "ebgp" : "ibgp", @@ -1574,107 +1650,130 @@ static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type, return CMD_SUCCESS; } -DEFUN (bgp_maxmed_admin, - bgp_maxmed_admin_cmd, - "bgp max-med administrative ", - BGP_STR - "Advertise routes with max-med\n" - "Administratively applied, for an indefinite period\n") +void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); + if (yang_dnode_get_bool(dnode, "./enable-med-admin")) { + uint32_t med_admin_val; - bgp->v_maxmed_admin = 1; - bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT; + vty_out(vty, " bgp max-med administrative"); + if ((med_admin_val = + yang_dnode_get_uint32(dnode, "./max-med-admin")) + != BGP_MAXMED_VALUE_DEFAULT) + vty_out(vty, " %u", med_admin_val); + vty_out(vty, "\n"); + } - bgp_maxmed_update(bgp); + if (yang_dnode_exists(dnode, "./max-med-onstart-up-time")) { + uint32_t onstartup_val; - return CMD_SUCCESS; + vty_out(vty, " bgp max-med on-startup %u", + yang_dnode_get_uint32(dnode, + "./max-med-onstart-up-time")); + onstartup_val = yang_dnode_get_uint32( + dnode, "./max-med-onstart-up-value"); + if (onstartup_val != BGP_MAXMED_VALUE_DEFAULT) + vty_out(vty, " %u", onstartup_val); + + vty_out(vty, "\n"); + } } -DEFUN (bgp_maxmed_admin_medv, - bgp_maxmed_admin_medv_cmd, - "bgp max-med administrative (0-4294967295)", - BGP_STR - "Advertise routes with max-med\n" - "Administratively applied, for an indefinite period\n" - "Max MED value to be used\n") +DEFUN_YANG(bgp_maxmed_admin, + bgp_maxmed_admin_cmd, + "bgp max-med administrative ", + BGP_STR + "Advertise routes with max-med\n" + "Administratively applied, for an indefinite period\n") +{ + nb_cli_enqueue_change(vty, "./global/med-config/enable-med-admin", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG(bgp_maxmed_admin_medv, + bgp_maxmed_admin_medv_cmd, + "bgp max-med administrative (0-4294967295)", + BGP_STR + "Advertise routes with max-med\n" + "Administratively applied, for an indefinite period\n" + "Max MED value to be used\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - bgp->v_maxmed_admin = 1; - bgp->maxmed_admin_value = strtoul(argv[idx_number]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./global/med-config/enable-med-admin", + NB_OP_MODIFY, "true"); - bgp_maxmed_update(bgp); + nb_cli_enqueue_change(vty, "./global/med-config/max-med-admin", + NB_OP_MODIFY, argv[idx_number]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_maxmed_admin, - no_bgp_maxmed_admin_cmd, - "no bgp max-med administrative [(0-4294967295)]", - NO_STR - BGP_STR - "Advertise routes with max-med\n" - "Administratively applied, for an indefinite period\n" - "Max MED value to be used\n") +DEFUN_YANG(no_bgp_maxmed_admin, + no_bgp_maxmed_admin_cmd, + "no bgp max-med administrative [(0-4294967295)]", + NO_STR BGP_STR + "Advertise routes with max-med\n" + "Administratively applied, for an indefinite period\n" + "Max MED value to be used\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->v_maxmed_admin = BGP_MAXMED_ADMIN_UNCONFIGURED; - bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT; - bgp_maxmed_update(bgp); + nb_cli_enqueue_change(vty, "./global/med-config/enable-med-admin", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/med-config/max-med-admin", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (bgp_maxmed_onstartup, - bgp_maxmed_onstartup_cmd, - "bgp max-med on-startup (5-86400) [(0-4294967295)]", - BGP_STR - "Advertise routes with max-med\n" - "Effective on a startup\n" - "Time (seconds) period for max-med\n" - "Max MED value to be used\n") +DEFUN_YANG (bgp_maxmed_onstartup, + bgp_maxmed_onstartup_cmd, + "bgp max-med on-startup (5-86400) [(0-4294967295)]", + BGP_STR + "Advertise routes with max-med\n" + "Effective on a startup\n" + "Time (seconds) period for max-med\n" + "Max MED value to be used\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx = 0; argv_find(argv, argc, "(5-86400)", &idx); - bgp->v_maxmed_onstartup = strtoul(argv[idx]->arg, NULL, 10); + nb_cli_enqueue_change(vty, + "./global/med-config/max-med-onstart-up-time", + NB_OP_MODIFY, argv[idx]->arg); + if (argv_find(argv, argc, "(0-4294967295)", &idx)) - bgp->maxmed_onstartup_value = strtoul(argv[idx]->arg, NULL, 10); + nb_cli_enqueue_change( + vty, "./global/med-config/max-med-onstart-up-value", + NB_OP_MODIFY, argv[idx]->arg); else - bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; - - bgp_maxmed_update(bgp); + nb_cli_enqueue_change( + vty, "./global/med-config/max-med-onstart-up-value", + NB_OP_MODIFY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_maxmed_onstartup, - no_bgp_maxmed_onstartup_cmd, - "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]", - NO_STR - BGP_STR - "Advertise routes with max-med\n" - "Effective on a startup\n" - "Time (seconds) period for max-med\n" - "Max MED value to be used\n") +DEFUN_YANG (no_bgp_maxmed_onstartup, + no_bgp_maxmed_onstartup_cmd, + "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]", + NO_STR BGP_STR + "Advertise routes with max-med\n" + "Effective on a startup\n" + "Time (seconds) period for max-med\n" + "Max MED value to be used\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* Cancel max-med onstartup if its on */ - if (bgp->t_maxmed_onstartup) { - THREAD_TIMER_OFF(bgp->t_maxmed_onstartup); - bgp->maxmed_onstartup_over = 1; - } + nb_cli_enqueue_change(vty, + "./global/med-config/max-med-onstart-up-time", + NB_OP_DESTROY, NULL); - bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED; - bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; + nb_cli_enqueue_change(vty, + "./global/med-config/max-med-onstart-up-value", + NB_OP_MODIFY, NULL); - bgp_maxmed_update(bgp); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } static int bgp_global_update_delay_config_vty(struct vty *vty, @@ -1858,22 +1957,16 @@ DEFPY (no_bgp_update_delay, } -static int bgp_wpkt_quanta_config_vty(struct vty *vty, uint32_t quanta, - bool set) +int bgp_wpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - quanta = set ? quanta : BGP_WRITE_PACKET_MAX; atomic_store_explicit(&bgp->wpkt_quanta, quanta, memory_order_relaxed); return CMD_SUCCESS; } -static int bgp_rpkt_quanta_config_vty(struct vty *vty, uint32_t quanta, - bool set) +int bgp_rpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - quanta = set ? quanta : BGP_READ_PACKET_MAX; atomic_store_explicit(&bgp->rpkt_quanta, quanta, memory_order_relaxed); @@ -1904,24 +1997,46 @@ void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp) * Furthermore, the maximums used here should correspond to * BGP_WRITE_PACKET_MAX and BGP_READ_PACKET_MAX. */ -DEFPY (bgp_wpkt_quanta, - bgp_wpkt_quanta_cmd, - "[no] write-quanta (1-64)$quanta", - NO_STR - "How many packets to write to peer socket per run\n" - "Number of packets\n") -{ - return bgp_wpkt_quanta_config_vty(vty, quanta, !no); -} +DEFPY_YANG (bgp_wpkt_quanta, + bgp_wpkt_quanta_cmd, + "[no] write-quanta (1-64)$quanta", + NO_STR + "How many packets to write to peer socket per run\n" + "Number of packets\n") +{ + if (!no) + nb_cli_enqueue_change( + vty, + "./global/global-neighbor-config/packet-quanta-config/wpkt-quanta", + NB_OP_MODIFY, quanta_str); + else + nb_cli_enqueue_change( + vty, + "./global/global-neighbor-config/packet-quanta-config/wpkt-quanta", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG (bgp_rpkt_quanta, + bgp_rpkt_quanta_cmd, + "[no] read-quanta (1-10)$quanta", + NO_STR + "How many packets to read from peer socket per I/O cycle\n" + "Number of packets\n") +{ + if (!no) + nb_cli_enqueue_change( + vty, + "./global/global-neighbor-config/packet-quanta-config/rpkt-quanta", + NB_OP_MODIFY, quanta_str); + else + nb_cli_enqueue_change( + vty, + "./global/global-neighbor-config/packet-quanta-config/rpkt-quanta", + NB_OP_MODIFY, NULL); -DEFPY (bgp_rpkt_quanta, - bgp_rpkt_quanta_cmd, - "[no] read-quanta (1-10)$quanta", - NO_STR - "How many packets to read from peer socket per I/O cycle\n" - "Number of packets\n") -{ - return bgp_rpkt_quanta_config_vty(vty, quanta, !no); + return nb_cli_apply_changes(vty, NULL); } void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp) @@ -1930,46 +2045,75 @@ void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp) vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time); } - -DEFUN (bgp_coalesce_time, - bgp_coalesce_time_cmd, - "coalesce-time (0-4294967295)", - "Subgroup coalesce timer\n" - "Subgroup coalesce timer value (in ms)\n") +void cli_show_router_global_update_group_config_coalesce_time( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); + vty_out(vty, " coalesce-time %u\n", yang_dnode_get_uint32(dnode, NULL)); +} + +DEFUN_YANG (bgp_coalesce_time, + bgp_coalesce_time_cmd, + "coalesce-time (0-4294967295)", + "Subgroup coalesce timer\n" + "Subgroup coalesce timer value (in ms)\n") +{ int idx = 0; + argv_find(argv, argc, "(0-4294967295)", &idx); - bgp->heuristic_coalesce = false; - bgp->coalesce_time = strtoul(argv[idx]->arg, NULL, 10); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, "./global/global-update-group-config/coalesce-time", + NB_OP_MODIFY, argv[idx]->arg); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_coalesce_time, - no_bgp_coalesce_time_cmd, - "no coalesce-time (0-4294967295)", - NO_STR - "Subgroup coalesce timer\n" - "Subgroup coalesce timer value (in ms)\n") +DEFUN_YANG(no_bgp_coalesce_time, + no_bgp_coalesce_time_cmd, + "no coalesce-time (0-4294967295)", + NO_STR + "Subgroup coalesce timer\n" + "Subgroup coalesce timer value (in ms)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change( + vty, "./global/global-update-group-config/coalesce-time", + NB_OP_MODIFY, NULL); - bgp->heuristic_coalesce = true; - bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* Maximum-paths configuration */ -DEFUN (bgp_maxpaths, - bgp_maxpaths_cmd, - "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM), - "Forward packets over multiple paths\n" - "Number of paths\n") +DEFUN_YANG (bgp_maxpaths, + bgp_maxpaths_cmd, + "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM), + "Forward packets over multiple paths\n" + "Number of paths\n") { int idx_number = 1; - return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, - argv[idx_number]->arg, 0, 1); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " maximum-paths %d\n", + yang_dnode_get_uint16(dnode, NULL)); } ALIAS_HIDDEN(bgp_maxpaths, bgp_maxpaths_hidden_cmd, @@ -1977,16 +2121,31 @@ ALIAS_HIDDEN(bgp_maxpaths, bgp_maxpaths_hidden_cmd, "Forward packets over multiple paths\n" "Number of paths\n") -DEFUN (bgp_maxpaths_ibgp, - bgp_maxpaths_ibgp_cmd, - "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM), - "Forward packets over multiple paths\n" - "iBGP-multipath\n" - "Number of paths\n") +DEFUN_YANG (bgp_maxpaths_ibgp, + bgp_maxpaths_ibgp_cmd, + "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM), + "Forward packets over multiple paths\n" + "iBGP-multipath\n" + "Number of paths\n") { int idx_number = 2; - return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, - argv[idx_number]->arg, 0, 1); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(bgp_maxpaths_ibgp, bgp_maxpaths_ibgp_hidden_cmd, @@ -1995,18 +2154,50 @@ ALIAS_HIDDEN(bgp_maxpaths_ibgp, bgp_maxpaths_ibgp_hidden_cmd, "iBGP-multipath\n" "Number of paths\n") -DEFUN (bgp_maxpaths_ibgp_cluster, - bgp_maxpaths_ibgp_cluster_cmd, - "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length", - "Forward packets over multiple paths\n" - "iBGP-multipath\n" - "Number of paths\n" - "Match the cluster length\n") +DEFUN_YANG (bgp_maxpaths_ibgp_cluster, + bgp_maxpaths_ibgp_cluster_cmd, + "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length", + "Forward packets over multiple paths\n" + "iBGP-multipath\n" + "Number of paths\n" + "Match the cluster length\n") { int idx_number = 2; - return bgp_maxpaths_config_vty( - vty, BGP_PEER_IBGP, argv[idx_number]->arg, - BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN, 1); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, + argv[idx_number]->arg); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/cluster-length-list", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " maximum-paths ibgp %d", + yang_dnode_get_uint16(dnode, "./maximum-paths")); + if (yang_dnode_get_bool(dnode, "./cluster-length-list")) + vty_out(vty, " equal-cluster-length"); + vty_out(vty, "\n"); } ALIAS_HIDDEN(bgp_maxpaths_ibgp_cluster, bgp_maxpaths_ibgp_cluster_hidden_cmd, @@ -2017,14 +2208,29 @@ ALIAS_HIDDEN(bgp_maxpaths_ibgp_cluster, bgp_maxpaths_ibgp_cluster_hidden_cmd, "Number of paths\n" "Match the cluster length\n") -DEFUN (no_bgp_maxpaths, - no_bgp_maxpaths_cmd, - "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", - NO_STR - "Forward packets over multiple paths\n" - "Number of paths\n") +DEFUN_YANG (no_bgp_maxpaths, + no_bgp_maxpaths_cmd, + "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", + NO_STR + "Forward packets over multiple paths\n" + "Number of paths\n") { - return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, NULL, 0, 0); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, @@ -2032,16 +2238,39 @@ ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, "Forward packets over multiple paths\n" "Number of paths\n") -DEFUN (no_bgp_maxpaths_ibgp, - no_bgp_maxpaths_ibgp_cmd, - "no maximum-paths ibgp [" CMD_RANGE_STR(1, MULTIPATH_NUM) " [equal-cluster-length]]", - NO_STR - "Forward packets over multiple paths\n" - "iBGP-multipath\n" - "Number of paths\n" - "Match the cluster length\n") +DEFUN_YANG (no_bgp_maxpaths_ibgp, + no_bgp_maxpaths_ibgp_cmd, + "no maximum-paths ibgp [" CMD_RANGE_STR(1, MULTIPATH_NUM) " [equal-cluster-length]]", + NO_STR + "Forward packets over multiple paths\n" + "iBGP-multipath\n" + "Number of paths\n" + "Match the cluster length\n") { - return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, NULL, 0, 0); + char base_xpath[XPATH_MAXLEN]; + afi_t afi; + safi_t safi; + + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, NULL); + + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/cluster-length-list", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(no_bgp_maxpaths_ibgp, no_bgp_maxpaths_ibgp_hidden_cmd, @@ -2073,129 +2302,181 @@ static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, /* BGP timers. */ -DEFUN (bgp_timers, - bgp_timers_cmd, - "timers bgp (0-65535) (0-65535)", - "Adjust routing timers\n" - "BGP timers\n" - "Keepalive interval\n" - "Holdtime\n") +DEFUN_YANG (bgp_timers, + bgp_timers_cmd, + "timers bgp (0-65535) (0-65535)", + "Adjust routing timers\n" + "BGP timers\n" + "Keepalive interval\n" + "Holdtime\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 2; int idx_number_2 = 3; - unsigned long keepalive = 0; - unsigned long holdtime = 0; - keepalive = strtoul(argv[idx_number]->arg, NULL, 10); - holdtime = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./global/global-config-timers/keepalive", + NB_OP_MODIFY, argv[idx_number]->arg); + nb_cli_enqueue_change(vty, "./global/global-config-timers/hold-time", + NB_OP_MODIFY, argv[idx_number_2]->arg); - /* Holdtime value check. */ - if (holdtime < 3 && holdtime != 0) { - vty_out(vty, - "%% hold time value must be either 0 or greater than 3\n"); - return CMD_WARNING_CONFIG_FAILED; - } + return nb_cli_apply_changes(vty, NULL); +} - bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY); +DEFUN_YANG (no_bgp_timers, + no_bgp_timers_cmd, + "no timers bgp [(0-65535) (0-65535)]", + NO_STR + "Adjust routing timers\n" + "BGP timers\n" + "Keepalive interval\n" + "Holdtime\n") +{ + nb_cli_enqueue_change(vty, "./global/global-config-timers/keepalive", + NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./global/global-config-timers/hold-time", + NB_OP_DESTROY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_timers, - no_bgp_timers_cmd, - "no timers bgp [(0-65535) (0-65535)]", - NO_STR - "Adjust routing timers\n" - "BGP timers\n" - "Keepalive interval\n" - "Holdtime\n") +void cli_show_router_bgp_route_reflector(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_timers_set(bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, - DFLT_BGP_CONNECT_RETRY); + if (yang_dnode_get_bool(dnode, "./no-client-reflect")) + vty_out(vty, " no bgp client-to-client reflection\n"); - return CMD_SUCCESS; + if (yang_dnode_get_bool(dnode, "./allow-outbound-policy")) + vty_out(vty, " bgp route-reflector allow-outbound-policy\n"); + + if (yang_dnode_exists(dnode, "./route-reflector-cluster-id")) + vty_out(vty, " bgp cluster-id %s\n", + yang_dnode_get_string(dnode, + "./route-reflector-cluster-id")); } +DEFUN_YANG(bgp_client_to_client_reflection, + bgp_client_to_client_reflection_cmd, + "bgp client-to-client reflection", + "BGP specific commands\n" + "Configure client to client route reflection\n" + "reflection of routes allowed\n") +{ + nb_cli_enqueue_change(vty, "./global/route-reflector/no-client-reflect", + NB_OP_MODIFY, "false"); -DEFUN (bgp_client_to_client_reflection, - bgp_client_to_client_reflection_cmd, - "bgp client-to-client reflection", - "BGP specific commands\n" - "Configure client to client route reflection\n" - "reflection of routes allowed\n") + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG(no_bgp_client_to_client_reflection, + no_bgp_client_to_client_reflection_cmd, + "no bgp client-to-client reflection", + NO_STR + "BGP specific commands\n" + "Configure client to client route reflection\n" + "reflection of routes allowed\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); - bgp_clear_star_soft_out(vty, bgp->name); + nb_cli_enqueue_change(vty, "./global/route-reflector/no-client-reflect", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_client_to_client_reflection, - no_bgp_client_to_client_reflection_cmd, - "no bgp client-to-client reflection", - NO_STR - "BGP specific commands\n" - "Configure client to client route reflection\n" - "reflection of routes allowed\n") +void cli_show_router_bgp_route_selection(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT); - bgp_clear_star_soft_out(vty, bgp->name); - return CMD_SUCCESS; + if (yang_dnode_get_bool(dnode, "./always-compare-med")) + vty_out(vty, " bgp always-compare-med\n"); + + if (yang_dnode_get_bool(dnode, "./ignore-as-path-length")) + vty_out(vty, " bgp bestpath as-path ignore\n"); + + if (yang_dnode_get_bool(dnode, "./aspath-confed")) + vty_out(vty, " bgp bestpath as-path confed\n"); + + if (yang_dnode_get_bool(dnode, "./external-compare-router-id")) + vty_out(vty, " bgp bestpath compare-routerid\n"); + + if (yang_dnode_get_bool(dnode, "./allow-multiple-as")) { + if (yang_dnode_get_bool(dnode, "./multi-path-as-set")) + vty_out(vty, + " bgp bestpath as-path multipath-relax as-set\n"); + else + vty_out(vty, " bgp bestpath as-path multipath-relax\n"); + } + + if (yang_dnode_get_bool(dnode, "./deterministic-med")) + vty_out(vty, " bgp deterministic-med\n"); + + if (yang_dnode_get_bool(dnode, "./confed-med") + || yang_dnode_get_bool(dnode, "./missing-as-worst-med")) { + vty_out(vty, " bgp bestpath med"); + if (yang_dnode_get_bool(dnode, "./confed-med")) + vty_out(vty, " confed"); + if (yang_dnode_get_bool(dnode, "./missing-as-worst-med")) + vty_out(vty, " missing-as-worst"); + vty_out(vty, "\n"); + } } /* "bgp always-compare-med" configuration. */ -DEFUN (bgp_always_compare_med, - bgp_always_compare_med_cmd, - "bgp always-compare-med", - "BGP specific commands\n" - "Allow comparing MED from different neighbors\n") +DEFUN_YANG(bgp_always_compare_med, + bgp_always_compare_med_cmd, + "bgp always-compare-med", + "BGP specific commands\n" + "Allow comparing MED from different neighbors\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/always-compare-med", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_always_compare_med, - no_bgp_always_compare_med_cmd, - "no bgp always-compare-med", - NO_STR - "BGP specific commands\n" - "Allow comparing MED from different neighbors\n") +DEFUN_YANG(no_bgp_always_compare_med, + no_bgp_always_compare_med_cmd, + "no bgp always-compare-med", + NO_STR + "BGP specific commands\n" + "Allow comparing MED from different neighbors\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/always-compare-med", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +DEFUN_YANG(bgp_ebgp_requires_policy, + bgp_ebgp_requires_policy_cmd, + "bgp ebgp-requires-policy", + "BGP specific commands\n" + "Require in and out policy for eBGP peers (RFC8212)\n") +{ + nb_cli_enqueue_change(vty, "./global/ebgp-requires-policy", + NB_OP_MODIFY, "true"); + return nb_cli_apply_changes(vty, NULL); +} -DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd, - "bgp ebgp-requires-policy", - "BGP specific commands\n" - "Require in and out policy for eBGP peers (RFC8212)\n") +DEFUN_YANG(no_bgp_ebgp_requires_policy, + no_bgp_ebgp_requires_policy_cmd, + "no bgp ebgp-requires-policy", + NO_STR + "BGP specific commands\n" + "Require in and out policy for eBGP peers (RFC8212)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/ebgp-requires-policy", + NB_OP_MODIFY, "false"); + return nb_cli_apply_changes(vty, NULL); } -DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd, - "no bgp ebgp-requires-policy", - NO_STR - "BGP specific commands\n" - "Require in and out policy for eBGP peers (RFC8212)\n") +void cli_show_router_bgp_ebgp_requires_policy(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); - return CMD_SUCCESS; + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_EBGP_REQUIRES_POLICY) + vty_out(vty, " bgp ebgp-requires-policy\n"); } DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, @@ -2250,62 +2531,31 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, } /* "bgp deterministic-med" configuration. */ -DEFUN (bgp_deterministic_med, +DEFUN_YANG (bgp_deterministic_med, bgp_deterministic_med_cmd, "bgp deterministic-med", "BGP specific commands\n" "Pick the best-MED path among paths advertised from the neighboring AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { - SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); - bgp_recalculate_all_bestpaths(bgp); - } + nb_cli_enqueue_change( + vty, "./global/route-selection-options/deterministic-med", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_deterministic_med, +DEFUN_YANG (no_bgp_deterministic_med, no_bgp_deterministic_med_cmd, "no bgp deterministic-med", NO_STR "BGP specific commands\n" "Pick the best-MED path among paths advertised from the neighboring AS\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int bestpath_per_as_used; - afi_t afi; - safi_t safi; - struct peer *peer; - struct listnode *node, *nnode; + nb_cli_enqueue_change( + vty, "./global/route-selection-options/deterministic-med", + NB_OP_MODIFY, "false"); - if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) { - bestpath_per_as_used = 0; - - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - FOREACH_AFI_SAFI (afi, safi) - if (bgp_addpath_dmed_required( - peer->addpath_type[afi][safi])) { - bestpath_per_as_used = 1; - break; - } - - if (bestpath_per_as_used) - break; - } - - if (bestpath_per_as_used) { - vty_out(vty, - "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use\n"); - return CMD_WARNING_CONFIG_FAILED; - } else { - UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED); - bgp_recalculate_all_bestpaths(bgp); - } - } - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp graceful-restart mode" configuration. */ @@ -2840,13 +3090,18 @@ DEFUN (no_bgp_graceful_restart_rib_stale_time, return CMD_SUCCESS; } -static inline void bgp_initiate_graceful_shut_unshut(struct vty *vty, - struct bgp *bgp) +static inline int bgp_initiate_graceful_shut_unshut(struct bgp *bgp, + char *errmsg, + size_t errmsg_len) { bgp_static_redo_import_check(bgp); bgp_redistribute_redo(bgp); - bgp_clear_star_soft_out(vty, bgp->name); - bgp_clear_star_soft_in(vty, bgp->name); + if (bgp_clear_star_soft_out(bgp->name, errmsg, errmsg_len) < 0) + return -1; + if (bgp_clear_star_soft_in(bgp->name, errmsg, errmsg_len) < 0) + return -1; + + return 0; } static int bgp_global_graceful_shutdown_config_vty(struct vty *vty) @@ -2854,6 +3109,7 @@ static int bgp_global_graceful_shutdown_config_vty(struct vty *vty) struct listnode *node, *nnode; struct bgp *bgp; bool vrf_cfg = false; + char errmsg[BUFSIZ] = {'\0'}; if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) return CMD_SUCCESS; @@ -2879,8 +3135,13 @@ static int bgp_global_graceful_shutdown_config_vty(struct vty *vty) SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN); /* Initiate processing for all BGP instances. */ - for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) - bgp_initiate_graceful_shut_unshut(vty, bgp); + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (bgp_initiate_graceful_shut_unshut(bgp, errmsg, + sizeof(errmsg)) + < 0) + if (strlen(errmsg)) + vty_out(vty, "%s\n", errmsg); + } return CMD_SUCCESS; } @@ -2889,6 +3150,7 @@ static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty) { struct listnode *node, *nnode; struct bgp *bgp; + char errmsg[BUFSIZ] = {'\0'}; if (!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) return CMD_SUCCESS; @@ -2897,8 +3159,13 @@ static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty) UNSET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN); /* Initiate processing for all BGP instances. */ - for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) - bgp_initiate_graceful_shut_unshut(vty, bgp); + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (bgp_initiate_graceful_shut_unshut(bgp, errmsg, + sizeof(errmsg)) + < 0) + if (strlen(errmsg)) + vty_out(vty, "%s\n", errmsg); + } return CMD_SUCCESS; } @@ -2913,24 +3180,13 @@ DEFUN (bgp_graceful_shutdown, if (vty->node == CONFIG_NODE) return bgp_global_graceful_shutdown_config_vty(vty); - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* if configured globally, per-instance config is not allowed */ - if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) { - vty_out(vty, - "%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) { - SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); - bgp_initiate_graceful_shut_unshut(vty, bgp); - } + nb_cli_enqueue_change(vty, "./global/graceful-shutdown/enable", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_graceful_shutdown, +DEFUN_YANG (no_bgp_graceful_shutdown, no_bgp_graceful_shutdown_cmd, "no bgp graceful-shutdown", NO_STR @@ -2940,111 +3196,120 @@ DEFUN (no_bgp_graceful_shutdown, if (vty->node == CONFIG_NODE) return bgp_global_graceful_shutdown_deconfig_vty(vty); - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, "./global/graceful-shutdown/enable", + NB_OP_MODIFY, "false"); - /* If configured globally, cannot remove from one bgp instance */ - if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) { - vty_out(vty, - "%%Failed: bgp graceful-shutdown configured globally. Delete per-vrf not permitted\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) { - UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN); - bgp_initiate_graceful_shut_unshut(vty, bgp); - } + return nb_cli_apply_changes(vty, NULL); +} - return CMD_SUCCESS; +void cli_show_router_bgp_graceful_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " bgp graceful-shutdown\n"); } /* "bgp fast-external-failover" configuration. */ -DEFUN (bgp_fast_external_failover, +DEFUN_YANG (bgp_fast_external_failover, bgp_fast_external_failover_cmd, "bgp fast-external-failover", BGP_STR "Immediately reset session if a link to a directly connected external peer goes down\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/fast-external-failover", + NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_fast_external_failover, +DEFUN_YANG (no_bgp_fast_external_failover, no_bgp_fast_external_failover_cmd, "no bgp fast-external-failover", NO_STR BGP_STR "Immediately reset session if a link to a directly connected external peer goes down\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/fast-external-failover", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_fast_external_failover(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no bgp fast-external-failover\n"); } /* "bgp bestpath compare-routerid" configuration. */ -DEFUN (bgp_bestpath_compare_router_id, - bgp_bestpath_compare_router_id_cmd, - "bgp bestpath compare-routerid", - "BGP specific commands\n" - "Change the default bestpath selection\n" - "Compare router-id for identical EBGP paths\n") +DEFUN_YANG(bgp_bestpath_compare_router_id, + bgp_bestpath_compare_router_id_cmd, + "bgp bestpath compare-routerid", + "BGP specific commands\n" + "Change the default bestpath selection\n" + "Compare router-id for identical EBGP paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, + "./global/route-selection-options/external-compare-router-id", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_compare_router_id, - no_bgp_bestpath_compare_router_id_cmd, - "no bgp bestpath compare-routerid", - NO_STR - "BGP specific commands\n" - "Change the default bestpath selection\n" - "Compare router-id for identical EBGP paths\n") +DEFUN_YANG(no_bgp_bestpath_compare_router_id, + no_bgp_bestpath_compare_router_id_cmd, + "no bgp bestpath compare-routerid", + NO_STR + "BGP specific commands\n" + "Change the default bestpath selection\n" + "Compare router-id for identical EBGP paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, + "./global/route-selection-options/external-compare-router-id", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath as-path ignore" configuration. */ -DEFUN (bgp_bestpath_aspath_ignore, - bgp_bestpath_aspath_ignore_cmd, - "bgp bestpath as-path ignore", - "BGP specific commands\n" - "Change the default bestpath selection\n" - "AS-path attribute\n" - "Ignore as-path length in selecting a route\n") +DEFUN_YANG(bgp_bestpath_aspath_ignore, + bgp_bestpath_aspath_ignore_cmd, + "bgp bestpath as-path ignore", + "BGP specific commands\n" + "Change the default bestpath selection\n" + "AS-path attribute\n" + "Ignore as-path length in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/ignore-as-path-length", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_aspath_ignore, - no_bgp_bestpath_aspath_ignore_cmd, - "no bgp bestpath as-path ignore", - NO_STR - "BGP specific commands\n" - "Change the default bestpath selection\n" - "AS-path attribute\n" - "Ignore as-path length in selecting a route\n") +DEFUN_YANG(no_bgp_bestpath_aspath_ignore, + no_bgp_bestpath_aspath_ignore_cmd, + "no bgp bestpath as-path ignore", + NO_STR + "BGP specific commands\n" + "Change the default bestpath selection\n" + "AS-path attribute\n" + "Ignore as-path length in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/ignore-as-path-length", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath as-path confed" configuration. */ -DEFUN (bgp_bestpath_aspath_confed, +DEFUN_YANG (bgp_bestpath_aspath_confed, bgp_bestpath_aspath_confed_cmd, "bgp bestpath as-path confed", "BGP specific commands\n" @@ -3052,14 +3317,14 @@ DEFUN (bgp_bestpath_aspath_confed, "AS-path attribute\n" "Compare path lengths including confederation sets & sequences in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./global/route-selection-options/aspath-confed", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_aspath_confed, +DEFUN_YANG (no_bgp_bestpath_aspath_confed, no_bgp_bestpath_aspath_confed_cmd, "no bgp bestpath as-path confed", NO_STR @@ -3068,15 +3333,15 @@ DEFUN (no_bgp_bestpath_aspath_confed, "AS-path attribute\n" "Compare path lengths including confederation sets & sequences in selecting a route\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change(vty, + "./global/route-selection-options/aspath-confed", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath as-path multipath-relax" configuration. */ -DEFUN (bgp_bestpath_aspath_multipath_relax, +DEFUN_YANG (bgp_bestpath_aspath_multipath_relax, bgp_bestpath_aspath_multipath_relax_cmd, "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]", "BGP specific commands\n" @@ -3086,23 +3351,26 @@ DEFUN (bgp_bestpath_aspath_multipath_relax, "Generate an AS_SET\n" "Do not generate an AS_SET\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx = 0; - SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); - /* no-as-set is now the default behavior so we can silently - * ignore it */ + nb_cli_enqueue_change( + vty, "./global/route-selection-options/allow-multiple-as", + NB_OP_MODIFY, "true"); if (argv_find(argv, argc, "as-set", &idx)) - SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + nb_cli_enqueue_change( + vty, + "./global/route-selection-options/multi-path-as-set", + NB_OP_MODIFY, "true"); else - UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); + nb_cli_enqueue_change( + vty, + "./global/route-selection-options/multi-path-as-set", + NB_OP_MODIFY, "false"); - bgp_recalculate_all_bestpaths(bgp); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_aspath_multipath_relax, +DEFUN_YANG (no_bgp_bestpath_aspath_multipath_relax, no_bgp_bestpath_aspath_multipath_relax_cmd, "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]", NO_STR @@ -3113,40 +3381,46 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax, "Generate an AS_SET\n" "Do not generate an AS_SET\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX); - UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET); - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/allow-multiple-as", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/multi-path-as-set", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp log-neighbor-changes" configuration. */ -DEFUN (bgp_log_neighbor_changes, - bgp_log_neighbor_changes_cmd, - "bgp log-neighbor-changes", - "BGP specific commands\n" - "Log neighbor up/down and reset reason\n") +DEFUN_YANG(bgp_log_neighbor_changes, + bgp_log_neighbor_changes_cmd, + "bgp log-neighbor-changes", + "BGP specific commands\n" + "Log neighbor up/down and reset reason\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, "./global/global-neighbor-config/log-neighbor-changes", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_log_neighbor_changes, - no_bgp_log_neighbor_changes_cmd, - "no bgp log-neighbor-changes", - NO_STR - "BGP specific commands\n" - "Log neighbor up/down and reset reason\n") +DEFUN_YANG(no_bgp_log_neighbor_changes, + no_bgp_log_neighbor_changes_cmd, + "no bgp log-neighbor-changes", + NO_STR + "BGP specific commands\n" + "Log neighbor up/down and reset reason\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, "./global/global-neighbor-config/log-neighbor-changes", + NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath med" configuration. */ -DEFUN (bgp_bestpath_med, +DEFUN_YANG (bgp_bestpath_med, bgp_bestpath_med_cmd, "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>", "BGP specific commands\n" @@ -3157,21 +3431,30 @@ DEFUN (bgp_bestpath_med, "Treat missing MED as the least preferred one\n" "Compare MED among confederation paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx = 0; + bool confed = false; + bool worst_med = false; + + if (argv_find(argv, argc, "confed", &idx)) - SET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + confed = true; + + nb_cli_enqueue_change(vty, + "./global/route-selection-options/confed-med", + NB_OP_MODIFY, confed ? "true" : "false"); + idx = 0; if (argv_find(argv, argc, "missing-as-worst", &idx)) - SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + worst_med = true; - bgp_recalculate_all_bestpaths(bgp); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/missing-as-worst-med", + NB_OP_MODIFY, worst_med ? "true" : "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_bestpath_med, +DEFUN_YANG (no_bgp_bestpath_med, no_bgp_bestpath_med_cmd, "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>", NO_STR @@ -3183,18 +3466,21 @@ DEFUN (no_bgp_bestpath_med, "Treat missing MED as the least preferred one\n" "Compare MED among confederation paths\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx = 0; + if (argv_find(argv, argc, "confed", &idx)) - UNSET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED); + nb_cli_enqueue_change( + vty, "./global/route-selection-options/confed-med", + NB_OP_MODIFY, "false"); + idx = 0; if (argv_find(argv, argc, "missing-as-worst", &idx)) - UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST); + nb_cli_enqueue_change( + vty, + "./global/route-selection-options/missing-as-worst-med", + NB_OP_MODIFY, "false"); - bgp_recalculate_all_bestpaths(bgp); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } /* "bgp bestpath bandwidth" configuration. */ @@ -3288,29 +3574,38 @@ DEFUN (bgp_default_ipv4_unicast, } /* Display hostname in certain command outputs */ -DEFUN (bgp_default_show_hostname, +DEFUN_YANG (bgp_default_show_hostname, bgp_default_show_hostname_cmd, "bgp default show-hostname", "BGP specific commands\n" "Configure BGP defaults\n" "Show hostname in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/show-hostname", NB_OP_MODIFY, + "true"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_default_show_hostname, - no_bgp_default_show_hostname_cmd, - "no bgp default show-hostname", - NO_STR - "BGP specific commands\n" - "Configure BGP defaults\n" - "Show hostname in certain command outputs\n") +DEFUN_YANG(no_bgp_default_show_hostname, + no_bgp_default_show_hostname_cmd, + "no bgp default show-hostname", + NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "Show hostname in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/show-hostname", NB_OP_MODIFY, + "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SHOW_HOSTNAME) + vty_out(vty, " bgp default show-hostname\n"); } /* Display hostname in certain command outputs */ @@ -3321,9 +3616,10 @@ DEFUN (bgp_default_show_nexthop_hostname, "Configure BGP defaults\n" "Show hostname for nexthop in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/show-nexthop-hostname", + NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); } DEFUN (no_bgp_default_show_nexthop_hostname, @@ -3334,26 +3630,32 @@ DEFUN (no_bgp_default_show_nexthop_hostname, "Configure BGP defaults\n" "Show hostname for nexthop in certain command outputs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/show-nexthop-hostname", + NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_show_nexthop_hostname(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SHOW_HOSTNAME) + vty_out(vty, " bgp default show-nexthop-hostname\n"); } /* "bgp network import-check" configuration. */ -DEFUN (bgp_network_import_check, - bgp_network_import_check_cmd, - "bgp network import-check", - "BGP specific commands\n" - "BGP network command\n" - "Check BGP network route exists in IGP\n") +DEFUN_YANG(bgp_network_import_check, + bgp_network_import_check_cmd, + "bgp network import-check", + "BGP specific commands\n" + "BGP network command\n" + "Check BGP network route exists in IGP\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) { - SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); - bgp_static_redo_import_check(bgp); - } + nb_cli_enqueue_change(vty, "./global/import-check", NB_OP_MODIFY, + "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd, @@ -3363,162 +3665,195 @@ ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd, "Check BGP network route exists in IGP\n" "Match route precisely\n") -DEFUN (no_bgp_network_import_check, - no_bgp_network_import_check_cmd, - "no bgp network import-check", - NO_STR - "BGP specific commands\n" - "BGP network command\n" - "Check BGP network route exists in IGP\n") +DEFUN_YANG(no_bgp_network_import_check, + no_bgp_network_import_check_cmd, + "no bgp network import-check", + NO_STR + "BGP specific commands\n" + "BGP network command\n" + "Check BGP network route exists in IGP\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) { - UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK); - bgp_static_redo_import_check(bgp); - } + nb_cli_enqueue_change(vty, "./global/import-check", NB_OP_MODIFY, + "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (bgp_default_local_preference, - bgp_default_local_preference_cmd, - "bgp default local-preference (0-4294967295)", - "BGP specific commands\n" - "Configure BGP defaults\n" - "local preference (higher=more preferred)\n" - "Configure default local preference value\n") +void cli_show_router_bgp_import_check(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_number = 3; - uint32_t local_pref; + if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_IMPORT_CHECK) + vty_out(vty, " bgp network import-check\n"); +} - local_pref = strtoul(argv[idx_number]->arg, NULL, 10); +DEFUN_YANG(bgp_default_local_preference, + bgp_default_local_preference_cmd, + "bgp default local-preference (0-4294967295)", + "BGP specific commands\n" + "Configure BGP defaults\n" + "local preference (higher=more preferred)\n" + "Configure default local preference value\n") +{ + int idx_number = 3; - bgp_default_local_preference_set(bgp, local_pref); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, "./global/local-pref", NB_OP_MODIFY, + argv[idx_number]->arg); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_default_local_preference, - no_bgp_default_local_preference_cmd, - "no bgp default local-preference [(0-4294967295)]", - NO_STR - "BGP specific commands\n" - "Configure BGP defaults\n" - "local preference (higher=more preferred)\n" - "Configure default local preference value\n") +DEFUN_YANG(no_bgp_default_local_preference, + no_bgp_default_local_preference_cmd, + "no bgp default local-preference [(0-4294967295)]", + NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "local preference (higher=more preferred)\n" + "Configure default local preference value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_default_local_preference_unset(bgp); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, "./global/local-pref", NB_OP_MODIFY, NULL); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_bgp_local_pref(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " bgp default local-preference %u\n", + yang_dnode_get_uint32(dnode, NULL)); +} -DEFUN (bgp_default_subgroup_pkt_queue_max, - bgp_default_subgroup_pkt_queue_max_cmd, - "bgp default subgroup-pkt-queue-max (20-100)", - "BGP specific commands\n" - "Configure BGP defaults\n" - "subgroup-pkt-queue-max\n" - "Configure subgroup packet queue max\n") + +DEFUN_YANG(bgp_default_subgroup_pkt_queue_max, + bgp_default_subgroup_pkt_queue_max_cmd, + "bgp default subgroup-pkt-queue-max (20-100)", + "BGP specific commands\n" + "Configure BGP defaults\n" + "subgroup-pkt-queue-max\n" + "Configure subgroup packet queue max\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - uint32_t max_size; - max_size = strtoul(argv[idx_number]->arg, NULL, 10); + nb_cli_enqueue_change( + vty, + "./global/global-update-group-config/subgroup-pkt-queue-size", + NB_OP_MODIFY, argv[idx_number]->arg); - bgp_default_subgroup_pkt_queue_max_set(bgp, max_size); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_default_subgroup_pkt_queue_max, - no_bgp_default_subgroup_pkt_queue_max_cmd, - "no bgp default subgroup-pkt-queue-max [(20-100)]", - NO_STR - "BGP specific commands\n" - "Configure BGP defaults\n" - "subgroup-pkt-queue-max\n" - "Configure subgroup packet queue max\n") +DEFUN_YANG(no_bgp_default_subgroup_pkt_queue_max, + no_bgp_default_subgroup_pkt_queue_max_cmd, + "no bgp default subgroup-pkt-queue-max [(20-100)]", + NO_STR + "BGP specific commands\n" + "Configure BGP defaults\n" + "subgroup-pkt-queue-max\n" + "Configure subgroup packet queue max\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_default_subgroup_pkt_queue_max_unset(bgp); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, + "./global/global-update-group-config/subgroup-pkt-queue-size", + NB_OP_MODIFY, NULL); + + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_global_update_group_config_subgroup_pkt_queue_size( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n", + yang_dnode_get_uint32(dnode, NULL)); +} -DEFUN (bgp_rr_allow_outbound_policy, - bgp_rr_allow_outbound_policy_cmd, - "bgp route-reflector allow-outbound-policy", - "BGP specific commands\n" - "Allow modifications made by out route-map\n" - "on ibgp neighbors\n") +DEFUN_YANG(bgp_rr_allow_outbound_policy, + bgp_rr_allow_outbound_policy_cmd, + "bgp route-reflector allow-outbound-policy", + "BGP specific commands\n" + "Allow modifications made by out route-map\n" + "on ibgp neighbors\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + nb_cli_enqueue_change(vty, + "./global/route-reflector/allow-outbound-policy", + NB_OP_MODIFY, "true"); - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { - SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); - update_group_announce_rrclients(bgp); - bgp_clear_star_soft_out(vty, bgp->name); - } + return nb_cli_apply_changes(vty, NULL); +} - return CMD_SUCCESS; +DEFUN_YANG(no_bgp_rr_allow_outbound_policy, + no_bgp_rr_allow_outbound_policy_cmd, + "no bgp route-reflector allow-outbound-policy", + NO_STR + "BGP specific commands\n" + "Allow modifications made by out route-map\n" + "on ibgp neighbors\n") +{ + nb_cli_enqueue_change(vty, + "./global/route-reflector/allow-outbound-policy", + NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_rr_allow_outbound_policy, - no_bgp_rr_allow_outbound_policy_cmd, - "no bgp route-reflector allow-outbound-policy", - NO_STR - "BGP specific commands\n" - "Allow modifications made by out route-map\n" - "on ibgp neighbors\n") + +void cli_show_router_global_neighbor_config(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) { - VTY_DECLVAR_CONTEXT(bgp, bgp); + uint32_t write_quanta, read_quanta; - if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { - UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY); - update_group_announce_rrclients(bgp); - bgp_clear_star_soft_out(vty, bgp->name); + if (yang_dnode_get_bool(dnode, "./log-neighbor-changes")) + vty_out(vty, " bgp log-neighbor-changes\n"); + + if (yang_dnode_exists(dnode, "./dynamic-neighbors-limit")) { + uint32_t listen_limit = yang_dnode_get_uint32( + dnode, "./dynamic-neighbors-limit"); + vty_out(vty, " bgp listen limit %u\n", listen_limit); } - return CMD_SUCCESS; + write_quanta = yang_dnode_get_uint32( + dnode, "./packet-quanta-config/wpkt-quanta"); + if (write_quanta != BGP_WRITE_PACKET_MAX) + vty_out(vty, " write-quanta %d\n", write_quanta); + + read_quanta = yang_dnode_get_uint32( + dnode, "./packet-quanta-config/rpkt-quanta"); + + if (read_quanta != BGP_READ_PACKET_MAX) + vty_out(vty, " read-quanta %d\n", read_quanta); } -DEFUN (bgp_listen_limit, - bgp_listen_limit_cmd, - "bgp listen limit (1-5000)", - "BGP specific commands\n" - "BGP Dynamic Neighbors listen commands\n" - "Maximum number of BGP Dynamic Neighbors that can be created\n" - "Configure Dynamic Neighbors listen limit value\n") +DEFUN_YANG(bgp_listen_limit, + bgp_listen_limit_cmd, + "bgp listen limit (1-5000)", + "BGP specific commands\n" + "BGP Dynamic Neighbors listen commands\n" + "Maximum number of BGP Dynamic Neighbors that can be created\n" + "Configure Dynamic Neighbors listen limit value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; - int listen_limit; - listen_limit = strtoul(argv[idx_number]->arg, NULL, 10); + nb_cli_enqueue_change( + vty, "./global/global-neighbor-config/dynamic-neighbors-limit", + NB_OP_MODIFY, argv[idx_number]->arg); - bgp_listen_limit_set(bgp, listen_limit); - - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_listen_limit, - no_bgp_listen_limit_cmd, - "no bgp listen limit [(1-5000)]", - NO_STR - "BGP specific commands\n" - "BGP Dynamic Neighbors listen commands\n" - "Maximum number of BGP Dynamic Neighbors that can be created\n" - "Configure Dynamic Neighbors listen limit value\n") +DEFUN_YANG(no_bgp_listen_limit, + no_bgp_listen_limit_cmd, + "no bgp listen limit [(1-5000)]", + NO_STR + "BGP specific commands\n" + "BGP Dynamic Neighbors listen commands\n" + "Maximum number of BGP Dynamic Neighbors that can be created\n" + "Configure Dynamic Neighbors listen limit value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_listen_limit_unset(bgp); - return CMD_SUCCESS; + nb_cli_enqueue_change( + vty, "./global/global-neighbor-config/dynamic-neighbors-limit", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } @@ -3680,7 +4015,6 @@ void bgp_config_write_listen(struct vty *vty, struct bgp *bgp) struct listnode *node, *nnode, *rnode, *nrnode; struct prefix *range; afi_t afi; - char buf[PREFIX2STR_BUFFER]; if (bgp->dynamic_neighbors_limit != BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT) vty_out(vty, " bgp listen limit %d\n", @@ -3690,43 +4024,48 @@ void bgp_config_write_listen(struct vty *vty, struct bgp *bgp) for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (ALL_LIST_ELEMENTS(group->listen_range[afi], rnode, nrnode, range)) { - prefix2str(range, buf, sizeof(buf)); vty_out(vty, - " bgp listen range %s peer-group %s\n", - buf, group->name); + " bgp listen range %pFX peer-group %s\n", + range, group->name); } } } } -DEFUN (bgp_disable_connected_route_check, - bgp_disable_connected_route_check_cmd, - "bgp disable-ebgp-connected-route-check", - "BGP specific commands\n" - "Disable checking if nexthop is connected on ebgp sessions\n") +DEFUN_YANG(bgp_disable_connected_route_check, + bgp_disable_connected_route_check_cmd, + "bgp disable-ebgp-connected-route-check", + "BGP specific commands\n" + "Disable checking if nexthop is connected on ebgp sessions\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, + "./global/ebgp-multihop-connected-route-check", + NB_OP_MODIFY, "true"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_bgp_disable_connected_route_check, - no_bgp_disable_connected_route_check_cmd, - "no bgp disable-ebgp-connected-route-check", - NO_STR - "BGP specific commands\n" - "Disable checking if nexthop is connected on ebgp sessions\n") +DEFUN_YANG(no_bgp_disable_connected_route_check, + no_bgp_disable_connected_route_check_cmd, + "no bgp disable-ebgp-connected-route-check", + NO_STR + "BGP specific commands\n" + "Disable checking if nexthop is connected on ebgp sessions\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK); - bgp_clear_star_soft_in(vty, bgp->name); + nb_cli_enqueue_change(vty, + "./global/ebgp-multihop-connected-route-check", + NB_OP_MODIFY, "false"); - return CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } +void cli_show_router_global_ebgp_multihop_connected_route_check( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " bgp disable-ebgp-connected-route-check\n"); +} static int peer_remote_as_vty(struct vty *vty, const char *peer_str, const char *as_str, afi_t afi, safi_t safi) @@ -3792,17 +4131,25 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str, return bgp_vty_return(vty, ret); } -DEFUN (bgp_default_shutdown, - bgp_default_shutdown_cmd, - "[no] bgp default shutdown", - NO_STR - BGP_STR - "Configure BGP defaults\n" - "Apply administrative shutdown to newly configured peers\n") +DEFUN_YANG(bgp_default_shutdown, + bgp_default_shutdown_cmd, + "[no] bgp default shutdown", + NO_STR BGP_STR + "Configure BGP defaults\n" + "Apply administrative shutdown to newly configured peers\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->autoshutdown = !strmatch(argv[0]->text, "no"); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, "./global/default-shutdown", NB_OP_MODIFY, + strmatch(argv[0]->text, "no") ? "false" : "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_router_bgp_default_shutdown(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " bgp default shutdown\n"); } DEFPY(bgp_shutdown_msg, bgp_shutdown_msg_cmd, "bgp shutdown message MSG...", @@ -6828,6 +7175,68 @@ ALIAS_HIDDEN(no_neighbor_filter_list, no_neighbor_filter_list_hidden_cmd, "Filter incoming routes\n" "Filter outgoing routes\n") +/* Set advertise-map to the peer. */ +static int peer_advertise_map_set_vty(struct vty *vty, const char *ip_str, + afi_t afi, safi_t safi, + const char *advertise_str, + const char *condition_str, bool condition, + bool set) +{ + int ret = CMD_WARNING_CONFIG_FAILED; + struct peer *peer; + struct route_map *advertise_map; + struct route_map *condition_map; + + peer = peer_and_group_lookup_vty(vty, ip_str); + if (!peer) + return ret; + + condition_map = route_map_lookup_warn_noexist(vty, condition_str); + advertise_map = route_map_lookup_warn_noexist(vty, advertise_str); + + if (set) + ret = peer_advertise_map_set(peer, afi, safi, advertise_str, + advertise_map, condition_str, + condition_map, condition); + else + ret = peer_advertise_map_unset(peer, afi, safi, advertise_str, + advertise_map, condition_str, + condition_map, condition); + + return bgp_vty_return(vty, ret); +} + +DEFPY (neighbor_advertise_map, + neighbor_advertise_map_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$exist WORD$condition_str", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Route-map to conditionally advertise routes\n" + "Name of advertise map\n" + "Advertise routes only if prefixes in exist-map are installed in BGP table\n" + "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n" + "Name of the exist or non exist map\n") +{ + bool condition = CONDITION_EXIST; + + if (!strcmp(exist, "non-exist-map")) + condition = CONDITION_NON_EXIST; + + return peer_advertise_map_set_vty(vty, neighbor, bgp_node_afi(vty), + bgp_node_safi(vty), advertise_str, + condition_str, condition, !no); +} + +ALIAS_HIDDEN(neighbor_advertise_map, neighbor_advertise_map_hidden_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$exist WORD$condition_str", + NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 + "Route-map to conditionally advertise routes\n" + "Name of advertise map\n" + "Advertise routes only if prefixes in exist-map are installed in BGP table\n" + "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n" + "Name of the exist or non exist map\n") + /* Set route-map to the peer. */ static int peer_route_map_set_vty(struct vty *vty, const char *ip_str, afi_t afi, safi_t safi, const char *name_str, @@ -7675,6 +8084,33 @@ static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, return CMD_SUCCESS; } +bool vpn_policy_check_import(struct bgp *bgp, afi_t afi, safi_t safi, + bool v2vimport, char *errmsg, size_t errmsg_len) +{ + if (!v2vimport) { + if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_VRF_IMPORT) + || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_VRF_EXPORT)) { + snprintf( + errmsg, errmsg_len, "%s", + "%% error: Please unconfigure import vrf commands before using vpn commands"); + return false; + } + } else { + if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) + || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) { + snprintf( + errmsg, errmsg_len, "%s", + "%% error: Please unconfigure vpn to vrf commands before using import vrf commands"); + return false; + } + } + return true; +} + /* * v2vimport is true if we are handling a `import vrf ...` command */ @@ -7717,57 +8153,45 @@ static afi_t vpn_policy_getafi(struct vty *vty, struct bgp *bgp, bool v2vimport) return afi; } -DEFPY (af_rd_vpn_export, - af_rd_vpn_export_cmd, - "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str", - NO_STR - "Specify route distinguisher\n" - "Between current address-family and vpn\n" - "For routes leaked from current address-family to vpn\n" - "Route Distinguisher (<as-number>:<number> | <ip-address>:<number>)\n") +DEFPY_YANG( + af_rd_vpn_export, + af_rd_vpn_export_cmd, + "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str", + NO_STR + "Specify route distinguisher\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n" + "Route Distinguisher (<as-number>:<number> | <ip-address>:<number>)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct prefix_rd prd; - int ret; + char base_xpath[XPATH_MAXLEN]; afi_t afi; + safi_t safi; int idx = 0; - bool yes = true; - - if (argv_find(argv, argc, "no", &idx)) - yes = false; - if (yes) { - ret = str2prefix_rd(rd_str, &prd); - if (!ret) { - vty_out(vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - afi = vpn_policy_getafi(vty, bgp, false); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); - /* - * pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, "./rd", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, "./rd", NB_OP_MODIFY, rd_str); - if (yes) { - bgp->vpn_policy[afi].tovpn_rd = prd; - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_RD_SET); - } else { - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_RD_SET); - } + return nb_cli_apply_changes(vty, base_xpath); +} - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; - return CMD_SUCCESS; + vty_out(vty, "%*srd vpn export %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); } ALIAS (af_rd_vpn_export, @@ -7868,7 +8292,7 @@ ALIAS (af_label_vpn_export, "Between current address-family and vpn\n" "For routes leaked from current address-family to vpn\n") -DEFPY (af_nexthop_vpn_export, +DEFPY_YANG (af_nexthop_vpn_export, af_nexthop_vpn_export_cmd, "[no] nexthop vpn export [<A.B.C.D|X:X::X:X>$nexthop_su]", NO_STR @@ -7878,8 +8302,10 @@ DEFPY (af_nexthop_vpn_export, "IPv4 prefix\n" "IPv6 prefix\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + char base_xpath[XPATH_MAXLEN]; afi_t afi; + safi_t safi; + int idx = 0; struct prefix p; if (!no) { @@ -7891,30 +8317,31 @@ DEFPY (af_nexthop_vpn_export, return CMD_WARNING_CONFIG_FAILED; } - afi = vpn_policy_getafi(vty, bgp, false); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - /* - * pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); - if (!no) { - bgp->vpn_policy[afi].tovpn_nexthop = p; - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); - } else { - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); - } + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, "./nexthop", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, "./nexthop", NB_OP_MODIFY, + nexthop_su_str); - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); + return nb_cli_apply_changes(vty, base_xpath); +} - return CMD_SUCCESS; +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; + + vty_out(vty, "%*snexthop vpn export %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); } static int vpn_policy_getdirs(struct vty *vty, const char *dstr, int *dodir) @@ -8015,7 +8442,7 @@ ALIAS (af_rt_vpn_imexport, "For routes leaked from current address-family to vpn\n" "both import and export\n") -DEFPY (af_route_map_vpn_imexport, +DEFPY_YANG (af_route_map_vpn_imexport, af_route_map_vpn_imexport_cmd, /* future: "route-map <vpn|evpn|vrf NAME> <import|export> RMAP" */ "[no] route-map vpn <import|export>$direction_str RMAP$rmap_str", @@ -8026,53 +8453,54 @@ DEFPY (af_route_map_vpn_imexport, "For routes leaked from current address-family to vpn\n" "name of route-map\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; - vpn_policy_direction_t dir; + char base_xpath[XPATH_MAXLEN]; afi_t afi; + safi_t safi; int idx = 0; - bool yes = true; - - if (argv_find(argv, argc, "no", &idx)) - yes = false; - afi = vpn_policy_getafi(vty, bgp, false); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; - - ret = vpn_policy_getdirs(vty, direction_str, dodir); - if (ret != CMD_SUCCESS) - return ret; + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); - for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { - if (!dodir[dir]) - continue; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); + + if (argv_find(argv, argc, "no", &idx)) { + if (!strcmp(direction_str, "import")) + nb_cli_enqueue_change(vty, "./rmap-import", + NB_OP_DESTROY, NULL); + else if (!strcmp(direction_str, "export")) + nb_cli_enqueue_change(vty, "./rmap-export", + NB_OP_DESTROY, NULL); + } else { + if (!strcmp(direction_str, "import")) + nb_cli_enqueue_change(vty, "./rmap-import", + NB_OP_MODIFY, rmap_str); + if (!strcmp(direction_str, "export")) + nb_cli_enqueue_change(vty, "./rmap-export", + NB_OP_MODIFY, rmap_str); + } + return nb_cli_apply_changes(vty, base_xpath); +} - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; - if (yes) { - if (bgp->vpn_policy[afi].rmap_name[dir]) - XFREE(MTYPE_ROUTE_MAP_NAME, - bgp->vpn_policy[afi].rmap_name[dir]); - bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP( - MTYPE_ROUTE_MAP_NAME, rmap_str); - bgp->vpn_policy[afi].rmap[dir] = - route_map_lookup_warn_noexist(vty, rmap_str); - if (!bgp->vpn_policy[afi].rmap[dir]) - return CMD_SUCCESS; - } else { - if (bgp->vpn_policy[afi].rmap_name[dir]) - XFREE(MTYPE_ROUTE_MAP_NAME, - bgp->vpn_policy[afi].rmap_name[dir]); - bgp->vpn_policy[afi].rmap_name[dir] = NULL; - bgp->vpn_policy[afi].rmap[dir] = NULL; - } + vty_out(vty, "%*sroute-map vpn import %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); +} - vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); - } +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + int indent = 2; - return CMD_SUCCESS; + vty_out(vty, "%*sroute-map vpn import %s\n", indent, "", + yang_dnode_get_string(dnode, NULL)); } ALIAS (af_route_map_vpn_imexport, @@ -8169,24 +8597,18 @@ DEFPY(af_no_import_vrf_route_map, af_no_import_vrf_route_map_cmd, return CMD_SUCCESS; } -DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, - "[no] import vrf VIEWVRFNAME$import_name", - NO_STR - "Import routes from another VRF\n" - "VRF to import from\n" - "The name of the VRF\n") +DEFPY_YANG(bgp_imexport_vrf, + bgp_imexport_vrf_cmd, + "[no] import vrf VIEWVRFNAME$import_name", + NO_STR + "Import routes from another VRF\n" + "VRF to import from\n" + "The name of the VRF\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct listnode *node; - struct bgp *vrf_bgp, *bgp_default; - int32_t ret = 0; - as_t as = bgp->as; - bool remove = false; - int32_t idx = 0; - char *vname; - enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF; + char base_xpath[XPATH_MAXLEN]; safi_t safi; afi_t afi; + int32_t idx = 0; if (import_name == NULL) { vty_out(vty, "%% Missing import name\n"); @@ -8198,70 +8620,32 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, return CMD_WARNING; } - if (argv_find(argv, argc, "no", &idx)) - remove = true; - - afi = vpn_policy_getafi(vty, bgp, true); - if (afi == AFI_MAX) - return CMD_WARNING_CONFIG_FAILED; - + afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type) - && (strcmp(import_name, VRF_DEFAULT_NAME) == 0)) - || (bgp->name && (strcmp(import_name, bgp->name) == 0))) { - vty_out(vty, "%% Cannot %s vrf %s into itself\n", - remove ? "unimport" : "import", import_name); - return CMD_WARNING; - } - - bgp_default = bgp_get_default(); - if (!bgp_default) { - /* Auto-create assuming the same AS */ - ret = bgp_get_vty(&bgp_default, &as, NULL, - BGP_INSTANCE_TYPE_DEFAULT); - - if (ret) { - vty_out(vty, - "VRF default is not configured as a bgp instance\n"); - return CMD_WARNING; - } - } - - vrf_bgp = bgp_lookup_by_name(import_name); - if (!vrf_bgp) { - if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) - vrf_bgp = bgp_default; - else - /* Auto-create assuming the same AS */ - ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); - - if (ret) { - vty_out(vty, - "VRF %s is not configured as a bgp instance\n", - import_name); - return CMD_WARNING; - } - } + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/import-vrf-list[vrf='%s']", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi), import_name); - if (remove) { - vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi); - } else { - /* Already importing from "import_vrf"? */ - for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node, - vname)) { - if (strcmp(vname, import_name) == 0) - return CMD_WARNING; - } + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - vrf_import_from_vrf(bgp, vrf_bgp, afi, safi); - } + return nb_cli_apply_changes(vty, base_xpath); +} - return CMD_SUCCESS; +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + vty_out(vty, " import vrf %s\n", + yang_dnode_get_string(dnode, "./vrf")); } /* This command is valid only in a bgp vrf instance or the default instance */ -DEFPY (bgp_imexport_vpn, +DEFPY_YANG (bgp_imexport_vpn, bgp_imexport_vpn_cmd, "[no] <import|export>$direction_str vpn", NO_STR @@ -8269,60 +8653,51 @@ DEFPY (bgp_imexport_vpn, "Export routes from this address-family\n" "to/from default instance VPN RIB\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int previous_state; - afi_t afi; + char base_xpath[XPATH_MAXLEN]; safi_t safi; - int idx = 0; - bool yes = true; - int flag; - vpn_policy_direction_t dir; - - if (argv_find(argv, argc, "no", &idx)) - yes = false; - - if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type && - BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { - - vty_out(vty, "%% import|export vpn valid only for bgp vrf or default instance\n"); - return CMD_WARNING_CONFIG_FAILED; - } + afi_t afi; + int32_t idx = 0; afi = bgp_node_afi(vty); safi = bgp_node_safi(vty); - if ((SAFI_UNICAST != safi) || ((AFI_IP != afi) && (AFI_IP6 != afi))) { - vty_out(vty, "%% import|export vpn valid only for unicast ipv4|ipv6\n"); - return CMD_WARNING_CONFIG_FAILED; - } if (!strcmp(direction_str, "import")) { - flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT; - dir = BGP_VPN_POLICY_DIR_FROMVPN; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/import-vpn", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); } else if (!strcmp(direction_str, "export")) { - flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT; - dir = BGP_VPN_POLICY_DIR_TOVPN; + snprintf( + base_xpath, sizeof(base_xpath), + "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/export-vpn", + yang_afi_safi_value2identity(afi, safi), + bgp_afi_safi_get_container_str(afi, safi)); } else { vty_out(vty, "%% unknown direction %s\n", direction_str); return CMD_WARNING_CONFIG_FAILED; } - previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag); + if (argv_find(argv, argc, "no", &idx)) + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, "true"); - if (yes) { - SET_FLAG(bgp->af_flags[afi][safi], flag); - if (!previous_state) { - /* trigger export current vrf */ - vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); - } - } else { - if (previous_state) { - /* trigger un-export current vrf */ - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); - } - UNSET_FLAG(bgp->af_flags[afi][safi], flag); - } + return nb_cli_apply_changes(vty, base_xpath); +} - return CMD_SUCCESS; +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " import vpn\n"); +} + +void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + if (yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " export vpn\n"); } DEFPY (af_routetarget_import, @@ -8388,6 +8763,51 @@ DEFPY (af_routetarget_import, return CMD_SUCCESS; } +void cli_show_bgp_global_afi_safi_header(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults) +{ + const char *af_name; + afi_t afi; + safi_t safi; + + af_name = yang_dnode_get_string(dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + vty_out(vty, " !\n address-family "); + if (afi == AFI_IP) { + if (safi == SAFI_UNICAST) + vty_out(vty, "ipv4 unicast"); + else if (safi == SAFI_LABELED_UNICAST) + vty_out(vty, "ipv4 labeled-unicast"); + else if (safi == SAFI_MULTICAST) + vty_out(vty, "ipv4 multicast"); + else if (safi == SAFI_MPLS_VPN) + vty_out(vty, "ipv4 vpn"); + else if (safi == SAFI_ENCAP) + vty_out(vty, "ipv4 encap"); + else if (safi == SAFI_FLOWSPEC) + vty_out(vty, "ipv4 flowspec"); + } else if (afi == AFI_IP6) { + if (safi == SAFI_UNICAST) + vty_out(vty, "ipv6 unicast"); + else if (safi == SAFI_LABELED_UNICAST) + vty_out(vty, "ipv6 labeled-unicast"); + else if (safi == SAFI_MULTICAST) + vty_out(vty, "ipv6 multicast"); + else if (safi == SAFI_MPLS_VPN) + vty_out(vty, "ipv6 vpn"); + else if (safi == SAFI_ENCAP) + vty_out(vty, "ipv6 encap"); + else if (safi == SAFI_FLOWSPEC) + vty_out(vty, "ipv6 flowspec"); + } else if (afi == AFI_L2VPN) { + if (safi == SAFI_EVPN) + vty_out(vty, "l2vpn evpn"); + } + vty_out(vty, "\n"); +} + DEFUN_NOSH (address_family_ipv4_safi, address_family_ipv4_safi_cmd, "address-family ipv4 [<unicast|multicast|vpn|labeled-unicast|flowspec>]", @@ -8396,19 +8816,28 @@ DEFUN_NOSH (address_family_ipv4_safi, BGP_SAFI_WITH_LABEL_HELP_STR) { + safi_t safi = SAFI_UNICAST; + const struct lyd_node *vrf_dnode, *bgp_glb_dnode; + const char *vrf_name = NULL; + if (argc == 3) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + safi = bgp_vty_safi_from_str(argv[2]->text); + + bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode, + VTY_CURR_XPATH); + vrf_dnode = yang_dnode_get_parent(bgp_glb_dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + + if (!strmatch(vrf_name, VRF_DEFAULT_NAME) && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); return CMD_WARNING_CONFIG_FAILED; } - vty->node = bgp_node_type(AFI_IP, safi); - } else - vty->node = BGP_IPV4_NODE; + } + vty->node = bgp_node_type(AFI_IP, safi); return CMD_SUCCESS; } @@ -8420,19 +8849,27 @@ DEFUN_NOSH (address_family_ipv6_safi, "Address Family\n" BGP_SAFI_WITH_LABEL_HELP_STR) { + safi_t safi = SAFI_UNICAST; + const struct lyd_node *vrf_dnode, *bgp_glb_dnode; + const char *vrf_name = NULL; + if (argc == 3) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + safi = bgp_vty_safi_from_str(argv[2]->text); + bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode, + VTY_CURR_XPATH); + vrf_dnode = yang_dnode_get_parent(bgp_glb_dnode, + "control-plane-protocol"); + vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf"); + + if (!strmatch(vrf_name, VRF_DEFAULT_NAME) && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); return CMD_WARNING_CONFIG_FAILED; } - vty->node = bgp_node_type(AFI_IP6, safi); - } else - vty->node = BGP_IPV6_NODE; + } + vty->node = bgp_node_type(AFI_IP6, safi); return CMD_SUCCESS; } @@ -8489,6 +8926,13 @@ DEFUN_NOSH (exit_address_family, return CMD_SUCCESS; } +void cli_show_bgp_global_afi_safi_header_end(struct vty *vty, + struct lyd_node *dnode + __attribute__((__unused__))) +{ + vty_out(vty, " exit-address-family\n"); +} + /* Recalculate bestpath and re-advertise a prefix */ static int bgp_clear_prefix(struct vty *vty, const char *view_name, const char *ip_str, afi_t afi, safi_t safi, @@ -8603,6 +9047,8 @@ DEFUN (clear_ip_bgp_all, char *clr_arg = NULL; int idx = 0; + char errmsg[BUFSIZ] = {'\0'}; + int ret; /* clear [ip] bgp */ if (argv_find(argv, argc, "ip", &idx)) @@ -8667,7 +9113,12 @@ DEFUN (clear_ip_bgp_all, } else clr_type = BGP_CLEAR_SOFT_NONE; - return bgp_clear_vty(vty, vrf, afi, safi, clr_sort, clr_type, clr_arg); + ret = bgp_clear_vty(vrf, afi, safi, clr_sort, clr_type, clr_arg, errmsg, + sizeof(errmsg)); + if (ret != NB_OK) + vty_out(vty, "Error description: %s\n", errmsg); + + return ret; } DEFUN (clear_ip_bgp_prefix, @@ -8855,10 +9306,14 @@ DEFUN (show_bgp_vrfs, int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) ? -1 : (int64_t)bgp->vrf_id; + char buf[BUFSIZ] = {0}; + json_object_string_add(json_vrf, "type", type); json_object_int_add(json_vrf, "vrfId", vrf_id_ui); json_object_string_add(json_vrf, "routerId", - inet_ntoa(bgp->router_id)); + inet_ntop(AF_INET, + &bgp->router_id, buf, + sizeof(buf))); json_object_int_add(json_vrf, "numConfiguredPeers", peers_cfg); json_object_int_add(json_vrf, "numEstablishedPeers", @@ -8873,13 +9328,11 @@ DEFUN (show_bgp_vrfs, bgp->vrf_id)); json_object_object_add(json_vrfs, name, json_vrf); } else { - vty_out(vty, - "%4s %-5d %-16s %-9u %-10u %-37s\n", + vty_out(vty, "%4s %-5d %-16pI4 %-9u %-10u %-37s\n", type, bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id, - inet_ntoa(bgp->router_id), peers_cfg, - peers_estb, name); + &bgp->router_id, peers_cfg, peers_estb, name); vty_out(vty,"%11s %-16u %-21s %-20s\n", " ", bgp->l3vni, prefix_mac2str(&bgp->rmac, buf, sizeof(buf)), @@ -8924,8 +9377,7 @@ static void show_tip_entry(struct hash_bucket *bucket, void *args) struct vty *vty = (struct vty *)args; struct tip_addr *tip = (struct tip_addr *)bucket->data; - vty_out(vty, "addr: %s, count: %d\n", inet_ntoa(tip->addr), - tip->refcnt); + vty_out(vty, "addr: %pI4, count: %d\n", &tip->addr, tip->refcnt); } static void bgp_show_martian_nexthops(struct vty *vty, struct bgp *bgp) @@ -9390,9 +9842,12 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, /* Usage summary and header */ if (use_json) { + char buf[BUFSIZ] = {0}; + json_object_string_add( json, "routerId", - inet_ntoa(bgp->router_id)); + inet_ntop(AF_INET, &bgp->router_id, buf, + sizeof(buf))); json_object_int_add(json, "as", bgp->as); json_object_int_add(json, "vrfId", vrf_id_ui); json_object_string_add( @@ -9403,8 +9858,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, : bgp->name); } else { vty_out(vty, - "BGP router identifier %s, local AS number %u vrf-id %d", - inet_ntoa(bgp->router_id), bgp->as, + "BGP router identifier %pI4, local AS number %u vrf-id %d", + &bgp->router_id, bgp->as, bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id); @@ -10486,6 +10941,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, json_object *json_prefA = NULL; json_object *json_prefB = NULL; json_object *json_addr = NULL; + json_object *json_advmap = NULL; if (use_json) { json_addr = json_object_new_object(); @@ -10760,6 +11216,26 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, "selectiveUnsuppressRouteMap", filter->usmap.name); + /* advertise-map */ + if (filter->advmap.aname) { + json_advmap = json_object_new_object(); + json_object_string_add(json_advmap, "condition", + filter->advmap.condition + ? "EXIST" + : "NON_EXIST"); + json_object_string_add(json_advmap, "conditionMap", + filter->advmap.cname); + json_object_string_add(json_advmap, "advertiseMap", + filter->advmap.aname); + json_object_string_add(json_advmap, "advertiseStatus", + filter->advmap.update_type + == ADVERTISE + ? "Advertise" + : "Withdraw"); + json_object_object_add(json_addr, "advertiseMap", + json_advmap); + } + /* Receive prefix count */ json_object_int_add(json_addr, "acceptedPrefixCounter", p->pcount[afi][safi]); @@ -11055,6 +11531,20 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, filter->usmap.map ? "*" : "", filter->usmap.name); + /* advertise-map */ + if (filter->advmap.aname && filter->advmap.cname) + vty_out(vty, + " Condition %s, Condition-map %s%s, Advertise-map %s%s, status: %s\n", + filter->advmap.condition ? "EXIST" + : "NON_EXIST", + filter->advmap.cmap ? "*" : "", + filter->advmap.cname, + filter->advmap.amap ? "*" : "", + filter->advmap.aname, + filter->advmap.update_type == ADVERTISE + ? "Advertise" + : "Withdraw"); + /* Receive prefix count */ vty_out(vty, " %u accepted prefixes\n", p->pcount[afi][safi]); @@ -13884,7 +14374,6 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group) struct prefix *range; struct peer *conf; struct peer *peer; - char buf[PREFIX2STR_BUFFER]; afi_t afi; safi_t safi; const char *peer_status; @@ -13938,10 +14427,8 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group) for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, - nnode, range)) { - prefix2str(range, buf, sizeof(buf)); - vty_out(vty, " %s\n", buf); - } + nnode, range)) + vty_out(vty, " %pFX\n", range); } } @@ -14024,24 +14511,23 @@ DEFUN (show_ip_bgp_peer_groups, /* Redistribute VTY commands. */ -DEFUN (bgp_redistribute_ipv4, - bgp_redistribute_ipv4_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD, - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD) +DEFUN_YANG (bgp_redistribute_ipv4, + bgp_redistribute_ipv4_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD, + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - bgp_redist_add(bgp, AFI_IP, type, 0); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, false); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14049,33 +14535,28 @@ ALIAS_HIDDEN( "redistribute " FRR_IP_REDIST_STR_BGPD, "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD) -DEFUN (bgp_redistribute_ipv4_rmap, - bgp_redistribute_ipv4_rmap_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (bgp_redistribute_ipv4_rmap, + bgp_redistribute_ipv4_rmap_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD", + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; - int type; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = route_map_lookup_warn_noexist( - vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14085,32 +14566,28 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv4_metric, - bgp_redistribute_ipv4_metric_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG (bgp_redistribute_ipv4_metric, + bgp_redistribute_ipv4_metric_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)", + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_number = 3; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14120,39 +14597,34 @@ ALIAS_HIDDEN( "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_rmap_metric, - bgp_redistribute_ipv4_rmap_metric_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG( + bgp_redistribute_ipv4_rmap_metric, + bgp_redistribute_ipv4_rmap_metric_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD + " route-map WORD metric (0-4294967295)", + "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; int idx_number = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14166,39 +14638,34 @@ ALIAS_HIDDEN( "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_metric_rmap, - bgp_redistribute_ipv4_metric_rmap_cmd, - "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + bgp_redistribute_ipv4_metric_rmap, + bgp_redistribute_ipv4_metric_rmap_cmd, + "redistribute " FRR_IP_REDIST_STR_BGPD + " metric (0-4294967295) route-map WORD", + "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int idx_number = 3; int idx_word = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + int idx_number = 3; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric); - changed |= - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14212,29 +14679,26 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv4_ospf, - bgp_redistribute_ipv4_ospf_cmd, - "redistribute <ospf|table> (1-65535)", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n") +DEFUN_YANG (bgp_redistribute_ipv4_ospf, + bgp_redistribute_ipv4_ospf_cmd, + "redistribute <ospf|table> (1-65535)", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; - unsigned short instance; - unsigned short protocol; + char base_xpath[XPATH_MAXLEN]; - instance = strtoul(argv[idx_number]->arg, NULL, 10); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - bgp_redist_add(bgp, AFI_IP, protocol, instance); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, false); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd, @@ -14244,37 +14708,32 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd, "Non-main Kernel Routing Table\n" "Instance ID/Table ID\n") -DEFUN (bgp_redistribute_ipv4_ospf_rmap, - bgp_redistribute_ipv4_ospf_rmap_cmd, - "redistribute <ospf|table> (1-65535) route-map WORD", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (bgp_redistribute_ipv4_ospf_rmap, + bgp_redistribute_ipv4_ospf_rmap_cmd, + "redistribute <ospf|table> (1-65535) route-map WORD", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_word = 4; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap, @@ -14287,38 +14746,32 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap, "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv4_ospf_metric, - bgp_redistribute_ipv4_ospf_metric_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG(bgp_redistribute_ipv4_ospf_metric, + bgp_redistribute_ipv4_ospf_metric_cmd, + "redistribute <ospf|table> (1-65535) metric (0-4294967295)", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_number_2 = 4; - uint32_t metric; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - metric = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, - metric); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number_2]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric, @@ -14331,45 +14784,38 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric, "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, - bgp_redistribute_ipv4_ospf_rmap_metric_cmd, - "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Route map reference\n" - "Pointer to route-map entries\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG( + bgp_redistribute_ipv4_ospf_rmap_metric, + bgp_redistribute_ipv4_ospf_rmap_metric_cmd, + "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_word = 4; int idx_number_2 = 6; - uint32_t metric; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - metric = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, - metric); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number_2]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14385,45 +14831,38 @@ ALIAS_HIDDEN( "Metric for redistributed routes\n" "Default metric\n") -DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, - bgp_redistribute_ipv4_ospf_metric_rmap_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD", - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + bgp_redistribute_ipv4_ospf_metric_rmap, + bgp_redistribute_ipv4_ospf_metric_rmap_cmd, + "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD", + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 1; + int idx_protocol = 1; int idx_number = 2; int idx_number_2 = 4; int idx_word = 6; - uint32_t metric; - struct bgp_redist *red; - unsigned short instance; - int protocol; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - metric = strtoul(argv[idx_number_2]->arg, NULL, 10); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number_2]->arg); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); - red = bgp_redist_add(bgp, AFI_IP, protocol, instance); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol, - metric); - changed |= - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14439,32 +14878,31 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (no_bgp_redistribute_ipv4_ospf, - no_bgp_redistribute_ipv4_ospf_cmd, - "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]", - NO_STR - "Redistribute information from another routing protocol\n" - "Open Shortest Path First (OSPFv2)\n" - "Non-main Kernel Routing Table\n" - "Instance ID/Table ID\n" - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (no_bgp_redistribute_ipv4_ospf, + no_bgp_redistribute_ipv4_ospf_cmd, + "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]", + NO_STR + "Redistribute information from another routing protocol\n" + "Open Shortest Path First (OSPFv2)\n" + "Non-main Kernel Routing Table\n" + "Instance ID/Table ID\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_ospf_table = 2; + int idx_protocol = 2; int idx_number = 3; - unsigned short instance; - int protocol; + char base_xpath[XPATH_MAXLEN]; - if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) - protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, argv[idx_number]->arg); - instance = strtoul(argv[idx_number]->arg, NULL, 10); - return bgp_redistribute_unset(bgp, AFI_IP, protocol, instance); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14480,27 +14918,28 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (no_bgp_redistribute_ipv4, - no_bgp_redistribute_ipv4_cmd, - "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]", - NO_STR - "Redistribute information from another routing protocol\n" - FRR_IP_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (no_bgp_redistribute_ipv4, + no_bgp_redistribute_ipv4_cmd, + "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]", + NO_STR + "Redistribute information from another routing protocol\n" + FRR_IP_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 2; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return bgp_redistribute_unset(bgp, AFI_IP, type, 0); + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN( @@ -14514,56 +14953,50 @@ ALIAS_HIDDEN( "Route map reference\n" "Pointer to route-map entries\n") -DEFUN (bgp_redistribute_ipv6, - bgp_redistribute_ipv6_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD, - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD) +DEFUN_YANG (bgp_redistribute_ipv6, + bgp_redistribute_ipv6_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD, + "Redistribute information from another routing protocol\n" + FRR_IP6_REDIST_HELP_STR_BGPD) { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); - bgp_redist_add(bgp, AFI_IP6, type, 0); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, false); + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_rmap, - bgp_redistribute_ipv6_rmap_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG (bgp_redistribute_ipv6_rmap, + bgp_redistribute_ipv6_rmap_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD", + "Redistribute information from another routing protocol\n" + FRR_IP6_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; - int type; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); + + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_metric, +DEFUN_YANG (bgp_redistribute_ipv6_metric, bgp_redistribute_ipv6_metric_cmd, "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295)", "Redistribute information from another routing protocol\n" @@ -14571,120 +15004,123 @@ DEFUN (bgp_redistribute_ipv6_metric, "Metric for redistributed routes\n" "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_number = 3; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_rmap_metric, - bgp_redistribute_ipv6_rmap_metric_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)", - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Route map reference\n" - "Pointer to route-map entries\n" - "Metric for redistributed routes\n" - "Default metric\n") +DEFUN_YANG( + bgp_redistribute_ipv6_rmap_metric, + bgp_redistribute_ipv6_rmap_metric_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD + " route-map WORD metric (0-4294967295)", + "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" + "Default metric\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; int idx_word = 3; int idx_number = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, - metric); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (bgp_redistribute_ipv6_metric_rmap, - bgp_redistribute_ipv6_metric_rmap_cmd, - "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD", - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + bgp_redistribute_ipv6_metric_rmap, + bgp_redistribute_ipv6_metric_rmap_cmd, + "redistribute " FRR_IP6_REDIST_STR_BGPD + " metric (0-4294967295) route-map WORD", + "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 1; - int idx_number = 3; int idx_word = 5; - int type; - uint32_t metric; - struct bgp_redist *red; - bool changed; - struct route_map *route_map = - route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - metric = strtoul(argv[idx_number]->arg, NULL, 10); + int idx_number = 3; + char base_xpath[XPATH_MAXLEN]; + + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - red = bgp_redist_add(bgp, AFI_IP6, type, 0); - changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST, - metric); - changed |= - bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); - return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed); + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE, + argv[idx_number]->arg); + nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE, + argv[idx_word]->arg); + + return nb_cli_apply_changes(vty, base_xpath); } -DEFUN (no_bgp_redistribute_ipv6, - no_bgp_redistribute_ipv6_cmd, - "no redistribute " FRR_IP6_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]", - NO_STR - "Redistribute information from another routing protocol\n" - FRR_IP6_REDIST_HELP_STR_BGPD - "Metric for redistributed routes\n" - "Default metric\n" - "Route map reference\n" - "Pointer to route-map entries\n") +DEFUN_YANG( + no_bgp_redistribute_ipv6, + no_bgp_redistribute_ipv6_cmd, + "no redistribute " FRR_IP6_REDIST_STR_BGPD + " [{metric (0-4294967295)|route-map WORD}]", + NO_STR + "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" + "Pointer to route-map entries\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_protocol = 2; - int type; + char base_xpath[XPATH_MAXLEN]; - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - if (type < 0) { - vty_out(vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } + snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH, + yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST), + bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST), + argv[idx_protocol]->text, "0"); - return bgp_redistribute_unset(bgp, AFI_IP6, type, 0); + nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, base_xpath); +} + +void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list( + struct vty *vty, struct lyd_node *dnode, bool show_defaults) +{ + uint32_t instance = 0; + + vty_out(vty, " redistribute %s", + yang_dnode_get_string(dnode, "./route-type")); + if ((instance = yang_dnode_get_uint16(dnode, "./route-instance"))) + vty_out(vty, " %d", instance); + if (yang_dnode_exists(dnode, "./metric")) + vty_out(vty, " metric %u", + yang_dnode_get_uint32(dnode, "./metric")); + if (yang_dnode_exists(dnode, "./rmap-policy-import")) + vty_out(vty, " route-map %s", + yang_dnode_get_string(dnode, "./rmap-policy-import")); + vty_out(vty, "\n"); } static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, @@ -14773,6 +15209,10 @@ static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi, return !!(filter->map[direct].name); case PEER_FT_UNSUPPRESS_MAP: return !!(filter->usmap.name); + case PEER_FT_ADVERTISE_MAP: + return !!(filter->advmap.aname + && ((filter->advmap.condition == direct) + && filter->advmap.cname)); default: return false; } @@ -14958,6 +15398,18 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer, vty_out(vty, " neighbor %s unsuppress-map %s\n", addr, filter->usmap.name); + /* advertise-map : always applied in OUT direction*/ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_ADVERTISE_MAP, + CONDITION_NON_EXIST)) + vty_out(vty, + " neighbor %s advertise-map %s non-exist-map %s\n", + addr, filter->advmap.aname, filter->advmap.cname); + + if (peergroup_filter_check(peer, afi, safi, PEER_FT_ADVERTISE_MAP, + CONDITION_EXIST)) + vty_out(vty, " neighbor %s advertise-map %s exist-map %s\n", + addr, filter->advmap.aname, filter->advmap.cname); + /* filter-list. */ if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST, FILTER_IN)) @@ -15668,8 +16120,8 @@ int bgp_config_write(struct vty *vty) /* BGP router ID. */ if (bgp->router_id_static.s_addr != 0) - vty_out(vty, " bgp router-id %s\n", - inet_ntoa(bgp->router_id_static)); + vty_out(vty, " bgp router-id %pI4\n", + &bgp->router_id_static); /* BGP log-neighbor-changes. */ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES) @@ -15735,8 +16187,8 @@ int bgp_config_write(struct vty *vty) /* BGP cluster ID. */ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID)) - vty_out(vty, " bgp cluster-id %s\n", - inet_ntoa(bgp->cluster_id)); + vty_out(vty, " bgp cluster-id %pI4\n", + &bgp->cluster_id); /* Disable ebgp connected nexthop check */ if (CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) @@ -17162,6 +17614,17 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd); + /* "neighbor advertise-map" commands. */ + install_element(BGP_NODE, &neighbor_advertise_map_hidden_cmd); + install_element(BGP_IPV4_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV4M_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV4L_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV6_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV6M_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_IPV6L_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_VPNV4_NODE, &neighbor_advertise_map_cmd); + install_element(BGP_VPNV6_NODE, &neighbor_advertise_map_cmd); + /* neighbor maximum-prefix-out commands. */ install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd); install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd); @@ -17709,9 +18172,10 @@ DEFUN (no_community_list_expanded_all, return CMD_SUCCESS; } -ALIAS(no_community_list_expanded_all, no_bgp_community_list_expanded_all_list_cmd, +ALIAS(no_community_list_expanded_all, + no_bgp_community_list_expanded_all_list_cmd, "no bgp community-list <(100-500)|expanded WORD>", - NO_STR IP_STR COMMUNITY_LIST_STR + NO_STR BGP_STR COMMUNITY_LIST_STR "Community list number (expanded)\n" "Add an expanded community-list entry\n" "Community list name\n") @@ -18330,7 +18794,7 @@ DEFUN (no_extcommunity_list_standard_all, ALIAS(no_extcommunity_list_standard_all, no_bgp_extcommunity_list_standard_all_list_cmd, "no bgp extcommunity-list <(1-99)|standard WORD>", - NO_STR IP_STR EXTCOMMUNITY_LIST_STR + NO_STR BGP_STR EXTCOMMUNITY_LIST_STR "Extended Community list number (standard)\n" "Specify standard extcommunity-list\n" "Community list name\n") @@ -18395,7 +18859,7 @@ DEFUN (no_extcommunity_list_expanded_all, ALIAS(no_extcommunity_list_expanded_all, no_bgp_extcommunity_list_expanded_all_list_cmd, "no bgp extcommunity-list <(100-500)|expanded WORD>", - NO_STR IP_STR EXTCOMMUNITY_LIST_STR + NO_STR BGP_STR EXTCOMMUNITY_LIST_STR "Extended Community list number (expanded)\n" "Specify expanded extcommunity-list\n" "Extended Community list name\n") diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 95eefbc36f..349efbac45 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -180,5 +180,19 @@ int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv, extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, safi_t safi, bool show_failed, bool show_established, bool use_json); +extern int bgp_clear_star_soft_in(const char *name, char *errmsg, + size_t errmsg_len); +extern int bgp_clear_star_soft_out(const char *name, char *errmsg, + size_t errmsg_len); +int bgp_wpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set); +int bgp_rpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set); +extern int bgp_maxpaths_config_vty(struct bgp *bgp, afi_t afi, safi_t safi, + int peer_type, uint16_t maxpaths, + uint16_t options, int set, char *errmsg, + size_t errmsg_len); +extern const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi); +extern bool vpn_policy_check_import(struct bgp *bgp, afi_t afi, safi_t safi, + bool v2vimport, char *errmsg, + size_t errmsg_len); #endif /* _QUAGGA_BGP_VTY_H */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index a32e47f446..957db4cbc1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -91,11 +91,9 @@ static int bgp_router_id_update(ZAPI_CALLBACK_ARGS) zebra_router_id_update_read(zclient->ibuf, &router_id); - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&router_id, buf, sizeof(buf)); - zlog_debug("Rx Router Id update VRF %u Id %s", vrf_id, buf); - } + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Rx Router Id update VRF %u Id %pFX", vrf_id, + &router_id); bgp_router_id_zebra_bump(vrf_id, &router_id); return 0; @@ -313,12 +311,9 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) if (ifc == NULL) return 0; - if (bgp_debug_zebra(ifc->address)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(ifc->address, buf, sizeof(buf)); - zlog_debug("Rx Intf address add VRF %u IF %s addr %s", vrf_id, - ifc->ifp->name, buf); - } + if (bgp_debug_zebra(ifc->address)) + zlog_debug("Rx Intf address add VRF %u IF %s addr %pFX", vrf_id, + ifc->ifp->name, ifc->address); if (!bgp) return 0; @@ -350,12 +345,9 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) if (ifc == NULL) return 0; - if (bgp_debug_zebra(ifc->address)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(ifc->address, buf, sizeof(buf)); - zlog_debug("Rx Intf address del VRF %u IF %s addr %s", vrf_id, - ifc->ifp->name, buf); - } + if (bgp_debug_zebra(ifc->address)) + zlog_debug("Rx Intf address del VRF %u IF %s addr %pFX", vrf_id, + ifc->ifp->name, ifc->address); if (bgp && if_is_operative(ifc->ifp)) { bgp_connected_delete(bgp, ifc); @@ -376,12 +368,9 @@ static int bgp_interface_nbr_address_add(ZAPI_CALLBACK_ARGS) if (ifc == NULL) return 0; - if (bgp_debug_zebra(ifc->address)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(ifc->address, buf, sizeof(buf)); - zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %s", vrf_id, - ifc->ifp->name, buf); - } + if (bgp_debug_zebra(ifc->address)) + zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %pFX", + vrf_id, ifc->ifp->name, ifc->address); if (if_is_operative(ifc->ifp)) { bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -402,12 +391,9 @@ static int bgp_interface_nbr_address_delete(ZAPI_CALLBACK_ARGS) if (ifc == NULL) return 0; - if (bgp_debug_zebra(ifc->address)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(ifc->address, buf, sizeof(buf)); - zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %s", vrf_id, - ifc->ifp->name, buf); - } + if (bgp_debug_zebra(ifc->address)) + zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %pFX", + vrf_id, ifc->ifp->name, ifc->address); if (if_is_operative(ifc->ifp)) { bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -534,22 +520,20 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS) } if (bgp_debug_zebra(&api.prefix)) { - char buf[2][PREFIX_STRLEN]; + char buf[PREFIX_STRLEN]; - prefix2str(&api.prefix, buf[0], sizeof(buf[0])); if (add) { - inet_ntop(api.prefix.family, &nexthop, buf[1], - sizeof(buf[1])); + inet_ntop(api.prefix.family, &nexthop, buf, + sizeof(buf)); zlog_debug( - "Rx route ADD VRF %u %s[%d] %s nexthop %s (type %d if %u) metric %u tag %" ROUTE_TAG_PRI, + "Rx route ADD VRF %u %s[%d] %pFX nexthop %s (type %d if %u) metric %u tag %" ROUTE_TAG_PRI, vrf_id, zebra_route_string(api.type), - api.instance, buf[0], buf[1], nhtype, - ifindex, api.metric, api.tag); + api.instance, &api.prefix, buf, nhtype, ifindex, + api.metric, api.tag); } else { - zlog_debug( - "Rx route DEL VRF %u %s[%d] %s", - vrf_id, zebra_route_string(api.type), - api.instance, buf[0]); + zlog_debug("Rx route DEL VRF %u %s[%d] %s", vrf_id, + zebra_route_string(api.type), api.instance, + buf); } } @@ -944,10 +928,8 @@ static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p, if (p->family == AF_INET) { char buf[2][INET_ADDRSTRLEN]; zlog_debug( - "Zebra rmap deny: IPv4 route %s/%d nexthop %s", - inet_ntop(AF_INET, &p->u.prefix4, buf[0], - sizeof(buf[0])), - p->prefixlen, + "Zebra rmap deny: IPv4 route %pFX nexthop %s", + p, inet_ntop(AF_INET, &path->attr->nexthop, buf[1], sizeof(buf[1]))); } @@ -958,12 +940,10 @@ static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p, nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex); zlog_debug( - "Zebra rmap deny: IPv6 route %s/%d nexthop %s", - inet_ntop(AF_INET6, &p->u.prefix6, buf[0], - sizeof(buf[0])), - p->prefixlen, - inet_ntop(AF_INET6, nexthop, - buf[1], sizeof(buf[1]))); + "Zebra rmap deny: IPv6 route %pFX nexthop %s", + p, + inet_ntop(AF_INET6, nexthop, buf[1], + sizeof(buf[1]))); } } return false; @@ -1440,18 +1420,17 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, } if (bgp_debug_zebra(p)) { - char prefix_buf[PREFIX_STRLEN]; char nh_buf[INET6_ADDRSTRLEN]; char eth_buf[ETHER_ADDR_STRLEN + 7] = {'\0'}; char buf1[ETHER_ADDR_STRLEN]; char label_buf[20]; int i; - prefix2str(&api.prefix, prefix_buf, sizeof(prefix_buf)); - zlog_debug("Tx route %s VRF %u %s metric %u tag %" ROUTE_TAG_PRI - " count %d", - valid_nh_count ? "add" : "delete", bgp->vrf_id, - prefix_buf, api.metric, api.tag, api.nexthop_num); + zlog_debug( + "Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI + " count %d", + valid_nh_count ? "add" : "delete", bgp->vrf_id, + &api.prefix, api.metric, api.tag, api.nexthop_num); for (i = 0; i < api.nexthop_num; i++) { api_nh = &api.nexthops[i]; @@ -1600,12 +1579,9 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, if (is_route_parent_evpn(info)) SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE); - if (bgp_debug_zebra(p)) { - char buf[PREFIX_STRLEN]; - - prefix2str(&api.prefix, buf, sizeof(buf)); - zlog_debug("Tx route delete VRF %u %s", bgp->vrf_id, buf); - } + if (bgp_debug_zebra(p)) + zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id, + &api.prefix); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } @@ -2414,6 +2390,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s, { struct prefix pfx; uint8_t fam = AF_INET; + char ifname[INTERFACE_NAMSIZ]; if (pbra->nh.type == NEXTHOP_TYPE_IPV6) fam = AF_INET6; @@ -2455,7 +2432,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s, stream_put(s, &pfx.u.prefix, prefix_blen(&pfx)); stream_putw(s, 0); /* dst port */ - + stream_putc(s, 0); /* dsfield */ /* if pbr present, fwmark is not used */ if (pbr) stream_putl(s, 0); @@ -2464,7 +2441,8 @@ static void bgp_encode_pbr_rule_action(struct stream *s, stream_putl(s, pbra->table_id); - stream_putl(s, 0); /* ifindex unused */ + memset(ifname, 0, sizeof(ifname)); + stream_put(s, ifname, INTERFACE_NAMSIZ); /* ifname unused */ } static void bgp_encode_pbr_ipset_match(struct stream *s, @@ -2569,6 +2547,7 @@ static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS) char buf[ESI_STR_LEN]; struct in_addr originator_ip; uint8_t active; + uint16_t df_pref; bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) @@ -2578,14 +2557,15 @@ static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS) stream_get(&esi, s, sizeof(esi_t)); originator_ip.s_addr = stream_get_ipv4(s); active = stream_getc(s); + df_pref = stream_getw(s); if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx add ESI %s originator-ip %s active %u", - esi_to_str(&esi, buf, sizeof(buf)), - inet_ntoa(originator_ip), - active); + zlog_debug( + "Rx add ESI %s originator-ip %pI4 active %u df_pref %u", + esi_to_str(&esi, buf, sizeof(buf)), + &originator_ip, active, df_pref); - bgp_evpn_local_es_add(bgp, &esi, originator_ip, active); + bgp_evpn_local_es_add(bgp, &esi, originator_ip, active, df_pref); return 0; } @@ -2792,7 +2772,6 @@ static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS) struct stream *s = NULL; struct bgp *bgp_vrf = NULL; struct prefix p; - char buf[PREFIX_STRLEN]; memset(&p, 0, sizeof(struct prefix)); s = zclient->ibuf; @@ -2803,8 +2782,7 @@ static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS) return; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Recv prefix %s %s on vrf %s", - prefix2str(&p, buf, sizeof(buf)), + zlog_debug("Recv prefix %pFX %s on vrf %s", &p, (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL", vrf_id_to_name(vrf_id)); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 4260970541..0095a1cab0 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -54,6 +54,7 @@ #include "bgpd/bgp_debug.h" #include "bgpd/bgp_errors.h" #include "bgpd/bgp_community.h" +#include "bgpd/bgp_conditional_adv.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_regex.h" #include "bgpd/bgp_clist.h" @@ -332,10 +333,9 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) if (bgp->established_peers == 0) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug( - "RID change : vrf %s(%u), RTR ID %s", + "RID change : vrf %s(%u), RTR ID %pI4", bgp->name_pretty, - bgp->vrf_id, - inet_ntoa(*addr)); + bgp->vrf_id, addr); /* * if old router-id was 0x0, set flag * to use this new value @@ -363,10 +363,9 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) if (bgp->established_peers == 0) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug( - "RID change : vrf %s(%u), RTR ID %s", + "RID change : vrf %s(%u), RTR ID %pI4", bgp->name_pretty, - bgp->vrf_id, - inet_ntoa(*addr)); + bgp->vrf_id, addr); /* * if old router-id was 0x0, set flag * to use this new value @@ -397,10 +396,6 @@ int bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id) struct peer *peer; struct listnode *node, *nnode; - if (bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID) - && IPV4_ADDR_SAME(&bgp->cluster_id, cluster_id)) - return 0; - IPV4_ADDR_COPY(&bgp->cluster_id, cluster_id); bgp_config_set(bgp, BGP_CONFIG_CLUSTER_ID); @@ -473,14 +468,14 @@ void bgp_timers_unset(struct bgp *bgp) } /* BGP confederation configuration. */ -int bgp_confederation_id_set(struct bgp *bgp, as_t as) +void bgp_confederation_id_set(struct bgp *bgp, as_t as) { struct peer *peer; struct listnode *node, *nnode; int already_confed; if (as == 0) - return BGP_ERR_INVALID_AS; + return; /* Remember - were we doing confederation before? */ already_confed = bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION); @@ -528,7 +523,7 @@ int bgp_confederation_id_set(struct bgp *bgp, as_t as) } } } - return 0; + return; } int bgp_confederation_id_unset(struct bgp *bgp) @@ -2744,7 +2739,6 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range) struct listnode *node, *nnode; struct peer *peer; afi_t afi; - char buf[PREFIX2STR_BUFFER]; afi = family2afi(range->family); @@ -2757,8 +2751,6 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range) if (!prefix) return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND; - prefix2str(prefix, buf, sizeof(buf)); - /* Dispose off any dynamic neighbors that exist due to this listen range */ for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { @@ -2769,8 +2761,8 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range) if (prefix_match(prefix, &prefix2)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "Deleting dynamic neighbor %s group %s upon delete of listen range %s", - peer->host, group->name, buf); + "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX", + peer->host, group->name, prefix); peer_delete(peer); } } @@ -2987,6 +2979,8 @@ static struct bgp *bgp_create(as_t *as, const char *name, } bgp_lock(bgp); + + bgp_process_queue_init(bgp); bgp->heuristic_coalesce = true; bgp->inst_type = inst_type; bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT @@ -3028,7 +3022,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->gr_info[afi][safi].eor_received = 0; bgp->gr_info[afi][safi].t_select_deferral = NULL; bgp->gr_info[afi][safi].t_route_select = NULL; - bgp->gr_info[afi][safi].route_list = list_new(); + bgp->gr_info[afi][safi].gr_deferred = 0; } bgp->v_update_delay = bm->v_update_delay; @@ -3242,12 +3236,10 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, return bgp_check_main_socket(create, bgp); } -/* Called from VTY commands. */ -int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, - enum bgp_instance_type inst_type) +int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name, + enum bgp_instance_type inst_type) { struct bgp *bgp; - struct vrf *vrf = NULL; /* Multiple instance check. */ if (name) @@ -3255,7 +3247,6 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, else bgp = bgp_get_default(); - /* Already exists. */ if (bgp) { if (bgp->as != *as) { *as = bgp->as; @@ -3266,6 +3257,27 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, *bgp_val = bgp; return BGP_SUCCESS; } + *bgp_val = NULL; + + return BGP_SUCCESS; +} + +/* Called from VTY commands. */ +int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, + enum bgp_instance_type inst_type) +{ + struct bgp *bgp; + struct vrf *vrf = NULL; + int ret = 0; + + ret = bgp_lookup_by_as_name_type(bgp_val, as, name, inst_type); + switch (ret) { + case BGP_ERR_INSTANCE_MISMATCH: + return ret; + case BGP_SUCCESS: + if (*bgp_val) + return ret; + } bgp = bgp_create(as, name, inst_type); if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name) @@ -3382,14 +3394,21 @@ int bgp_delete(struct bgp *bgp) /* Delete the graceful restart info */ FOREACH_AFI_SAFI (afi, safi) { + struct thread *t; + gr_info = &bgp->gr_info[afi][safi]; if (!gr_info) continue; BGP_TIMER_OFF(gr_info->t_select_deferral); + + t = gr_info->t_route_select; + if (t) { + void *info = THREAD_ARG(t); + + XFREE(MTYPE_TMP, info); + } BGP_TIMER_OFF(gr_info->t_route_select); - if (gr_info->route_list) - list_delete(&gr_info->route_list); } if (BGP_DEBUG(zebra, ZEBRA)) { @@ -3493,6 +3512,9 @@ int bgp_delete(struct bgp *bgp) bgp_set_evpn(bgp_get_default()); } + if (bgp->process_queue) + work_queue_free_and_null(&bgp->process_queue); + thread_master_free_unused(bm->master); bgp_unlock(bgp); /* initial reference */ @@ -3758,7 +3780,6 @@ struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su) struct prefix *listen_range; int dncount; char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; sockunion2hostprefix(su, &prefix); @@ -3775,12 +3796,11 @@ struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su) return NULL; prefix2str(&prefix, buf, sizeof(buf)); - prefix2str(listen_range, buf1, sizeof(buf1)); if (bgp_debug_neighbor_events(NULL)) zlog_debug( - "Dynamic Neighbor %s matches group %s listen range %s", - buf, group->name, buf1); + "Dynamic Neighbor %s matches group %s listen range %pFX", + buf, group->name, listen_range); /* Are we within the listen limit? */ dncount = gbgp->dynamic_neighbors_count; @@ -6573,6 +6593,172 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi) return 0; } +static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi, + safi_t safi, const char *amap_name, + struct route_map *amap, + const char *cmap_name, + struct route_map *cmap, + bool condition, bool set) +{ + struct bgp_filter *filter; + bool filter_exists = false; + + filter = &peer->filter[afi][safi]; + + /* advertise-map is already configured. */ + if (filter->advmap.aname) { + filter_exists = true; + XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname); + XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname); + } + + route_map_counter_decrement(filter->advmap.amap); + + /* Removed advertise-map configuration */ + if (!set) { + memset(filter, 0, sizeof(struct bgp_filter)); + + /* decrement condition_filter_count delete timer if + * this is the last advertise-map to be removed. + */ + if (filter_exists) + bgp_conditional_adv_disable(peer, afi, safi); + + return; + } + + /* Update filter data with newly configured values. */ + filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name); + filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name); + filter->advmap.amap = amap; + filter->advmap.cmap = cmap; + filter->advmap.condition = condition; + route_map_counter_increment(filter->advmap.amap); + peer->advmap_config_change[afi][safi] = true; + + /* Increment condition_filter_count and/or create timer. */ + if (!filter_exists) { + filter->advmap.update_type = ADVERTISE; + bgp_conditional_adv_enable(peer, afi, safi); + } +} + +/* Set advertise-map to the peer but do not process peer route updates here. * + * Hold filter changes until the conditional routes polling thread is called * + * AS we need to advertise/withdraw prefixes (in advertise-map) based on the * + * condition (exist-map/non-exist-map) and routes(specified in condition-map) * + * in BGP table. So do not call peer_on_policy_change() here, only create * + * polling timer thread, update filters and increment condition_filter_count. + */ +int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, bool condition) +{ + struct peer *member; + struct listnode *node, *nnode; + + /* Set configuration on peer. */ + peer_advertise_map_filter_update(peer, afi, safi, advertise_name, + advertise_map, condition_name, + condition_map, condition, true); + + /* Check if handling a regular peer & Skip peer-group mechanics. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + /* Set override-flag and process peer route updates. */ + SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP); + return 0; + } + + /* + * Set configuration on all peer-group members, unless they are + * explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP)) + continue; + + /* Set configuration on peer-group member. */ + peer_advertise_map_filter_update( + member, afi, safi, advertise_name, advertise_map, + condition_name, condition_map, condition, true); + } + + return 0; +} + +/* Unset advertise-map from the peer. */ +int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, bool condition) +{ + struct peer *member; + struct listnode *node, *nnode; + + /* advertise-map is not configured */ + if (!peer->filter[afi][safi].advmap.aname) + return 0; + + /* Unset override-flag unconditionally. */ + UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP); + + /* Inherit configuration from peer-group if peer is member. */ + if (peer_group_active(peer)) { + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].advmap.aname, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].advmap.amap); + } else + peer_advertise_map_filter_update( + peer, afi, safi, advertise_name, advertise_map, + condition_name, condition_map, condition, false); + + /* Check if handling a regular peer and skip peer-group mechanics. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + /* Process peer route updates. */ + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Send normal update to %s for %s", + __func__, peer->host, + get_afi_safi_str(afi, safi, false)); + + peer_on_policy_change(peer, afi, safi, 1); + return 0; + } + + /* + * Remove configuration on all peer-group members, unless they are + * explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT], + PEER_FT_ADVERTISE_MAP)) + continue; + /* Remove configuration on peer-group member. */ + peer_advertise_map_filter_update( + member, afi, safi, advertise_name, advertise_map, + condition_name, condition_map, condition, false); + + /* Process peer route updates. */ + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: Send normal update to %s for %s ", + __func__, member->host, + get_afi_safi_str(afi, safi, false)); + + peer_on_policy_change(member, afi, safi, 1); + } + + return 0; +} + int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi, uint32_t max, uint8_t threshold, int warning, uint16_t restart, bool force) @@ -7073,8 +7259,6 @@ void bgp_master_init(struct thread_master *master, const int buffer_size) bm->terminating = false; bm->socket_buffer = buffer_size; - bgp_process_queue_init(); - bgp_mac_init(); /* init the rd id space. assign 0th index in the bitfield, @@ -7279,14 +7463,10 @@ void bgp_terminate(void) bgp_notify_send(peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); - if (bm->process_main_queue) - work_queue_free_and_null(&bm->process_main_queue); - if (bm->t_rmap_update) BGP_TIMER_OFF(bm->t_rmap_update); bgp_mac_finish(); - bgp_evpn_mh_finish(); } struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9f72a3e19e..480a3ad129 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -122,9 +122,6 @@ struct bgp_master { /* BGP thread master. */ struct thread_master *master; - /* work queues */ - struct work_queue *process_main_queue; - /* Listening sockets */ struct list *listen_sockets; @@ -268,8 +265,8 @@ struct graceful_restart_info { uint32_t eor_received; /* Deferral Timer */ struct thread *t_select_deferral; - /* Route list */ - struct list *route_list; + /* Routes Deferred */ + uint32_t gr_deferred; /* Best route select */ struct thread *t_route_select; /* AFI, SAFI enabled */ @@ -391,8 +388,9 @@ struct bgp { *t_maxmed_onstartup; /* non-null when max-med onstartup is on */ uint8_t maxmed_onstartup_over; /* Flag to make it effective only once */ - uint8_t v_maxmed_admin; /* 1/0 if max-med administrative is on/off */ -#define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */ + bool v_maxmed_admin; /* true/false if max-med administrative is on/off + */ +#define BGP_MAXMED_ADMIN_UNCONFIGURED false /* Off by default */ uint32_t maxmed_admin_value; /* Max-med value when administrative in on */ #define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */ @@ -681,6 +679,13 @@ struct bgp { /* Weighted ECMP related config. */ enum bgp_link_bw_handling lb_handling; + /* Process Queue for handling routes */ + struct work_queue *process_queue; + + /* BGP Conditional advertisement */ + uint32_t condition_filter_count; + struct thread *t_condition_check; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp) @@ -758,6 +763,12 @@ struct bgp_nexthop { #define BGP_GTSM_HOPS_DISABLED 0 #define BGP_GTSM_HOPS_CONNECTED 1 +/* Advertise map */ +#define CONDITION_NON_EXIST false +#define CONDITION_EXIST true + +enum update_type { WITHDRAW, ADVERTISE }; + #include "filter.h" /* BGP filter structure. */ @@ -791,6 +802,19 @@ struct bgp_filter { char *name; struct route_map *map; } usmap; + + /* Advertise-map */ + struct { + char *aname; + struct route_map *amap; + + bool condition; + + char *cname; + struct route_map *cmap; + + enum update_type update_type; + } advmap; }; /* IBGP/EBGP identifier. We also have a CONFED peer, which is to say, @@ -1354,6 +1378,7 @@ struct peer { #define PEER_FT_PREFIX_LIST (1U << 2) /* prefix-list */ #define PEER_FT_ROUTE_MAP (1U << 3) /* route-map */ #define PEER_FT_UNSUPPRESS_MAP (1U << 4) /* unsuppress-map */ +#define PEER_FT_ADVERTISE_MAP (1U << 5) /* advertise-map */ /* ORF Prefix-list */ struct prefix_list *orf_plist[AFI_MAX][SAFI_MAX]; @@ -1447,6 +1472,10 @@ struct peer { /* Sender side AS path loop detection. */ bool as_path_loop_detection; + /* Conditional advertisement */ + bool advmap_config_change[AFI_MAX][SAFI_MAX]; + bool advmap_table_change; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(peer) @@ -1827,7 +1856,7 @@ extern void bgp_router_id_static_set(struct bgp *, struct in_addr); extern int bgp_cluster_id_set(struct bgp *, struct in_addr *); extern int bgp_cluster_id_unset(struct bgp *); -extern int bgp_confederation_id_set(struct bgp *, as_t); +extern void bgp_confederation_id_set(struct bgp *, as_t); extern int bgp_confederation_id_unset(struct bgp *); extern bool bgp_confederation_peers_check(struct bgp *, as_t); @@ -1938,11 +1967,25 @@ extern int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi, const char *name, struct route_map *route_map); +extern int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, + bool condition); + extern int peer_password_set(struct peer *, const char *); extern int peer_password_unset(struct peer *); extern int peer_unsuppress_map_unset(struct peer *, afi_t, safi_t); +extern int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, + const char *advertise_name, + struct route_map *advertise_map, + const char *condition_name, + struct route_map *condition_map, + bool condition); + extern int peer_maximum_prefix_set(struct peer *, afi_t, safi_t, uint32_t, uint8_t, int, uint16_t, bool force); extern int peer_maximum_prefix_unset(struct peer *, afi_t, safi_t); @@ -2180,6 +2223,9 @@ extern struct peer *peer_new(struct bgp *bgp); extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, const char *ip_str, bool use_json); +extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, + const char *name, + enum bgp_instance_type inst_type); /* Hooks */ DECLARE_HOOK(peer_status_changed, (struct peer * peer), (peer)) diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index 2bcef97fc3..88c92f7954 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -170,14 +170,8 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, #ifdef BGP_VNC_DEBUG_MATCH_GROUP { - char buf[PREFIX_STRLEN]; - - prefix2str(vn, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s: vn prefix: %s", __func__, buf); - - prefix2str(un, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s: un prefix: %s", __func__, buf); - + vnc_zlog_debug_verbose("%s: vn prefix: %pFX", __func__, vn); + vnc_zlog_debug_verbose("%s: un prefix: %pFX", __func__, un); vnc_zlog_debug_verbose( "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p", __func__, rn_vn, rn_un, rfg_vn, rfg_un); @@ -4215,23 +4209,13 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) ++write; vty_out(vty, " vnc nve-group %s\n", rfg->name); - if (rfg->vn_prefix.family && rfg->vn_node) { - char buf[PREFIX_STRLEN]; + if (rfg->vn_prefix.family && rfg->vn_node) + vty_out(vty, " prefix %s %pFX\n", "vn", + &rfg->vn_prefix); - prefix2str(&rfg->vn_prefix, buf, - sizeof(buf)); - vty_out(vty, " prefix %s %s\n", "vn", - buf); - } - - if (rfg->un_prefix.family && rfg->un_node) { - char buf[PREFIX_STRLEN]; - - prefix2str(&rfg->un_prefix, buf, - sizeof(buf)); - vty_out(vty, " prefix %s %s\n", "un", - buf); - } + if (rfg->un_prefix.family && rfg->un_node) + vty_out(vty, " prefix %s %pFX\n", "un", + &rfg->un_prefix); if (rfg->rd.prefixlen) { diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 0ff4b2c825..2d81a6ce65 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -362,12 +362,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd, afi_t afi; /* of the VN address */ struct bgp_dest *bn; struct bgp_path_info *bpi; - char buf[PREFIX_STRLEN]; char buf2[RD_ADDRSTRLEN]; struct prefix_rd prd0; - prefix2str(p, buf, sizeof(buf)); - afi = family2afi(p->family); assert(afi == AFI_IP || afi == AFI_IP6); @@ -380,9 +377,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd, bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); vnc_zlog_debug_verbose( - "%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", - __func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)), - afi, safi, bn, (bn ? bgp_dest_get_bgp_path_info(bn) : NULL)); + "%s: peer=%p, prefix=%pFX, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", + __func__, peer, p, prefix_rd2str(prd, buf2, sizeof(buf2)), afi, + safi, bn, (bn ? bgp_dest_get_bgp_path_info(bn) : NULL)); for (bpi = (bn ? bgp_dest_get_bgp_path_info(bn) : NULL); bpi; bpi = bpi->next) { @@ -418,8 +415,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd, * no local nexthops */ vnc_zlog_debug_verbose( - "%s: lnh list already empty at prefix %s", - __func__, buf); + "%s: lnh list already empty at prefix %pFX", + __func__, p); goto done; } @@ -445,8 +442,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd, * list->del on data */ rfapi_nexthop_free(pLnh); } else { - vnc_zlog_debug_verbose("%s: desired lnh not found %s", - __func__, buf); + vnc_zlog_debug_verbose("%s: desired lnh not found %pFX", + __func__, p); } goto done; } @@ -459,10 +456,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd, rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill); if (bpi) { - prefix2str(p, buf, sizeof(buf)); vnc_zlog_debug_verbose( - "%s: Found route (safi=%d) to delete at prefix %s", - __func__, safi, buf); + "%s: Found route (safi=%d) to delete at prefix %pFX", + __func__, safi, p); if (safi == SAFI_MPLS_VPN) { struct bgp_dest *pdest = NULL; @@ -488,8 +484,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd, bgp_process(bgp, bn, afi, safi); } else { vnc_zlog_debug_verbose( - "%s: Couldn't find route (safi=%d) at prefix %s", - __func__, safi, buf); + "%s: Couldn't find route (safi=%d) at prefix %pFX", + __func__, safi, p); } done: bgp_dest_unlock_node(bn); @@ -1577,12 +1573,10 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, } { - char buf[PREFIX_STRLEN]; char *s; - prefix2str(&p, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s(rfd=%p, target=%s, ppNextHop=%p)", - __func__, rfd, buf, ppNextHopEntry); + vnc_zlog_debug_verbose("%s(rfd=%p, target=%pFX, ppNextHop=%p)", + __func__, rfd, &p, ppNextHopEntry); s = ecommunity_ecom2str(rfd->import_table->rt_import_list, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); @@ -2397,16 +2391,10 @@ int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix, afi = family2afi(prefix->prefix.addr_family); assert(afi); - - { - char buf[PREFIX_STRLEN]; - - prefix2str(&p, buf, sizeof(buf)); - vnc_zlog_debug_verbose( - "%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)", - __func__, rfd, buf, lifetime, options_un, options_vn, - action_str); - } + vnc_zlog_debug_verbose( + "%s(rfd=%p, pfx=%pFX, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)", + __func__, rfd, &p, lifetime, options_un, options_vn, + action_str); /* * These tests come after the prefix conversion so that we can diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index c3ad95ff28..e3581addee 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -265,11 +265,12 @@ void rfapiCheckRefcount(struct agg_node *rn, safi_t safi, int lockoffset) } } - if (count_bpi + count_monitor + lockoffset != rn->lock) { + if (count_bpi + count_monitor + lockoffset + != agg_node_get_lock_count(rn)) { vnc_zlog_debug_verbose( "%s: count_bpi=%d, count_monitor=%d, lockoffset=%d, rn->lock=%d", __func__, count_bpi, count_monitor, lockoffset, - rn->lock); + agg_node_get_lock_count(rn)); assert(0); } } @@ -611,11 +612,8 @@ rfapiMonitorMoveShorter(struct agg_node *original_vpn_node, int lockoffset) #ifdef DEBUG_MONITOR_MOVE_SHORTER { - char buf[PREFIX_STRLEN]; - - prefix2str(&original_vpn_node->p, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__, - buf); + vnc_zlog_debug_verbose("%s: called with node pfx=%pFX", + __func__, &original_vpn_node->p); } #endif @@ -750,11 +748,8 @@ rfapiMonitorMoveShorter(struct agg_node *original_vpn_node, int lockoffset) #ifdef DEBUG_MONITOR_MOVE_SHORTER { - char buf[PREFIX_STRLEN]; - - prefix2str(&par->p, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s: moved to node pfx=%s", __func__, - buf); + vnc_zlog_debug_verbose("%s: moved to node pfx=%pFX", __func__, + &par->p); } #endif @@ -863,9 +858,9 @@ static void rfapiBgpInfoChainFree(struct bgp_path_info *bpi) if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra->vnc.import.timer) { - struct thread *t = - (struct thread *)bpi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; + struct thread **t = + &(bpi->extra->vnc.import.timer); + struct rfapi_withdraw *wcb = (*t)->arg; XFREE(MTYPE_RFAPI_WITHDRAW, wcb); thread_cancel(t); @@ -1555,12 +1550,9 @@ static int rfapiNhlAddNodeRoutes( } if (!skiplist_search(seen_nexthops, &pfx_vn, NULL)) { #ifdef DEBUG_RETURNED_NHL - char buf[PREFIX_STRLEN]; - - prefix2str(&pfx_vn, buf, sizeof(buf)); vnc_zlog_debug_verbose( - "%s: already put VN/nexthop %s, skip", __func__, - buf); + "%s: already put VN/nexthop %pFX, skip", + __func__, &pfx_vn); #endif continue; } @@ -3101,10 +3093,9 @@ static void rfapiBgpInfoFilteredImportEncap( if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra->vnc.import.timer) { - struct thread *t = - (struct thread *)bpi->extra->vnc - .import.timer; - struct rfapi_withdraw *wcb = t->arg; + struct thread **t = + &(bpi->extra->vnc.import.timer); + struct rfapi_withdraw *wcb = (*t)->arg; XFREE(MTYPE_RFAPI_WITHDRAW, wcb); thread_cancel(t); @@ -3194,9 +3185,9 @@ static void rfapiBgpInfoFilteredImportEncap( "%s: removing holddown bpi matching NVE of new route", __func__); if (bpi->extra->vnc.import.timer) { - struct thread *t = - (struct thread *)bpi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; + struct thread **t = + &(bpi->extra->vnc.import.timer); + struct rfapi_withdraw *wcb = (*t)->arg; XFREE(MTYPE_RFAPI_WITHDRAW, wcb); thread_cancel(t); @@ -3557,10 +3548,9 @@ void rfapiBgpInfoFilteredImportVPN( if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra->vnc.import.timer) { - struct thread *t = - (struct thread *)bpi->extra->vnc - .import.timer; - struct rfapi_withdraw *wcb = t->arg; + struct thread **t = + &(bpi->extra->vnc.import.timer); + struct rfapi_withdraw *wcb = (*t)->arg; XFREE(MTYPE_RFAPI_WITHDRAW, wcb); thread_cancel(t); @@ -3633,12 +3623,9 @@ void rfapiBgpInfoFilteredImportVPN( rfapiCopyUnEncap2VPN(ern->info, info_new); agg_unlock_node(ern); /* undo lock in route_note_match */ } else { - char bpf[PREFIX_STRLEN]; - - prefix2str(&vn_prefix, bpf, sizeof(bpf)); /* Not a big deal, just means VPN route got here first */ - vnc_zlog_debug_verbose("%s: no encap route for vn addr %s", - __func__, bpf); + vnc_zlog_debug_verbose("%s: no encap route for vn addr %pFX", + __func__, &vn_prefix); info_new->extra->vnc.import.un_family = 0; } @@ -3665,7 +3652,8 @@ void rfapiBgpInfoFilteredImportVPN( } vnc_zlog_debug_verbose("%s: inserting bpi %p at prefix %pRN #%d", - __func__, info_new, rn, rn->lock); + __func__, info_new, rn, + agg_node_get_lock_count(rn)); rfapiBgpInfoAttachSorted(rn, info_new, afi, SAFI_MPLS_VPN); rfapiItBiIndexAdd(rn, info_new); @@ -3778,9 +3766,9 @@ void rfapiBgpInfoFilteredImportVPN( "%s: removing holddown bpi matching NVE of new route", __func__); if (bpi->extra->vnc.import.timer) { - struct thread *t = - (struct thread *)bpi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; + struct thread **t = + &(bpi->extra->vnc.import.timer); + struct rfapi_withdraw *wcb = (*t)->arg; XFREE(MTYPE_RFAPI_WITHDRAW, wcb); thread_cancel(t); @@ -4439,13 +4427,9 @@ static void rfapiDeleteRemotePrefixesIt( struct bgp_path_info *next; const struct prefix *rn_p = agg_node_get_prefix(rn); - if (p && VNC_DEBUG(IMPORT_DEL_REMOTE)) { - char p1line[PREFIX_STRLEN]; - - prefix2str(p, p1line, sizeof(p1line)); - vnc_zlog_debug_any("%s: want %s, have %pRN", - __func__, p1line, rn); - } + if (p && VNC_DEBUG(IMPORT_DEL_REMOTE)) + vnc_zlog_debug_any("%s: want %pFX, have %pRN", + __func__, p, rn); if (p && prefix_cmp(p, rn_p)) continue; @@ -4512,12 +4496,11 @@ static void rfapiDeleteRemotePrefixesIt( continue; if (bpi->extra->vnc.import.timer) { - struct thread *t = - (struct thread *)bpi - ->extra->vnc - .import.timer; + struct thread **t = + &(bpi->extra->vnc + .import.timer); struct rfapi_withdraw *wcb = - t->arg; + (*t)->arg; wcb->import_table ->holddown_count[afi] -= diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index cd26892b84..ce916c104b 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -620,10 +620,7 @@ void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, rfapiMonitorDetachImport(m); } - if (m->timer) { - thread_cancel(m->timer); - m->timer = NULL; - } + thread_cancel(&m->timer); /* * remove from rfd list @@ -660,10 +657,7 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd) rfapiMonitorDetachImport(m); } - if (m->timer) { - thread_cancel(m->timer); - m->timer = NULL; - } + thread_cancel(&m->timer); XFREE(MTYPE_RFAPI_MONITOR, m); rn->info = NULL; @@ -697,10 +691,7 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd) #endif } - if (mon_eth->timer) { - thread_cancel(mon_eth->timer); - mon_eth->timer = NULL; - } + thread_cancel(&mon_eth->timer); /* * remove from rfd list @@ -766,8 +757,7 @@ static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m) if (m->rfd->response_lifetime - remain < 2) return; - thread_cancel(m->timer); - m->timer = NULL; + thread_cancel(&m->timer); } { @@ -846,9 +836,6 @@ void rfapiMonitorItNodeChanged( struct bgp *bgp = bgp_get_default(); const struct prefix *p = agg_node_get_prefix(rn); afi_t afi = family2afi(p->family); -#if DEBUG_L2_EXTRA - char buf_prefix[PREFIX_STRLEN]; -#endif assert(bgp); assert(import_table); @@ -856,9 +843,8 @@ void rfapiMonitorItNodeChanged( nves_seen = skiplist_new(0, NULL, NULL); #if DEBUG_L2_EXTRA - prefix2str(&it_node->p, buf_prefix, sizeof(buf_prefix)); - vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%s", - __func__, import_table, it_node, buf_prefix); + vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%pFX", + __func__, import_table, it_node, &it_node->p); #endif if (AFI_L2VPN == afi) { @@ -934,14 +920,10 @@ void rfapiMonitorItNodeChanged( assert(!skiplist_insert(nves_seen, m->rfd, NULL)); - char buf_target_pfx[PREFIX_STRLEN]; - - prefix2str(&m->p, buf_target_pfx, - sizeof(buf_target_pfx)); vnc_zlog_debug_verbose( - "%s: update rfd %p attached to pfx %pRN (targ=%s)", + "%s: update rfd %p attached to pfx %pRN (targ=%pFX)", __func__, m->rfd, m->node, - buf_target_pfx); + &m->p); /* * update its RIB @@ -1086,8 +1068,7 @@ static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m) if (m->rfd->response_lifetime - remain < 2) return; - thread_cancel(m->timer); - m->timer = NULL; + thread_cancel(&m->timer); } { @@ -1269,21 +1250,15 @@ static void rfapiMonitorEthDetachImport( rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); assert(rn); -#if DEBUG_L2_EXTRA - char buf_prefix[PREFIX_STRLEN]; - - prefix2str(agg_node_get_prefix(rn), buf_prefix, sizeof(buf_prefix)); -#endif - /* * Get sl to detach from */ sl = RFAPI_MONITOR_ETH(rn); #if DEBUG_L2_EXTRA vnc_zlog_debug_verbose( - "%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%s, LNI=%d, detaching eth mon %p", - __func__, it, rn, rn->lock, sl, buf_prefix, mon->logical_net_id, - mon); + "%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%pFX, LNI=%d, detaching eth mon %p", + __func__, it, rn, rn->lock, sl, agg_node_get_prefix(rn), + mon->logical_net_id, mon); #endif assert(sl); @@ -1432,10 +1407,7 @@ void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd, rfapiMonitorEthDetachImport(bgp, val); } - if (val->timer) { - thread_cancel(val->timer); - val->timer = NULL; - } + thread_cancel(&val->timer); /* * remove from rfd list diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index e068eb7af6..630a379ec2 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -269,9 +269,8 @@ static void rfapi_info_free(struct rfapi_info *goner) struct rfapi_rib_tcb *tcb; tcb = goner->timer->arg; - thread_cancel(goner->timer); + thread_cancel(&goner->timer); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); - goner->timer = NULL; } XFREE(MTYPE_RFAPI_INFO, goner); } @@ -338,13 +337,11 @@ static void rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct agg_node *rn, /* route node attached to */ int deleted) { - struct thread *t = ri->timer; struct rfapi_rib_tcb *tcb = NULL; - if (t) { - tcb = t->arg; - thread_cancel(t); - ri->timer = NULL; + if (ri->timer) { + tcb = ri->timer->arg; + thread_cancel(&ri->timer); } else { tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE, sizeof(struct rfapi_rib_tcb)); @@ -802,7 +799,7 @@ int rfapiRibPreloadBi( */ trn = agg_node_get(rfd->rsp_times[afi], p); /* locks trn */ trn->info = (void *)(uintptr_t)bgp_clock(); - if (trn->lock > 1) + if (agg_node_get_lock_count(trn) > 1) agg_unlock_node(trn); return 0; @@ -907,10 +904,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, delete_list = list_new(); while (0 == skiplist_first(slRibPt, NULL, (void **)&ri)) { - - char buf[PREFIX_STRLEN]; - char buf2[PREFIX_STRLEN]; - listnode_add(delete_list, ri); vnc_zlog_debug_verbose( "%s: after listnode_add, delete_list->count=%d", @@ -921,18 +914,15 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, if (ri->timer) { struct rfapi_rib_tcb *tcb; - tcb = ((struct thread *)ri->timer)->arg; - thread_cancel(ri->timer); + tcb = ri->timer->arg; + thread_cancel(&ri->timer); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); - ri->timer = NULL; } - prefix2str(&ri->rk.vn, buf, sizeof(buf)); - prefix2str(&ri->un, buf2, sizeof(buf2)); vnc_zlog_debug_verbose( - "%s: put dl pfx=%pRN vn=%s un=%s cost=%d life=%d vn_options=%p", - __func__, pn, buf, buf2, ri->cost, - ri->lifetime, ri->vn_options); + "%s: put dl pfx=%pRN vn=%pFX un=%pFX cost=%d life=%d vn_options=%p", + __func__, pn, &ri->rk.vn, &ri->un, + ri->cost, ri->lifetime, ri->vn_options); skiplist_delete_first(slRibPt); } @@ -1009,11 +999,9 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, if (ori->timer) { struct rfapi_rib_tcb *tcb; - tcb = ((struct thread *)ori->timer) - ->arg; - thread_cancel(ori->timer); + tcb = ori->timer->arg; + thread_cancel(&ori->timer); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); - ori->timer = NULL; } #if DEBUG_PROCESS_PENDING_NODE @@ -1242,7 +1230,7 @@ callback: trn = agg_node_get(rfd->rsp_times[afi], p); /* locks trn */ trn->info = (void *)(uintptr_t)bgp_clock(); - if (trn->lock > 1) + if (agg_node_get_lock_count(trn) > 1) agg_unlock_node(trn); rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ); @@ -1357,11 +1345,9 @@ callback: if (ri->timer) { struct rfapi_rib_tcb *tcb; - tcb = ((struct thread *)ri->timer)->arg; - thread_cancel( - (struct thread *)ri->timer); + tcb = ri->timer->arg; + thread_cancel(&ri->timer); XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); - ri->timer = NULL; } RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); @@ -1589,7 +1575,6 @@ void rfapiRibUpdatePendingNode( afi_t afi; uint32_t queued_flag; int count = 0; - char buf[PREFIX_STRLEN]; vnc_zlog_debug_verbose("%s: entry", __func__); @@ -1602,8 +1587,7 @@ void rfapiRibUpdatePendingNode( prefix = agg_node_get_prefix(it_node); afi = family2afi(prefix->family); - prefix2str(prefix, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf); + vnc_zlog_debug_verbose("%s: prefix=%pFX", __func__, prefix); pn = agg_node_get(rfd->rib_pending[afi], prefix); assert(pn); @@ -1809,11 +1793,8 @@ int rfapiRibFTDFilterRecentPrefix( #ifdef DEBUG_FTD_FILTER_RECENT { - char buf_pfx[PREFIX_STRLEN]; - - prefix2str(agg_node_get_prefix(it_rn), buf_pfx, - sizeof(buf_pfx)); - vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); + vnc_zlog_debug_verbose("%s: prefix %pFX", __func__, + agg_node_get_prefix(it_rn)); } #endif @@ -1833,7 +1814,7 @@ int rfapiRibFTDFilterRecentPrefix( */ trn = agg_node_get(rfd->rsp_times[afi], p); /* locks trn */ prefix_time = (time_t)trn->info; - if (trn->lock > 1) + if (agg_node_get_lock_count(trn) > 1) agg_unlock_node(trn); #ifdef DEBUG_FTD_FILTER_RECENT @@ -1974,21 +1955,18 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, #if DEBUG_NHL { - char str_vn[PREFIX_STRLEN]; char str_aux_prefix[PREFIX_STRLEN]; - str_vn[0] = 0; str_aux_prefix[0] = 0; - prefix2str(&rk.vn, str_vn, sizeof(str_vn)); prefix2str(&rk.aux_prefix, str_aux_prefix, sizeof(str_aux_prefix)); if (!rk.aux_prefix.family) { } vnc_zlog_debug_verbose( - "%s: rk.vn=%s rk.aux_prefix=%s", __func__, - str_vn, + "%s: rk.vn=%pFX rk.aux_prefix=%s", __func__, + &rk.vn, (rk.aux_prefix.family ? str_aux_prefix : "-")); } vnc_zlog_debug_verbose( @@ -2069,20 +2047,13 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, */ trn = agg_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */ trn->info = (void *)(uintptr_t)bgp_clock(); - if (trn->lock > 1) + if (agg_node_get_lock_count(trn) > 1) agg_unlock_node(trn); - { - char str_pfx[PREFIX_STRLEN]; - char str_pfx_vn[PREFIX_STRLEN]; - - prefix2str(&pfx, str_pfx, sizeof(str_pfx)); - prefix2str(&rk.vn, str_pfx_vn, sizeof(str_pfx_vn)); - vnc_zlog_debug_verbose( - "%s: added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", - __func__, str_pfx, str_pfx_vn, nhp->prefix.cost, - nhp->lifetime, allowed); - } + vnc_zlog_debug_verbose( + "%s: added pfx=%pFX nh[vn]=%pFX, cost=%u, lifetime=%u, allowed=%d", + __func__, &pfx, &rk.vn, nhp->prefix.cost, nhp->lifetime, + allowed); if (allowed) { if (tail) diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index d74404ea56..b9a6c4ddc4 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -751,7 +751,7 @@ void rfapiShowItNode(void *stream, struct agg_node *rn) if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) return; - fp(out, "%pRN @%p #%d%s", rn, rn, rn->lock, HVTYNL); + fp(out, "%pRN @%p #%d%s", rn, rn, agg_node_get_lock_count(rn), HVTYNL); for (bpi = rn->info; bpi; bpi = bpi->next) { rfapiPrintBi(stream, bpi); @@ -787,7 +787,8 @@ void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt, } fp(out, "%s/%d @%p #%d%s", buf, p->prefixlen, rn, - rn->lock - 1, /* account for loop iterator locking */ + agg_node_get_lock_count(rn) + - 1, /* account for loop iterator locking */ HVTYNL); for (bpi = rn->info; bpi; bpi = bpi->next) { @@ -1595,7 +1596,6 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd) int rc; afi_t afi; struct rfapi_adb *adb; - char buf[PREFIX_STRLEN]; vty_out(vty, "%-10p ", rfd); rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); @@ -1647,9 +1647,8 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd) if (family != adb->u.s.prefix_ip.family) continue; - prefix2str(&adb->u.s.prefix_ip, buf, sizeof(buf)); - - vty_out(vty, " Adv Pfx: %s%s", buf, HVTYNL); + vty_out(vty, " Adv Pfx: %pFX%s", &adb->u.s.prefix_ip, + HVTYNL); rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); } @@ -1658,10 +1657,7 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd) (void **)&adb, &cursor); rc == 0; rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL, (void **)&adb, &cursor)) { - - prefix2str(&adb->u.s.prefix_eth, buf, sizeof(buf)); - - vty_out(vty, " Adv Pfx: %s%s", buf, HVTYNL); + vty_out(vty, " Adv Pfx: %pFX%s", &adb->u.s.prefix_eth, HVTYNL); /* TBD update the following function to print ethernet info */ /* Also need to pass/use rd */ @@ -1862,11 +1858,9 @@ void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops) break; case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP: - prefix2str(&vo->v.local_nexthop.addr, - pbuf, sizeof(pbuf)); - fp(out, "%sLNH %s cost=%d%s", offset, - pbuf, vo->v.local_nexthop.cost, - HVTYNL); + fp(out, "%sLNH %pFX cost=%d%s", offset, + &vo->v.local_nexthop.addr, + vo->v.local_nexthop.cost, HVTYNL); break; default: diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 0480704b27..11f39b2b82 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -1711,14 +1711,11 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, rfapiGetVncLifetime(attr, &eti->lifetime); eti->lifetime = rfapiGetHolddownFromLifetime(eti->lifetime); - if (eti->timer) { - /* - * export expiration timer is already running on - * this route: cancel it - */ - thread_cancel(eti->timer); - eti->timer = NULL; - } + /* + * export expiration timer is already running on + * this route: cancel it + */ + thread_cancel(&eti->timer); bgp_update(peer, prefix, /* prefix */ 0, /* addpath_id */ @@ -1865,7 +1862,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi) if (!bgp_dest_has_bgp_path_info_data(dest)) continue; - vnc_zlog_debug_verbose("%s: checking prefix %pRN", + vnc_zlog_debug_verbose("%s: checking prefix %pBD", __func__, dest); dest_p = bgp_dest_get_prefix(dest); @@ -1947,15 +1944,12 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi) rfapiGetVncLifetime(ri->attr, &eti->lifetime); - if (eti->timer) { - /* - * export expiration timer is - * already running on - * this route: cancel it - */ - thread_cancel(eti->timer); - eti->timer = NULL; - } + /* + * export expiration timer is + * already running on + * this route: cancel it + */ + thread_cancel(&eti->timer); vnc_zlog_debug_verbose( "%s: calling bgp_update", @@ -2024,8 +2018,7 @@ void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi) ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); if (eti) { - if (eti->timer) - thread_cancel(eti->timer); + thread_cancel(&eti->timer); vnc_eti_delete(eti); } diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 85d64b5a72..0b6b39b966 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -206,19 +206,11 @@ static void print_rhn_list(const char *tag1, const char *tag2) /* XXX uses secret knowledge of skiplist structure */ for (p = sl->header->forward[0]; p; p = p->forward[0]) { - char kbuf[PREFIX_STRLEN]; - char hbuf[PREFIX_STRLEN]; - char ubuf[PREFIX_STRLEN]; - pb = p->value; - prefix2str(p->key, kbuf, sizeof(kbuf)); - prefix2str(&pb->hpfx, hbuf, sizeof(hbuf)); - prefix2str(&pb->upfx, ubuf, sizeof(ubuf)); - vnc_zlog_debug_verbose( - "RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubpi=%p", - ++count, p, kbuf, ubuf, hbuf, pb->ubpi); + "RHN Entry %d (q=%p): kpfx=%pFX, upfx=%pFX, hpfx=%pFX, ubpi=%p", + ++count, p, p->key, &pb->upfx, &pb->hpfx, pb->ubpi); } } #endif @@ -260,15 +252,9 @@ static void vnc_rhnck(char *tag) * pfx */ assert(!vnc_prefix_cmp(&pb->hpfx, pkey)); if (vnc_prefix_cmp(&pb->hpfx, &pfx_orig_nexthop)) { - char str_onh[PREFIX_STRLEN]; - char str_nve_pfx[PREFIX_STRLEN]; - - prefix2str(&pfx_orig_nexthop, str_onh, sizeof(str_onh)); - prefix2str(&pb->hpfx, str_nve_pfx, sizeof(str_nve_pfx)); - vnc_zlog_debug_verbose( - "%s: %s: FATAL: resolve_nve_nexthop list item bpi nexthop %s != nve pfx %s", - __func__, tag, str_onh, str_nve_pfx); + "%s: %s: FATAL: resolve_nve_nexthop list item bpi nexthop %pFX != nve pfx %pFX", + __func__, tag, &pfx_orig_nexthop, &pb->hpfx); assert(0); } } @@ -529,13 +515,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_rd( if (!table_rd) return; - { - char str_nh[PREFIX_STRLEN]; - - prefix2str(ubpi_nexthop, str_nh, sizeof(str_nh)); - - vnc_zlog_debug_verbose("%s: ubpi_nexthop=%s", __func__, str_nh); - } + vnc_zlog_debug_verbose("%s: ubpi_nexthop=%pFX", __func__, ubpi_nexthop); /* exact match */ bd = bgp_node_lookup(table_rd, ubpi_nexthop); @@ -574,12 +554,9 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( /*debugging */ if (VNC_DEBUG(VERBOSE)) { - char str_pfx[PREFIX_STRLEN]; char str_nh[PREFIX_STRLEN]; struct prefix nh; - prefix2str(prefix, str_pfx, sizeof(str_pfx)); - nh.prefixlen = 0; rfapiUnicastNexthop2Prefix(afi, info->attr, &nh); if (nh.prefixlen) { @@ -590,8 +567,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve( } vnc_zlog_debug_verbose( - "%s(bgp=%p, unicast prefix=%s, unicast nh=%s)", - __func__, bgp, str_pfx, str_nh); + "%s(bgp=%p, unicast prefix=%pFX, unicast nh=%s)", + __func__, bgp, prefix, str_nh); } if (info->type != ZEBRA_ROUTE_BGP) { @@ -713,12 +690,7 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, uint32_t local_pref; uint32_t *med = NULL; - { - char buf[PREFIX_STRLEN]; - - prefix2str(prefix, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf); - } + vnc_zlog_debug_verbose("%s(prefix=%pFX) entry", __func__, prefix); if (!afi) { flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of prefix", @@ -783,12 +755,8 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV; } - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { - char buf[PREFIX_STRLEN]; - - prefix2str(vn_pfx, buf, sizeof(buf)); - vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf); - } + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) + vnc_zlog_debug_any("%s vn_pfx=%pFX", __func__, vn_pfx); /* * Compute VN address @@ -899,12 +867,7 @@ static void vnc_import_bgp_add_route_mode_nvegroup( struct route_map *rmap = NULL; uint32_t local_pref; - { - char buf[PREFIX_STRLEN]; - - prefix2str(prefix, buf, sizeof(buf)); - vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf); - } + vnc_zlog_debug_verbose("%s(prefix=%pFX) entry", __func__, prefix); assert(rfg); @@ -985,12 +948,8 @@ static void vnc_import_bgp_add_route_mode_nvegroup( vncHDBgpDirect.un_addr = pfx_un.prefix; } - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { - char buf[PREFIX_STRLEN]; - - prefix2str(vn_pfx, buf, sizeof(buf)); - vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf); - } + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) + vnc_zlog_debug_any("%s vn_pfx=%pFX", __func__, vn_pfx); /* * Compute VN address @@ -1288,12 +1247,7 @@ static void vnc_import_bgp_del_route_mode_resolve_nve_one_rd( if (!table_rd) return; - { - char str_nh[PREFIX_STRLEN]; - - prefix2str(ubpi_nexthop, str_nh, sizeof(str_nh)); - vnc_zlog_debug_verbose("%s: ubpi_nexthop=%s", __func__, str_nh); - } + vnc_zlog_debug_verbose("%s: ubpi_nexthop=%pFX", __func__, ubpi_nexthop); /* exact match */ @@ -1467,17 +1421,11 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( memset(&pfx_unicast_nexthop, 0, sizeof(struct prefix)); /* keep valgrind happy */ - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { - char hbuf[PREFIX_STRLEN]; - char ubuf[PREFIX_STRLEN]; - - prefix2str(&pb->hpfx, hbuf, sizeof(hbuf)); - prefix2str(&pb->upfx, ubuf, sizeof(ubuf)); - + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) vnc_zlog_debug_any( - "%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubpi=%p", - __func__, cursor, ubuf, hbuf, pb->ubpi); - } + "%s: examining RHN Entry (q=%p): upfx=%pFX, hpfx=%pFX, ubpi=%p", + __func__, cursor, &pb->upfx, &pb->hpfx, + pb->ubpi); if (process_unicast_route(bgp, afi, &pb->upfx, pb->ubpi, &ecom, &pfx_unicast_nexthop)) { @@ -1497,16 +1445,9 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( * Sanity check */ if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) { - char str_unh[PREFIX_STRLEN]; - char str_nve_pfx[PREFIX_STRLEN]; - - prefix2str(&pfx_unicast_nexthop, str_unh, - sizeof(str_unh)); - prefix2str(prefix, str_nve_pfx, sizeof(str_nve_pfx)); - vnc_zlog_debug_verbose( - "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %s != nve pfx %s", - __func__, str_unh, str_nve_pfx); + "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %pFX != nve pfx %pFX", + __func__, &pfx_unicast_nexthop, prefix); assert(0); } @@ -1521,13 +1462,9 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( #if DEBUG_RHN_LIST /* debug */ { - char pbuf[PREFIX_STRLEN]; - - prefix2str(prefix, pbuf, sizeof(pbuf)); - vnc_zlog_debug_verbose( - "%s: advancing past RHN Entry (q=%p): with prefix %s", - __func__, cursor, pbuf); + "%s: advancing past RHN Entry (q=%p): with prefix %pFX", + __func__, cursor, prefix); print_rhn_list(__func__, NULL); /* debug */ } #endif @@ -1550,14 +1487,8 @@ void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( struct rfapi_cfg *hc = NULL; int rc; - { - char str_pfx[PREFIX_STRLEN]; - - prefix2str(prefix, str_pfx, sizeof(str_pfx)); - - vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%s)", __func__, - bgp, str_pfx); - } + vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%pFX)", __func__, bgp, + prefix); if (afi != AFI_IP && afi != AFI_IP6) return; @@ -1621,16 +1552,9 @@ void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( * Sanity check */ if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) { - char str_unh[PREFIX_STRLEN]; - char str_nve_pfx[PREFIX_STRLEN]; - - prefix2str(&pfx_unicast_nexthop, str_unh, - sizeof(str_unh)); - prefix2str(prefix, str_nve_pfx, sizeof(str_nve_pfx)); - vnc_zlog_debug_verbose( - "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %s != nve pfx %s", - __func__, str_unh, str_nve_pfx); + "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %pFX != nve pfx %pFX", + __func__, &pfx_unicast_nexthop, prefix); assert(0); } @@ -2305,13 +2229,11 @@ void vnc_import_bgp_exterior_add_route_interior( (void **)&pfx_exterior, &cursor)) { struct prefix pfx_nexthop; - char buf[PREFIX_STRLEN]; afi_t afi_exterior = family2afi(pfx_exterior->family); - prefix2str(pfx_exterior, buf, sizeof(buf)); vnc_zlog_debug_verbose( - "%s: checking exterior orphan at prefix %s", __func__, - buf); + "%s: checking exterior orphan at prefix %pFX", __func__, + pfx_exterior); if (afi_exterior != afi) { vnc_zlog_debug_verbose( @@ -2602,15 +2524,10 @@ void vnc_import_bgp_add_route(struct bgp *bgp, const struct prefix *prefix, if (VNC_DEBUG(VERBOSE)) { struct prefix pfx_nexthop; - char buf[PREFIX_STRLEN]; - char buf_nh[PREFIX_STRLEN]; - prefix2str(prefix, buf, sizeof(buf)); rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop); - prefix2str(&pfx_nexthop, buf_nh, sizeof(buf_nh)); - - vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf, - buf_nh); + vnc_zlog_debug_verbose("%s: pfx %pFX, nh %pFX", __func__, + prefix, &pfx_nexthop); } #if DEBUG_RHN_LIST print_rhn_list(__func__, "ENTER "); @@ -2673,15 +2590,10 @@ void vnc_import_bgp_del_route(struct bgp *bgp, const struct prefix *prefix, { struct prefix pfx_nexthop; - char buf[PREFIX_STRLEN]; - char buf_nh[PREFIX_STRLEN]; - prefix2str(prefix, buf, sizeof(buf)); rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop); - prefix2str(&pfx_nexthop, buf_nh, sizeof(buf_nh)); - - vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf, - buf_nh); + vnc_zlog_debug_verbose("%s: pfx %pFX, nh %pFX", __func__, + prefix, &pfx_nexthop); } #if DEBUG_RHN_LIST print_rhn_list(__func__, "ENTER "); diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 008c7b28b7..b254f11ce7 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -363,15 +363,11 @@ static int vnc_zebra_read_route(ZAPI_CALLBACK_ARGS) else vnc_redistribute_delete(&api.prefix, api.type); - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[PREFIX_STRLEN]; - - prefix2str(&api.prefix, buf, sizeof(buf)); + if (BGP_DEBUG(zebra, ZEBRA)) vnc_zlog_debug_verbose( - "%s: Zebra rcvd: route delete %s %s metric %u", - __func__, zebra_route_string(api.type), buf, + "%s: Zebra rcvd: route delete %s %pFX metric %u", + __func__, zebra_route_string(api.type), &api.prefix, api.metric); - } return 0; } @@ -425,14 +421,10 @@ static void vnc_zebra_route_msg(const struct prefix *p, unsigned int nhp_count, } } - if (BGP_DEBUG(zebra, ZEBRA)) { - char buf[PREFIX_STRLEN]; - - prefix2str(&api.prefix, buf, sizeof(buf)); + if (BGP_DEBUG(zebra, ZEBRA)) vnc_zlog_debug_verbose( - "%s: Zebra send: route %s %s, nhp_count=%d", __func__, - (add ? "add" : "del"), buf, nhp_count); - } + "%s: Zebra send: route %s %pFX, nhp_count=%d", __func__, + (add ? "add" : "del"), &api.prefix, nhp_count); zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE), zclient_vnc, &api); diff --git a/bgpd/subdir.am b/bgpd/subdir.am index d1f93957ee..ea60b921d1 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -61,6 +61,7 @@ bgpd_libbgp_a_SOURCES = \ bgpd/bgp_bfd.c \ bgpd/bgp_clist.c \ bgpd/bgp_community.c \ + bgpd/bgp_conditional_adv.c \ bgpd/bgp_damp.c \ bgpd/bgp_debug.c \ bgpd/bgp_dump.c \ @@ -102,6 +103,9 @@ bgpd_libbgp_a_SOURCES = \ bgpd/bgp_vty.c \ bgpd/bgp_zebra.c \ bgpd/bgpd.c \ + bgpd/bgp_nb.c \ + bgpd/bgp_nb_config.c \ + bgpd/bgp_trace.c \ # end if ENABLE_BGP_VNC @@ -134,6 +138,7 @@ noinst_HEADERS += \ bgpd/bgp_bfd.h \ bgpd/bgp_clist.h \ bgpd/bgp_community.h \ + bgpd/bgp_conditional_adv.h \ bgpd/bgp_damp.h \ bgpd/bgp_debug.h \ bgpd/bgp_dump.h \ @@ -175,6 +180,8 @@ noinst_HEADERS += \ bgpd/bgp_vty.h \ bgpd/bgp_zebra.h \ bgpd/bgpd.h \ + bgpd/bgp_nb.h \ + bgpd/bgp_trace.h \ \ bgpd/rfapi/bgp_rfapi_cfg.h \ bgpd/rfapi/rfapi_import.h \ @@ -205,8 +212,8 @@ bgpd_bgpd_CFLAGS = $(AM_CFLAGS) bgpd_bgp_btoa_CFLAGS = $(AM_CFLAGS) # RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am -bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) -bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) +bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS) +bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS) bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99 @@ -231,3 +238,16 @@ clippy_scan += \ bgpd/bgp_rpki.c \ bgpd/bgp_vty.c \ # end + +nodist_bgpd_bgpd_SOURCES = \ + yang/frr-bgp-types.yang.c \ + yang/frr-bgp.yang.c \ + yang/frr-bgp-common-structure.yang.c \ + yang/frr-bgp-common.yang.c \ + yang/frr-bgp-common-multiprotocol.yang.c \ + yang/frr-bgp-neighbor.yang.c \ + yang/frr-bgp-peer-group.yang.c \ + yang/frr-bgp-bmp.yang.c \ + yang/frr-bgp-rpki.yang.c \ + yang/frr-deviations-bgp-datacenter.yang.c \ + # end diff --git a/configure.ac b/configure.ac index 3cc74c4110..237552c140 100755 --- a/configure.ac +++ b/configure.ac @@ -139,6 +139,13 @@ AC_ARG_WITH([yangmodelsdir], [AS_HELP_STRING([--with-yangmodelsdir=DIR], [yang m ]) AC_SUBST([yangmodelsdir]) +AC_ARG_WITH([vici-socket], [AS_HELP_STRING([--with-vici-socket=PATH], [vici-socket (/var/run/charon.vici)])], [ + vici_socket="$withval" +], [ + vici_socket="/var/run/charon.vici" +]) +AC_DEFINE_UNQUOTED([VICI_SOCKET], ["$vici_socket"], [StrongSWAN vici socket path]) + AC_ARG_ENABLE(tcmalloc, AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]), [case "${enableval}" in @@ -444,6 +451,11 @@ fi AC_SUBST([AC_LDFLAGS]) AM_CONDITIONAL([STATIC_BIN], [test "$enable_static_bin" = "yes"]) +AC_ARG_ENABLE([rpath], + [AS_HELP_STRING([--enable-rpath], [set hardcoded rpaths in the executable @<:@default=yes@:>@])], + [], + [enable_rpath=yes]) + dnl $AR and $RANLIB are set by LT_INIT above AC_MSG_CHECKING([whether $AR supports D option]) if $AR crD conftest.a >/dev/null 2>/dev/null; then @@ -559,6 +571,10 @@ AC_ARG_ENABLE([grpc], AS_HELP_STRING([--enable-grpc], [enable the gRPC northbound plugin])) AC_ARG_ENABLE([zeromq], AS_HELP_STRING([--enable-zeromq], [enable ZeroMQ handler (libfrrzmq)])) +AC_ARG_ENABLE([lttng], + AS_HELP_STRING([--enable-lttng], [enable LTTng tracing])) +AC_ARG_ENABLE([usdt], + AS_HELP_STRING([--enable-usdt], [enable USDT probes])) AC_ARG_WITH([libpam], AS_HELP_STRING([--with-libpam], [use libpam for PAM support in vtysh])) AC_ARG_ENABLE([ospfapi], @@ -1844,6 +1860,30 @@ if test "$enable_grpc" = "yes"; then ]) fi +dnl ----- +dnl LTTng +dnl ----- +if test "$enable_lttng" = "yes"; then + PKG_CHECK_MODULES([UST], [lttng-ust >= 2.12.0], [ + AC_DEFINE([HAVE_LTTNG], [1], [Enable LTTng support]) + LTTNG=true + ], [ + AC_MSG_ERROR([configuration specifies --enable-lttng but lttng-ust was not found]) + ]) +fi + +dnl ---- +dnl USDT +dnl ---- +if test "$enable_usdt" = "yes"; then + AC_CHECK_HEADERS([sys/sdt.h], [ + AC_DEFINE([HAVE_USDT], [1], [Enable USDT probes]) + USDT=true + ], [ + AC_MSG_ERROR([configuration specifies --enable-usdt but no USDT kernel headers (sys/sdt.h) found]) + ]) +fi + dnl ------ dnl ZeroMQ dnl ------ @@ -2492,6 +2532,14 @@ AS_IF([test "$with_pkg_git_version" = "yes"], [ ## It's already in CVS until texinfo 4.7 is more common. AC_OUTPUT +if test "$enable_rpath" = "yes" ; then + true +else + # See https://old-en.opensuse.org/openSUSE:Packaging_Guidelines#Removing_Rpath + sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool + sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool +fi + echo " FRRouting configuration ------------------------------ @@ -2512,6 +2560,7 @@ group for vty sockets : ${enable_vty_group} config file mask : ${enable_configfile_mask} log file mask : ${enable_logfile_mask} zebra protobuf enabled : ${enable_protobuf:-no} +vici socket path : ${vici_socket} The above user and group must have read/write access to the state file directory and to the config files in the config file directory." diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 9acfab739a..f4bb65ec79 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -21,48 +21,48 @@ from sphinx.highlighting import lexers # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.0' +needs_sphinx = "1.0" # prolog for various variable substitutions -rst_prolog = '' +rst_prolog = "" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.todo', 'sphinx.ext.graphviz'] +extensions = ["sphinx.ext.todo", "sphinx.ext.graphviz"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'FRR' -copyright = u'2017, FRR' -author = u'FRR authors' +project = u"FRR" +copyright = u"2017, FRR" +author = u"FRR authors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The short X.Y version. -version = u'?.?' +version = u"?.?" # The full version, including alpha/beta/rc tags. -release = u'?.?-?' +release = u"?.?-?" # ----------------------------------------------------------------------------- @@ -72,48 +72,49 @@ release = u'?.?-?' # Various installation prefixes. Values are extracted from config.status. # Reasonable defaults are set in case that file does not exist. replace_vars = { - 'AUTHORS': author, - 'COPYRIGHT_YEAR': '1999-2005', - 'COPYRIGHT_STR': 'Copyright (c) 1999-2005', - 'PACKAGE_NAME': project.lower(), - 'PACKAGE_TARNAME': project.lower(), - 'PACKAGE_STRING': project.lower() + ' latest', - 'PACKAGE_URL': 'https://frrouting.org/', - 'PACKAGE_VERSION': 'latest', - 'INSTALL_PREFIX_ETC': '/etc/frr', - 'INSTALL_PREFIX_SBIN': '/usr/lib/frr', - 'INSTALL_PREFIX_STATE': '/var/run/frr', - 'INSTALL_PREFIX_MODULES': '/usr/lib/frr/modules', - 'INSTALL_USER': 'frr', - 'INSTALL_GROUP': 'frr', - 'INSTALL_VTY_GROUP': 'frrvty', - 'GROUP': 'frr', - 'USER': 'frr', + "AUTHORS": author, + "COPYRIGHT_YEAR": "1999-2005", + "COPYRIGHT_STR": "Copyright (c) 1999-2005", + "PACKAGE_NAME": project.lower(), + "PACKAGE_TARNAME": project.lower(), + "PACKAGE_STRING": project.lower() + " latest", + "PACKAGE_URL": "https://frrouting.org/", + "PACKAGE_VERSION": "latest", + "INSTALL_PREFIX_ETC": "/etc/frr", + "INSTALL_PREFIX_SBIN": "/usr/lib/frr", + "INSTALL_PREFIX_STATE": "/var/run/frr", + "INSTALL_PREFIX_MODULES": "/usr/lib/frr/modules", + "INSTALL_USER": "frr", + "INSTALL_GROUP": "frr", + "INSTALL_VTY_GROUP": "frrvty", + "GROUP": "frr", + "USER": "frr", } # extract version information, installation location, other stuff we need to # use when building final documents val = re.compile('^S\["([^"]+)"\]="(.*)"$') try: - with open('../../config.status', 'r') as cfgstatus: + with open("../../config.status", "r") as cfgstatus: for ln in cfgstatus.readlines(): m = val.match(ln) - if not m or m.group(1) not in replace_vars.keys(): continue + if not m or m.group(1) not in replace_vars.keys(): + continue replace_vars[m.group(1)] = m.group(2) except IOError: # if config.status doesn't exist, just ignore it pass # manually fill out some of these we can't get from config.status -replace_vars['COPYRIGHT_STR'] = "Copyright (c)" -replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR']) -replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS']) -release = replace_vars['PACKAGE_VERSION'] -version = release.split('-')[0] +replace_vars["COPYRIGHT_STR"] = "Copyright (c)" +replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["COPYRIGHT_YEAR"]) +replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["AUTHORS"]) +release = replace_vars["PACKAGE_VERSION"] +version = release.split("-")[0] # add substitutions to prolog for key, value in replace_vars.items(): - rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value) + rst_prolog += ".. |{0}| replace:: {1}\n".format(key, value) # The language for content autogenerated by Sphinx. Refer to documentation @@ -125,37 +126,42 @@ language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'building-libyang.rst', 'topotests-snippets.rst', 'include-compile.rst'] +exclude_patterns = [ + "_build", + "building-libyang.rst", + "topotests-snippets.rst", + "include-compile.rst", +] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True @@ -165,165 +171,158 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" try: import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' + html_theme = "sphinx_rtd_theme" except ImportError: pass # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = { +# html_theme_options = { # 'sidebarbgcolor': '#374249' -#} +# } # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '../figures/frr-icon.svg' +html_logo = "../figures/frr-icon.svg" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -html_favicon = '../figures/frr-logo-icon.png' +html_favicon = "../figures/frr-logo-icon.png" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a <link> tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'FRRdoc' +htmlhelp_basename = "FRRdoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'FRR.tex', u"FRR Developer's Manual", - u'FRR', 'manual'), + (master_doc, "FRR.tex", u"FRR Developer's Manual", u"FRR", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -latex_logo = '../figures/frr-logo-medium.png' +latex_logo = "../figures/frr-logo-medium.png" # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'frr', u"FRR Developer's Manual", - [author], 1) -] +man_pages = [(master_doc, "frr", u"FRR Developer's Manual", [author], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -332,38 +331,44 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'frr', u"FRR Developer's Manual", - author, 'FRR', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "frr", + u"FRR Developer's Manual", + author, + "FRR", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # contents of ../extra/frrlexer.py. # This is read here to support VPATH build. Since this section is execfile()'d # with the file location, we can safely use a relative path here to save the # contents of the lexer file for later use even if our relative path changes # due to VPATH. -with open('../extra/frrlexer.py', 'rb') as lex: +with open("../extra/frrlexer.py", "rb") as lex: frrlexerpy = lex.read() # custom extensions here def setup(app): # object type for FRR CLI commands, can be extended to document parent CLI # node later on - app.add_object_type('clicmd', 'clicmd') + app.add_object_type("clicmd", "clicmd") # css overrides for HTML theme - app.add_stylesheet('overrides.css') + app.add_stylesheet("overrides.css") # load Pygments lexer for FRR config syntax # # NB: in Pygments 2.2+ this can be done with `load_lexer_from_file`, but we @@ -373,4 +378,4 @@ def setup(app): # frrlexer = pygments.lexers.load_lexer_from_file('../extra/frrlexer.py', lexername="FRRLexer") custom_namespace = {} exec(frrlexerpy, custom_namespace) - lexers['frr'] = custom_namespace['FRRLexer']() + lexers["frr"] = custom_namespace["FRRLexer"]() diff --git a/doc/developer/index.rst b/doc/developer/index.rst index 1f803b3772..1ba0f31c8a 100644 --- a/doc/developer/index.rst +++ b/doc/developer/index.rst @@ -9,6 +9,7 @@ FRRouting Developer's Guide packaging process-architecture library + tracing testing bgpd fpm diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst index 0430ad72a3..2f2444373c 100644 --- a/doc/developer/logging.rst +++ b/doc/developer/logging.rst @@ -83,6 +83,8 @@ Extensions +-----------+--------------------------+----------------------------------------------+ | ``%pNHs`` | ``struct nexthop *`` | ``1.2.3.4 if 15`` | +-----------+--------------------------+----------------------------------------------+ +| ``%pFX`` + ``struct bgp_dest *`` | ``fe80::1234/64`` available in BGP only | ++-----------+--------------------------+----------------------------------------------+ Printf features like field lengths can be used normally with these extensions, e.g. ``%-15pI4`` works correctly. diff --git a/doc/developer/tracing.rst b/doc/developer/tracing.rst new file mode 100644 index 0000000000..ee0a6be008 --- /dev/null +++ b/doc/developer/tracing.rst @@ -0,0 +1,314 @@ +.. _tracing: + +Tracing +======= + +FRR has a small but growing number of static tracepoints available for use with +various tracing systems. These tracepoints can assist with debugging, +performance analysis and to help understand program flow. They can also be used +for monitoring. + +Developers are encouraged to write new static tracepoints where sensible. They +are not compiled in by default, and even when they are, they have no overhead +unless enabled by a tracer, so it is okay to be liberal with them. + + +Supported tracers +----------------- + +Presently two types of tracepoints are supported: + +- `LTTng tracepoints <https://lttng.org/>`_ +- `USDT probes <http://dtrace.org/guide/chp-usdt.html>`_ + +LTTng is a tracing framework for Linux only. It offers extremely low overhead +and very rich tracing capabilities. FRR supports LTTng-UST, which is the +userspace implementation. LTTng tracepoints are very rich in detail. No kernel +modules are needed. Besides only being available for Linux, the primary +downside of LTTng is the need to link to ``lttng-ust``. + +USDT probes originate from Solaris, where they were invented for use with +dtrace. They are a kernel feature. At least Linux and FreeBSD support them. No +library is needed; support is compiled in via a system header +(``<sys/sdt.h>``). USDT probes are much slower than LTTng tracepoints and offer +less flexibility in what information can be gleaned from them. + +LTTng is capable of tracing USDT probes but has limited support for them. +SystemTap and dtrace both work only with USDT probes. + + +Usage +----- + +To compile with tracepoints, use one of the following configure flags: + +.. program:: configure.ac + +.. option:: --enable-lttng=yes + + Generate LTTng tracepoints + +.. option:: --enable-usdt=yes + + Generate USDT probes + +To trace with LTTng, compile with either one (prefer :option:`--enable-lttng` +run the target in non-forking mode (no ``-d``) and use LTTng as usual (refer to +LTTng user manual). When using USDT probes with LTTng, follow the example in +`this article +<https://lttng.org/blog/2019/10/15/new-dynamic-user-space-tracing-in-lttng/>`_. +To trace with dtrace or SystemTap, compile with :option:`--enable-usdt=yes` and +use your tracer as usual. + +To see available USDT probes:: + + readelf -n /usr/lib/frr/bgpd + +Example:: + + root@host ~> readelf -n /usr/lib/frr/bgpd + + Displaying notes found in: .note.ABI-tag + Owner Data size Description + GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) + OS: Linux, ABI: 3.2.0 + + Displaying notes found in: .note.gnu.build-id + Owner Data size Description + GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) + Build ID: 4f42933a69dcb42a519bc459b2105177c8adf55d + + Displaying notes found in: .note.stapsdt + Owner Data size Description + stapsdt 0x00000045 NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: packet_read + Location: 0x000000000045ee48, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-96(%rbp) 8@-104(%rbp) + stapsdt 0x00000047 NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: open_process + Location: 0x000000000047c43b, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-224(%rbp) 2@-226(%rbp) + stapsdt 0x00000049 NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: update_process + Location: 0x000000000047c4bf, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-208(%rbp) 2@-210(%rbp) + stapsdt 0x0000004f NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: notification_process + Location: 0x000000000047c557, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-192(%rbp) 2@-194(%rbp) + stapsdt 0x0000004c NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: keepalive_process + Location: 0x000000000047c5db, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-176(%rbp) 2@-178(%rbp) + stapsdt 0x0000004a NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: refresh_process + Location: 0x000000000047c673, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-160(%rbp) 2@-162(%rbp) + stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: capability_process + Location: 0x000000000047c6f7, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-144(%rbp) 2@-146(%rbp) + stapsdt 0x0000006f NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: output_filter + Location: 0x000000000048e33a, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp) + stapsdt 0x0000007d NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: process_update + Location: 0x0000000000491f10, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-800(%rbp) 8@-808(%rbp) 4@-812(%rbp) 4@-816(%rbp) 4@-820(%rbp) 8@-832(%rbp) + stapsdt 0x0000006e NT_STAPSDT (SystemTap probe descriptors) + Provider: frr_bgp + Name: input_filter + Location: 0x00000000004940ed, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000 + Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp) + + +To see available LTTng probes, run the target, create a session and then:: + + lttng list --userspace | grep frr + +Example:: + + root@host ~> lttng list --userspace | grep frr + PID: 11157 - Name: /usr/lib/frr/bgpd + frr_libfrr:route_node_get (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_sort (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_delete_node (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_remove (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:list_add (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:memfree (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:memalloc (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:frr_pthread_stop (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:frr_pthread_run (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint) + frr_libfrr:thread_call (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:thread_cancel_async (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:thread_cancel (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_write (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_read (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_event (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:schedule_timer (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:hash_release (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:hash_insert (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_libfrr:hash_get (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:output_filter (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:input_filter (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:process_update (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:packet_read (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:refresh_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:capability_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:notification_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:update_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:keepalive_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + frr_bgp:open_process (loglevel: TRACE_INFO (6)) (type: tracepoint) + +When using LTTng, you can also get zlogs as trace events by enabling +the ``lttng_ust_tracelog:*`` event class. + +Concepts +-------- + +Tracepoints are statically defined points in code where a developer has +determined that outside observers might gain something from knowing what is +going on at that point. It's like logging but with the ability to dump large +amounts of internal data with much higher performance. LTTng has a good summary +`here <https://lttng.org/docs/#doc-what-is-tracing>`_. + +Each tracepoint has a "provider" and name. The provider is basically a +namespace; for example, ``bgpd`` uses the provider name ``frr_bgp``. The name +is arbitrary, but because providers share a global namespace on the user's +system, all providers from FRR should be prefixed by ``frr_``. The tracepoint +name is just the name of the event. Events are globally named by their provider +and name. For example, the event when BGP reads a packet from a peer is +``frr_bgp:packet_read``. + +To do tracing, the tracing tool of choice is told which events to listen to. +For example, to listen to all events from FRR's BGP implementation, you would +enable the events ``frr_bgp:*``. In the same tracing session you could also +choose to record all memory allocations by enabling the ``malloc`` tracepoints +in ``libc`` as well as all kernel skb operations using the various in-kernel +tracepoints. This allows you to build as complete a view as desired of what the +system is doing during the tracing window (subject to what tracepoints are +available). + +Of particular use are the tracepoints for FRR's internal event scheduler; +tracing these allows you to see all events executed by all event loops for the +target(s) in question. Here's a couple events selected from a trace of BGP +during startup:: + + ... + + [18:41:35.750131763] (+0.000048901) host frr_libfrr:thread_call: { cpu_id = + 1 }, { threadmaster_name = "default", function_name = "zclient_connect", + scheduled_from = "lib/zclient.c", scheduled_on_line = 3877, thread_addr = + 0x0, file_descriptor = 0, event_value = 0, argument_ptr = 0xA37F70, timer = + 0 } + + [18:41:35.750175124] (+0.000020001) host frr_libfrr:thread_call: { cpu_id = + 1 }, { threadmaster_name = "default", function_name = "frr_config_read_in", + scheduled_from = "lib/libfrr.c", scheduled_on_line = 934, thread_addr = 0x0, + file_descriptor = 0, event_value = 0, argument_ptr = 0x0, timer = 0 } + + [18:41:35.753341264] (+0.000010532) host frr_libfrr:thread_call: { cpu_id = + 1 }, { threadmaster_name = "default", function_name = "bgp_event", + scheduled_from = "bgpd/bgpd.c", scheduled_on_line = 142, thread_addr = 0x0, + file_descriptor = 2, event_value = 2, argument_ptr = 0xE4D780, timer = 2 } + + [18:41:35.753404186] (+0.000004910) host frr_libfrr:thread_call: { cpu_id = + 1 }, { threadmaster_name = "default", function_name = "zclient_read", + scheduled_from = "lib/zclient.c", scheduled_on_line = 3891, thread_addr = + 0x0, file_descriptor = 40, event_value = 40, argument_ptr = 0xA37F70, timer + = 40 } + + ... + + +Very useful for getting a time-ordered look into what the process is doing. + + +Adding Tracepoints +------------------ + +Adding new tracepoints is a two step process: + +1. Define the tracepoint +2. Use the tracepoint + +Tracepoint definitions state the "provider" and name of the tracepoint, along +with any values it will produce, and how to format them. This is done with +macros provided by LTTng. USDT probes do not use definitions and are inserted +at the trace site with a single macro. However, to maintain support for both +platforms, you must define an LTTng tracepoint when adding a new one. +``frrtrace()`` will expand to the appropriate ``DTRACE_PROBEn`` macro when USDT +is in use. + +If you are adding new tracepoints to a daemon that has no tracepoints, that +daemon's ``subdir.am`` must be updated to conditionally link ``lttng-ust``. +Look at ``bgpd/subdir.am`` for an example of how to do this; grep for +``UST_LIBS``. Create new files named ``<daemon>_trace.[ch]``. Use +``bgpd/bgp_trace.[h]`` as boilerplate. If you are adding tracepoints to a +daemon that already has them, look for the ``<daemon>_trace.h`` file; +tracepoints are written here. + +Refer to the `LTTng developer docs +<https://lttng.org/docs/#doc-c-application>`_ for details on how to define +tracepoints. + +To use them, simply add a call to ``frrtrace()`` at the point you'd like the +event to be emitted, like so: + +.. code-block:: c + + ... + + switch (type) { + case BGP_MSG_OPEN: + frrtrace(2, frr_bgp, open_process, peer, size); /* tracepoint */ + atomic_fetch_add_explicit(&peer->open_in, 1, + memory_order_relaxed); + mprc = bgp_open_receive(peer, size); + + ... + +After recompiling this tracepoint will now be available, either as a USDT probe +or LTTng tracepoint, depending on your compilation choice. + + +trace.h +^^^^^^^ + +Because FRR supports multiple types of tracepoints, the code for creating them +abstracts away the underlying system being used. This abstraction code is in +``lib/trace.h``. There are 2 function-like macros that are used for working +with tracepoints. + +- ``frrtrace()`` defines tracepoints +- ``frrtrace_enabled()`` checks whether a tracepoint is enabled + +There is also ``frrtracelog()``, which is used in zlog core code to make zlog +messages available as trace events to LTTng. This should not be used elsewhere. + +There is additional documentation in the header. The key thing to note is that +you should never include ``trace.h`` in source where you plan to put +tracepoints; include the tracepoint definition header instead (e.g. +:file:`bgp_trace.h`). + + +Limitations +----------- + +Tracers do not like ``fork()`` or ``dlopen()``. LTTng has some workarounds for +this involving interceptor libraries using ``LD_PRELOAD``. + +USDT tracepoints are relatively high overhead and probably shouldn't be used +for "flight recorder" functionality, i.e. enabling and passively recording all +events for monitoring purposes. It's generally okay to use LTTng like this, +though. diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index f345464a35..4183ac6480 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -779,13 +779,12 @@ necessary replacements. .. _style-exceptions: Exceptions -^^^^^^^^^^ +"""""""""" FRR project code comes from a variety of sources, so there are some stylistic exceptions in place. They are organized here by branch. -For ``master`` -"""""""""""""" +For ``master``: BSD coding style applies to: @@ -797,8 +796,7 @@ BSD coding style applies to: - Indents are 4 spaces - Function return types are on their own line -For ``stable/3.0`` and ``stable/2.0`` -""""""""""""""""""""""""""""""""""""" +For ``stable/3.0`` and ``stable/2.0``: GNU coding style apply to the following parts: @@ -816,6 +814,21 @@ BSD coding style applies to: - ``ldpd/`` + +Python Code +^^^^^^^^^^^ + +Format all Python code with `black <https://github.com/psf/black>`_. + +In a line:: + + python3 -m black <file.py> + +Run this on any Python files you modify before committing. + +FRR's Python code has been formatted with black version 19.10b. + + YANG ^^^^ diff --git a/doc/extra/frrlexer.py b/doc/extra/frrlexer.py index 528bec985b..e177c3983f 100644 --- a/doc/extra/frrlexer.py +++ b/doc/extra/frrlexer.py @@ -22,17 +22,18 @@ class FRRLexer(RegexLexer): name = "frr" aliases = ["frr"] tokens = { - 'root': [ - (r'^[ \t]*!.*?\n', Comment.Singleline), + "root": [ + (r"^[ \t]*!.*?\n", Comment.Singleline), (r'"(\\\\|\\"|[^"])*"', String.Double), - (r'[a-f0-9]*:[a-f0-9]*:[a-f0-9:]*(:\d+\.\d+\.\d+\.\d+)?(/\d+)?', - Number), # IPv6 - (r'\d+\.\d+\.\d+\.\d+(/\d+)?', Number), # IPv4 - (r'^([ \t]*)(no[ \t]+)?([-\w]+)', - bygroups(Text, Keyword, Name.Function)), - (r'[ \t]+', Text), - (r'\n', Text), - (r'\d+', Number), - (r'\S+', Text), + ( + r"[a-f0-9]*:[a-f0-9]*:[a-f0-9:]*(:\d+\.\d+\.\d+\.\d+)?(/\d+)?", + Number, + ), # IPv6 + (r"\d+\.\d+\.\d+\.\d+(/\d+)?", Number), # IPv4 + (r"^([ \t]*)(no[ \t]+)?([-\w]+)", bygroups(Text, Keyword, Name.Function)), + (r"[ \t]+", Text), + (r"\n", Text), + (r"\d+", Number), + (r"\S+", Text), ], } diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py index 8b9bb021a3..186f7932b2 100644 --- a/doc/manpages/conf.py +++ b/doc/manpages/conf.py @@ -19,48 +19,48 @@ import re # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.0' +needs_sphinx = "1.0" # prolog for various variable substitutions -rst_prolog = '' +rst_prolog = "" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.todo'] +extensions = ["sphinx.ext.todo"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'FRR' -copyright = u'2017, FRR' -author = u'FRR authors' +project = u"FRR" +copyright = u"2017, FRR" +author = u"FRR authors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The short X.Y version. -version = u'?.?' +version = u"?.?" # The full version, including alpha/beta/rc tags. -release = u'?.?-?' +release = u"?.?-?" # ----------------------------------------------------------------------------- @@ -70,48 +70,49 @@ release = u'?.?-?' # Various installation prefixes. Values are extracted from config.status. # Reasonable defaults are set in case that file does not exist. replace_vars = { - 'AUTHORS': author, - 'COPYRIGHT_YEAR': '1999-2005', - 'COPYRIGHT_STR': 'Copyright (c) 1999-2005', - 'PACKAGE_NAME': project.lower(), - 'PACKAGE_TARNAME': project.lower(), - 'PACKAGE_STRING': project.lower() + ' latest', - 'PACKAGE_URL': 'https://frrouting.org/', - 'PACKAGE_VERSION': 'latest', - 'INSTALL_PREFIX_ETC': '/etc/frr', - 'INSTALL_PREFIX_SBIN': '/usr/lib/frr', - 'INSTALL_PREFIX_STATE': '/var/run/frr', - 'INSTALL_PREFIX_MODULES': '/usr/lib/frr/modules', - 'INSTALL_USER': 'frr', - 'INSTALL_GROUP': 'frr', - 'INSTALL_VTY_GROUP': 'frrvty', - 'GROUP': 'frr', - 'USER': 'frr', + "AUTHORS": author, + "COPYRIGHT_YEAR": "1999-2005", + "COPYRIGHT_STR": "Copyright (c) 1999-2005", + "PACKAGE_NAME": project.lower(), + "PACKAGE_TARNAME": project.lower(), + "PACKAGE_STRING": project.lower() + " latest", + "PACKAGE_URL": "https://frrouting.org/", + "PACKAGE_VERSION": "latest", + "INSTALL_PREFIX_ETC": "/etc/frr", + "INSTALL_PREFIX_SBIN": "/usr/lib/frr", + "INSTALL_PREFIX_STATE": "/var/run/frr", + "INSTALL_PREFIX_MODULES": "/usr/lib/frr/modules", + "INSTALL_USER": "frr", + "INSTALL_GROUP": "frr", + "INSTALL_VTY_GROUP": "frrvty", + "GROUP": "frr", + "USER": "frr", } # extract version information, installation location, other stuff we need to # use when building final documents val = re.compile('^S\["([^"]+)"\]="(.*)"$') try: - with open('../../config.status', 'r') as cfgstatus: + with open("../../config.status", "r") as cfgstatus: for ln in cfgstatus.readlines(): m = val.match(ln) - if not m or m.group(1) not in replace_vars.keys(): continue + if not m or m.group(1) not in replace_vars.keys(): + continue replace_vars[m.group(1)] = m.group(2) except IOError: # if config.status doesn't exist, just ignore it pass # manually fill out some of these we can't get from config.status -replace_vars['COPYRIGHT_STR'] = "Copyright (c)" -replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR']) -replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS']) -release = replace_vars['PACKAGE_VERSION'] -version = release.split('-')[0] +replace_vars["COPYRIGHT_STR"] = "Copyright (c)" +replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["COPYRIGHT_YEAR"]) +replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["AUTHORS"]) +release = replace_vars["PACKAGE_VERSION"] +version = release.split("-")[0] # add substitutions to prolog for key, value in replace_vars.items(): - rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value) + rst_prolog += ".. |{0}| replace:: {1}\n".format(key, value) # The language for content autogenerated by Sphinx. Refer to documentation @@ -123,37 +124,43 @@ language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'common-options.rst', 'epilogue.rst', 'defines.rst', 'bfd-options.rst'] +exclude_patterns = [ + "_build", + "common-options.rst", + "epilogue.rst", + "defines.rst", + "bfd-options.rst", +] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True @@ -163,31 +170,31 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -197,109 +204,105 @@ html_static_path = [] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a <link> tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'FRRdoc' +htmlhelp_basename = "FRRdoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'FRR.tex', u'FRR User Manual', - u'FRR', 'manual'), + (master_doc, "FRR.tex", u"FRR User Manual", u"FRR", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- @@ -308,33 +311,45 @@ latex_documents = [ # (source start file, name, description, authors, manual section). # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False fwfrr = "{0} routing engine for use with FRRouting." man_pages = [ - ('frr-bfdd', 'frr-bfdd', fwfrr.format("a bfd"), [], 8), - ('frr-bgpd', 'frr-bgpd', fwfrr.format("a BGPv4, BGPv4+, BGPv4-"), [], 8), - ('frr-eigrpd', 'frr-eigrpd', fwfrr.format("an EIGRP"), [], 8), - ('frr-fabricd', 'frr-fabricd', fwfrr.format("an OpenFabric"), [], 8), - ('frr-isisd', 'frr-isisd', fwfrr.format("an IS-IS"), [], 8), - ('frr-ldpd', 'frr-ldpd', fwfrr.format("an LDP"), [], 8), - ('frr-nhrpd', 'frr-nhrpd', fwfrr.format("a Next Hop Routing Protocol"), [], 8), - ('frr-ospf6d', 'frr-ospf6d', fwfrr.format("an OSPFv3"), [], 8), - ('frr-ospfclient', 'frr-ospfclient', 'an example ospf-api client', [], 8), - ('frr-ospfd', 'frr-ospfd', fwfrr.format("an OSPFv2"), [], 8), - ('frr-pbrd', 'frr-pbrd', fwfrr.format("a PBR"), [], 8), - ('frr-pimd', 'frr-pimd', fwfrr.format("a PIM"), [], 8), - ('frr-ripd', 'frr-ripd', fwfrr.format("a RIP"), [], 8), - ('frr-ripngd', 'frr-ripngd', fwfrr.format("a RIPNG"), [], 8), - ('frr-sharpd', 'frr-sharpd', fwfrr.format("a SHARP"), [], 8), - ('frr-staticd', 'frr-staticd', fwfrr.format("a static route manager"), [], 8), - ('frr-vrrpd', 'frr-vrrpd', fwfrr.format("a VRRP"), [], 8), - ('frr-watchfrr', 'frr-watchfrr', 'a program to monitor the status of FRRouting daemons', [], 8), - ('frr-zebra', 'frr-zebra', 'a routing manager for use with associated FRRouting components.', [], 8), - ('frr', 'frr', 'a systemd interaction script', [], 1), - ('mtracebis', 'mtracebis', "a multicast trace client", [], 8), - ('vtysh', 'vtysh', 'an integrated shell for FRRouting.', [], 1), + ("frr-bfdd", "frr-bfdd", fwfrr.format("a bfd"), [], 8), + ("frr-bgpd", "frr-bgpd", fwfrr.format("a BGPv4, BGPv4+, BGPv4-"), [], 8), + ("frr-eigrpd", "frr-eigrpd", fwfrr.format("an EIGRP"), [], 8), + ("frr-fabricd", "frr-fabricd", fwfrr.format("an OpenFabric"), [], 8), + ("frr-isisd", "frr-isisd", fwfrr.format("an IS-IS"), [], 8), + ("frr-ldpd", "frr-ldpd", fwfrr.format("an LDP"), [], 8), + ("frr-nhrpd", "frr-nhrpd", fwfrr.format("a Next Hop Routing Protocol"), [], 8), + ("frr-ospf6d", "frr-ospf6d", fwfrr.format("an OSPFv3"), [], 8), + ("frr-ospfclient", "frr-ospfclient", "an example ospf-api client", [], 8), + ("frr-ospfd", "frr-ospfd", fwfrr.format("an OSPFv2"), [], 8), + ("frr-pbrd", "frr-pbrd", fwfrr.format("a PBR"), [], 8), + ("frr-pimd", "frr-pimd", fwfrr.format("a PIM"), [], 8), + ("frr-ripd", "frr-ripd", fwfrr.format("a RIP"), [], 8), + ("frr-ripngd", "frr-ripngd", fwfrr.format("a RIPNG"), [], 8), + ("frr-sharpd", "frr-sharpd", fwfrr.format("a SHARP"), [], 8), + ("frr-staticd", "frr-staticd", fwfrr.format("a static route manager"), [], 8), + ("frr-vrrpd", "frr-vrrpd", fwfrr.format("a VRRP"), [], 8), + ( + "frr-watchfrr", + "frr-watchfrr", + "a program to monitor the status of FRRouting daemons", + [], + 8, + ), + ( + "frr-zebra", + "frr-zebra", + "a routing manager for use with associated FRRouting components.", + [], + 8, + ), + ("frr", "frr", "a systemd interaction script", [], 1), + ("mtracebis", "mtracebis", "a multicast trace client", [], 8), + ("vtysh", "vtysh", "an integrated shell for FRRouting.", [], 1), ] # -- Options for Texinfo output ------------------------------------------- @@ -344,15 +359,15 @@ man_pages = [ # dir menu entry, description, category) # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # custom extensions here diff --git a/doc/manpages/frr-zebra.rst b/doc/manpages/frr-zebra.rst index cfb368bf44..722b011ecd 100644 --- a/doc/manpages/frr-zebra.rst +++ b/doc/manpages/frr-zebra.rst @@ -25,10 +25,6 @@ OPTIONS available for the |DAEMON| command: Runs in batch mode, zebra parses its config and exits. -.. option:: -k, --keep_kernel - - On startup, don't delete self inserted routes. - .. option:: -s, --nl-bufsize <netlink-buffer-size> Set netlink receive buffer size. There are cases where zebra daemon can't handle flood of netlink messages from kernel. If you ever see "recvmsg overrun" messages in zebra log, you are in trouble. diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 10eaaee9fb..3572734ba9 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -999,6 +999,18 @@ Route Aggregation-IPv4 Address Family This command specifies an aggregate address. Aggregated routes will not be announced. +.. index:: aggregate-address A.B.C.D/M matching-MED-only +.. clicmd:: aggregate-address A.B.C.D/M matching-MED-only + + Configure the aggregated address to only be created when the routes MED + match, otherwise no aggregated route will be created. + +.. index:: aggregate-address A.B.C.D/M suppress-map NAME +.. clicmd:: aggregate-address A.B.C.D/M suppress-map NAME + + Similar to `summary-only`, but will only suppress more specific routes that + are matched by the selected route-map. + .. index:: no aggregate-address A.B.C.D/M .. clicmd:: no aggregate-address A.B.C.D/M @@ -1051,6 +1063,18 @@ Route Aggregation-IPv6 Address Family This command specifies an aggregate address. Aggregated routes will not be announced. +.. index:: aggregate-address X:X::X:X/M matching-MED-only +.. clicmd:: aggregate-address X:X::X:X/M matching-MED-only + + Configure the aggregated address to only be created when the routes MED + match, otherwise no aggregated route will be created. + +.. index:: aggregate-address X:X::X:X/M suppress-map NAME +.. clicmd:: aggregate-address X:X::X:X/M suppress-map NAME + + Similar to `summary-only`, but will only suppress more specific routes that + are matched by the selected route-map. + .. index:: no aggregate-address X:X::X:X/M .. clicmd:: no aggregate-address X:X::X:X/M @@ -2550,6 +2574,113 @@ the same behavior of using same next-hop and RMAC values. Enables or disables advertise-pip feature, specifiy system-IP and/or system-MAC parameters. +EVPN Multihoming +^^^^^^^^^^^^^^^^ + +All-Active Multihoming is used for redundancy and load sharing. Servers +are attached to two or more PEs and the links are bonded (link-aggregation). +This group of server links is referred to as an Ethernet Segment. + +Ethernet Segments +""""""""""""""""" +An Ethernet Segment can be configured by specifying a system-MAC and a +local discriminatior against the bond interface on the PE (via zebra) - + +.. index:: [no] evpn mh es-id [(1-16777215)$es_lid] +.. clicmd:: [no] evpn mh es-id [(1-16777215)$es_lid] + +.. index:: [no$no] evpn mh es-sys-mac [X:X:X:X:X:X$mac] +.. clicmd:: [no$no] evpn mh es-sys-mac [X:X:X:X:X:X$mac] + +The sys-mac and local discriminator are used for generating a 10-byte, +Type-3 Ethernet Segment ID. + +Type-1 (EAS-per-ES and EAD-per-EVI) routes are used to advertise the locally +attached ESs and to learn off remote ESs in the network. Local Type-2/MAC-IP +routes are also advertised with a destination ESI allowing for MAC-IP syncing +between Ethernet Segment peers. +Reference: RFC 7432, RFC 8365 + +EVPN-MH is intended as a replacement for MLAG or Anycast VTEPs. In +multihoming each PE has an unique VTEP address which requires the introduction +of a new dataplane construct, MAC-ECMP. Here a MAC/FDB entry can point to a +list of remote PEs/VTEPs. + +BUM handling +"""""""""""" +Type-4 (ESR) routes are used for Designated Forwarder (DF) election. DFs +forward BUM traffic received via the overlay network. This implementation +uses a preference based DF election specified by draft-ietf-bess-evpn-pref-df. +The DF preference is configurable per-ES (via zebra) - + +.. index:: [no] evpn mh es-df-pref [(1-16777215)$df_pref] +.. clicmd:: [no] evpn mh es-df-pref [(1-16777215)$df_pref] + +BUM traffic is rxed via the overlay by all PEs attached to a server but +only the DF can forward the de-capsulated traffic to the access port. To +accomodate that non-DF filters are installed in the dataplane to drop +the traffic. + +Similarly traffic received from ES peers via the overlay cannot be forwarded +to the server. This is split-horizon-filtering with local bias. + +Fast failover +""""""""""""" +As the primary purpose of EVPN-MH is redundancy keeping the failover efficient +is a recurring theme in the implementation. Following sub-features have +been introduced for the express purpose of efficient ES failovers. + +- Layer-2 Nexthop Groups and MAC-ECMP via L2NHG. + +- Host routes (for symmetric IRB) via L3NHG. + On dataplanes that support layer3 nexthop groups the feature can be turned + on via the following BGP config - + +.. index:: [no$no] use-es-l3nhg +.. clicmd:: [no$no] use-es-l3nhg + +- Local ES (MAC/Neigh) failover via ES-redirect. + On dataplanes that do not have support for ES-redirect the feature can be + turned off via the following zebra config - + +.. index:: [no$no] evpn mh redirect-off +.. clicmd:: [no$no] evpn mh redirect-off + +Uplink/Core tracking +"""""""""""""""""""" +When all the underlay links go down the PE no longer has access to the VxLAN ++overlay. To prevent blackholing of traffic the server/ES links are +protodowned on the PE. A link can be setup for uplink tracking via the +following zebra configuration - + +.. index:: [no] evpn mh uplink +.. clicmd:: [no] evpn mh uplink + +Proxy advertisements +"""""""""""""""""""" +To handle hitless upgrades support for proxy advertisement has been added +as specified by draft-rbickhart-evpn-ip-mac-proxy-adv. This allows a PE +(say PE1) to proxy advertise a MAC-IP rxed from an ES peer (say PE2). When +the ES peer (PE2) goes down PE1 continues to advertise hosts learnt from PE2 +for a holdtime during which it attempts to establish local reachability of +the host. This holdtime is configurable via the following zebra commands - + +.. index:: [no$no] evpn mh neigh-holdtime (0-86400)$duration +.. clicmd:: [no$no] evpn mh neigh-holdtime (0-86400)$duration + +.. index:: [no$no] evpn mh mac-holdtime (0-86400)$duration +.. clicmd:: [no$no] evpn mh mac-holdtime (0-86400)$duration + +Startup delay +""""""""""""" +When a switch is rebooted we wait for a brief period to allow the underlay +and EVPN network to converge before enabling the ESs. For this duration the +ES bonds are held protodown. The startup delay is configurable via the +following zebra command - + +.. index:: [no] evpn mh startup-delay(0-3600)$duration +.. clicmd:: [no] evpn mh startup-delay(0-3600)$duration + +Support with VRF network namespace backend +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It is possible to separate overlay networks contained in VXLAN interfaces from @@ -2571,6 +2702,194 @@ This makes it possible to separate not only layer 3 networks like VRF-lite netwo Also, VRF netns based make possible to separate layer 2 networks on separate VRF instances. +.. _bgp-conditional-advertisement: + +BGP Conditional Advertisement +----------------------------- +The BGP conditional advertisement feature uses the ``non-exist-map`` or the +``exist-map`` and the ``advertise-map`` keywords of the neighbor advertise-map +command in order to track routes by the route prefix. + +``non-exist-map`` + 1. If a route prefix is not present in the output of non-exist-map command, + then advertise the route specified by the advertise-map command. + + 2. If a route prefix is present in the output of non-exist-map command, + then do not advertise the route specified by the addvertise-map command. + +``exist-map`` + 1. If a route prefix is present in the output of exist-map command, + then advertise the route specified by the advertise-map command. + + 2. If a route prefix is not present in the output of exist-map command, + then do not advertise the route specified by the advertise-map command. + +This feature is useful when some prefixes are advertised to one of its peers +only if the information from the other peer is not present (due to failure in +peering session or partial reachability etc). + +The conditional BGP announcements are sent in addition to the normal +announcements that a BGP router sends to its peer. + +The conditional advertisement process is triggered by the BGP scanner process, +which runs every 60 seconds. This means that the maximum time for the conditional +advertisement to take effect is 60 seconds. The conditional advertisement can take +effect depending on when the tracked route is removed from the BGP table and +when the next instance of the BGP scanner occurs. + +.. index:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME +.. clicmd:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME + + This command enables BGP scanner process to monitor routes specified by + exist-map or non-exist-map command in BGP table and conditionally advertises + the routes specified by advertise-map command. + +Sample Configuration +^^^^^^^^^^^^^^^^^^^^^ +.. code-block:: frr + + interface enp0s9 + ip address 10.10.10.2/24 + ! + interface enp0s10 + ip address 10.10.20.2/24 + ! + interface lo + ip address 203.0.113.1/32 + ! + router bgp 2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.10.1 remote-as 1 + neighbor 10.10.20.3 remote-as 3 + ! + address-family ipv4 unicast + neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 10.10.20.3 soft-reconfiguration inbound + neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP + exit-address-family + ! + ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32 + ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32 + ip prefix-list EXIST seq 5 permit 10.10.10.10/32 + ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0 + ip prefix-list IP1 seq 5 permit 10.139.224.0/20 + ! + bgp community-list standard DC-ROUTES seq 5 permit 64952:3008 + bgp community-list standard DC-ROUTES seq 10 permit 64671:501 + bgp community-list standard DC-ROUTES seq 15 permit 64950:3009 + bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200 + ! + route-map ADV-MAP permit 10 + match ip address prefix-list IP1 + ! + route-map ADV-MAP permit 20 + match community DC-ROUTES + ! + route-map EXIST-MAP permit 10 + match community DEFAULT-ROUTE + match ip address prefix-list DEFAULT-ROUTE + ! + +Sample Output +^^^^^^^^^^^^^ + +When default route is present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are not advertised to R3. + +.. code-block:: frr + + Router2# show ip bgp + BGP table version is 20, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 0.0.0.0/0 10.10.10.1 0 0 1 i + *> 10.139.224.0/20 10.10.10.1 0 0 1 ? + *> 192.0.2.1/32 10.10.10.1 0 0 1 i + *> 192.0.2.5/32 10.10.10.1 0 0 1 i + + Displayed 4 routes and 4 total paths + Router2# show ip bgp neighbors 10.10.20.3 + + !--- Output suppressed. + + For address family: IPv4 Unicast + Update group 7, subgroup 7 + Packet Queue length 0 + Inbound soft reconfiguration allowed + Community attribute sent to this neighbor(all) + Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Withdraw + 0 accepted prefixes + + !--- Output suppressed. + + Router2# show ip bgp neighbors 10.10.20.3 advertised-routes + BGP table version is 20, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 0.0.0.0/0 0.0.0.0 0 1 i + *> 192.0.2.5/32 0.0.0.0 0 1 i + + Total number of prefixes 2 + +When default route is not present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are advertised to R3. + +.. code-block:: frr + + Router2# show ip bgp + BGP table version is 21, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 10.139.224.0/20 10.10.10.1 0 0 1 ? + *> 192.0.2.1/32 10.10.10.1 0 0 1 i + *> 192.0.2.5/32 10.10.10.1 0 0 1 i + + Displayed 3 routes and 3 total paths + + Router2# show ip bgp neighbors 10.10.20.3 + + !--- Output suppressed. + + For address family: IPv4 Unicast + Update group 7, subgroup 7 + Packet Queue length 0 + Inbound soft reconfiguration allowed + Community attribute sent to this neighbor(all) + Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Advertise + 0 accepted prefixes + + !--- Output suppressed. + + Router2# show ip bgp neighbors 10.10.20.3 advertised-routes + BGP table version is 21, local router ID is 203.0.113.1, vrf id 0 + Default local pref 100, local AS 2 + Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed + Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self + Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path + *> 10.139.224.0/20 0.0.0.0 0 1 ? + *> 192.0.2.1/32 0.0.0.0 0 1 i + *> 192.0.2.5/32 0.0.0.0 0 1 i + + Total number of prefixes 3 + Router2# + .. _bgp-debugging: Debugging diff --git a/doc/user/conf.py b/doc/user/conf.py index 1f6f050bcf..79b37e7850 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -22,48 +22,48 @@ from sphinx.highlighting import lexers # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.0' +needs_sphinx = "1.0" # prolog for various variable substitutions -rst_prolog = '' +rst_prolog = "" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.todo'] +extensions = ["sphinx.ext.todo"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'FRR' -copyright = u'2017, FRR' -author = u'FRR authors' +project = u"FRR" +copyright = u"2017, FRR" +author = u"FRR authors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The short X.Y version. -version = u'?.?' +version = u"?.?" # The full version, including alpha/beta/rc tags. -release = u'?.?-?' +release = u"?.?-?" # ----------------------------------------------------------------------------- @@ -73,48 +73,49 @@ release = u'?.?-?' # Various installation prefixes. Values are extracted from config.status. # Reasonable defaults are set in case that file does not exist. replace_vars = { - 'AUTHORS': author, - 'COPYRIGHT_YEAR': '1999-2005', - 'COPYRIGHT_STR': 'Copyright (c) 1999-2005', - 'PACKAGE_NAME': project.lower(), - 'PACKAGE_TARNAME': project.lower(), - 'PACKAGE_STRING': project.lower() + ' latest', - 'PACKAGE_URL': 'https://frrouting.org/', - 'PACKAGE_VERSION': 'latest', - 'INSTALL_PREFIX_ETC': '/etc/frr', - 'INSTALL_PREFIX_SBIN': '/usr/lib/frr', - 'INSTALL_PREFIX_STATE': '/var/run/frr', - 'INSTALL_PREFIX_MODULES': '/usr/lib/frr/modules', - 'INSTALL_USER': 'frr', - 'INSTALL_GROUP': 'frr', - 'INSTALL_VTY_GROUP': 'frrvty', - 'GROUP': 'frr', - 'USER': 'frr', + "AUTHORS": author, + "COPYRIGHT_YEAR": "1999-2005", + "COPYRIGHT_STR": "Copyright (c) 1999-2005", + "PACKAGE_NAME": project.lower(), + "PACKAGE_TARNAME": project.lower(), + "PACKAGE_STRING": project.lower() + " latest", + "PACKAGE_URL": "https://frrouting.org/", + "PACKAGE_VERSION": "latest", + "INSTALL_PREFIX_ETC": "/etc/frr", + "INSTALL_PREFIX_SBIN": "/usr/lib/frr", + "INSTALL_PREFIX_STATE": "/var/run/frr", + "INSTALL_PREFIX_MODULES": "/usr/lib/frr/modules", + "INSTALL_USER": "frr", + "INSTALL_GROUP": "frr", + "INSTALL_VTY_GROUP": "frrvty", + "GROUP": "frr", + "USER": "frr", } # extract version information, installation location, other stuff we need to # use when building final documents val = re.compile('^S\["([^"]+)"\]="(.*)"$') try: - with open('../../config.status', 'r') as cfgstatus: + with open("../../config.status", "r") as cfgstatus: for ln in cfgstatus.readlines(): m = val.match(ln) - if not m or m.group(1) not in replace_vars.keys(): continue + if not m or m.group(1) not in replace_vars.keys(): + continue replace_vars[m.group(1)] = m.group(2) except IOError: # if config.status doesn't exist, just ignore it pass # manually fill out some of these we can't get from config.status -replace_vars['COPYRIGHT_STR'] = "Copyright (c)" -replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR']) -replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS']) -release = replace_vars['PACKAGE_VERSION'] -version = release.split('-')[0] +replace_vars["COPYRIGHT_STR"] = "Copyright (c)" +replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["COPYRIGHT_YEAR"]) +replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["AUTHORS"]) +release = replace_vars["PACKAGE_VERSION"] +version = release.split("-")[0] # add substitutions to prolog for key, value in replace_vars.items(): - rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value) + rst_prolog += ".. |{0}| replace:: {1}\n".format(key, value) # The language for content autogenerated by Sphinx. Refer to documentation @@ -126,39 +127,45 @@ language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build', 'rpki.rst', 'routeserver.rst', - 'ospf_fundamentals.rst', 'flowspec.rst', 'snmptrap.rst', - 'wecmp_linkbw.rst'] +exclude_patterns = [ + "_build", + "rpki.rst", + "routeserver.rst", + "ospf_fundamentals.rst", + "flowspec.rst", + "snmptrap.rst", + "wecmp_linkbw.rst", +] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True @@ -168,165 +175,158 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" try: import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' + html_theme = "sphinx_rtd_theme" except ImportError: pass # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = { +# html_theme_options = { # 'sidebarbgcolor': '#374249' -#} +# } # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '../figures/frr-icon.svg' +html_logo = "../figures/frr-icon.svg" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -html_favicon = '../figures/frr-logo-icon.png' +html_favicon = "../figures/frr-logo-icon.png" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a <link> tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'FRRdoc' +htmlhelp_basename = "FRRdoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'FRR.tex', u'FRR User Manual', - u'FRR', 'manual'), + (master_doc, "FRR.tex", u"FRR User Manual", u"FRR", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -latex_logo = '../figures/frr-logo-medium.png' +latex_logo = "../figures/frr-logo-medium.png" # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'frr', u'FRR User Manual', - [author], 1) -] +man_pages = [(master_doc, "frr", u"FRR User Manual", [author], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -335,29 +335,35 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'frr', u'FRR User Manual', - author, 'FRR', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "frr", + u"FRR User Manual", + author, + "FRR", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # contents of ../extra/frrlexer.py. # This is read here to support VPATH build. Since this section is execfile()'d # with the file location, we can safely use a relative path here to save the # contents of the lexer file for later use even if our relative path changes # due to VPATH. -with open('../extra/frrlexer.py', 'rb') as lex: +with open("../extra/frrlexer.py", "rb") as lex: frrlexerpy = lex.read() # Parse version string into int array @@ -365,7 +371,7 @@ def vparse(s): a = [] for c in s: - if c != '.': + if c != ".": a.append(int(c)) while len(a) < 3: @@ -373,22 +379,23 @@ def vparse(s): return a[:3] + # custom extensions here def setup(app): # object type for FRR CLI commands, can be extended to document parent CLI # node later on - app.add_object_type('clicmd', 'clicmd') + app.add_object_type("clicmd", "clicmd") # css overrides for HTML theme # Note sphinx version differences sver = vparse(sphinx.__version__) - if sver < vparse('1.8.0') : - app.add_stylesheet('overrides.css') - app.add_javascript('overrides.js') + if sver < vparse("1.8.0"): + app.add_stylesheet("overrides.css") + app.add_javascript("overrides.js") else: - app.add_css_file('overrides.css') - app.add_js_file('overrides.js') + app.add_css_file("overrides.css") + app.add_js_file("overrides.js") # load Pygments lexer for FRR config syntax # @@ -399,4 +406,4 @@ def setup(app): # frrlexer = pygments.lexers.load_lexer_from_file('../extra/frrlexer.py', lexername="FRRLexer") custom_namespace = {} exec(frrlexerpy, custom_namespace) - lexers['frr'] = custom_namespace['FRRLexer']() + lexers["frr"] = custom_namespace["FRRLexer"]() diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 0fd33eace8..5d5dfa5cc5 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -273,15 +273,15 @@ options from the list below. With this option, we provide a way to strip out these characters for APK dev package builds. -..option:: --disable-version-build-config +.. option:: --disable-version-build-config Remove the "configuerd with" field that has all of the build configuration arguments when reporting the version string in `show version` command. -..option:: --with-pkg-extra-version=VER +.. option:: --with-pkg-extra-version=VER Add extra version field, for packagers/distributions -..option:: --with-pkg-git-version +.. option:: --with-pkg-git-version Add git information to MOTD and build version string @@ -355,6 +355,10 @@ options from the list below. Turn on the usage of PCRE Posix libs for regex functionality. +.. option:: --enable-rpath + + Set hardcoded rpaths in the executable [default=yes]. + You may specify any combination of the above options to the configure script. By default, the executables are placed in :file:`/usr/local/sbin` and the configuration files in :file:`/usr/local/etc`. The :file:`/usr/local/` @@ -380,6 +384,10 @@ options to the configuration script. Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR YANG modules will be installed here. +.. option:: --with-vici-socket <path> + + Set StrongSWAN vici interface socket path [/var/run/charon.vici]. + Python dependency, documentation and tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 8cbbe0809f..98f5aff7db 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -355,6 +355,11 @@ ISIS interface Enable or disable :rfc:`5303` Three-Way Handshake for P2P adjacencies. Three-Way Handshake is enabled by default. +.. index:: [no] isis fast-reroute ti-lfa [level-1|level-2] [node-protection] +.. clicmd:: [no] isis fast-reroute ti-lfa [level-1|level-2] [node-protection] + + Enable per-prefix TI-LFA fast reroute link or node protection. + .. _showing-isis-information: Showing ISIS information @@ -418,8 +423,8 @@ Showing ISIS information Show topology IS-IS paths to Intermediate Systems, globally, in area (level-1) or domain (level-2). -.. index:: show isis route [level-1|level-2] -.. clicmd:: show isis route [level-1|level-2] +.. index:: show isis route [level-1|level-2] [prefix-sid|backup] +.. clicmd:: show isis route [level-1|level-2] [prefix-sid|backup] Show the ISIS routing table, as determined by the most recent SPF calculation. @@ -510,14 +515,16 @@ Known limitations: MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value is 32. -.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null] -.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null] +.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null] [n-flag-clear] +.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null] [n-flag-clear] Set the Segment Routing index or absolute label value for the specified prefix. The 'no-php-flag' means NO Penultimate Hop Popping that allows SR node to request to its neighbor to not pop the label. The 'explicit-null' flag allows SR node to request to its neighbor to send IP packet with the - EXPLICIT-NULL label. + EXPLICIT-NULL label. The 'n-flag-clear' option can be used to explicitly + clear the Node flag that is set by default for Prefix-SIDs associated to + loopback addresses. This option is necessary to configure Anycast-SIDs. .. index:: show isis segment-routing prefix-sids .. clicmd:: show isis segment-routing prefix-sids @@ -633,6 +640,14 @@ Debugging ISIS IS-IS Segment Routing events. +.. index:: debug isis ti-lfa +.. clicmd:: debug isis ti-lfa + +.. index:: no debug isis ti-lfa +.. clicmd:: no debug isis ti-lfa + + IS-IS TI-LFA events. + .. index:: show debugging isis .. clicmd:: show debugging isis diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index 010526b637..31b0df70ae 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -853,6 +853,50 @@ Redistribution .. index:: no router zebra .. clicmd:: no router zebra +Graceful Restart Helper +======================= + +.. index:: graceful-restart helper-only [A.B.C.D] +.. clicmd:: graceful-restart helper-only [A.B.C.D] + +.. index:: no graceful-restart helper-only [A.B.C.D] +.. clicmd:: no graceful-restart helper-only [A.B.C.D] + + Configure Graceful Restart (RFC 3623) helper support. + By default, helper support is disabled for all neighbours. + This config enables/disables helper support on this router + for all neighbours. + To enable/disable helper support for a specific + neighbour, the router-id (A.B.C.D) has to be specified. + +.. index:: graceful-restart helper strict-lsa-checking +.. clicmd:: graceful-restart helper strict-lsa-checking + +.. index:: no graceful-restart helper strict-lsa-checking +.. clicmd:: no graceful-restart helper strict-lsa-checking + + If 'strict-lsa-checking' is configured then the helper will + abort the Graceful Restart when a LSA change occurs which + affects the restarting router. + By default 'strict-lsa-checking' is enabled" + +.. index:: graceful-restart helper supported-grace-time +.. clicmd:: graceful-restart helper supported-grace-time + +.. index:: no graceful-restart helper supported-grace-time +.. clicmd:: no graceful-restart helper supported-grace-time + + Supports as HELPER for configured grace period. + +.. index:: graceful-restart helper planned-only +.. clicmd:: graceful-restart helper planned-only + +.. index:: no graceful-restart helper planned-only +.. clicmd:: no graceful-restart helper planned-only + + It helps to support as HELPER only for planned + restarts. By default, it supports both planned and + unplanned outages. .. _showing-ospf-information: @@ -861,63 +905,73 @@ Showing Information .. _show-ip-ospf: -.. index:: show ip ospf -.. clicmd:: show ip ospf +.. index:: show ip ospf [json] +.. clicmd:: show ip ospf [json] Show information on a variety of general OSPF and area state and configuration information. -.. index:: show ip ospf interface [INTERFACE] -.. clicmd:: show ip ospf interface [INTERFACE] +.. index:: show ip ospf interface [INTERFACE] [json] +.. clicmd:: show ip ospf interface [INTERFACE] [json] Show state and configuration of OSPF the specified interface, or all interfaces if no interface is given. -.. index:: show ip ospf neighbor -.. clicmd:: show ip ospf neighbor +.. index:: show ip ospf neighbor [json] +.. clicmd:: show ip ospf neighbor [json] -.. index:: show ip ospf neighbor INTERFACE -.. clicmd:: show ip ospf neighbor INTERFACE +.. index:: show ip ospf neighbor INTERFACE [json] +.. clicmd:: show ip ospf neighbor INTERFACE [json] -.. index:: show ip ospf neighbor detail -.. clicmd:: show ip ospf neighbor detail +.. index:: show ip ospf neighbor detail [json] +.. clicmd:: show ip ospf neighbor detail [json] -.. index:: show ip ospf neighbor INTERFACE detail -.. clicmd:: show ip ospf neighbor INTERFACE detail +.. index:: show ip ospf neighbor INTERFACE detail [json] +.. clicmd:: show ip ospf neighbor INTERFACE detail [json] -.. index:: show ip ospf database -.. clicmd:: show ip ospf database + Display lsa information of LSDB. + Json o/p of this command covers base route information + i.e all LSAs except opaque lsa info. -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) +.. index:: show ip ospf database [json] +.. clicmd:: show ip ospf database [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] -.. index:: show ip ospf database max-age -.. clicmd:: show ip ospf database max-age +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] -.. index:: show ip ospf database self-originate -.. clicmd:: show ip ospf database self-originate +.. index:: show ip ospf database max-age [json] +.. clicmd:: show ip ospf database max-age [json] -.. index:: show ip ospf route -.. clicmd:: show ip ospf route +.. index:: show ip ospf database self-originate [json] +.. clicmd:: show ip ospf database self-originate [json] + +.. index:: show ip ospf route [json] +.. clicmd:: show ip ospf route [json] Show the OSPF routing table, as determined by the most recent SPF calculation. +.. index:: show ip ospf graceful-restart helper [detail] [json] +.. clicmd:: show ip ospf graceful-restart helper [detail] [json] + + Displays the Grcaeful Restart Helper details including helper + config changes. + .. _opaque-lsa: Opaque LSA @@ -1127,6 +1181,41 @@ dataplane. self router. Optional JSON output can be obtained by appending 'json' to the end of the command. +External Route Summarisation +============================ +This feature summarises originated external LSAs(Type-5 and Type-7). +Summary Route will be originated on-behalf of all matched external LSAs. + +.. index:: [no] summary-address A.B.C.D/M [tag (1-4294967295)] +.. clicmd:: [no] summary-address A.B.C.D/M [tag (1-4294967295)] + + This command enable/disables summarisation for the configured address + range. Tag is the optional parameter. If tag configured Summary route + will be originated with the configured tag. + +.. index:: [no] summary-address A.B.C.D/M no-advertise +.. clicmd:: [no] summary-address A.B.C.D/M no-advertise + + This command to ensure not advertise the summary lsa for the matched + external LSAs. + +.. index:: aggregation timer (5-1800) +.. clicmd:: aggregation timer (5-1800) + + Configure aggregation delay timer interval. Summarisation starts only after + this delay timer expiry. By default, delay interval is 5 secs. + +.. index:: no aggregation timer +.. clicmd:: no aggregation timer + + Resetting the aggregation delay interval to default value. + +.. index:: show ip ospf [vrf <NAME|all>] summary-address [detail] [json] +.. clicmd:: show ip ospf [vrf <NAME|all>] summary-address [detail] [json] + + Show configuration for display all configured summary routes with + matching external LSA information. + Debugging OSPF ============== @@ -1218,9 +1307,21 @@ Debugging OSPF Show debug information of ZEBRA API +.. index:: debug ospf graceful-restart helper +.. clicmd:: debug ospf graceful-restart helper + +.. index:: no debug ospf graceful-restart helper +.. clicmd:: no debug ospf graceful-restart helper + + Enable/disable debug information for OSPF Graceful Restart Helper + .. index:: show debugging ospf .. clicmd:: show debugging ospf +.. index:: [no] debug ospf lsa aggregate +.. clicmd:: [no] debug ospf lsa aggregate + + Debug commnd to enable/disable external route summarisation specific debugs. OSPF Configuration Examples =========================== diff --git a/doc/user/pim.rst b/doc/user/pim.rst index d5899ab455..b0a90bfc48 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -337,6 +337,42 @@ caution. Most of the time this will not be necessary. Insert into the Multicast Rib Route A.B.C.D/M using the specified INTERFACE. The distance can be specified as well if desired. +.. _msdp-configuration: + +Multicast Source Discovery Protocol (MSDP) Configuration +======================================================== + +.. index:: ip msdp mesh-group [WORD] member A.B.C.D +.. clicmd:: ip msdp mesh-group [WORD] member A.B.C.D + + Include a MSDP peer as a member of a MSDP mesh-group. + +.. index:: ip msdp mesh-group [WORD] source A.B.C.D +.. clicmd:: ip msdp mesh-group [WORD] source A.B.C.D + + Create a MSDP mesh-group, defining a name for it and an associated local source + address. + +.. index:: ip msdp peer A.B.C.D source A.B.C.D +.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D + + Establish a MSDP connection with a peer. + +.. index:: no ip msdp mesh-group [WORD] member A.B.C.D +.. clicmd:: no ip msdp mesh-group [WORD] member A.B.C.D + + Remove a MSDP peer member from a MSDP mesh-group. + +.. index:: no ip msdp mesh-group [WORD] source A.B.C.D +.. clicmd:: no ip msdp mesh-group [WORD] source A.B.C.D + + Delete a MSDP mesh-group. + +.. index:: no ip msdp peer A.B.C.D +.. clicmd:: no ip msdp peer A.B.C.D + + Delete a MSDP peer connection. + .. _show-pim-information: Show PIM Information @@ -422,6 +458,19 @@ cause great confusion. Display total number of S,G mroutes and number of S,G mroutes installed into the kernel for all vrfs. +.. index:: show ip msdp mesh-group +.. clicmd:: show ip msdp mesh-group + + Display the configured mesh-groups, the local address associated with each + mesh-group, the peer members included in each mesh-group, and their status. + +.. index:: show ip msdp peer +.. clicmd:: show ip msdp peer + + Display information about the MSDP peers. That includes the peer address, + the local address used to establish the connection to the peer, the + connection status, and the number of active sources. + .. index:: show ip pim assert .. clicmd:: show ip pim assert diff --git a/doc/user/snmp.rst b/doc/user/snmp.rst index d214926245..0087d41a23 100644 --- a/doc/user/snmp.rst +++ b/doc/user/snmp.rst @@ -39,6 +39,7 @@ can be achieved by amending the default view from SNMP :file:`/etc/snmp/snmpd.conf`: :: + # This is the default view view all included .1 80 # Remove ipRouteTable from view diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 98655e6cba..624e3cfe1a 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1033,14 +1033,15 @@ zebra Terminal Mode Commands total number of route nodes in the table. Which will be higher than the actual number of routes that are held. -.. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] -.. clicmd:: show nexthop-group rib [ID] [vrf NAME] +.. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] [type] +.. clicmd:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] [type] Display nexthop groups created by zebra. The [vrf NAME] option is only meaningful if you have started zebra with the --vrfwnetns option as that nexthop groups are per namespace in linux. If you specify singleton you would like to see the singleton - nexthop groups that do have an afi. + nexthop groups that do have an afi. [type] allows you to filter those + only coming from a specific NHG type (protocol). Router-id diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 97de73116b..dfce2acad4 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -122,8 +122,8 @@ void eigrp_ip_header_dump(struct ip *iph) zlog_debug("ip_ttl %u", iph->ip_ttl); zlog_debug("ip_p %u", iph->ip_p); zlog_debug("ip_sum 0x%x", (uint32_t)iph->ip_sum); - zlog_debug("ip_src %s", inet_ntoa(iph->ip_src)); - zlog_debug("ip_dst %s", inet_ntoa(iph->ip_dst)); + zlog_debug("ip_src %pI4", &iph->ip_src); + zlog_debug("ip_dst %pI4", &iph->ip_dst); } /* @@ -204,8 +204,7 @@ void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr, int detail) { - vty_out(vty, "%-3u %-17s %-21s", 0, eigrp_neigh_ip_string(nbr), - IF_NAME(nbr->ei)); + vty_out(vty, "%-3u %-17pI4 %-21s", 0, &nbr->src, IF_NAME(nbr->ei)); if (nbr->t_holddown) vty_out(vty, "%-7lu", thread_timer_remain_second(nbr->t_holddown)); @@ -231,8 +230,8 @@ void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr, */ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp) { - vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%s)\n\n", eigrp->AS, - inet_ntoa(eigrp->router_id)); + vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%pI4)\n\n", + eigrp->AS, &eigrp->router_id); vty_out(vty, "Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply\n r - reply Status, s - sia Status\n\n"); } @@ -240,12 +239,10 @@ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp) void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) { struct list *successors = eigrp_topology_get_successor(tn); - char buffer[PREFIX_STRLEN]; vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P'); - vty_out(vty, "%s, ", - prefix2str(tn->destination, buffer, PREFIX_STRLEN)); + vty_out(vty, "%pFX, ", tn->destination); vty_out(vty, "%u successors, ", (successors) ? successors->count : 0); vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance, tn->serno); @@ -269,8 +266,8 @@ void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, vty_out(vty, "%-7s%s, %s\n", " ", "via Connected", IF_NAME(te->ei)); else { - vty_out(vty, "%-7s%s%s (%u/%u), %s\n", " ", "via ", - inet_ntoa(te->adv_router->src), te->distance, + vty_out(vty, "%-7s%s%pI4 (%u/%u), %s\n", " ", "via ", + &te->adv_router->src, te->distance, te->reported_distance, IF_NAME(te->ei)); } } diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h index f141f3cbc6..348356bb3c 100644 --- a/eigrpd/eigrp_dump.h +++ b/eigrpd/eigrp_dump.h @@ -138,21 +138,6 @@ extern unsigned long term_debug_eigrp_zebra; /* Prototypes. */ extern const char *eigrp_if_name_string(struct eigrp_interface *); -static inline const char -*eigrp_topology_ip_string(struct eigrp_prefix_entry *tn) -{ - return inet_ntoa(tn->destination->u.prefix4); -} - -static inline const char *eigrp_if_ip_string(struct eigrp_interface *ei) -{ - return ei ? inet_ntoa(ei->address.u.prefix4) : "inactive"; -} - -static inline const char *eigrp_neigh_ip_string(struct eigrp_neighbor *nbr) -{ - return inet_ntoa(nbr->src); -} extern void eigrp_ip_header_dump(struct ip *); extern void eigrp_header_dump(struct eigrp_header *); diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c index 9d5d45ca50..009b57e05f 100644 --- a/eigrpd/eigrp_filter.c +++ b/eigrpd/eigrp_filter.c @@ -159,13 +159,10 @@ void eigrp_distribute_update(struct distribute_ctx *ctx, #endif // TODO: check Graceful restart after 10sec - /* check if there is already GR scheduled */ - if (e->t_distribute != NULL) { - /* if is, cancel schedule */ - thread_cancel(e->t_distribute); - } + /* cancel GR scheduled */ + thread_cancel(&(e->t_distribute)); + /* schedule Graceful restart for whole process in 10sec */ - e->t_distribute = NULL; thread_add_timer(master, eigrp_distribute_timer_process, e, (10), &e->t_distribute); @@ -267,11 +264,8 @@ void eigrp_distribute_update(struct distribute_ctx *ctx, #endif // TODO: check Graceful restart after 10sec - /* check if there is already GR scheduled */ - if (ei->t_distribute != NULL) { - /* if is, cancel schedule */ - thread_cancel(ei->t_distribute); - } + /* Cancel GR scheduled */ + thread_cancel(&(ei->t_distribute)); /* schedule Graceful restart for interface in 10sec */ e->t_distribute = NULL; thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10, diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index e43eca0e0d..a69a3eec0a 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -417,9 +417,9 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg) enum eigrp_fsm_events event = eigrp_get_fsm_event(msg); zlog_info( - "EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s", + "EIGRP AS: %d State: %s Event: %s Network: %pI4 Packet Type: %s Reply RIJ Count: %d change: %s", msg->eigrp->AS, prefix_state2str(msg->prefix->state), - fsm_state2str(event), eigrp_topology_ip_string(msg->prefix), + fsm_state2str(event), &msg->prefix->destination->u.prefix4, packet_type2str(msg->packet_type), msg->prefix->rij->count, change2str(msg->change)); (*(NSM[msg->prefix->state][event].func))(msg); diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index 6f93cd7b3e..f512833e0a 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -144,10 +144,11 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr, && (eigrp->k_values[4] == nbr->K5)) { if (eigrp_nbr_state_get(nbr) == EIGRP_NEIGHBOR_DOWN) { - zlog_info("Neighbor %s (%s) is pending: new adjacency", - inet_ntoa(nbr->src), - ifindex2ifname(nbr->ei->ifp->ifindex, - eigrp->vrf_id)); + zlog_info( + "Neighbor %pI4 (%s) is pending: new adjacency", + &nbr->src, + ifindex2ifname(nbr->ei->ifp->ifindex, + eigrp->vrf_id)); /* Expedited hello sent */ eigrp_hello_send(nbr->ei, EIGRP_HELLO_NORMAL, NULL); @@ -164,16 +165,16 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr, & param->K5) == 255) { zlog_info( - "Neighbor %s (%s) is down: Interface PEER-TERMINATION received", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) is down: Interface PEER-TERMINATION received", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); eigrp_nbr_delete(nbr); return NULL; } else { zlog_info( - "Neighbor %s (%s) going down: Kvalue mismatch", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) going down: Kvalue mismatch", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); @@ -253,9 +254,10 @@ static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr, uint32_t received_ip = param->neighbor_ip; if (my_ip == received_ip) { - zlog_info("Neighbor %s (%s) is down: Peer Termination received", - inet_ntoa(nbr->src), - ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); + zlog_info( + "Neighbor %pI4 (%s) is down: Peer Termination received", + &nbr->src, + ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); /* set neighbor to DOWN */ nbr->state = EIGRP_NEIGHBOR_DOWN; /* delete neighbor */ @@ -330,9 +332,9 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph, assert(nbr); if (IS_DEBUG_EIGRP_PACKET(eigrph->opcode - 1, RECV)) - zlog_debug("Processing Hello size[%u] int(%s) nbr(%s)", size, + zlog_debug("Processing Hello size[%u] int(%s) nbr(%pI4)", size, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id), - inet_ntoa(nbr->src)); + &nbr->src); size -= EIGRP_HEADER_LEN; if (size < 0) @@ -403,8 +405,7 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph, } if (IS_DEBUG_EIGRP_PACKET(0, RECV)) - zlog_debug("Hello Packet received from %s", - inet_ntoa(nbr->src)); + zlog_debug("Hello Packet received from %pI4", &nbr->src); } uint32_t FRR_MAJOR; @@ -708,9 +709,8 @@ void eigrp_hello_send_ack(struct eigrp_neighbor *nbr) if (ep) { if (IS_DEBUG_EIGRP_PACKET(0, SEND)) - zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%s]", - nbr->recv_sequence_number, - inet_ntoa(nbr->src)); + zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%pI4]", + nbr->recv_sequence_number, &nbr->src); /* Add packet to the top of the interface output queue*/ eigrp_fifo_push(nbr->ei->obuf, ep); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 9ef4e86237..dd43dd0478 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -331,8 +331,7 @@ int eigrp_if_down(struct eigrp_interface *ei) return 0; /* Shutdown packet reception and sending */ - if (ei->t_hello) - THREAD_OFF(ei->t_hello); + THREAD_OFF(ei->t_hello); eigrp_if_stream_unset(ei); @@ -359,7 +358,7 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei) if (ei->on_write_q) { listnode_delete(eigrp->oi_write_q, ei); if (list_isempty(eigrp->oi_write_q)) - thread_cancel(eigrp->t_write); + thread_cancel(&(eigrp->t_write)); ei->on_write_q = 0; } } @@ -421,7 +420,7 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) struct eigrp *eigrp = ei->eigrp; if (source == INTERFACE_DOWN_BY_VTY) { - THREAD_OFF(ei->t_hello); + thread_cancel(&ei->t_hello); eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); } diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index 2ae3997fae..2d5bb0a7d1 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -87,10 +87,6 @@ static struct eigrp_neighbor *eigrp_nbr_add(struct eigrp_interface *ei, nbr = eigrp_nbr_new(ei); nbr->src = iph->ip_src; - // if (IS_DEBUG_EIGRP_EVENT) - // zlog_debug("NSM[%s:%s]: start", IF_NAME (nbr->oi), - // inet_ntoa (nbr->router_id)); - return nbr; } @@ -197,8 +193,7 @@ int holddown_timer_expired(struct thread *thread) struct eigrp_neighbor *nbr = THREAD_ARG(thread); struct eigrp *eigrp = nbr->ei->eigrp; - zlog_info("Neighbor %s (%s) is down: holding time expired", - inet_ntoa(nbr->src), + zlog_info("Neighbor %pI4 (%s) is down: holding time expired", &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); nbr->state = EIGRP_NEIGHBOR_DOWN; eigrp_nbr_delete(nbr); @@ -330,13 +325,12 @@ void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty) { struct eigrp *eigrp = nbr->ei->eigrp; - zlog_debug("Neighbor %s (%s) is down: manually cleared", - inet_ntoa(nbr->src), + zlog_debug("Neighbor %pI4 (%s) is down: manually cleared", &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); if (vty != NULL) { vty_time_print(vty, 0); - vty_out(vty, "Neighbor %s (%s) is down: manually cleared\n", - inet_ntoa(nbr->src), + vty_out(vty, "Neighbor %pI4 (%s) is down: manually cleared\n", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); } diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 92b5ce3482..bd8ec2f879 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -160,9 +160,8 @@ int eigrp_if_ipmulticast(struct eigrp *top, struct prefix *p, ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex); if (ret < 0) zlog_warn( - "can't setsockopt IP_MULTICAST_IF (fd %d, addr %s, ifindex %u): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, - safe_strerror(errno)); + "can't setsockopt IP_MULTICAST_IF (fd %d, addr %pI4, ifindex %u): %s", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); return ret; } @@ -178,12 +177,11 @@ int eigrp_if_add_allspfrouters(struct eigrp *top, struct prefix *p, htonl(EIGRP_MULTICAST_ADDRESS), ifindex); if (ret < 0) zlog_warn( - "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?", - top->fd, inet_ntoa(p->u.prefix4), ifindex, - safe_strerror(errno)); + "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); else - zlog_debug("interface %s [%u] join EIGRP Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); + zlog_debug("interface %pI4 [%u] join EIGRP Multicast group.", + &p->u.prefix4, ifindex); return ret; } @@ -198,12 +196,11 @@ int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, htonl(EIGRP_MULTICAST_ADDRESS), ifindex); if (ret < 0) zlog_warn( - "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, - safe_strerror(errno)); + "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); else - zlog_debug("interface %s [%u] leave EIGRP Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); + zlog_debug("interface %pI4 [%u] leave EIGRP Multicast group.", + &p->u.prefix4, ifindex); return ret; } diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c index 13887368f7..5b87f72640 100644 --- a/eigrpd/eigrp_northbound.c +++ b/eigrpd/eigrp_northbound.c @@ -243,10 +243,12 @@ static int eigrpd_instance_active_time_modify(struct nb_cb_modify_args *args) switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: + snprintf(args->errmsg, args->errmsg_len, + "active time not implemented yet"); /* NOTHING */ break; } @@ -677,11 +679,12 @@ static int eigrpd_instance_neighbor_create(struct nb_cb_create_args *args) switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* NOTHING */ + snprintf(args->errmsg, args->errmsg_len, + "neighbor Command is not implemented yet"); break; } @@ -693,11 +696,12 @@ static int eigrpd_instance_neighbor_destroy(struct nb_cb_destroy_args *args) switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* NOTHING */ + snprintf(args->errmsg, args->errmsg_len, + "no neighbor Command is not implemented yet"); break; } @@ -768,11 +772,13 @@ eigrpd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args) switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* NOTHING */ + snprintf( + args->errmsg, args->errmsg_len, + "'redistribute X route-map FOO' command not implemented yet"); break; } @@ -785,11 +791,13 @@ eigrpd_instance_redistribute_route_map_destroy(struct nb_cb_destroy_args *args) switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* NOTHING */ + snprintf( + args->errmsg, args->errmsg_len, + "'no redistribute X route-map FOO' command not implemented yet"); break; } @@ -1079,10 +1087,12 @@ lib_interface_eigrp_split_horizon_modify(struct nb_cb_modify_args *args) switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: + snprintf(args->errmsg, args->errmsg_len, + "split-horizon command not implemented yet"); /* NOTHING */ break; } @@ -1161,11 +1171,12 @@ static int lib_interface_eigrp_instance_summarize_addresses_create( switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: - /* NOTHING */ + snprintf(args->errmsg, args->errmsg_len, + "summary command not implemented yet"); break; } @@ -1178,10 +1189,12 @@ static int lib_interface_eigrp_instance_summarize_addresses_destroy( switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ - return NB_ERR_INCONSISTENCY; case NB_EV_PREPARE: case NB_EV_ABORT: + return NB_OK; case NB_EV_APPLY: + snprintf(args->errmsg, args->errmsg_len, + "no summary command not implemented yet"); /* NOTHING */ break; } diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index cfff63f839..f5f6ab5dff 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -442,17 +442,16 @@ int eigrp_write(struct thread *thread) if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND)) { eigrph = (struct eigrp_header *)STREAM_DATA(ep->s); zlog_debug( - "Sending [%s][%d/%d] to [%s] via [%s] ret [%d].", + "Sending [%s][%d/%d] to [%pI4] via [%s] ret [%d].", lookup_msg(eigrp_packet_type_str, eigrph->opcode, NULL), - seqno, ack, inet_ntoa(ep->dst), IF_NAME(ei), ret); + seqno, ack, &ep->dst, IF_NAME(ei), ret); } if (ret < 0) zlog_warn( - "*** sendmsg in eigrp_write failed to %s, id %d, off %d, len %d, interface %s, mtu %u: %s", - inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, - iph.ip_len, ei->ifp->name, ei->ifp->mtu, - safe_strerror(errno)); + "*** sendmsg in eigrp_write failed to %pI4, id %d, off %d, len %d, interface %s, mtu %u: %s", + &iph.ip_dst, iph.ip_id, iph.ip_off, iph.ip_len, + ei->ifp->name, ei->ifp->mtu, safe_strerror(errno)); /* Now delete packet from queue. */ eigrp_packet_delete(ei); @@ -552,8 +551,8 @@ int eigrp_read(struct thread *thread) || (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) { if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) zlog_debug( - "eigrp_read[%s]: Dropping self-originated packet", - inet_ntoa(srcaddr)); + "eigrp_read[%pI4]: Dropping self-originated packet", + &srcaddr); return 0; } @@ -596,8 +595,9 @@ int eigrp_read(struct thread *thread) */ else if (ei->ifp != ifp) { if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) - zlog_warn("Packet from [%s] received on wrong link %s", - inet_ntoa(iph->ip_src), ifp->name); + zlog_warn( + "Packet from [%pI4] received on wrong link %s", + &iph->ip_src, ifp->name); return 0; } @@ -606,8 +606,8 @@ int eigrp_read(struct thread *thread) if (ret < 0) { if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) zlog_debug( - "eigrp_read[%s]: Header check failed, dropping.", - inet_ntoa(iph->ip_src)); + "eigrp_read[%pI4]: Header check failed, dropping.", + &iph->ip_src); return ret; } @@ -615,17 +615,12 @@ int eigrp_read(struct thread *thread) start of the eigrp TLVs */ opcode = eigrph->opcode; - if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) { - char src[PREFIX_STRLEN], dst[PREFIX_STRLEN]; - - strlcpy(src, inet_ntoa(iph->ip_src), sizeof(src)); - strlcpy(dst, inet_ntoa(iph->ip_dst), sizeof(dst)); + if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) zlog_debug( - "Received [%s][%d/%d] length [%u] via [%s] src [%s] dst [%s]", + "Received [%s][%d/%d] length [%u] via [%s] src [%pI4] dst [%pI4]", lookup_msg(eigrp_packet_type_str, opcode, NULL), ntohl(eigrph->sequence), ntohl(eigrph->ack), length, - IF_NAME(ei), src, dst); - } + IF_NAME(ei), &iph->ip_src, &iph->ip_dst); /* Read rest of the packet and call each sort of packet routine. */ stream_forward_getp(ibuf, EIGRP_HEADER_LEN); @@ -648,8 +643,9 @@ int eigrp_read(struct thread *thread) && (ntohl(eigrph->ack) == nbr->init_sequence_number)) { eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_UP); - zlog_info("Neighbor(%s) adjacency became full", - inet_ntoa(nbr->src)); + zlog_info( + "Neighbor(%pI4) adjacency became full", + &nbr->src); nbr->init_sequence_number = 0; nbr->recv_sequence_number = ntohl(eigrph->sequence); @@ -957,8 +953,8 @@ static int eigrp_verify_header(struct stream *ibuf, struct eigrp_interface *ei, /* Check network mask, Silently discarded. */ if (!eigrp_check_network_mask(ei, iph->ip_src)) { zlog_warn( - "interface %s: eigrp_read network address is not same [%s]", - IF_NAME(ei), inet_ntoa(iph->ip_src)); + "interface %s: eigrp_read network address is not same [%pI4]", + IF_NAME(ei), &iph->ip_src); return -1; } // diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 79405efbbf..26bb27d7ac 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -168,13 +168,10 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, * Destination must exists */ if (!dest) { - char buf[PREFIX_STRLEN]; - flog_err( EC_EIGRP_PACKET, - "%s: Received prefix %s which we do not know about", - __func__, - prefix2str(&dest_addr, buf, sizeof(buf))); + "%s: Received prefix %pFX which we do not know about", + __func__, &dest_addr); eigrp_IPv4_InternalTLV_free(tlv); continue; } diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 7676af15f2..2dbee16694 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -133,14 +133,10 @@ void eigrp_prefix_entry_add(struct route_table *topology, rn = route_node_get(topology, pe->destination); if (rn->info) { - if (IS_DEBUG_EIGRP_EVENT) { - char buf[PREFIX_STRLEN]; - + if (IS_DEBUG_EIGRP_EVENT) zlog_debug( - "%s: %s Should we have found this entry in the topo table?", - __func__, - prefix2str(pe->destination, buf, sizeof(buf))); - } + "%s: %pFX Should we have found this entry in the topo table?", + __func__, pe->destination); route_unlock_node(rn); } diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index 6e2a81e32a..cd30eb5ab5 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -141,10 +141,8 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, /* iterate over all prefixes which weren't advertised by neighbor */ for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) { - char buffer[PREFIX_STRLEN]; - zlog_debug( - "GR receive: Neighbor not advertised %s", - prefix2str(prefix->destination, buffer, PREFIX_STRLEN)); + zlog_debug("GR receive: Neighbor not advertised %pFX", + prefix->destination); fsm_msg.metrics = prefix->reported_metric; /* set delay to MAX */ @@ -209,18 +207,18 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, nbr->recv_sequence_number = ntohl(eigrph->sequence); if (IS_DEBUG_EIGRP_PACKET(0, RECV)) zlog_debug( - "Processing Update size[%u] int(%s) nbr(%s) seq [%u] flags [%0x]", + "Processing Update size[%u] int(%s) nbr(%pI4) seq [%u] flags [%0x]", size, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id), - inet_ntoa(nbr->src), nbr->recv_sequence_number, flags); + &nbr->src, nbr->recv_sequence_number, flags); if ((flags == (EIGRP_INIT_FLAG + EIGRP_RS_FLAG + EIGRP_EOT_FLAG)) && (!same)) { /* Graceful restart Update received with all routes */ - zlog_info("Neighbor %s (%s) is resync: peer graceful-restart", - inet_ntoa(nbr->src), + zlog_info("Neighbor %pI4 (%s) is resync: peer graceful-restart", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); /* get all prefixes from neighbor from topology table */ @@ -231,8 +229,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, /* Graceful restart Update received, routes also in next packet */ - zlog_info("Neighbor %s (%s) is resync: peer graceful-restart", - inet_ntoa(nbr->src), + zlog_info("Neighbor %pI4 (%s) is resync: peer graceful-restart", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); /* get all prefixes from neighbor from topology table */ @@ -279,15 +277,16 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN); eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr); nbr->recv_sequence_number = ntohl(eigrph->sequence); - zlog_info("Neighbor %s (%s) is down: peer restarted", - inet_ntoa(nbr->src), + zlog_info("Neighbor %pI4 (%s) is down: peer restarted", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING); - zlog_info("Neighbor %s (%s) is pending: new adjacency", - inet_ntoa(nbr->src), - ifindex2ifname(nbr->ei->ifp->ifindex, - eigrp->vrf_id)); + zlog_info( + "Neighbor %pI4 (%s) is pending: new adjacency", + &nbr->src, + ifindex2ifname(nbr->ei->ifp->ifindex, + eigrp->vrf_id)); eigrp_update_send_init(nbr); } } @@ -450,8 +449,9 @@ void eigrp_update_send_init(struct eigrp_neighbor *nbr) nbr->init_sequence_number = nbr->ei->eigrp->sequence_number; ep->sequence_number = nbr->ei->eigrp->sequence_number; if (IS_DEBUG_EIGRP_PACKET(0, RECV)) - zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]", - ep->length, ep->sequence_number, inet_ntoa(ep->dst)); + zlog_debug( + "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]", + ep->length, ep->sequence_number, &ep->dst); /*Put packet to retransmission queue*/ eigrp_fifo_push(nbr->retrans_queue, ep); @@ -480,8 +480,9 @@ static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr, ep->sequence_number = seq_no; if (IS_DEBUG_EIGRP_PACKET(0, RECV)) - zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]", - ep->length, ep->sequence_number, inet_ntoa(ep->dst)); + zlog_debug( + "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]", + ep->length, ep->sequence_number, &ep->dst); /*Put packet to retransmission queue*/ eigrp_fifo_push(nbr->retrans_queue, ep); @@ -815,8 +816,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, dest_addr)) { /* do not send filtered route */ - zlog_info("Filtered prefix %s won't be sent out.", - inet_ntoa(dest_addr->u.prefix4)); + zlog_info("Filtered prefix %pI4 won't be sent out.", + &dest_addr->u.prefix4); } else { /* sending route which wasn't filtered */ length += eigrp_add_internalTLV_to_stream(ep->s, pe); @@ -830,8 +831,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN, dest_addr)) { /* do not send filtered route */ - zlog_info("Filtered prefix %s will be removed.", - inet_ntoa(dest_addr->u.prefix4)); + zlog_info("Filtered prefix %pI4 will be removed.", + &dest_addr->u.prefix4); /* prepare message for FSM */ struct eigrp_fsm_action_message fsm_msg; @@ -880,8 +881,9 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) ep->sequence_number = eigrp->sequence_number; if (IS_DEBUG_EIGRP_PACKET(0, RECV)) - zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]", - ep->length, ep->sequence_number, inet_ntoa(ep->dst)); + zlog_debug( + "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]", + ep->length, ep->sequence_number, &ep->dst); /*Put packet to retransmission queue*/ eigrp_fifo_push(nbr->retrans_queue, ep); @@ -963,20 +965,20 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type, if (gr_type == EIGRP_GR_FILTER) { /* function was called after applying filtration */ zlog_info( - "Neighbor %s (%s) is resync: route configuration changed", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) is resync: route configuration changed", + &nbr->src, ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id)); } else if (gr_type == EIGRP_GR_MANUAL) { /* Graceful restart was called manually */ - zlog_info("Neighbor %s (%s) is resync: manually cleared", - inet_ntoa(nbr->src), + zlog_info("Neighbor %pI4 (%s) is resync: manually cleared", + &nbr->src, ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id)); if (vty != NULL) { vty_time_print(vty, 0); vty_out(vty, - "Neighbor %s (%s) is resync: manually cleared\n", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) is resync: manually cleared\n", + &nbr->src, ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id)); } diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 4426cf67e9..66dfbaa538 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -360,14 +360,14 @@ DEFPY (clear_ip_eigrp_neighbors, for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { if (nbr->state != EIGRP_NEIGHBOR_DOWN) { zlog_debug( - "Neighbor %s (%s) is down: manually cleared", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) is down: manually cleared", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); vty_time_print(vty, 0); vty_out(vty, - "Neighbor %s (%s) is down: manually cleared\n", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) is down: manually cleared\n", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); @@ -420,14 +420,15 @@ DEFPY (clear_ip_eigrp_neighbors_int, /* iterate over all neighbors on eigrp interface */ for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { if (nbr->state != EIGRP_NEIGHBOR_DOWN) { - zlog_debug("Neighbor %s (%s) is down: manually cleared", - inet_ntoa(nbr->src), - ifindex2ifname(nbr->ei->ifp->ifindex, - eigrp->vrf_id)); + zlog_debug( + "Neighbor %pI4 (%s) is down: manually cleared", + &nbr->src, + ifindex2ifname(nbr->ei->ifp->ifindex, + eigrp->vrf_id)); vty_time_print(vty, 0); vty_out(vty, - "Neighbor %s (%s) is down: manually cleared\n", - inet_ntoa(nbr->src), + "Neighbor %pI4 (%s) is down: manually cleared\n", + &nbr->src, ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id)); diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 3205f13922..473cc75a2a 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -150,12 +150,9 @@ static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS) if (c == NULL) return 0; - if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) { - char buf[128]; - prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address add %s", c->ifp->name, - buf); - } + if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: interface %s address add %pFX", c->ifp->name, + c->address); eigrp_if_update(c->ifp); @@ -173,12 +170,9 @@ static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS) if (c == NULL) return 0; - if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) { - char buf[128]; - prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address delete %s", - c->ifp->name, buf); - } + if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: interface %s address delete %pFX", + c->ifp->name, c->address); ifp = c->ifp; ei = ifp->info; @@ -234,10 +228,9 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p, api.nexthop_num = count; if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][PREFIX_STRLEN]; - zlog_debug("Zebra: Route add %s nexthop %s", - prefix2str(p, buf[0], PREFIX_STRLEN), - inet_ntop(AF_INET, 0, buf[1], PREFIX_STRLEN)); + char buf[PREFIX_STRLEN]; + zlog_debug("Zebra: Route add %pFX nexthop %s", p, + inet_ntop(AF_INET, 0, buf, PREFIX_STRLEN)); } zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); @@ -257,11 +250,8 @@ void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p) memcpy(&api.prefix, p, sizeof(*p)); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); - if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[PREFIX_STRLEN]; - zlog_debug("Zebra: Route del %s", - prefix2str(p, buf, PREFIX_STRLEN)); - } + if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route del %pFX", p); return; } diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 820f015b57..5002630796 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -110,10 +110,6 @@ void eigrp_router_id_update(struct eigrp *eigrp) eigrp->router_id = router_id; if (router_id_old.s_addr != router_id.s_addr) { - // if (IS_DEBUG_EIGRP_EVENT) - // zlog_debug("Router-ID[NEW:%s]: Update", - // inet_ntoa(eigrp->router_id)); - /* update eigrp_interface's */ FOR_ALL_INTERFACES (vrf, ifp) eigrp_if_update(ifp); diff --git a/isisd/fabricd.c b/isisd/fabricd.c index 1a081bbea6..57e9e91c15 100644 --- a/isisd/fabricd.c +++ b/isisd/fabricd.c @@ -239,14 +239,11 @@ struct fabricd *fabricd_new(struct isis_area *area) void fabricd_finish(struct fabricd *f) { - if (f->initial_sync_timeout) - thread_cancel(f->initial_sync_timeout); + thread_cancel(&(f->initial_sync_timeout)); - if (f->tier_calculation_timer) - thread_cancel(f->tier_calculation_timer); + thread_cancel(&(f->tier_calculation_timer)); - if (f->tier_set_timer) - thread_cancel(f->tier_set_timer); + thread_cancel(&(f->tier_set_timer)); isis_spftree_del(f->spftree); neighbor_lists_clear(f); @@ -340,8 +337,7 @@ void fabricd_initial_sync_finish(struct isis_area *area) f->initial_sync_circuit->interface->name); f->initial_sync_state = FABRICD_SYNC_COMPLETE; f->initial_sync_circuit = NULL; - thread_cancel(f->initial_sync_timeout); - f->initial_sync_timeout = NULL; + thread_cancel(&(f->initial_sync_timeout)); } static void fabricd_bump_tier_calculation_timer(struct fabricd *f); @@ -437,22 +433,15 @@ static int fabricd_tier_calculation_cb(struct thread *thread) static void fabricd_bump_tier_calculation_timer(struct fabricd *f) { /* Cancel timer if we already know our tier */ - if (f->tier != ISIS_TIER_UNDEFINED - || f->tier_set_timer) { - if (f->tier_calculation_timer) { - thread_cancel(f->tier_calculation_timer); - f->tier_calculation_timer = NULL; - } + if (f->tier != ISIS_TIER_UNDEFINED || f->tier_set_timer) { + thread_cancel(&(f->tier_calculation_timer)); return; } /* If we need to calculate the tier, wait some * time for the topology to settle before running * the calculation */ - if (f->tier_calculation_timer) { - thread_cancel(f->tier_calculation_timer); - f->tier_calculation_timer = NULL; - } + thread_cancel(&(f->tier_calculation_timer)); thread_add_timer(master, fabricd_tier_calculation_cb, f, 2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1], @@ -737,7 +726,7 @@ void fabricd_trigger_csnp(struct isis_area *area, bool circuit_scoped) if (!circuit->t_send_csnp[1]) continue; - thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]); + thread_cancel(&(circuit->t_send_csnp[ISIS_LEVEL2 - 1])); thread_add_timer_msec(master, send_l2_csnp, circuit, isis_jitter(f->csnp_delay, CSNP_JITTER), &circuit->t_send_csnp[ISIS_LEVEL2 - 1]); diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 5bfbb2cf7e..71d4758163 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -147,7 +147,7 @@ void isis_delete_adj(void *arg) if (!adj) return; - THREAD_TIMER_OFF(adj->t_expire); + thread_cancel(&adj->t_expire); if (adj->adj_state != ISIS_ADJ_DOWN) adj->adj_state = ISIS_ADJ_DOWN; @@ -393,7 +393,7 @@ void isis_adj_print(struct isis_adjacency *adj) if (adj->ipv4_address_count) { zlog_debug("IPv4 Address(es):"); for (unsigned int i = 0; i < adj->ipv4_address_count; i++) - zlog_debug("%s", inet_ntoa(adj->ipv4_addresses[i])); + zlog_debug("%pI4", &adj->ipv4_addresses[i]); } if (adj->ipv6_address_count) { @@ -562,8 +562,8 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, vty_out(vty, " IPv4 Address(es):\n"); for (unsigned int i = 0; i < adj->ipv4_address_count; i++) - vty_out(vty, " %s\n", - inet_ntoa(adj->ipv4_addresses[i])); + vty_out(vty, " %pI4\n", + &adj->ipv4_addresses[i]); } if (adj->ipv6_address_count) { vty_out(vty, " IPv6 Address(es):\n"); diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index d6988095e5..e3c70264f8 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -71,13 +71,14 @@ DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp)) int isis_if_new_hook(struct interface *); int isis_if_delete_hook(struct interface *); -struct isis_circuit *isis_circuit_new(void) +struct isis_circuit *isis_circuit_new(struct isis *isis) { struct isis_circuit *circuit; int i; circuit = XCALLOC(MTYPE_ISIS_CIRCUIT, sizeof(struct isis_circuit)); + circuit->isis = isis; /* * Default values */ @@ -252,9 +253,6 @@ void isis_circuit_add_addr(struct isis_circuit *circuit, { struct listnode *node; struct prefix_ipv4 *ipv4; -#if defined(EXTREME_DEBUG) - char buf[PREFIX2STR_BUFFER]; -#endif struct prefix_ipv6 *ipv6; if (connected->address->family == AF_INET) { @@ -286,9 +284,8 @@ void isis_circuit_add_addr(struct isis_circuit *circuit, 0); #ifdef EXTREME_DEBUG - prefix2str(connected->address, buf, sizeof(buf)); - zlog_debug("Added IP address %s to circuit %s", buf, - circuit->interface->name); + zlog_debug("Added IP address %pFX to circuit %s", + connected->address, circuit->interface->name); #endif /* EXTREME_DEBUG */ } if (connected->address->family == AF_INET6) { @@ -317,9 +314,8 @@ void isis_circuit_add_addr(struct isis_circuit *circuit, 0); #ifdef EXTREME_DEBUG - prefix2str(connected->address, buf, sizeof(buf)); - zlog_debug("Added IPv6 address %s to circuit %s", buf, - circuit->interface->name); + zlog_debug("Added IPv6 address %pFX to circuit %s", + connected->address, circuit->interface->name); #endif /* EXTREME_DEBUG */ } return; @@ -330,7 +326,6 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, { struct prefix_ipv4 *ipv4, *ip = NULL; struct listnode *node; - char buf[PREFIX2STR_BUFFER]; struct prefix_ipv6 *ipv6, *ip6 = NULL; int found = 0; @@ -351,16 +346,14 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); } else { - prefix2str(connected->address, buf, sizeof(buf)); zlog_warn( - "Nonexistent ip address %s removal attempt from circuit %s", - buf, circuit->interface->name); + "Nonexistent ip address %pFX removal attempt from circuit %s", + connected->address, circuit->interface->name); zlog_warn("Current ip addresses on %s:", circuit->interface->name); for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ip)) { - prefix2str(ip, buf, sizeof(buf)); - zlog_warn(" %s", buf); + zlog_warn(" %pFX", ip); } zlog_warn("End of addresses"); } @@ -399,25 +392,18 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, } if (!found) { - prefix2str(connected->address, buf, sizeof(buf)); zlog_warn( - "Nonexistent ip address %s removal attempt from circuit %s", - buf, circuit->interface->name); + "Nonexistent ip address %pFX removal attempt from circuit %s", + connected->address, circuit->interface->name); zlog_warn("Current ip addresses on %s:", circuit->interface->name); for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, - ip6)) { - prefix2str((struct prefix *)ip6, (char *)buf, - sizeof(buf)); - zlog_warn(" %s", buf); - } + ip6)) + zlog_warn(" %pFX", (struct prefix *)ip6); zlog_warn(" -----"); for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, - ip6)) { - prefix2str((struct prefix *)ip6, (char *)buf, - sizeof(buf)); - zlog_warn(" %s", buf); - } + ip6)) + zlog_warn(" %pFX", (struct prefix *)ip6); zlog_warn("End of addresses"); } else if (circuit->area) lsp_regenerate_schedule(circuit->area, circuit->is_type, @@ -612,8 +598,20 @@ int isis_circuit_up(struct isis_circuit *circuit) if (circuit->state == C_STATE_UP) return ISIS_OK; - if (circuit->is_passive) + if (circuit->is_passive) { + /* make sure the union fields are initialized, else we + * could end with garbage values from a previous circuit + * type, which would then cause a segfault when building + * LSPs or computing the SPF tree + */ + if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + circuit->u.bc.adjdb[0] = list_new(); + circuit->u.bc.adjdb[1] = list_new(); + } else if (circuit->circ_type == CIRCUIT_T_P2P) { + circuit->u.p2p.neighbor = NULL; + } return ISIS_OK; + } if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) { flog_err( @@ -626,8 +624,8 @@ int isis_circuit_up(struct isis_circuit *circuit) } if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - circuit->circuit_id = isis_circuit_id_gen(circuit->area->isis, - circuit->interface); + circuit->circuit_id = + isis_circuit_id_gen(circuit->isis, circuit->interface); if (!circuit->circuit_id) { flog_err( EC_ISIS_CONFIG, @@ -802,30 +800,30 @@ void isis_circuit_down(struct isis_circuit *circuit) memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1); memset(circuit->u.bc.snpa, 0, ETH_ALEN); - THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[0]); - THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[1]); - THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[0]); - THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[1]); - THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]); - THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]); + thread_cancel(&circuit->u.bc.t_send_lan_hello[0]); + thread_cancel(&circuit->u.bc.t_send_lan_hello[1]); + thread_cancel(&circuit->u.bc.t_run_dr[0]); + thread_cancel(&circuit->u.bc.t_run_dr[1]); + thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[0]); + thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[1]); circuit->lsp_regenerate_pending[0] = 0; circuit->lsp_regenerate_pending[1] = 0; - _ISIS_CLEAR_FLAG(circuit->area->isis->circuit_ids_used, + _ISIS_CLEAR_FLAG(circuit->isis->circuit_ids_used, circuit->circuit_id); circuit->circuit_id = 0; } else if (circuit->circ_type == CIRCUIT_T_P2P) { isis_delete_adj(circuit->u.p2p.neighbor); circuit->u.p2p.neighbor = NULL; - THREAD_TIMER_OFF(circuit->u.p2p.t_send_p2p_hello); + thread_cancel(&circuit->u.p2p.t_send_p2p_hello); } /* Cancel all active threads */ - THREAD_TIMER_OFF(circuit->t_send_csnp[0]); - THREAD_TIMER_OFF(circuit->t_send_csnp[1]); - THREAD_TIMER_OFF(circuit->t_send_psnp[0]); - THREAD_TIMER_OFF(circuit->t_send_psnp[1]); - THREAD_OFF(circuit->t_read); + thread_cancel(&circuit->t_send_csnp[0]); + thread_cancel(&circuit->t_send_csnp[1]); + thread_cancel(&circuit->t_send_psnp[0]); + thread_cancel(&circuit->t_send_psnp[1]); + thread_cancel(&circuit->t_read); if (circuit->tx_queue) { isis_tx_queue_free(circuit->tx_queue); @@ -894,7 +892,6 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, if (detail == ISIS_UI_LEVEL_DETAIL) { struct listnode *node; struct prefix *ip_addr; - char buf[BUFSIZ]; vty_out(vty, " Interface: %s", circuit->interface->name); vty_out(vty, ", State: %s", @@ -979,27 +976,21 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, if (circuit->ip_addrs && listcount(circuit->ip_addrs) > 0) { vty_out(vty, " IP Prefix(es):\n"); for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, - ip_addr)) { - prefix2str(ip_addr, buf, sizeof(buf)); - vty_out(vty, " %s\n", buf); - } + ip_addr)) + vty_out(vty, " %pFX\n", ip_addr); } if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) { vty_out(vty, " IPv6 Link-Locals:\n"); for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, - ip_addr)) { - prefix2str(ip_addr, (char *)buf, BUFSIZ); - vty_out(vty, " %s\n", buf); - } + ip_addr)) + vty_out(vty, " %pFX\n", ip_addr); } if (circuit->ipv6_non_link && listcount(circuit->ipv6_non_link) > 0) { vty_out(vty, " IPv6 Prefixes:\n"); for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, - ip_addr)) { - prefix2str(ip_addr, (char *)buf, BUFSIZ); - vty_out(vty, " %s\n", buf); - } + ip_addr)) + vty_out(vty, " %pFX\n", ip_addr); } vty_out(vty, "\n"); diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index 5766d1962f..b4b03bf6b9 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -79,6 +79,7 @@ struct isis_circuit_arg { struct isis_circuit { int state; uint8_t circuit_id; /* l1/l2 bcast CircuitID */ + struct isis *isis; struct isis_area *area; /* back pointer to the area */ struct interface *interface; /* interface info from z */ int fd; /* IS-IS l1/2 socket */ @@ -140,6 +141,8 @@ struct isis_circuit { bool disable_threeway_adj; struct bfd_info *bfd_info; struct ldp_sync_info *ldp_sync_info; + bool tilfa_protection[ISIS_LEVELS]; + bool tilfa_node_protection[ISIS_LEVELS]; /* * Counters as in 10589--11.2.5.9 */ @@ -163,7 +166,7 @@ struct isis_circuit { DECLARE_QOBJ_TYPE(isis_circuit) void isis_circuit_init(void); -struct isis_circuit *isis_circuit_new(void); +struct isis_circuit *isis_circuit_new(struct isis *isis); void isis_circuit_del(struct isis_circuit *circuit); struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp, struct list *list); diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index d303cbe98d..203fa8eb8d 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -1628,17 +1628,18 @@ DEFPY_YANG (isis_sr_prefix_sid, "segment-routing prefix\ <A.B.C.D/M|X:X::X:X/M>$prefix\ <absolute$sid_type (16-1048575)$sid_value|index$sid_type (0-65535)$sid_value>\ - [<no-php-flag|explicit-null>$lh_behavior]", + [<no-php-flag|explicit-null>$lh_behavior] [n-flag-clear$n_flag_clear]", SR_STR "Prefix SID\n" "IPv4 Prefix\n" "IPv6 Prefix\n" - "Specify the absolute value of Prefix Segement ID\n" + "Specify the absolute value of Prefix Segment ID\n" "The Prefix Segment ID value\n" - "Specify the index of Prefix Segement ID\n" + "Specify the index of Prefix Segment ID\n" "The Prefix Segment ID index\n" "Don't request Penultimate Hop Popping (PHP)\n" - "Upstream neighbor must replace prefix-sid with explicit null label\n") + "Upstream neighbor must replace prefix-sid with explicit null label\n" + "Not a node SID\n") { nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type); @@ -1656,6 +1657,8 @@ DEFPY_YANG (isis_sr_prefix_sid, } else nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY, NULL); + nb_cli_enqueue_change(vty, "./n-flag-clear", NB_OP_MODIFY, + n_flag_clear ? "true" : "false"); return nb_cli_apply_changes( vty, "./segment-routing/prefix-sid-map/prefix-sid[prefix='%s']", @@ -1665,18 +1668,20 @@ DEFPY_YANG (isis_sr_prefix_sid, DEFPY_YANG (no_isis_sr_prefix_sid, no_isis_sr_prefix_sid_cmd, "no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\ - [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]", + [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]\ + [n-flag-clear]", NO_STR SR_STR "Prefix SID\n" "IPv4 Prefix\n" "IPv6 Prefix\n" - "Specify the absolute value of Prefix Segement ID\n" + "Specify the absolute value of Prefix Segment ID\n" "The Prefix Segment ID value\n" - "Specify the index of Prefix Segement ID\n" + "Specify the index of Prefix Segment ID\n" "The Prefix Segment ID index\n" "Don't request Penultimate Hop Popping (PHP)\n" - "Upstream neighbor must replace prefix-sid with explicit null label\n") + "Upstream neighbor must replace prefix-sid with explicit null label\n" + "Not a node SID\n") { nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL); @@ -1692,11 +1697,13 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode, const char *lh_behavior; const char *sid_value_type; const char *sid_value; + bool n_flag_clear; prefix = yang_dnode_get_string(dnode, "./prefix"); lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior"); sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type"); sid_value = yang_dnode_get_string(dnode, "./sid-value"); + n_flag_clear = yang_dnode_get_bool(dnode, "./n-flag-clear"); vty_out(vty, " segment-routing prefix %s", prefix); if (strmatch(sid_value_type, "absolute")) @@ -1708,6 +1715,8 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode, vty_out(vty, " no-php-flag"); else if (strmatch(lh_behavior, "explicit-null")) vty_out(vty, " explicit-null"); + if (n_flag_clear) + vty_out(vty, " n-flag-clear"); vty_out(vty, "\n"); } @@ -2368,6 +2377,102 @@ void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode, } /* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/ti-lfa/enable + */ +DEFPY(isis_ti_lfa, isis_ti_lfa_cmd, + "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection]", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable TI-LFA computation\n" + "Enable TI-LFA computation for Level 1 only\n" + "Enable TI-LFA computation for Level 2 only\n" + "Protect against node failures\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection", + NB_OP_MODIFY, + node_protection ? "true" : "false"); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable", + NB_OP_MODIFY, "false"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable", + NB_OP_MODIFY, "true"); + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection", + NB_OP_MODIFY, + node_protection ? "true" : "false"); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ip_isis_ti_lfa(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + bool l1_enabled, l2_enabled; + bool l1_node_protection, l2_node_protection; + + l1_enabled = yang_dnode_get_bool(dnode, "./level-1/ti-lfa/enable"); + l2_enabled = yang_dnode_get_bool(dnode, "./level-2/ti-lfa/enable"); + l1_node_protection = + yang_dnode_get_bool(dnode, "./level-1/ti-lfa/node-protection"); + l2_node_protection = + yang_dnode_get_bool(dnode, "./level-2/ti-lfa/node-protection"); + + if (l1_enabled == l2_enabled + && l1_node_protection == l2_node_protection) { + vty_out(vty, " isis fast-reroute ti-lfa"); + if (l1_node_protection) + vty_out(vty, " node-protection"); + vty_out(vty, "\n"); + } else { + if (l1_enabled) { + vty_out(vty, " isis fast-reroute ti-lfa level-1"); + if (l1_node_protection) + vty_out(vty, " node-protection"); + vty_out(vty, "\n"); + } + if (l2_enabled) { + vty_out(vty, " isis fast-reroute ti-lfa level-2"); + if (l2_node_protection) + vty_out(vty, " node-protection"); + vty_out(vty, "\n"); + } + } +} + +/* * XPath: /frr-isisd:isis/instance/log-adjacency-changes */ DEFPY_YANG(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes", @@ -2661,6 +2766,8 @@ void isis_cli_init(void) install_element(INTERFACE_NODE, &isis_priority_cmd); install_element(INTERFACE_NODE, &no_isis_priority_cmd); + install_element(INTERFACE_NODE, &isis_ti_lfa_cmd); + install_element(ISIS_NODE, &log_adj_changes_cmd); install_element(ISIS_NODE, &isis_mpls_ldp_sync_cmd); diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c index 929b4c26e8..736d8d63f9 100644 --- a/isisd/isis_csm.c +++ b/isisd/isis_csm.c @@ -65,6 +65,7 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) { int old_state; struct isis *isis = NULL; + struct isis_area *area = NULL; old_state = circuit ? circuit->state : C_STATE_NA; if (IS_DEBUG_EVENTS) @@ -77,21 +78,22 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) assert(circuit == NULL); switch (event) { case ISIS_ENABLE: - circuit = isis_circuit_new(); - isis_circuit_configure(circuit, - (struct isis_area *)arg); + area = arg; + + circuit = isis_circuit_new(area->isis); + isis_circuit_configure(circuit, area); circuit->state = C_STATE_CONF; break; case IF_UP_FROM_Z: - circuit = isis_circuit_new(); - isis_circuit_if_add(circuit, (struct interface *)arg); - isis = isis_lookup_by_vrfid(circuit->interface->vrf_id); + isis = isis_lookup_by_vrfid(((struct interface *)arg)->vrf_id); if (isis == NULL) { zlog_warn( " %s : ISIS routing instance not found", __func__); break; } + circuit = isis_circuit_new(isis); + isis_circuit_if_add(circuit, (struct interface *)arg); listnode_add(isis->init_circ_list, circuit); circuit->state = C_STATE_INIT; break; @@ -117,7 +119,7 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) circuit->state = C_STATE_UP; isis_event_circuit_state_change(circuit, circuit->area, 1); - listnode_delete(circuit->area->isis->init_circ_list, + listnode_delete(circuit->isis->init_circ_list, circuit); break; case IF_UP_FROM_Z: @@ -129,15 +131,8 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) break; case IF_DOWN_FROM_Z: isis_circuit_if_del(circuit, (struct interface *)arg); - isis = isis_lookup_by_vrfid(circuit->interface->vrf_id); - if (isis == NULL) { - zlog_warn( - "%s : ISIS routing instance not found", - __func__); - break; - } - - listnode_delete(isis->init_circ_list, circuit); + listnode_delete(circuit->isis->init_circ_list, + circuit); isis_circuit_del(circuit); circuit = NULL; break; @@ -152,6 +147,7 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) case IF_UP_FROM_Z: isis_circuit_if_add(circuit, (struct interface *)arg); if (isis_circuit_up(circuit) != ISIS_OK) { + isis_circuit_if_del(circuit, (struct interface *)arg); flog_err( EC_ISIS_CONFIG, "Could not bring up %s because of invalid config.", @@ -183,21 +179,13 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg) zlog_warn("circuit already connected"); break; case ISIS_DISABLE: + isis = circuit->isis; isis_circuit_down(circuit); isis_circuit_deconfigure(circuit, (struct isis_area *)arg); circuit->state = C_STATE_INIT; isis_event_circuit_state_change( circuit, (struct isis_area *)arg, 0); - - isis = isis_lookup_by_vrfid(circuit->interface->vrf_id); - if (isis == NULL) { - zlog_warn( - "%s : ISIS routing instance not found", - __func__); - break; - } - listnode_add(isis->init_circ_list, circuit); break; case IF_DOWN_FROM_Z: diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c index 318fb9fab8..d03f857a0c 100644 --- a/isisd/isis_dr.c +++ b/isisd/isis_dr.c @@ -221,11 +221,11 @@ int isis_dr_resign(struct isis_circuit *circuit, int level) circuit->u.bc.is_dr[level - 1] = 0; circuit->u.bc.run_dr_elect[level - 1] = 0; - THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[level - 1]); - THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + thread_cancel(&circuit->u.bc.t_run_dr[level - 1]); + thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); circuit->lsp_regenerate_pending[level - 1] = 0; - memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN); + memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN); LSP_PSEUDO_ID(id) = circuit->circuit_id; LSP_FRAGMENT(id) = 0; lsp_purge_pseudo(id, circuit, level); @@ -246,7 +246,7 @@ int isis_dr_resign(struct isis_circuit *circuit, int level) &circuit->t_send_psnp[1]); } - THREAD_TIMER_OFF(circuit->t_send_csnp[level - 1]); + thread_cancel(&circuit->t_send_csnp[level - 1]); thread_add_timer(master, isis_run_dr, &circuit->level_arg[level - 1], @@ -278,7 +278,7 @@ int isis_dr_commence(struct isis_circuit *circuit, int level) /* there was a dr elected, purge its LSPs from the db */ lsp_purge_pseudo(old_dr, circuit, level); } - memcpy(circuit->u.bc.l1_desig_is, circuit->area->isis->sysid, + memcpy(circuit->u.bc.l1_desig_is, circuit->isis->sysid, ISIS_SYS_ID_LEN); *(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id; @@ -300,7 +300,7 @@ int isis_dr_commence(struct isis_circuit *circuit, int level) /* there was a dr elected, purge its LSPs from the db */ lsp_purge_pseudo(old_dr, circuit, level); } - memcpy(circuit->u.bc.l2_desig_is, circuit->area->isis->sysid, + memcpy(circuit->u.bc.l2_desig_is, circuit->isis->sysid, ISIS_SYS_ID_LEN); *(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id; diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 717a5fd046..0b987fc5cf 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -49,14 +49,6 @@ #include "isisd/isis_spf.h" #include "isisd/isis_errors.h" -/* debug isis-spf spf-events - 4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4 - 4w4d: ISIS-Spf (tlt): L2, 0000.0000.0042.01-00 TLV contents changed, code 0x2 - 4w4d: ISIS-Spf (tlt): L2, new LSP 0 DEAD.BEEF.0043.00-00 - 4w5d: ISIS-Spf (tlt): L1 SPF needed, periodic SPF, from 0x6091C844 - 4w5d: ISIS-Spf (tlt): L2 SPF needed, periodic SPF, from 0x6091C844 -*/ - void isis_event_circuit_state_change(struct isis_circuit *circuit, struct isis_area *area, int up) { @@ -117,13 +109,13 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level) circuit->area->area_tag, circuit->circuit_id, circuit->interface->name, level); - THREAD_TIMER_OFF(circuit->t_send_csnp[idx]); - THREAD_TIMER_OFF(circuit->t_send_psnp[idx]); + thread_cancel(&circuit->t_send_csnp[idx]); + thread_cancel(&circuit->t_send_psnp[idx]); if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[idx]); - THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[idx]); - THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]); + thread_cancel(&circuit->u.bc.t_send_lan_hello[idx]); + thread_cancel(&circuit->u.bc.t_run_dr[idx]); + thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[idx]); circuit->lsp_regenerate_pending[idx] = 0; circuit->u.bc.run_dr_elect[idx] = 0; circuit->u.bc.is_dr[idx] = 0; diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c index c15b59a8cf..988af64c48 100644 --- a/isisd/isis_ldp_sync.c +++ b/isisd/isis_ldp_sync.c @@ -135,8 +135,8 @@ int isis_ldp_sync_announce_update(struct ldp_igp_sync_announce announce) } } - THREAD_TIMER_OFF(isis->ldp_sync_cmd.t_hello); - isis->ldp_sync_cmd.t_hello = NULL; + THREAD_OFF(isis->ldp_sync_cmd.t_hello); + isis->ldp_sync_cmd.sequence = 0; isis_ldp_sync_hello_timer_add(); @@ -186,7 +186,7 @@ int isis_ldp_sync_hello_update(struct ldp_igp_sync_hello hello) } } } else { - THREAD_TIMER_OFF(isis->ldp_sync_cmd.t_hello); + THREAD_OFF(isis->ldp_sync_cmd.t_hello); isis_ldp_sync_hello_timer_add(); } isis->ldp_sync_cmd.sequence = hello.sequence; @@ -280,8 +280,9 @@ void isis_ldp_sync_if_complete(struct isis_circuit *circuit) if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) { if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP) ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP; - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; + + THREAD_OFF(ldp_sync_info->t_holddown); + isis_ldp_sync_set_if_metric(circuit, true); } } @@ -300,10 +301,7 @@ void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit) if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED && ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) { - if (ldp_sync_info->t_holddown != NULL) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; - } + THREAD_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; isis_ldp_sync_set_if_metric(circuit, true); } @@ -326,8 +324,7 @@ void isis_ldp_sync_if_remove(struct isis_circuit *circuit, bool remove) ils_debug("ldp_sync: remove if %s", circuit->interface ? circuit->interface->name : ""); - if (ldp_sync_info->t_holddown) - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); + THREAD_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; isis_ldp_sync_set_if_metric(circuit, true); if (remove) { @@ -666,8 +663,7 @@ void isis_ldp_sync_gbl_exit(bool remove) UNSET_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE); UNSET_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN); isis->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; - THREAD_TIMER_OFF(isis->ldp_sync_cmd.t_hello); - isis->ldp_sync_cmd.t_hello = NULL; + THREAD_OFF(isis->ldp_sync_cmd.t_hello); /* remove LDP-SYNC on all ISIS interfaces */ FOR_ALL_INTERFACES (vrf, ifp) { diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c new file mode 100644 index 0000000000..f22e4a7085 --- /dev/null +++ b/isisd/isis_lfa.c @@ -0,0 +1,1112 @@ +/* + * Copyright (C) 2020 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "linklist.h" +#include "log.h" +#include "memory.h" +#include "vrf.h" +#include "table.h" +#include "srcdest_table.h" + +#include "isis_common.h" +#include "isisd.h" +#include "isis_misc.h" +#include "isis_adjacency.h" +#include "isis_circuit.h" +#include "isis_lsp.h" +#include "isis_spf.h" +#include "isis_route.h" +#include "isis_mt.h" +#include "isis_tlvs.h" +#include "isis_spf_private.h" +#include "isisd/isis_errors.h" + +DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_NODE, "ISIS SPF Node"); + +static inline int isis_spf_node_compare(const struct isis_spf_node *a, + const struct isis_spf_node *b) +{ + return memcmp(a->sysid, b->sysid, sizeof(a->sysid)); +} +RB_GENERATE(isis_spf_nodes, isis_spf_node, entry, isis_spf_node_compare) + +/** + * Initialize list of SPF nodes. + * + * @param nodes List of SPF nodes + */ +void isis_spf_node_list_init(struct isis_spf_nodes *nodes) +{ + RB_INIT(isis_spf_nodes, nodes); +} + +/** + * Clear list of SPF nodes, releasing all allocated memory. + * + * @param nodes List of SPF nodes + */ +void isis_spf_node_list_clear(struct isis_spf_nodes *nodes) +{ + while (!RB_EMPTY(isis_spf_nodes, nodes)) { + struct isis_spf_node *node = RB_ROOT(isis_spf_nodes, nodes); + + if (node->adjacencies) + list_delete(&node->adjacencies); + if (node->lfa.spftree) + isis_spftree_del(node->lfa.spftree); + if (node->lfa.spftree_reverse) + isis_spftree_del(node->lfa.spftree_reverse); + isis_spf_node_list_clear(&node->lfa.p_space); + RB_REMOVE(isis_spf_nodes, nodes, node); + XFREE(MTYPE_ISIS_SPF_NODE, node); + } +} + +/** + * Add new node to list of SPF nodes. + * + * @param nodes List of SPF nodes + * @param sysid Node System ID + * + * @return Pointer to new IS-IS SPF node structure. + */ +struct isis_spf_node *isis_spf_node_new(struct isis_spf_nodes *nodes, + const uint8_t *sysid) +{ + struct isis_spf_node *node; + + node = XCALLOC(MTYPE_ISIS_SPF_NODE, sizeof(*node)); + memcpy(node->sysid, sysid, sizeof(node->sysid)); + node->adjacencies = list_new(); + isis_spf_node_list_init(&node->lfa.p_space); + RB_INSERT(isis_spf_nodes, nodes, node); + + return node; +} + +/** + * Lookup SPF node by its System ID on the given list. + * + * @param nodes List of SPF nodes + * @param sysid Node System ID + * + * @return Pointer to SPF node if found, NULL otherwise + */ +struct isis_spf_node *isis_spf_node_find(const struct isis_spf_nodes *nodes, + const uint8_t *sysid) +{ + struct isis_spf_node node = {}; + + memcpy(node.sysid, sysid, sizeof(node.sysid)); + return RB_FIND(isis_spf_nodes, nodes, &node); +} + +/** + * Check if a given IS-IS adjacency needs to be excised when computing the SPF + * post-convergence tree. + * + * @param spftree IS-IS SPF tree + * @param id Adjacency System ID (or LAN ID of the designated router + * for broadcast interfaces) + * + * @return true if the adjacency needs to be excised, false + * otherwise + */ +bool isis_lfa_excise_adj_check(const struct isis_spftree *spftree, + const uint8_t *id) +{ + const struct lfa_protected_resource *resource; + + if (spftree->type != SPF_TYPE_TI_LFA) + return false; + + /* + * Adjacencies formed over the failed interface should be excised both + * when using link and node protection. + */ + resource = &spftree->lfa.protected_resource; + if (!memcmp(resource->adjacency, id, ISIS_SYS_ID_LEN + 1)) + return true; + + return false; +} + +/** + * Check if a given IS-IS node needs to be excised when computing the SPF + * post-convergence tree. + * + * @param spftree IS-IS SPF tree + * @param id Node System ID + * + * @return true if the node needs to be excised, false otherwise + */ +bool isis_lfa_excise_node_check(const struct isis_spftree *spftree, + const uint8_t *id) +{ + const struct lfa_protected_resource *resource; + + if (spftree->type != SPF_TYPE_TI_LFA) + return false; + + /* + * When using node protection, nodes reachable over the failed interface + * must be excised. + */ + resource = &spftree->lfa.protected_resource; + if (resource->type == LFA_LINK_PROTECTION) + return false; + + if (isis_spf_node_find(&resource->nodes, id)) + return true; + + return false; +} + +struct tilfa_find_pnode_prefix_sid_args { + uint32_t sid_index; +}; + +static int tilfa_find_pnode_prefix_sid_cb(const struct prefix *prefix, + uint32_t metric, bool external, + struct isis_subtlvs *subtlvs, + void *arg) +{ + struct tilfa_find_pnode_prefix_sid_args *args = arg; + struct isis_prefix_sid *psid; + + if (!subtlvs || subtlvs->prefix_sids.count == 0) + return LSP_ITER_CONTINUE; + + psid = (struct isis_prefix_sid *)subtlvs->prefix_sids.head; + + /* Require the node flag to be set. */ + if (!CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_NODE)) + return LSP_ITER_CONTINUE; + + args->sid_index = psid->value; + + return LSP_ITER_STOP; +} + +/* Find Prefix-SID associated to a System ID. */ +static uint32_t tilfa_find_pnode_prefix_sid(struct isis_spftree *spftree, + const uint8_t *sysid) +{ + struct isis_lsp *lsp; + struct tilfa_find_pnode_prefix_sid_args args; + + lsp = isis_root_system_lsp(spftree->lspdb, sysid); + if (!lsp) + return UINT32_MAX; + + args.sid_index = UINT32_MAX; + isis_lsp_iterate_ip_reach(lsp, spftree->family, spftree->mtid, + tilfa_find_pnode_prefix_sid_cb, &args); + + return args.sid_index; +} + +struct tilfa_find_qnode_adj_sid_args { + const uint8_t *qnode_sysid; + mpls_label_t label; +}; + +static int tilfa_find_qnode_adj_sid_cb(const uint8_t *id, uint32_t metric, + bool oldmetric, + struct isis_ext_subtlvs *subtlvs, + void *arg) +{ + struct tilfa_find_qnode_adj_sid_args *args = arg; + struct isis_adj_sid *adj_sid; + + if (memcmp(id, args->qnode_sysid, ISIS_SYS_ID_LEN)) + return LSP_ITER_CONTINUE; + if (!subtlvs || subtlvs->adj_sid.count == 0) + return LSP_ITER_CONTINUE; + + adj_sid = (struct isis_adj_sid *)subtlvs->adj_sid.head; + args->label = adj_sid->sid; + + return LSP_ITER_STOP; +} + +/* Find Adj-SID associated to a pair of System IDs. */ +static mpls_label_t tilfa_find_qnode_adj_sid(struct isis_spftree *spftree, + const uint8_t *source_sysid, + const uint8_t *qnode_sysid) +{ + struct isis_lsp *lsp; + struct tilfa_find_qnode_adj_sid_args args; + + lsp = isis_root_system_lsp(spftree->lspdb, source_sysid); + if (!lsp) + return MPLS_INVALID_LABEL; + + args.qnode_sysid = qnode_sysid; + args.label = MPLS_INVALID_LABEL; + isis_lsp_iterate_is_reach(lsp, spftree->mtid, + tilfa_find_qnode_adj_sid_cb, &args); + + return args.label; +} + +/* + * Compute the MPLS label stack associated to a TI-LFA repair list. This + * needs to be computed separately for each adjacency since different + * neighbors can have different SRGBs. + */ +static struct mpls_label_stack * +tilfa_compute_label_stack(struct lspdb_head *lspdb, + const struct isis_spf_adj *sadj, + const struct list *repair_list) +{ + struct mpls_label_stack *label_stack; + struct isis_tilfa_sid *sid; + struct listnode *node; + size_t i = 0; + + /* Allocate label stack. */ + label_stack = XCALLOC(MTYPE_ISIS_NEXTHOP_LABELS, + sizeof(struct mpls_label_stack) + + listcount(repair_list) + * sizeof(mpls_label_t)); + label_stack->num_labels = listcount(repair_list); + + for (ALL_LIST_ELEMENTS_RO(repair_list, node, sid)) { + const uint8_t *target_node; + struct isis_sr_block *srgb; + mpls_label_t label; + + switch (sid->type) { + case TILFA_SID_PREFIX: + if (sid->value.index.remote) + target_node = sid->value.index.remote_sysid; + else + target_node = sadj->id; + srgb = isis_sr_find_srgb(lspdb, target_node); + if (!srgb) { + zlog_warn("%s: SRGB not found for node %s", + __func__, + print_sys_hostname(target_node)); + goto error; + } + + /* Check if the SID index falls inside the SRGB. */ + if (sid->value.index.value >= srgb->range_size) { + flog_warn( + EC_ISIS_SID_OVERFLOW, + "%s: SID index %u falls outside remote SRGB range", + __func__, sid->value.index.value); + goto error; + } + + /* + * Prefix-SID: map SID index to label value within the + * SRGB. + */ + label = srgb->lower_bound + sid->value.index.value; + break; + case TILFA_SID_ADJ: + /* Adj-SID: absolute label value can be used directly */ + label = sid->value.label; + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown TI-LFA SID type [%u]", __func__, + sid->type); + exit(1); + } + label_stack->label[i++] = label; + } + + return label_stack; + +error: + XFREE(MTYPE_ISIS_NEXTHOP_LABELS, label_stack); + return NULL; +} + +static int tilfa_repair_list_apply(struct isis_spftree *spftree, + struct isis_vertex *vertex_dest, + const struct isis_vertex *vertex_pnode, + const struct list *repair_list) +{ + struct isis_vertex_adj *vadj; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(vertex_dest->Adj_N, node, vadj)) { + struct isis_spf_adj *sadj = vadj->sadj; + struct mpls_label_stack *label_stack; + + if (!isis_vertex_adj_exists(spftree, vertex_pnode, sadj)) + continue; + + assert(!vadj->label_stack); + label_stack = tilfa_compute_label_stack(spftree->lspdb, sadj, + repair_list); + if (!label_stack) { + char buf[VID2STR_BUFFER]; + + vid2string(vertex_dest, buf, sizeof(buf)); + zlog_warn( + "%s: %s %s adjacency %s: failed to compute label stack", + __func__, vtype2string(vertex_dest->type), buf, + print_sys_hostname(sadj->id)); + return -1; + } + + vadj->label_stack = label_stack; + } + + return 0; +} + +/* + * Check if a node belongs to the extended P-space corresponding to a given + * destination. + */ +static bool lfa_ext_p_space_check(const struct isis_spftree *spftree_pc, + const struct isis_vertex *vertex_dest, + const struct isis_vertex *vertex) +{ + struct isis_spftree *spftree_old = spftree_pc->lfa.old.spftree; + struct isis_vertex_adj *vadj; + struct listnode *node; + + /* Check the local P-space first. */ + if (isis_spf_node_find(&spftree_pc->lfa.p_space, vertex->N.id)) + return true; + + /* + * Check the P-space of the adjacent routers used to reach the + * destination. + */ + for (ALL_LIST_ELEMENTS_RO(vertex_dest->Adj_N, node, vadj)) { + struct isis_spf_adj *sadj = vadj->sadj; + struct isis_spf_node *adj_node; + + adj_node = + isis_spf_node_find(&spftree_old->adj_nodes, sadj->id); + if (!adj_node) + continue; + + if (isis_spf_node_find(&adj_node->lfa.p_space, vertex->N.id)) + return true; + } + + return false; +} + +/* Check if a node belongs to the Q-space. */ +static bool lfa_q_space_check(const struct isis_spftree *spftree_pc, + const struct isis_vertex *vertex) +{ + return isis_spf_node_find(&spftree_pc->lfa.q_space, vertex->N.id); +} + +/* This is a recursive function. */ +static int tilfa_build_repair_list(struct isis_spftree *spftree_pc, + struct isis_vertex *vertex_dest, + const struct isis_vertex *vertex, + const struct isis_vertex *vertex_child, + struct isis_spf_nodes *used_pnodes, + struct list *repair_list) +{ + struct isis_vertex *pvertex; + struct listnode *node; + bool is_pnode, is_qnode; + char buf[VID2STR_BUFFER]; + struct isis_tilfa_sid sid_dest = {}, sid_qnode = {}, sid_pnode = {}; + uint32_t sid_index; + mpls_label_t label_qnode; + + if (IS_DEBUG_TILFA) { + vid2string(vertex, buf, sizeof(buf)); + zlog_debug("ISIS-TI-LFA: vertex %s %s", + vtype2string(vertex->type), buf); + } + + /* Push original Prefix-SID label when necessary. */ + if (VTYPE_IP(vertex->type) && vertex->N.ip.sr.present) { + pvertex = listnode_head(vertex->parents); + assert(pvertex); + + sid_index = vertex->N.ip.sr.sid.value; + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: pushing Prefix-SID to %pFX (index %u)", + &vertex->N.ip.p.dest, sid_index); + sid_dest.type = TILFA_SID_PREFIX; + sid_dest.value.index.value = sid_index; + sid_dest.value.index.remote = true; + memcpy(sid_dest.value.index.remote_sysid, pvertex->N.id, + sizeof(sid_dest.value.index.remote_sysid)); + listnode_add_head(repair_list, &sid_dest); + } + + if (!vertex_child) + goto parents; + if (vertex->type != VTYPE_NONPSEUDO_IS + && vertex->type != VTYPE_NONPSEUDO_TE_IS) + goto parents; + if (!VTYPE_IS(vertex_child->type)) + vertex_child = NULL; + + /* Check if node is part of the extended P-space and/or Q-space. */ + is_pnode = lfa_ext_p_space_check(spftree_pc, vertex_dest, vertex); + is_qnode = lfa_q_space_check(spftree_pc, vertex); + + /* Push Adj-SID label when necessary. */ + if ((!is_qnode + || spftree_pc->lfa.protected_resource.type == LFA_NODE_PROTECTION) + && vertex_child) { + label_qnode = tilfa_find_qnode_adj_sid(spftree_pc, vertex->N.id, + vertex_child->N.id); + if (label_qnode == MPLS_INVALID_LABEL) { + zlog_warn("ISIS-TI-LFA: failed to find %s->%s Adj-SID", + print_sys_hostname(vertex->N.id), + print_sys_hostname(vertex_child->N.id)); + return -1; + } + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: pushing %s->%s Adj-SID (label %u)", + print_sys_hostname(vertex->N.id), + print_sys_hostname(vertex_child->N.id), + label_qnode); + sid_qnode.type = TILFA_SID_ADJ; + sid_qnode.value.label = label_qnode; + listnode_add_head(repair_list, &sid_qnode); + } + + /* Push Prefix-SID label when necessary. */ + if (is_pnode) { + /* The same P-node can't be used more than once. */ + if (isis_spf_node_find(used_pnodes, vertex->N.id)) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: skipping already used P-node"); + return 0; + } + isis_spf_node_new(used_pnodes, vertex->N.id); + + if (!vertex_child) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: destination is within Ext-P-Space"); + return 0; + } + + sid_index = + tilfa_find_pnode_prefix_sid(spftree_pc, vertex->N.id); + if (sid_index == UINT32_MAX) { + zlog_warn( + "ISIS-TI-LFA: failed to find Prefix-SID corresponding to PQ-node %s", + print_sys_hostname(vertex->N.id)); + return -1; + } + + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: pushing Node-SID to %s (index %u)", + print_sys_hostname(vertex->N.id), sid_index); + sid_pnode.type = TILFA_SID_PREFIX; + sid_pnode.value.index.value = sid_index; + listnode_add_head(repair_list, &sid_pnode); + + /* Apply repair list. */ + if (tilfa_repair_list_apply(spftree_pc, vertex_dest, vertex, + repair_list) + != 0) + return -1; + return 0; + } + +parents: + for (ALL_LIST_ELEMENTS_RO(vertex->parents, node, pvertex)) { + struct list *repair_list_parent; + bool ecmp; + int ret; + + ecmp = (listcount(vertex->parents) > 1) ? true : false; + repair_list_parent = ecmp ? list_dup(repair_list) : repair_list; + ret = tilfa_build_repair_list(spftree_pc, vertex_dest, pvertex, + vertex, used_pnodes, + repair_list_parent); + if (ecmp) + list_delete(&repair_list_parent); + if (ret != 0) + return ret; + } + + return 0; +} + +static const char *lfa_protection_type2str(enum lfa_protection_type type) +{ + switch (type) { + case LFA_LINK_PROTECTION: + return "link protection"; + case LFA_NODE_PROTECTION: + return "node protection"; + default: + return "unknown protection type"; + } +} + +static const char * +lfa_protected_resource2str(const struct lfa_protected_resource *resource) +{ + const uint8_t *fail_id; + static char buffer[128]; + + fail_id = resource->adjacency; + snprintf(buffer, sizeof(buffer), "%s.%u's failure (%s)", + print_sys_hostname(fail_id), LSP_PSEUDO_ID(fail_id), + lfa_protection_type2str(resource->type)); + + return buffer; +} + +static bool +spf_adj_check_is_affected(const struct isis_spf_adj *sadj, + const struct lfa_protected_resource *resource, + const uint8_t *root_sysid, bool reverse) +{ + if (!!CHECK_FLAG(sadj->flags, F_ISIS_SPF_ADJ_BROADCAST) + != !!LSP_PSEUDO_ID(resource->adjacency)) + return false; + + if (CHECK_FLAG(sadj->flags, F_ISIS_SPF_ADJ_BROADCAST)) { + if (!memcmp(sadj->lan.desig_is_id, resource->adjacency, + ISIS_SYS_ID_LEN + 1)) + return true; + } else { + if (!reverse + && !memcmp(sadj->id, resource->adjacency, ISIS_SYS_ID_LEN)) + return true; + if (reverse && !memcmp(sadj->id, root_sysid, ISIS_SYS_ID_LEN)) + return true; + } + + return false; +} + +/* Check if the given SPF vertex needs LFA protection. */ +static bool lfa_check_needs_protection(const struct isis_spftree *spftree_pc, + const struct isis_vertex *vertex) +{ + struct isis_vertex *vertex_old; + struct listnode *node; + size_t affected_nhs = 0; + struct isis_vertex_adj *vadj; + + /* Local routes don't need protection. */ + if (VTYPE_IP(vertex->type) && vertex->depth == 1) + return false; + + /* Only local adjacencies need Adj-SID protection. */ + if (VTYPE_IS(vertex->type) + && !isis_adj_find(spftree_pc->area, spftree_pc->level, + vertex->N.id)) + return false; + + vertex_old = isis_find_vertex(&spftree_pc->lfa.old.spftree->paths, + &vertex->N, vertex->type); + if (!vertex_old) + return false; + + for (ALL_LIST_ELEMENTS_RO(vertex_old->Adj_N, node, vadj)) { + struct isis_spf_adj *sadj = vadj->sadj; + + if (spf_adj_check_is_affected( + sadj, &spftree_pc->lfa.protected_resource, + spftree_pc->sysid, false)) + affected_nhs++; + } + + /* + * No need to compute backup paths for ECMP routes, except if all + * primary nexthops share the same broadcast interface. + */ + if (listcount(vertex_old->Adj_N) == affected_nhs) + return true; + + return false; +} + +/** + * Check if the given SPF vertex needs protection and, if so, compute and + * install the corresponding repair paths. + * + * @param spftree_pc The post-convergence SPF tree + * @param vertex IS-IS SPF vertex to check + * + * @return 0 if the vertex needs to be protected, -1 otherwise + */ +int isis_lfa_check(struct isis_spftree *spftree_pc, struct isis_vertex *vertex) +{ + struct isis_spf_nodes used_pnodes; + char buf[VID2STR_BUFFER]; + struct list *repair_list; + int ret; + + if (!spftree_pc->area->srdb.enabled) + return -1; + + if (IS_DEBUG_TILFA) + vid2string(vertex, buf, sizeof(buf)); + + if (!lfa_check_needs_protection(spftree_pc, vertex)) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: %s %s unaffected by %s", + vtype2string(vertex->type), buf, + lfa_protected_resource2str( + &spftree_pc->lfa.protected_resource)); + + return -1; + } + + /* + * Check if the route/adjacency was already covered by node protection. + */ + if (VTYPE_IS(vertex->type)) { + struct isis_adjacency *adj; + + adj = isis_adj_find(spftree_pc->area, spftree_pc->level, + vertex->N.id); + if (adj + && isis_sr_adj_sid_find(adj, spftree_pc->family, + ISIS_SR_LAN_BACKUP)) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: %s %s already covered by node protection", + vtype2string(vertex->type), buf); + + return -1; + } + } + if (VTYPE_IP(vertex->type)) { + struct route_table *route_table; + + route_table = spftree_pc->lfa.old.spftree->route_table_backup; + if (route_node_lookup(route_table, &vertex->N.ip.p.dest)) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: %s %s already covered by node protection", + vtype2string(vertex->type), buf); + + return -1; + } + } + + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: computing repair path(s) of %s %s w.r.t %s", + vtype2string(vertex->type), buf, + lfa_protected_resource2str( + &spftree_pc->lfa.protected_resource)); + + /* Create base repair list. */ + repair_list = list_new(); + + isis_spf_node_list_init(&used_pnodes); + ret = tilfa_build_repair_list(spftree_pc, vertex, vertex, NULL, + &used_pnodes, repair_list); + isis_spf_node_list_clear(&used_pnodes); + list_delete(&repair_list); + if (ret != 0) + zlog_warn("ISIS-TI-LFA: failed to compute repair path(s)"); + + return ret; +} + +static bool +spf_adj_node_is_affected(struct isis_spf_node *adj_node, + const struct lfa_protected_resource *resource, + const uint8_t *root_sysid) +{ + struct isis_spf_adj *sadj; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(adj_node->adjacencies, node, sadj)) { + if (sadj->metric != adj_node->best_metric) + continue; + if (spf_adj_check_is_affected(sadj, resource, root_sysid, + false)) + return true; + } + + return false; +} + +static bool vertex_is_affected(struct isis_spftree *spftree_root, + const struct isis_spf_nodes *adj_nodes, + bool p_space, const struct isis_vertex *vertex, + const struct lfa_protected_resource *resource) +{ + struct isis_vertex *pvertex; + struct listnode *node, *vnode; + + for (ALL_LIST_ELEMENTS_RO(vertex->parents, node, pvertex)) { + struct isis_spftree *spftree_parent; + struct isis_vertex *vertex_child; + struct isis_vertex_adj *vadj; + bool reverse = false; + char buf1[VID2STR_BUFFER]; + char buf2[VID2STR_BUFFER]; + + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-TI-LFA: vertex %s parent %s", + vid2string(vertex, buf1, sizeof(buf1)), + vid2string(pvertex, buf2, sizeof(buf2))); + + if (p_space && resource->type == LFA_NODE_PROTECTION) { + if (isis_spf_node_find(&resource->nodes, vertex->N.id)) + return true; + goto parents; + } + + /* Check if either the vertex or its parent is the root node. */ + if (memcmp(vertex->N.id, spftree_root->sysid, ISIS_SYS_ID_LEN) + && memcmp(pvertex->N.id, spftree_root->sysid, + ISIS_SYS_ID_LEN)) + goto parents; + + /* Get SPT of the parent vertex. */ + if (!memcmp(pvertex->N.id, spftree_root->sysid, + ISIS_SYS_ID_LEN)) + spftree_parent = spftree_root; + else { + struct isis_spf_node *adj_node; + + adj_node = isis_spf_node_find(adj_nodes, pvertex->N.id); + assert(adj_node); + spftree_parent = adj_node->lfa.spftree; + assert(spftree_parent); + reverse = true; + } + + /* Get paths pvertex uses to reach vertex. */ + vertex_child = isis_find_vertex(&spftree_parent->paths, + &vertex->N, vertex->type); + if (!vertex_child) + goto parents; + + /* Check if any of these paths use the protected resource. */ + for (ALL_LIST_ELEMENTS_RO(vertex_child->Adj_N, vnode, vadj)) + if (spf_adj_check_is_affected(vadj->sadj, resource, + spftree_root->sysid, + reverse)) + return true; + + parents: + if (vertex_is_affected(spftree_root, adj_nodes, p_space, + pvertex, resource)) + return true; + } + + return false; +} + +/* Calculate set of nodes reachable without using the protected interface. */ +static void lfa_calc_reach_nodes(struct isis_spftree *spftree, + struct isis_spftree *spftree_root, + const struct isis_spf_nodes *adj_nodes, + bool p_space, + const struct lfa_protected_resource *resource, + struct isis_spf_nodes *nodes) +{ + struct isis_vertex *vertex; + struct listnode *node; + + for (ALL_QUEUE_ELEMENTS_RO(&spftree->paths, node, vertex)) { + char buf[VID2STR_BUFFER]; + + if (!VTYPE_IS(vertex->type)) + continue; + + /* Skip root node. */ + if (!memcmp(vertex->N.id, spftree_root->sysid, ISIS_SYS_ID_LEN)) + continue; + + /* Don't add the same node twice. */ + if (isis_spf_node_find(nodes, vertex->N.id)) + continue; + + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-TI-LFA: checking %s", + vid2string(vertex, buf, sizeof(buf))); + + if (!vertex_is_affected(spftree_root, adj_nodes, p_space, + vertex, resource)) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: adding %s", + vid2string(vertex, buf, sizeof(buf))); + + isis_spf_node_new(nodes, vertex->N.id); + } + } +} + +/** + * Helper function used to create an SPF tree structure and run reverse SPF on + * it. + * + * @param spftree IS-IS SPF tree + * + * @return Pointer to new SPF tree structure. + */ +struct isis_spftree *isis_spf_reverse_run(const struct isis_spftree *spftree) +{ + struct isis_spftree *spftree_reverse; + + spftree_reverse = isis_spftree_new( + spftree->area, spftree->lspdb, spftree->sysid, spftree->level, + spftree->tree_id, SPF_TYPE_REVERSE, + F_SPFTREE_NO_ADJACENCIES | F_SPFTREE_NO_ROUTES); + isis_run_spf(spftree_reverse); + + return spftree_reverse; +} + +/* + * Calculate the Extended P-space and Q-space associated to a given link + * failure. + */ +static void lfa_calc_pq_spaces(struct isis_spftree *spftree_pc, + const struct lfa_protected_resource *resource) +{ + struct isis_spftree *spftree; + struct isis_spftree *spftree_reverse; + struct isis_spf_nodes *adj_nodes; + struct isis_spf_node *adj_node; + + /* Obtain pre-failure SPTs and list of adjacent nodes. */ + spftree = spftree_pc->lfa.old.spftree; + spftree_reverse = spftree_pc->lfa.old.spftree_reverse; + adj_nodes = &spftree->adj_nodes; + + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-TI-LFA: computing P-space (self)"); + lfa_calc_reach_nodes(spftree, spftree, adj_nodes, true, resource, + &spftree_pc->lfa.p_space); + + RB_FOREACH (adj_node, isis_spf_nodes, adj_nodes) { + if (spf_adj_node_is_affected(adj_node, resource, + spftree->sysid)) { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: computing Q-space (%s)", + print_sys_hostname(adj_node->sysid)); + + /* + * Compute the reverse SPF in the behalf of the node + * adjacent to the failure. + */ + adj_node->lfa.spftree_reverse = + isis_spf_reverse_run(adj_node->lfa.spftree); + + lfa_calc_reach_nodes(adj_node->lfa.spftree_reverse, + spftree_reverse, adj_nodes, false, + resource, + &spftree_pc->lfa.q_space); + } else { + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: computing P-space (%s)", + print_sys_hostname(adj_node->sysid)); + lfa_calc_reach_nodes(adj_node->lfa.spftree, spftree, + adj_nodes, true, resource, + &adj_node->lfa.p_space); + } + } +} + +/** + * Compute the TI-LFA backup paths for a given protected interface. + * + * @param area IS-IS area + * @param spftree IS-IS SPF tree + * @param spftree_reverse IS-IS Reverse SPF tree + * @param resource Protected resource + * + * @return Pointer to the post-convergence SPF tree + */ +struct isis_spftree *isis_tilfa_compute(struct isis_area *area, + struct isis_spftree *spftree, + struct isis_spftree *spftree_reverse, + struct lfa_protected_resource *resource) +{ + struct isis_spftree *spftree_pc; + struct isis_spf_node *adj_node; + + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-TI-LFA: computing the P/Q spaces w.r.t. %s", + lfa_protected_resource2str(resource)); + + /* Populate list of nodes affected by link failure. */ + if (resource->type == LFA_NODE_PROTECTION) { + isis_spf_node_list_init(&resource->nodes); + RB_FOREACH (adj_node, isis_spf_nodes, &spftree->adj_nodes) { + if (spf_adj_node_is_affected(adj_node, resource, + spftree->sysid)) + isis_spf_node_new(&resource->nodes, + adj_node->sysid); + } + } + + /* Create post-convergence SPF tree. */ + spftree_pc = isis_spftree_new(area, spftree->lspdb, spftree->sysid, + spftree->level, spftree->tree_id, + SPF_TYPE_TI_LFA, spftree->flags); + spftree_pc->lfa.old.spftree = spftree; + spftree_pc->lfa.old.spftree_reverse = spftree_reverse; + spftree_pc->lfa.protected_resource = *resource; + + /* Compute the extended P-space and Q-space. */ + lfa_calc_pq_spaces(spftree_pc, resource); + + if (IS_DEBUG_TILFA) + zlog_debug( + "ISIS-TI-LFA: computing the post convergence SPT w.r.t. %s", + lfa_protected_resource2str(resource)); + + /* Re-run SPF in the local node to find the post-convergence paths. */ + isis_run_spf(spftree_pc); + + /* Clear list of nodes affeted by link failure. */ + if (resource->type == LFA_NODE_PROTECTION) + isis_spf_node_list_clear(&resource->nodes); + + return spftree_pc; +} + +/** + * Run forward SPF on all adjacent routers. + * + * @param spftree IS-IS SPF tree + * + * @return 0 on success, -1 otherwise + */ +int isis_spf_run_neighbors(struct isis_spftree *spftree) +{ + struct isis_lsp *lsp; + struct isis_spf_node *adj_node; + + lsp = isis_root_system_lsp(spftree->lspdb, spftree->sysid); + if (!lsp) + return -1; + + RB_FOREACH (adj_node, isis_spf_nodes, &spftree->adj_nodes) { + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-TI-LFA: running SPF on neighbor %s", + print_sys_hostname(adj_node->sysid)); + + /* Compute the SPT on behalf of the neighbor. */ + adj_node->lfa.spftree = isis_spftree_new( + spftree->area, spftree->lspdb, adj_node->sysid, + spftree->level, spftree->tree_id, SPF_TYPE_FORWARD, + F_SPFTREE_NO_ADJACENCIES | F_SPFTREE_NO_ROUTES); + isis_run_spf(adj_node->lfa.spftree); + } + + return 0; +} + +/** + * Run the TI-LFA algorithm for all proctected interfaces. + * + * @param area IS-IS area + * @param spftree IS-IS SPF tree + */ +void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree) +{ + struct isis_spftree *spftree_reverse; + struct isis_circuit *circuit; + struct listnode *node; + + /* Run reverse SPF locally. */ + spftree_reverse = isis_spf_reverse_run(spftree); + + /* Run forward SPF on all adjacent routers. */ + isis_spf_run_neighbors(spftree); + + /* Check which interfaces are protected. */ + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { + struct lfa_protected_resource resource = {}; + struct isis_adjacency *adj; + struct isis_spftree *spftree_pc_link; + struct isis_spftree *spftree_pc_node; + static uint8_t null_sysid[ISIS_SYS_ID_LEN + 1]; + + if (!(circuit->is_type & spftree->level)) + continue; + + if (!circuit->tilfa_protection[spftree->level - 1]) + continue; + + /* Fill in the protected resource. */ + switch (circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + if (spftree->level == 1) + memcpy(resource.adjacency, + circuit->u.bc.l1_desig_is, + ISIS_SYS_ID_LEN + 1); + else + memcpy(resource.adjacency, + circuit->u.bc.l2_desig_is, + ISIS_SYS_ID_LEN + 1); + /* Do nothing if no DR was elected yet. */ + if (!memcmp(resource.adjacency, null_sysid, + ISIS_SYS_ID_LEN + 1)) + continue; + break; + case CIRCUIT_T_P2P: + adj = circuit->u.p2p.neighbor; + if (!adj) + continue; + memcpy(resource.adjacency, adj->sysid, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(resource.adjacency) = 0; + break; + default: + continue; + } + + /* Compute node protecting repair paths first (if necessary). */ + if (circuit->tilfa_node_protection[spftree->level - 1]) { + resource.type = LFA_NODE_PROTECTION; + spftree_pc_node = isis_tilfa_compute( + area, spftree, spftree_reverse, &resource); + isis_spftree_del(spftree_pc_node); + } + + /* Compute link protecting repair paths. */ + resource.type = LFA_LINK_PROTECTION; + spftree_pc_link = isis_tilfa_compute( + area, spftree, spftree_reverse, &resource); + isis_spftree_del(spftree_pc_link); + } + + isis_spftree_del(spftree_reverse); +} diff --git a/isisd/isis_lfa.h b/isisd/isis_lfa.h new file mode 100644 index 0000000000..835618760c --- /dev/null +++ b/isisd/isis_lfa.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_ISIS_LFA_H +#define _FRR_ISIS_LFA_H + +enum isis_tilfa_sid_type { + TILFA_SID_PREFIX = 1, + TILFA_SID_ADJ, +}; + +struct isis_tilfa_sid { + enum isis_tilfa_sid_type type; + union { + struct { + uint32_t value; + bool remote; + uint8_t remote_sysid[ISIS_SYS_ID_LEN]; + } index; + mpls_label_t label; + } value; +}; + +RB_HEAD(isis_spf_nodes, isis_spf_node); +RB_PROTOTYPE(isis_spf_nodes, isis_spf_node, entry, isis_spf_node_compare) +struct isis_spf_node { + RB_ENTRY(isis_spf_node) entry; + + /* Node's System ID. */ + uint8_t sysid[ISIS_SYS_ID_LEN]; + + /* Local adjacencies over which this node is reachable. */ + struct list *adjacencies; + + /* Best metric of all adjacencies used to reach this node. */ + uint32_t best_metric; + + struct { + /* Node's forward SPT. */ + struct isis_spftree *spftree; + + /* Node's reverse SPT. */ + struct isis_spftree *spftree_reverse; + + /* Node's P-space. */ + struct isis_spf_nodes p_space; + } lfa; +}; + +enum lfa_protection_type { + LFA_LINK_PROTECTION = 1, + LFA_NODE_PROTECTION, +}; + +struct lfa_protected_resource { + /* The protection type. */ + enum lfa_protection_type type; + + /* The protected adjacency (might be a pseudonode). */ + uint8_t adjacency[ISIS_SYS_ID_LEN + 1]; + + /* List of nodes reachable over the protected interface. */ + struct isis_spf_nodes nodes; +}; + +/* Forward declaration(s). */ +struct isis_vertex; + +/* Prototypes. */ +void isis_spf_node_list_init(struct isis_spf_nodes *nodes); +void isis_spf_node_list_clear(struct isis_spf_nodes *nodes); +struct isis_spf_node *isis_spf_node_new(struct isis_spf_nodes *nodes, + const uint8_t *sysid); +struct isis_spf_node *isis_spf_node_find(const struct isis_spf_nodes *nodes, + const uint8_t *sysid); +bool isis_lfa_excise_adj_check(const struct isis_spftree *spftree, + const uint8_t *id); +bool isis_lfa_excise_node_check(const struct isis_spftree *spftree, + const uint8_t *id); +struct isis_spftree *isis_spf_reverse_run(const struct isis_spftree *spftree); +int isis_spf_run_neighbors(struct isis_spftree *spftree); +void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree); +int isis_lfa_check(struct isis_spftree *spftree, struct isis_vertex *vertex); +struct isis_spftree * +isis_tilfa_compute(struct isis_area *area, struct isis_spftree *spftree, + struct isis_spftree *spftree_reverse, + struct lfa_protected_resource *protected_resource); + +#endif /* _FRR_ISIS_LFA_H */ diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 1af6f417dc..d8ad4cd510 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -852,7 +852,6 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0, static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) { int level = lsp->level; - char buf[PREFIX2STR_BUFFER]; struct listnode *node; struct isis_lsp *frag; @@ -964,9 +963,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) */ if (area->isis->router_id != 0) { struct in_addr id = {.s_addr = area->isis->router_id}; - inet_ntop(AF_INET, &id, buf, sizeof(buf)); - lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.", - area->area_tag, buf); + lsp_debug("ISIS (%s): Adding router ID %pI4 as IPv4 tlv.", + area->area_tag, &id); isis_tlvs_add_ipv4_address(lsp->tlvs, &id); /* If new style TLV's are in use, add TE router ID TLV @@ -1033,10 +1031,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) ipv4)) { if (area->oldmetric) { lsp_debug( - "ISIS (%s): Adding old-style IP reachability for %s", - area->area_tag, - prefix2str(ipv4, buf, - sizeof(buf))); + "ISIS (%s): Adding old-style IP reachability for %pFX", + area->area_tag, ipv4); isis_tlvs_add_oldstyle_ip_reach( lsp->tlvs, ipv4, metric); } @@ -1045,10 +1041,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) struct sr_prefix_cfg *pcfg = NULL; lsp_debug( - "ISIS (%s): Adding te-style IP reachability for %s", - area->area_tag, - prefix2str(ipv4, buf, - sizeof(buf))); + "ISIS (%s): Adding te-style IP reachability for %pFX", + area->area_tag, ipv4); if (area->srdb.enabled) pcfg = isis_sr_cfg_prefix_find( @@ -1071,9 +1065,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) struct sr_prefix_cfg *pcfg = NULL; lsp_debug( - "ISIS (%s): Adding IPv6 reachability for %s", - area->area_tag, - prefix2str(ipv6, buf, sizeof(buf))); + "ISIS (%s): Adding IPv6 reachability for %pFX", + area->area_tag, ipv6); if (area->srdb.enabled) pcfg = isis_sr_cfg_prefix_find(area, @@ -1248,7 +1241,7 @@ int lsp_generate(struct isis_area *area, int level) refresh_time = lsp_refresh_time(newlsp, rem_lifetime); - THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]); + thread_cancel(&area->t_lsp_refresh[level - 1]); area->lsp_regenerate_pending[level - 1] = 0; thread_add_timer(master, lsp_refresh, &area->lsp_refresh_arg[level - 1], refresh_time, @@ -1458,7 +1451,7 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level, "ISIS (%s): Will schedule regen timer. Last run was: %lld, Now is: %lld", area->area_tag, (long long)lsp->last_generated, (long long)now); - THREAD_TIMER_OFF(area->t_lsp_refresh[lvl - 1]); + thread_cancel(&area->t_lsp_refresh[lvl - 1]); diff = now - lsp->last_generated; if (diff < area->lsp_gen_interval[lvl - 1] && !(area->bfd_signalled_down)) { @@ -1611,7 +1604,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level) || (circuit->u.bc.is_dr[level - 1] == 0)) return ISIS_ERROR; - memcpy(lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN); + memcpy(lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN); LSP_FRAGMENT(lsp_id) = 0; LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id; @@ -1635,7 +1628,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level) lsp_flood(lsp, NULL); refresh_time = lsp_refresh_time(lsp, rem_lifetime); - THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); + thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[level - 1]); circuit->lsp_regenerate_pending[level - 1] = 0; if (level == IS_LEVEL_1) thread_add_timer( @@ -1671,7 +1664,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level) || (circuit->u.bc.is_dr[level - 1] == 0)) return ISIS_ERROR; - memcpy(lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN); + memcpy(lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN); LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id; LSP_FRAGMENT(lsp_id) = 0; @@ -1728,7 +1721,7 @@ static int lsp_l1_refresh_pseudo(struct thread *thread) if ((circuit->u.bc.is_dr[0] == 0) || (circuit->is_type & IS_LEVEL_1) == 0) { - memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN); + memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN); LSP_PSEUDO_ID(id) = circuit->circuit_id; LSP_FRAGMENT(id) = 0; lsp_purge_pseudo(id, circuit, IS_LEVEL_1); @@ -1750,7 +1743,7 @@ static int lsp_l2_refresh_pseudo(struct thread *thread) if ((circuit->u.bc.is_dr[1] == 0) || (circuit->is_type & IS_LEVEL_2) == 0) { - memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN); + memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN); LSP_PSEUDO_ID(id) = circuit->circuit_id; LSP_FRAGMENT(id) = 0; lsp_purge_pseudo(id, circuit, IS_LEVEL_2); @@ -1826,7 +1819,7 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level) "ISIS (%s): Will schedule PSN regen timer. Last run was: %lld, Now is: %lld", area->area_tag, (long long)lsp->last_generated, (long long)now); - THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); + thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]); diff = now - lsp->last_generated; if (diff < circuit->area->lsp_gen_interval[lvl - 1]) { timeout = diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c index 2725459767..a64decc14f 100644 --- a/isisd/isis_memory.c +++ b/isisd/isis_memory.c @@ -39,6 +39,7 @@ DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree") DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex") DEFINE_MTYPE(ISISD, ISIS_ROUTE_INFO, "ISIS route info") DEFINE_MTYPE(ISISD, ISIS_NEXTHOP, "ISIS nexthop") +DEFINE_MTYPE(ISISD, ISIS_NEXTHOP_LABELS, "ISIS nexthop MPLS labels") DEFINE_MTYPE(ISISD, ISIS_DICT, "ISIS dictionary") DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node") DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route") diff --git a/isisd/isis_memory.h b/isisd/isis_memory.h index e672340e84..6b63b3ccb8 100644 --- a/isisd/isis_memory.h +++ b/isisd/isis_memory.h @@ -38,6 +38,7 @@ DECLARE_MTYPE(ISIS_SPFTREE) DECLARE_MTYPE(ISIS_VERTEX) DECLARE_MTYPE(ISIS_ROUTE_INFO) DECLARE_MTYPE(ISIS_NEXTHOP) +DECLARE_MTYPE(ISIS_NEXTHOP_LABELS) DECLARE_MTYPE(ISIS_DICT) DECLARE_MTYPE(ISIS_DICT_NODE) DECLARE_MTYPE(ISIS_EXT_ROUTE) diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 14ea1170c4..2d3c7e1e38 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -538,6 +538,12 @@ const struct frr_yang_module_info frr_isisd_info = { }, }, { + .xpath = "/frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear", + .cbs = { + .modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify, + } + }, + { .xpath = "/frr-isisd:isis/instance/mpls/ldp-sync", .cbs = { .cli_show = cli_show_isis_mpls_ldp_sync, @@ -819,6 +825,36 @@ const struct frr_yang_module_info frr_isisd_info = { }, }, { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute", + .cbs = { + .cli_show = cli_show_ip_isis_ti_lfa, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable", + .cbs = { + .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection", + .cbs = { + .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable", + .cbs = { + .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection", + .cbs = { + .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify, + } + }, + { .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis", .cbs = { .get_elem = lib_interface_state_isis_get_elem, diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index 8a6d24b845..fb843131d9 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -206,6 +206,8 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_modify( struct nb_cb_modify_args *args); int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify( struct nb_cb_modify_args *args); +int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify( + struct nb_cb_modify_args *args); int isis_instance_mpls_ldp_sync_destroy(struct nb_cb_destroy_args *args); int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args); int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args); @@ -256,6 +258,14 @@ int lib_interface_isis_multi_topology_ipv6_dstsrc_modify( int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args); int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args); int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args); +int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify( + struct nb_cb_modify_args *args); struct yang_data * lib_interface_state_isis_get_elem(struct nb_cb_get_elem_args *args); const void *lib_interface_state_isis_adjacencies_adjacency_get_next( @@ -432,6 +442,8 @@ void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode, bool show_defaults); void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_ip_isis_ti_lfa(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode, bool show_defaults); void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode, diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 6edbc2956a..6cb7d32c25 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -43,6 +43,7 @@ #include "isisd/isis_csm.h" #include "isisd/isis_adjacency.h" #include "isisd/isis_spf.h" +#include "isisd/isis_spf_private.h" #include "isisd/isis_te.h" #include "isisd/isis_memory.h" #include "isisd/isis_mt.h" @@ -85,15 +86,13 @@ int isis_instance_destroy(struct nb_cb_destroy_args *args) if (args->event != NB_EV_APPLY) return NB_OK; area = nb_running_unset_entry(args->dnode); - vrf_id = area->isis->vrf_id; - isis_area_destroy(area); - /* remove ldp-sync config */ if (vrf_id == VRF_DEFAULT) isis_ldp_sync_gbl_exit(true); + isis_area_destroy(area); return NB_OK; } @@ -1839,6 +1838,23 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo } /* + * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear + */ +int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify( + struct nb_cb_modify_args *args) +{ + struct sr_prefix_cfg *pcfg; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + pcfg = nb_running_get_entry(args->dnode, NULL, true); + pcfg->n_flag_clear = yang_dnode_get_bool(args->dnode, NULL); + + return NB_OK; +} + +/* * XPath: /frr-isisd:isis/instance/mpls/ldp-sync */ int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args) @@ -1847,18 +1863,29 @@ int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args) struct listnode *node; struct isis_circuit *circuit; struct interface *ifp; - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); - struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct vrf *vrf; + struct isis *isis; switch (args->event) { case NB_EV_VALIDATE: - if (isis == NULL) + area = nb_running_get_entry(args->dnode, NULL, false); + if (area == NULL || area->isis == NULL) return NB_ERR_VALIDATION; + + if (area->isis->vrf_id != VRF_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "LDP-Sync only runs on Default VRF"); + return NB_ERR_VALIDATION; + } break; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: + area = nb_running_get_entry(args->dnode, NULL, true); + isis = area->isis; + vrf = vrf_lookup_by_id(isis->vrf_id); + /* register with opaque client to recv LDP-IGP Sync msgs */ zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE); zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE); @@ -1906,19 +1933,29 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args) struct listnode *node; struct isis_circuit *circuit; struct interface *ifp; - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf; uint16_t holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; - struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct isis *isis; switch (args->event) { case NB_EV_VALIDATE: - if (isis == NULL) + area = nb_running_get_entry(args->dnode, NULL, false); + if (area == NULL || area->isis == NULL) + return NB_ERR_VALIDATION; + + if (area->isis->vrf_id != VRF_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "LDP-Sync only runs on Default VRF"); return NB_ERR_VALIDATION; + } break; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: + area = nb_running_get_entry(args->dnode, NULL, true); + isis = area->isis; + vrf = vrf_lookup_by_id(isis->vrf_id); holddown = yang_dnode_get_uint16(args->dnode, NULL); if (holddown == LDP_IGP_SYNC_HOLDDOWN_DEFAULT) @@ -2056,7 +2093,6 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args) struct interface *ifp; struct vrf *vrf; const char *area_tag, *ifname, *vrfname; - struct isis *isis = NULL; if (args->event == NB_EV_VALIDATE) { /* libyang doesn't like relative paths across module boundaries @@ -2072,11 +2108,7 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args) if (!ifp) return NB_OK; - isis = isis_lookup_by_vrfid(ifp->vrf_id); - if (isis == NULL) - return NB_ERR_VALIDATION; - - circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list); + circuit = circuit_scan_by_ifp(ifp); area_tag = yang_dnode_get_string(args->dnode, NULL); if (circuit && circuit->area && circuit->area->area_tag && strcmp(circuit->area->area_tag, area_tag)) { @@ -2116,11 +2148,11 @@ int lib_interface_isis_vrf_modify(struct nb_cb_modify_args *args) vrf_name = yang_dnode_get_string(args->dnode, NULL); circuit = circuit_scan_by_ifp(ifp); - if (circuit && circuit->area && circuit->area->isis - && strcmp(circuit->area->isis->name, vrf_name)) { + if (circuit && circuit->area && circuit->isis + && strcmp(circuit->isis->name, vrf_name)) { snprintf(args->errmsg, args->errmsg_len, "ISIS circuit is already defined on vrf %s", - circuit->area->isis->name); + circuit->isis->name); return NB_ERR_VALIDATION; } } @@ -2778,23 +2810,31 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args) struct isis_circuit *circuit; struct ldp_sync_info *ldp_sync_info; bool ldp_sync_enable; - struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct isis *isis; switch (args->event) { case NB_EV_VALIDATE: - if (isis == NULL) + circuit = nb_running_get_entry(args->dnode, NULL, false); + if (circuit == NULL || circuit->area == NULL) return NB_ERR_VALIDATION; - break; + if (circuit->isis->vrf_id != VRF_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "LDP-Sync only runs on Default VRF"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: circuit = nb_running_get_entry(args->dnode, NULL, true); ldp_sync_enable = yang_dnode_get_bool(args->dnode, NULL); + isis = circuit->isis; if (circuit->ldp_sync_info == NULL) isis_ldp_sync_if_init(circuit, isis); + assert(circuit->ldp_sync_info != NULL); ldp_sync_info = circuit->ldp_sync_info; if (ldp_sync_enable) { @@ -2821,8 +2861,7 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args) SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; + THREAD_OFF(ldp_sync_info->t_holddown); isis_ldp_sync_set_if_metric(circuit, true); } break; @@ -2838,23 +2877,31 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args) struct isis_circuit *circuit; struct ldp_sync_info *ldp_sync_info; uint16_t holddown; - struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct isis *isis; switch (args->event) { case NB_EV_VALIDATE: - if (isis == NULL) + circuit = nb_running_get_entry(args->dnode, NULL, false); + if (circuit == NULL || circuit->area == NULL) return NB_ERR_VALIDATION; - break; + if (circuit->isis->vrf_id != VRF_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "LDP-Sync only runs on Default VRF"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: circuit = nb_running_get_entry(args->dnode, NULL, true); holddown = yang_dnode_get_uint16(args->dnode, NULL); + isis = circuit->isis; if (circuit->ldp_sync_info == NULL) isis_ldp_sync_if_init(circuit, isis); + assert(circuit->ldp_sync_info != NULL); ldp_sync_info = circuit->ldp_sync_info; SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN); @@ -2868,22 +2915,27 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args) { struct isis_circuit *circuit; struct ldp_sync_info *ldp_sync_info; - struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct isis *isis; switch (args->event) { case NB_EV_VALIDATE: - if (isis == NULL) - return NB_ERR_VALIDATION; - circuit = nb_running_get_entry(args->dnode, NULL, true); - if (circuit->ldp_sync_info == NULL) + circuit = nb_running_get_entry(args->dnode, NULL, false); + if (circuit == NULL || circuit->ldp_sync_info == NULL + || circuit->area == NULL) return NB_ERR_VALIDATION; + if (circuit->isis->vrf_id != VRF_DEFAULT) { + snprintf(args->errmsg, args->errmsg_len, + "LDP-Sync only runs on Default VRF"); + return NB_ERR_VALIDATION; + } break; case NB_EV_PREPARE: case NB_EV_ABORT: break; case NB_EV_APPLY: circuit = nb_running_get_entry(args->dnode, NULL, true); + isis = circuit->isis; ldp_sync_info = circuit->ldp_sync_info; UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN); @@ -2894,5 +2946,108 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args) ldp_sync_info->holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; break; } + + return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable + */ +int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->tilfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL); + if (circuit->tilfa_protection[0]) + circuit->area->lfa_protected_links[0]++; + else { + assert(circuit->area->lfa_protected_links[0] > 0); + circuit->area->lfa_protected_links[0]--; + } + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection + */ +int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->tilfa_node_protection[0] = + yang_dnode_get_bool(args->dnode, NULL); + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable + */ +int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->tilfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL); + if (circuit->tilfa_protection[1]) + circuit->area->lfa_protected_links[1]++; + else { + assert(circuit->area->lfa_protected_links[1] > 0); + circuit->area->lfa_protected_links[1]--; + } + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection + */ +int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->tilfa_node_protection[1] = + yang_dnode_get_bool(args->dnode, NULL); + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + return NB_OK; } diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 43b9f6685e..72de5d6543 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -76,8 +76,7 @@ static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit, lenp = stream_get_endp(circuit->snd_stream); stream_putw(circuit->snd_stream, 0); /* PDU length */ - stream_put(circuit->snd_stream, circuit->area->isis->sysid, - ISIS_SYS_ID_LEN); + stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN); stream_putc(circuit->snd_stream, circuit->idx); stream_putc(circuit->snd_stream, 9); /* code */ stream_putc(circuit->snd_stream, 16); /* len */ @@ -143,8 +142,8 @@ static int process_p2p_hello(struct iih_info *iih) } if (tw_adj->neighbor_set - && (memcmp(tw_adj->neighbor_id, - iih->circuit->area->isis->sysid, ISIS_SYS_ID_LEN) + && (memcmp(tw_adj->neighbor_id, iih->circuit->isis->sysid, + ISIS_SYS_ID_LEN) || tw_adj->neighbor_circuit_id != (uint32_t)iih->circuit->idx)) { @@ -206,7 +205,7 @@ static int process_p2p_hello(struct iih_info *iih) adj); /* lets take care of the expiry */ - THREAD_TIMER_OFF(adj->t_expire); + thread_cancel(&adj->t_expire); thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, &adj->t_expire); @@ -498,7 +497,7 @@ static int process_lan_hello(struct iih_info *iih) adj); /* lets take care of the expiry */ - THREAD_TIMER_OFF(adj->t_expire); + thread_cancel(&adj->t_expire); thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time, &adj->t_expire); @@ -728,7 +727,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit, goto out; } - if (!memcmp(iih.sys_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN)) { + if (!memcmp(iih.sys_id, circuit->isis->sysid, ISIS_SYS_ID_LEN)) { zlog_warn( "ISIS-Adj (%s): Received IIH with own sysid - discard", circuit->area->area_tag); @@ -1044,7 +1043,7 @@ dontcheckadj: ack_lsp(&hdr, circuit, level); goto out; /* FIXME: do we need a purge? */ } else { - if (memcmp(hdr.lsp_id, circuit->area->isis->sysid, + if (memcmp(hdr.lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN)) { /* LSP by some other system -> do 7.3.16.4 b) */ /* 7.3.16.4 b) 1) */ @@ -1139,8 +1138,7 @@ dontcheckadj: } /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a * purge */ - if (memcmp(hdr.lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN) - == 0) { + if (memcmp(hdr.lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN) == 0) { if (!lsp) { /* 7.3.16.4: initiate a purge */ lsp_purge_non_exist(level, &hdr, circuit->area); @@ -1427,7 +1425,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, entry = entry->next) { struct isis_lsp *lsp = lsp_search(&circuit->area->lspdb[level - 1], entry->id); - bool own_lsp = !memcmp(entry->id, circuit->area->isis->sysid, + bool own_lsp = !memcmp(entry->id, circuit->isis->sysid, ISIS_SYS_ID_LEN); if (lsp) { /* 7.3.15.2 b) 1) is this LSP newer */ @@ -1468,7 +1466,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit, * insert it and set SSN on it */ if (entry->rem_lifetime && entry->checksum && entry->seqno - && memcmp(entry->id, circuit->area->isis->sysid, + && memcmp(entry->id, circuit->isis->sysid, ISIS_SYS_ID_LEN)) { struct isis_lsp *lsp0 = NULL; @@ -1679,11 +1677,11 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa) if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr field */ && max_area_addrs != 0 - && max_area_addrs != circuit->area->isis->max_area_addrs) { + && max_area_addrs != circuit->isis->max_area_addrs) { flog_err( EC_ISIS_PACKET, "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %hhu while the parameter for this IS is %u", - max_area_addrs, circuit->area->isis->max_area_addrs); + max_area_addrs, circuit->isis->max_area_addrs); circuit->max_area_addr_mismatches++; #ifndef FABRICD /* send northbound notification */ @@ -1792,8 +1790,7 @@ static void put_hello_hdr(struct isis_circuit *circuit, int level, fill_fixed_hdr(pdu_type, circuit->snd_stream); stream_putc(circuit->snd_stream, circuit->is_type); - stream_put(circuit->snd_stream, circuit->area->isis->sysid, - ISIS_SYS_ID_LEN); + stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN); uint32_t holdtime = circuit->hello_multiplier[level - 1] * circuit->hello_interval[level - 1]; @@ -1990,7 +1987,7 @@ static void _send_hello_sched(struct isis_circuit *circuit, if (thread_timer_remain_msec(*threadp) < (unsigned long)delay) return; - thread_cancel(*threadp); + thread_cancel(threadp); } thread_add_timer_msec(master, send_hello_cb, @@ -2064,8 +2061,7 @@ int send_csnp(struct isis_circuit *circuit, int level) size_t len_pointer = stream_get_endp(circuit->snd_stream); stream_putw(circuit->snd_stream, 0); - stream_put(circuit->snd_stream, circuit->area->isis->sysid, - ISIS_SYS_ID_LEN); + stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN); /* with zero circuit id - ref 9.10, 9.11 */ stream_putc(circuit->snd_stream, 0); @@ -2242,8 +2238,7 @@ static int send_psnp(int level, struct isis_circuit *circuit) size_t len_pointer = stream_get_endp(circuit->snd_stream); stream_putw(circuit->snd_stream, 0); /* length is filled in later */ - stream_put(circuit->snd_stream, circuit->area->isis->sysid, - ISIS_SYS_ID_LEN); + stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN); stream_putc(circuit->snd_stream, circuit->idx); struct isis_passwd *passwd = (level == ISIS_LEVEL1) diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index 44422ff664..e6c7a734bd 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -231,11 +231,8 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p, int level; struct isis_redist *redist; - char debug_buf[BUFSIZ]; - prefix2str(p, debug_buf, sizeof(debug_buf)); - - zlog_debug("%s: New route %s from %s: distance %d.", __func__, - debug_buf, zebra_route_string(type), distance); + zlog_debug("%s: New route %pFX from %s: distance %d.", __func__, p, + zebra_route_string(type), distance); if (!ei_table) { zlog_warn("%s: External information table not initialized.", @@ -282,10 +279,7 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p, int level; struct isis_redist *redist; - char debug_buf[BUFSIZ]; - prefix2str(p, debug_buf, sizeof(debug_buf)); - - zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf, + zlog_debug("%s: Removing route %pFX from %s.", __func__, p, zebra_route_string(type)); if (is_default_prefix(p) @@ -307,11 +301,9 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p, ei_node = srcdest_rnode_lookup(ei_table, p, src_p); if (!ei_node || !ei_node->info) { - char buf[BUFSIZ]; - prefix2str(p, buf, sizeof(buf)); zlog_warn( - "%s: Got a delete for %s route %s, but that route was never added.", - __func__, zebra_route_string(type), buf); + "%s: Got a delete for %s route %pFX, but that route was never added.", + __func__, zebra_route_string(type), p); if (ei_node) route_unlock_node(ei_node); return; diff --git a/isisd/isis_route.c b/isisd/isis_route.c index fa06572555..d664a6f896 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -71,13 +71,13 @@ static struct isis_nexthop *isis_nexthop_create(int family, union g_addr *ip, nexthop->family = family; nexthop->ifindex = ifindex; nexthop->ip = *ip; - isis_sr_nexthop_reset(&nexthop->sr); return nexthop; } -static void isis_nexthop_delete(struct isis_nexthop *nexthop) +void isis_nexthop_delete(struct isis_nexthop *nexthop) { + XFREE(MTYPE_ISIS_NEXTHOP_LABELS, nexthop->label_stack); XFREE(MTYPE_ISIS_NEXTHOP, nexthop); } @@ -115,8 +115,9 @@ static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family, return NULL; } -static void adjinfo2nexthop(int family, struct list *nexthops, - struct isis_adjacency *adj) +void adjinfo2nexthop(int family, struct list *nexthops, + struct isis_adjacency *adj, struct isis_sr_psid_info *sr, + struct mpls_label_stack *label_stack) { struct isis_nexthop *nh; union g_addr ip = {}; @@ -132,6 +133,9 @@ static void adjinfo2nexthop(int family, struct list *nexthops, AF_INET, &ip, adj->circuit->interface->ifindex); memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid)); + if (sr) + nh->sr = *sr; + nh->label_stack = label_stack; listnode_add(nexthops, nh); break; } @@ -147,6 +151,9 @@ static void adjinfo2nexthop(int family, struct list *nexthops, AF_INET6, &ip, adj->circuit->interface->ifindex); memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid)); + if (sr) + nh->sr = *sr; + nh->label_stack = label_stack; listnode_add(nexthops, nh); break; } @@ -160,21 +167,23 @@ static void adjinfo2nexthop(int family, struct list *nexthops, } static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo, - const uint8_t *sysid) + const uint8_t *sysid, + struct isis_sr_psid_info *sr, + struct mpls_label_stack *label_stack) { struct isis_nexthop *nh; nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop)); memcpy(nh->sysid, sysid, sizeof(nh->sysid)); - isis_sr_nexthop_reset(&nh->sr); + nh->sr = *sr; + nh->label_stack = label_stack; listnode_add(rinfo->nexthops, nh); } -static struct isis_route_info *isis_route_info_new(struct prefix *prefix, - struct prefix_ipv6 *src_p, - uint32_t cost, - uint32_t depth, - struct list *adjacencies) +static struct isis_route_info * +isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p, + uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr, + struct list *adjacencies) { struct isis_route_info *rinfo; struct isis_vertex_adj *vadj; @@ -186,13 +195,16 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix, for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) { struct isis_spf_adj *sadj = vadj->sadj; struct isis_adjacency *adj = sadj->adj; + struct isis_sr_psid_info *sr = &vadj->sr; + struct mpls_label_stack *label_stack = vadj->label_stack; /* * Create dummy nexthops when running SPF on a testing * environment. */ if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) { - isis_route_add_dummy_nexthops(rinfo, sadj->id); + isis_route_add_dummy_nexthops(rinfo, sadj->id, sr, + label_stack); continue; } @@ -219,11 +231,13 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix, prefix->family); exit(1); } - adjinfo2nexthop(prefix->family, rinfo->nexthops, adj); + adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, sr, + label_stack); } rinfo->cost = cost; rinfo->depth = depth; + rinfo->sr = *sr; return rinfo; } @@ -239,12 +253,34 @@ static void isis_route_info_delete(struct isis_route_info *route_info) XFREE(MTYPE_ISIS_ROUTE_INFO, route_info); } +void isis_route_node_cleanup(struct route_table *table, struct route_node *node) +{ + if (node->info) + isis_route_info_delete(node->info); +} + +static bool isis_sr_psid_info_same(struct isis_sr_psid_info *new, + struct isis_sr_psid_info *old) +{ + if (new->present != old->present) + return false; + + if (new->label != old->label) + return false; + + if (new->sid.flags != old->sid.flags + || new->sid.value != old->sid.value) + return false; + + return true; +} + static int isis_route_info_same(struct isis_route_info *new, struct isis_route_info *old, char *buf, size_t buf_size) { struct listnode *node; - struct isis_nexthop *nexthop; + struct isis_nexthop *new_nh, *old_nh; if (new->cost != old->cost) { if (buf) @@ -260,6 +296,12 @@ static int isis_route_info_same(struct isis_route_info *new, return 0; } + if (!isis_sr_psid_info_same(&new->sr, &old->sr)) { + if (buf) + snprintf(buf, buf_size, "SR input label"); + return 0; + } + if (new->nexthops->count != old->nexthops->count) { if (buf) snprintf(buf, buf_size, "nhops num (old: %u, new: %u)", @@ -267,14 +309,20 @@ static int isis_route_info_same(struct isis_route_info *new, return 0; } - for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) { - if (!nexthoplookup(old->nexthops, nexthop->family, &nexthop->ip, - nexthop->ifindex)) { + for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, new_nh)) { + old_nh = nexthoplookup(old->nexthops, new_nh->family, + &new_nh->ip, new_nh->ifindex); + if (!old_nh) { if (buf) snprintf(buf, buf_size, "new nhop"); /* TODO: print nhop */ return 0; } + if (!isis_sr_psid_info_same(&new_nh->sr, &old_nh->sr)) { + if (buf) + snprintf(buf, buf_size, "nhop SR label"); + return 0; + } } /* only the resync flag needs to be checked */ @@ -288,57 +336,53 @@ static int isis_route_info_same(struct isis_route_info *new, return 1; } -struct isis_route_info *isis_route_create(struct prefix *prefix, - struct prefix_ipv6 *src_p, - uint32_t cost, - uint32_t depth, - struct list *adjacencies, - struct isis_area *area, - struct route_table *table) +struct isis_route_info * +isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p, + uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr, + struct list *adjacencies, struct isis_area *area, + struct route_table *table) { struct route_node *route_node; struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL; - char buff[PREFIX2STR_BUFFER]; char change_buf[64]; - /* for debugs */ - prefix2str(prefix, buff, sizeof(buff)); - if (!table) return NULL; - rinfo_new = isis_route_info_new(prefix, src_p, cost, - depth, adjacencies); + rinfo_new = isis_route_info_new(prefix, src_p, cost, depth, sr, + adjacencies); route_node = srcdest_rnode_get(table, prefix, src_p); rinfo_old = route_node->info; if (!rinfo_old) { if (IS_DEBUG_RTE_EVENTS) - zlog_debug("ISIS-Rte (%s) route created: %s", - area->area_tag, buff); + zlog_debug("ISIS-Rte (%s) route created: %pFX", + area->area_tag, prefix); route_info = rinfo_new; UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); } else { route_unlock_node(route_node); #ifdef EXTREME_DEBUG if (IS_DEBUG_RTE_EVENTS) - zlog_debug("ISIS-Rte (%s) route already exists: %s", - area->area_tag, buff); + zlog_debug("ISIS-Rte (%s) route already exists: %pFX", + area->area_tag, prefix); #endif /* EXTREME_DEBUG */ if (isis_route_info_same(rinfo_new, rinfo_old, change_buf, sizeof(change_buf))) { #ifdef EXTREME_DEBUG if (IS_DEBUG_RTE_EVENTS) - zlog_debug("ISIS-Rte (%s) route unchanged: %s", - area->area_tag, buff); + zlog_debug( + "ISIS-Rte (%s) route unchanged: %pFX", + area->area_tag, prefix); #endif /* EXTREME_DEBUG */ isis_route_info_delete(rinfo_new); route_info = rinfo_old; } else { if (IS_DEBUG_RTE_EVENTS) zlog_debug( - "ISIS-Rte (%s): route changed: %s, change: %s", - area->area_tag, buff, change_buf); + "ISIS-Rte (%s): route changed: %pFX, change: %s", + area->area_tag, prefix, change_buf); + rinfo_new->sr_previous = rinfo_old->sr; isis_route_info_delete(rinfo_old); route_info = rinfo_new; UNSET_FLAG(route_info->flag, @@ -394,7 +438,25 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix, if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; - isis_zebra_route_add_route(area->isis, prefix, src_p, route_info); + /* + * Explicitly uninstall previous Prefix-SID label if it has + * changed or was removed. + */ + if (route_info->sr_previous.present + && (!route_info->sr.present + || route_info->sr_previous.label + != route_info->sr.label)) + isis_zebra_prefix_sid_uninstall( + area, prefix, route_info, + &route_info->sr_previous); + + /* Install route. */ + isis_zebra_route_add_route(area->isis, prefix, src_p, + route_info); + /* Install/reinstall Prefix-SID label. */ + if (route_info->sr.present) + isis_zebra_prefix_sid_install(area, prefix, route_info, + &route_info->sr); hook_call(isis_route_update_hook, area, prefix, route_info); SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); @@ -403,7 +465,13 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix, if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; - isis_zebra_route_del_route(area->isis, prefix, src_p, route_info); + /* Uninstall Prefix-SID label. */ + if (route_info->sr.present) + isis_zebra_prefix_sid_uninstall( + area, prefix, route_info, &route_info->sr); + /* Uninstall route. */ + isis_zebra_route_del_route(area->isis, prefix, src_p, + route_info); hook_call(isis_route_update_hook, area, prefix, route_info); UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); @@ -412,6 +480,7 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix, static void _isis_route_verify_table(struct isis_area *area, struct route_table *table, + struct route_table *table_backup, struct route_table **tables) { struct route_node *rnode, *drnode; @@ -433,6 +502,19 @@ static void _isis_route_verify_table(struct isis_area *area, (const struct prefix **)&dst_p, (const struct prefix **)&src_p); + /* Link primary route to backup route. */ + if (table_backup) { + struct route_node *rnode_bck; + + rnode_bck = srcdest_rnode_lookup(table_backup, dst_p, + src_p); + if (rnode_bck) { + rinfo->backup = rnode_bck->info; + UNSET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } + } + #ifdef EXTREME_DEBUG if (IS_DEBUG_RTE_EVENTS) { srcdest2str(dst_p, src_p, buff, sizeof(buff)); @@ -490,9 +572,10 @@ static void _isis_route_verify_table(struct isis_area *area, } } -void isis_route_verify_table(struct isis_area *area, struct route_table *table) +void isis_route_verify_table(struct isis_area *area, struct route_table *table, + struct route_table *table_backup) { - _isis_route_verify_table(area, table, NULL); + _isis_route_verify_table(area, table, table_backup, NULL); } /* Function to validate route tables for L1L2 areas. In this case we can't use @@ -507,9 +590,13 @@ void isis_route_verify_table(struct isis_area *area, struct route_table *table) * to the RIB with different zebra route types and let RIB handle this? */ void isis_route_verify_merge(struct isis_area *area, struct route_table *level1_table, - struct route_table *level2_table) + struct route_table *level1_table_backup, + struct route_table *level2_table, + struct route_table *level2_table_backup) { - struct route_table *tables[] = { level1_table, level2_table }; + struct route_table *tables[] = {level1_table, level2_table}; + struct route_table *tables_backup[] = {level1_table_backup, + level2_table_backup}; struct route_table *merge; struct route_node *rnode, *mrnode; @@ -519,6 +606,8 @@ void isis_route_verify_merge(struct isis_area *area, for (rnode = route_top(tables[level - 1]); rnode; rnode = srcdest_route_next(rnode)) { struct isis_route_info *rinfo = rnode->info; + struct route_node *rnode_bck; + if (!rinfo) continue; @@ -528,6 +617,16 @@ void isis_route_verify_merge(struct isis_area *area, srcdest_rnode_prefixes(rnode, (const struct prefix **)&prefix, (const struct prefix **)&src_p); + + /* Link primary route to backup route. */ + rnode_bck = srcdest_rnode_lookup( + tables_backup[level - 1], prefix, src_p); + if (rnode_bck) { + rinfo->backup = rnode_bck->info; + UNSET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } + mrnode = srcdest_rnode_get(merge, prefix, src_p); struct isis_route_info *mrinfo = mrnode->info; if (mrinfo) { @@ -566,7 +665,7 @@ void isis_route_verify_merge(struct isis_area *area, } } - _isis_route_verify_table(area, merge, tables); + _isis_route_verify_table(area, merge, NULL, tables); route_table_finish(merge); } @@ -580,6 +679,14 @@ void isis_route_invalidate_table(struct isis_area *area, continue; rinfo = rode->info; + if (rinfo->backup) { + rinfo->backup = NULL; + /* + * For now, always force routes that have backup + * nexthops to be reinstalled. + */ + UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE); } } diff --git a/isisd/isis_route.h b/isisd/isis_route.h index 0356668d7e..b5e4aed6cc 100644 --- a/isisd/isis_route.h +++ b/isisd/isis_route.h @@ -32,7 +32,8 @@ struct isis_nexthop { int family; union g_addr ip; uint8_t sysid[ISIS_SYS_ID_LEN]; - struct sr_nexthop_info sr; + struct isis_sr_psid_info sr; + struct mpls_label_stack *label_stack; }; struct isis_route_info { @@ -42,7 +43,10 @@ struct isis_route_info { uint8_t flag; uint32_t cost; uint32_t depth; + struct isis_sr_psid_info sr; + struct isis_sr_psid_info sr_previous; struct list *nexthops; + struct isis_route_info *backup; }; DECLARE_HOOK(isis_route_update_hook, @@ -50,26 +54,34 @@ DECLARE_HOOK(isis_route_update_hook, struct isis_route_info *route_info), (area, prefix, route_info)) -struct isis_route_info *isis_route_create(struct prefix *prefix, - struct prefix_ipv6 *src_p, - uint32_t cost, - uint32_t depth, - struct list *adjacencies, - struct isis_area *area, - struct route_table *table); +void isis_nexthop_delete(struct isis_nexthop *nexthop); +void adjinfo2nexthop(int family, struct list *nexthops, + struct isis_adjacency *adj, struct isis_sr_psid_info *sr, + struct mpls_label_stack *label_stack); +struct isis_route_info * +isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p, + uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr, + struct list *adjacencies, struct isis_area *area, + struct route_table *table); /* Walk the given table and install new routes to zebra and remove old ones. * route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */ -void isis_route_verify_table(struct isis_area *area, - struct route_table *table); +void isis_route_verify_table(struct isis_area *area, struct route_table *table, + struct route_table *table_backup); /* Same as isis_route_verify_table, but merge L1 and L2 routes before */ void isis_route_verify_merge(struct isis_area *area, struct route_table *level1_table, - struct route_table *level2_table); + struct route_table *level1_table_backup, + struct route_table *level2_table, + struct route_table *level2_table_backup); /* Unset ISIS_ROUTE_FLAG_ACTIVE on all routes. Used before running spf. */ void isis_route_invalidate_table(struct isis_area *area, struct route_table *table); +/* Cleanup route node when freeing routing table. */ +void isis_route_node_cleanup(struct route_table *table, + struct route_node *node); + #endif /* _ZEBRA_ISIS_ROUTE_H */ diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index dd0a6ec824..690ea9f1a5 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -138,7 +138,7 @@ static void remove_excess_adjs(struct list *adjs) return; } -static const char *vtype2string(enum vertextype vtype) +const char *vtype2string(enum vertextype vtype) { switch (vtype) { case VTYPE_PSEUDO_IS: @@ -167,7 +167,7 @@ static const char *vtype2string(enum vertextype vtype) return NULL; /* Not reached */ } -const char *vid2string(struct isis_vertex *vertex, char *buff, int size) +const char *vid2string(const struct isis_vertex *vertex, char *buff, int size) { if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) { const char *hostname = print_sys_hostname(vertex->N.id); @@ -176,9 +176,8 @@ const char *vid2string(struct isis_vertex *vertex, char *buff, int size) } if (VTYPE_IP(vertex->type)) { - srcdest2str(&vertex->N.ip.dest, - &vertex->N.ip.src, - buff, size); + srcdest2str(&vertex->N.ip.p.dest, &vertex->N.ip.p.src, buff, + size); return buff; } @@ -215,13 +214,33 @@ static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree, return vertex; } -static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_vertex *vertex, - struct isis_spf_adj *sadj) +static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_spftree *spftree, + struct isis_vertex *vertex, + struct isis_spf_adj *sadj, + struct isis_prefix_sid *psid) { struct isis_vertex_adj *vadj; vadj = XCALLOC(MTYPE_ISIS_VERTEX_ADJ, sizeof(*vadj)); vadj->sadj = sadj; + if (psid) { + if (vertex->N.ip.sr.present + && vertex->N.ip.sr.sid.value != psid->value) + zlog_warn( + "ISIS-SPF: ignoring different Prefix-SID for route %pFX", + &vertex->N.ip.p.dest); + else { + bool last_hop; + + last_hop = (vertex->depth == 2); + vadj->sr.sid = *psid; + vadj->sr.label = sr_prefix_out_label( + spftree->lspdb, vertex->N.ip.p.dest.family, + psid, sadj->id, last_hop); + if (vadj->sr.label != MPLS_INVALID_LABEL) + vadj->sr.present = true; + } + } listnode_add(vertex->Adj_N, vadj); return vadj; @@ -286,6 +305,9 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area, isis_vertex_queue_init(&tree->tents, "IS-IS SPF tents", true); isis_vertex_queue_init(&tree->paths, "IS-IS SPF paths", false); tree->route_table = srcdest_table_init(); + tree->route_table->cleanup = isis_route_node_cleanup; + tree->route_table_backup = srcdest_table_init(); + tree->route_table_backup->cleanup = isis_route_node_cleanup; tree->area = area; tree->lspdb = lspdb; tree->sadj_list = list_new(); @@ -300,16 +322,26 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area, tree->tree_id = tree_id; tree->family = (tree->tree_id == SPFTREE_IPV4) ? AF_INET : AF_INET6; tree->flags = flags; + if (tree->type == SPF_TYPE_TI_LFA) { + isis_spf_node_list_init(&tree->lfa.p_space); + isis_spf_node_list_init(&tree->lfa.q_space); + } return tree; } void isis_spftree_del(struct isis_spftree *spftree) { + if (spftree->type == SPF_TYPE_TI_LFA) { + isis_spf_node_list_clear(&spftree->lfa.q_space); + isis_spf_node_list_clear(&spftree->lfa.p_space); + } + isis_spf_node_list_clear(&spftree->adj_nodes); list_delete(&spftree->sadj_list); isis_vertex_queue_free(&spftree->tents); isis_vertex_queue_free(&spftree->paths); route_table_finish(spftree->route_table); + route_table_finish(spftree->route_table_backup); spftree->route_table = NULL; XFREE(MTYPE_ISIS_SPFTREE, spftree); @@ -389,8 +421,8 @@ static int spf_adj_state_change(struct isis_adjacency *adj) * Find the system LSP: returns the LSP in our LSP database * associated with the given system ID. */ -static struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb, - uint8_t *sysid) +struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb, + const uint8_t *sysid) { struct isis_lsp *lsp; uint8_t lspid[ISIS_SYS_ID_LEN + 2]; @@ -421,7 +453,7 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree) isis_vertex_queue_append(&spftree->paths, vertex); #ifdef EXTREME_DEBUG - zlog_debug("ISIS-Spf: added this IS %s %s depth %d dist %d to PATHS", + zlog_debug("ISIS-SPF: added this IS %s %s depth %d dist %d to PATHS", vtype2string(vertex->type), vid2string(vertex, buff, sizeof(buff)), vertex->depth, vertex->d_N); @@ -453,11 +485,10 @@ static void vertex_update_firsthops(struct isis_vertex *vertex, /* * Add a vertex to TENT sorted by cost and by vertextype on tie break situation */ -static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, - enum vertextype vtype, void *id, - uint32_t cost, int depth, - struct isis_spf_adj *sadj, - struct isis_vertex *parent) +static struct isis_vertex * +isis_spf_add2tent(struct isis_spftree *spftree, enum vertextype vtype, void *id, + uint32_t cost, int depth, struct isis_spf_adj *sadj, + struct isis_prefix_sid *psid, struct isis_vertex *parent) { struct isis_vertex *vertex; struct listnode *node; @@ -483,6 +514,16 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, vertex = isis_vertex_new(spftree, id, vtype); vertex->d_N = cost; vertex->depth = depth; + if (VTYPE_IP(vtype) && psid) { + bool local; + + local = (vertex->depth == 1); + vertex->N.ip.sr.sid = *psid; + vertex->N.ip.sr.label = + sr_prefix_in_label(spftree->area, psid, local); + if (vertex->N.ip.sr.label != MPLS_INVALID_LABEL) + vertex->N.ip.sr.present = true; + } if (parent) { listnode_add(vertex->parents, parent); @@ -495,14 +536,15 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, struct isis_vertex_adj *parent_vadj; for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_vadj)) - isis_vertex_adj_add(vertex, parent_vadj->sadj); + isis_vertex_adj_add(spftree, vertex, parent_vadj->sadj, + psid); } else if (sadj) { - isis_vertex_adj_add(vertex, sadj); + isis_vertex_adj_add(spftree, vertex, sadj, psid); } #ifdef EXTREME_DEBUG zlog_debug( - "ISIS-Spf: add to TENT %s %s %s depth %d dist %d adjcount %d", + "ISIS-SPF: add to TENT %s %s %s depth %d dist %d adjcount %d", print_sys_hostname(vertex->N.id), vtype2string(vertex->type), vid2string(vertex, buff, sizeof(buff)), vertex->depth, vertex->d_N, listcount(vertex->Adj_N)); @@ -515,6 +557,7 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree, static void isis_spf_add_local(struct isis_spftree *spftree, enum vertextype vtype, void *id, struct isis_spf_adj *sadj, uint32_t cost, + struct isis_prefix_sid *psid, struct isis_vertex *parent) { struct isis_vertex *vertex; @@ -525,7 +568,8 @@ static void isis_spf_add_local(struct isis_spftree *spftree, /* C.2.5 c) */ if (vertex->d_N == cost) { if (sadj) - isis_vertex_adj_add(vertex, sadj); + isis_vertex_adj_add(spftree, vertex, sadj, + psid); /* d) */ if (!CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES) @@ -545,13 +589,13 @@ static void isis_spf_add_local(struct isis_spftree *spftree, } } - isis_spf_add2tent(spftree, vtype, id, cost, 1, sadj, parent); + isis_spf_add2tent(spftree, vtype, id, cost, 1, sadj, psid, parent); return; } static void process_N(struct isis_spftree *spftree, enum vertextype vtype, void *id, uint32_t dist, uint16_t depth, - struct isis_vertex *parent) + struct isis_prefix_sid *psid, struct isis_vertex *parent) { struct isis_vertex *vertex; #ifdef EXTREME_DEBUG @@ -588,7 +632,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, if (vertex) { #ifdef EXTREME_DEBUG zlog_debug( - "ISIS-Spf: process_N %s %s %s dist %d already found from PATH", + "ISIS-SPF: process_N %s %s %s dist %d already found from PATH", print_sys_hostname(vertex->N.id), vtype2string(vtype), vid2string(vertex, buff, sizeof(buff)), dist); #endif /* EXTREME_DEBUG */ @@ -602,7 +646,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, /* 1) */ #ifdef EXTREME_DEBUG zlog_debug( - "ISIS-Spf: process_N %s %s %s dist %d parent %s adjcount %d", + "ISIS-SPF: process_N %s %s %s dist %d parent %s adjcount %d", print_sys_hostname(vertex->N.id), vtype2string(vtype), vid2string(vertex, buff, sizeof(buff)), dist, (parent ? print_sys_hostname(parent->N.id) : "null"), @@ -615,8 +659,9 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, parent_vadj)) if (!isis_vertex_adj_exists(spftree, vertex, parent_vadj->sadj)) - isis_vertex_adj_add(vertex, - parent_vadj->sadj); + isis_vertex_adj_add(spftree, vertex, + parent_vadj->sadj, + psid); if (CHECK_FLAG(spftree->flags, F_SPFTREE_HOPCOUNT_METRIC)) vertex_update_firsthops(vertex, parent); @@ -638,12 +683,12 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, } #ifdef EXTREME_DEBUG - zlog_debug("ISIS-Spf: process_N add2tent %s %s dist %d parent %s", + zlog_debug("ISIS-SPF: process_N add2tent %s %s dist %d parent %s", print_sys_hostname(id), vtype2string(vtype), dist, (parent ? print_sys_hostname(parent->N.id) : "null")); #endif /* EXTREME_DEBUG */ - isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, parent); + isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, psid, parent); return; } @@ -662,6 +707,14 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree, static const uint8_t null_sysid[ISIS_SYS_ID_LEN]; struct isis_mt_router_info *mt_router_info = NULL; struct prefix_pair ip_info; + bool has_valid_psid; + + if (isis_lfa_excise_node_check(spftree, lsp->hdr.lsp_id)) { + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-LFA: excising node %s", + print_sys_hostname(lsp->hdr.lsp_id)); + return ISIS_OK; + } if (!lsp->tlvs) return ISIS_OK; @@ -691,7 +744,7 @@ lspfragloop: } #ifdef EXTREME_DEBUG - zlog_debug("ISIS-Spf: process_lsp %s", + zlog_debug("ISIS-SPF: process_lsp %s", print_sys_hostname(lsp->hdr.lsp_id)); #endif /* EXTREME_DEBUG */ @@ -719,7 +772,7 @@ lspfragloop: LSP_PSEUDO_ID(r->id) ? VTYPE_PSEUDO_IS : VTYPE_NONPSEUDO_IS, - (void *)r->id, dist, depth + 1, + (void *)r->id, dist, depth + 1, NULL, parent); } } @@ -753,7 +806,8 @@ lspfragloop: process_N(spftree, LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS : VTYPE_NONPSEUDO_TE_IS, - (void *)er->id, dist, depth + 1, parent); + (void *)er->id, dist, depth + 1, NULL, + parent); } } @@ -778,7 +832,7 @@ lspfragloop: ip_info.dest.u.prefix4 = r->prefix.prefix; ip_info.dest.prefixlen = r->prefix.prefixlen; process_N(spftree, vtype, &ip_info, - dist, depth + 1, parent); + dist, depth + 1, NULL, parent); } } } @@ -803,8 +857,34 @@ lspfragloop: dist = cost + r->metric; ip_info.dest.u.prefix4 = r->prefix.prefix; ip_info.dest.prefixlen = r->prefix.prefixlen; - process_N(spftree, VTYPE_IPREACH_TE, &ip_info, - dist, depth + 1, parent); + + /* Parse list of Prefix-SID subTLVs */ + has_valid_psid = false; + if (r->subtlvs) { + for (struct isis_item *i = + r->subtlvs->prefix_sids.head; + i; i = i->next) { + struct isis_prefix_sid *psid = + (struct isis_prefix_sid *)i; + + if (psid->algorithm != SR_ALGORITHM_SPF) + continue; + + has_valid_psid = true; + process_N(spftree, VTYPE_IPREACH_TE, + &ip_info, dist, depth + 1, + psid, parent); + /* + * Stop the Prefix-SID iteration since + * we only support the SPF algorithm for + * now. + */ + break; + } + } + if (!has_valid_psid) + process_N(spftree, VTYPE_IPREACH_TE, &ip_info, + dist, depth + 1, NULL, parent); } } @@ -845,8 +925,34 @@ lspfragloop: } ip_info.src = *r->subtlvs->source_prefix; } - process_N(spftree, vtype, &ip_info, dist, - depth + 1, parent); + + /* Parse list of Prefix-SID subTLVs */ + has_valid_psid = false; + if (r->subtlvs) { + for (struct isis_item *i = + r->subtlvs->prefix_sids.head; + i; i = i->next) { + struct isis_prefix_sid *psid = + (struct isis_prefix_sid *)i; + + if (psid->algorithm != SR_ALGORITHM_SPF) + continue; + + has_valid_psid = true; + process_N(spftree, vtype, &ip_info, + dist, depth + 1, psid, + parent); + /* + * Stop the Prefix-SID iteration since + * we only support the SPF algorithm for + * now. + */ + break; + } + } + if (!has_valid_psid) + process_N(spftree, vtype, &ip_info, dist, + depth + 1, NULL, parent); } } @@ -902,6 +1008,7 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, struct isis_vertex *parent = args->parent; struct prefix_pair ip_info; enum vertextype vtype; + bool has_valid_psid = false; if (external) return LSP_ITER_CONTINUE; @@ -916,7 +1023,30 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, else vtype = VTYPE_IP6REACH_INTERNAL; - isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, parent); + /* Parse list of Prefix-SID subTLVs */ + if (subtlvs) { + for (struct isis_item *i = subtlvs->prefix_sids.head; i; + i = i->next) { + struct isis_prefix_sid *psid = + (struct isis_prefix_sid *)i; + + if (psid->algorithm != SR_ALGORITHM_SPF) + continue; + + has_valid_psid = true; + isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, + psid, parent); + + /* + * Stop the Prefix-SID iteration since we only support + * the SPF algorithm for now. + */ + break; + } + } + if (!has_valid_psid) + isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, NULL, + parent); return LSP_ITER_CONTINUE; } @@ -940,8 +1070,22 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree, /* Iterate over adjacencies. */ for (ALL_LIST_ELEMENTS_RO(spftree->sadj_list, node, sadj)) { + const uint8_t *adj_id; uint32_t metric; + if (CHECK_FLAG(sadj->flags, F_ISIS_SPF_ADJ_BROADCAST)) + adj_id = sadj->lan.desig_is_id; + else + adj_id = sadj->id; + + if (isis_lfa_excise_adj_check(spftree, adj_id)) { + if (IS_DEBUG_TILFA) + zlog_debug("ISIS-SPF: excising adjacency %s", + isis_format_id(sadj->id, + ISIS_SYS_ID_LEN + 1)); + continue; + } + metric = CHECK_FLAG(spftree->flags, F_SPFTREE_HOPCOUNT_METRIC) ? 1 : sadj->metric; @@ -951,7 +1095,8 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree, F_ISIS_SPF_ADJ_OLDMETRIC) ? VTYPE_NONPSEUDO_IS : VTYPE_NONPSEUDO_TE_IS, - sadj->id, sadj, metric, parent); + sadj->id, sadj, metric, NULL, + parent); } else if (sadj->lan.lsp_pseudo) { isis_spf_process_lsp(spftree, sadj->lan.lsp_pseudo, metric, 0, spftree->sysid, parent); @@ -1076,6 +1221,17 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree, /* Add adjacency to the list. */ listnode_add(spftree->sadj_list, sadj); + if (!LSP_PSEUDO_ID(id)) { + struct isis_spf_node *node; + + node = isis_spf_node_find(&spftree->adj_nodes, id); + if (!node) + node = isis_spf_node_new(&spftree->adj_nodes, id); + if (node->best_metric == 0 || sadj->metric < node->best_metric) + node->best_metric = sadj->metric; + listnode_add(node->adjacencies, sadj); + } + /* Parse pseudonode LSP too. */ if (LSP_PSEUDO_ID(id)) { uint8_t lspid[ISIS_SYS_ID_LEN + 2]; @@ -1086,7 +1242,7 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree, lsp_pseudo = lsp_search(spftree->lspdb, lspid); if (lsp_pseudo == NULL || lsp_pseudo->hdr.rem_lifetime == 0) { zlog_warn( - "ISIS-Spf: No LSP found from root to L%d DR %s", + "ISIS-SPF: No LSP found from root to L%d DR %s", spftree->level, rawlspid_print(id)); return; } @@ -1177,39 +1333,26 @@ static void isis_spf_build_adj_list(struct isis_spftree *spftree, static void add_to_paths(struct isis_spftree *spftree, struct isis_vertex *vertex) { +#ifdef EXTREME_DEBUG char buff[VID2STR_BUFFER]; +#endif /* EXTREME_DEBUG */ if (isis_find_vertex(&spftree->paths, &vertex->N, vertex->type)) return; isis_vertex_queue_append(&spftree->paths, vertex); #ifdef EXTREME_DEBUG - zlog_debug("ISIS-Spf: added %s %s %s depth %d dist %d to PATHS", + zlog_debug("ISIS-SPF: added %s %s %s depth %d dist %d to PATHS", print_sys_hostname(vertex->N.id), vtype2string(vertex->type), vid2string(vertex, buff, sizeof(buff)), vertex->depth, vertex->d_N); #endif /* EXTREME_DEBUG */ - - if (VTYPE_IP(vertex->type) - && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ROUTES)) { - if (listcount(vertex->Adj_N) > 0) - isis_route_create(&vertex->N.ip.dest, &vertex->N.ip.src, - vertex->d_N, vertex->depth, - vertex->Adj_N, spftree->area, - spftree->route_table); - else if (IS_DEBUG_SPF_EVENTS) - zlog_debug( - "ISIS-Spf: no adjacencies do not install route for %s depth %d dist %d", - vid2string(vertex, buff, sizeof(buff)), - vertex->depth, vertex->d_N); - } - - return; } static void init_spt(struct isis_spftree *spftree, int mtid) { /* Clear data from previous run. */ + isis_spf_node_list_clear(&spftree->adj_nodes); list_delete_all_node(spftree->sadj_list); isis_vertex_queue_clear(&spftree->tents); isis_vertex_queue_clear(&spftree->paths); @@ -1217,18 +1360,73 @@ static void init_spt(struct isis_spftree *spftree, int mtid) spftree->mtid = mtid; } +static void spf_path_process(struct isis_spftree *spftree, + struct isis_vertex *vertex) +{ + struct isis_area *area = spftree->area; + char buff[VID2STR_BUFFER]; + + if (VTYPE_IS(vertex->type) + && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) { + if (listcount(vertex->Adj_N) > 0) { + if (spftree->type == SPF_TYPE_TI_LFA) { + struct isis_adjacency *adj; + + if (isis_lfa_check(spftree, vertex) != 0) + return; + + adj = isis_adj_find(area, spftree->level, + vertex->N.id); + if (adj) + sr_adj_sid_add_single( + adj, spftree->family, true, + vertex->Adj_N); + } + } else if (IS_DEBUG_SPF_EVENTS) + zlog_debug( + "ISIS-SPF: no adjacencies, do not install backup Adj-SID for %s depth %d dist %d", + vid2string(vertex, buff, sizeof(buff)), + vertex->depth, vertex->d_N); + } + + if (VTYPE_IP(vertex->type) + && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ROUTES)) { + if (vertex->depth == 1 || listcount(vertex->Adj_N) > 0) { + struct route_table *route_table; + + if (spftree->type == SPF_TYPE_TI_LFA) { + if (isis_lfa_check(spftree, vertex) != 0) + return; + route_table = spftree->lfa.old.spftree + ->route_table_backup; + } else + route_table = spftree->route_table; + + isis_route_create(&vertex->N.ip.p.dest, + &vertex->N.ip.p.src, vertex->d_N, + vertex->depth, &vertex->N.ip.sr, + vertex->Adj_N, area, route_table); + } else if (IS_DEBUG_SPF_EVENTS) + zlog_debug( + "ISIS-SPF: no adjacencies, do not install route for %s depth %d dist %d", + vid2string(vertex, buff, sizeof(buff)), + vertex->depth, vertex->d_N); + } +} + static void isis_spf_loop(struct isis_spftree *spftree, uint8_t *root_sysid) { struct isis_vertex *vertex; struct isis_lsp *lsp; + struct listnode *node; while (isis_vertex_queue_count(&spftree->tents)) { vertex = isis_vertex_queue_pop(&spftree->tents); #ifdef EXTREME_DEBUG zlog_debug( - "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS", + "ISIS-SPF: get TENT node %s %s depth %d dist %d to PATHS", print_sys_hostname(vertex->N.id), vtype2string(vertex->type), vertex->depth, vertex->d_N); #endif /* EXTREME_DEBUG */ @@ -1239,7 +1437,7 @@ static void isis_spf_loop(struct isis_spftree *spftree, lsp = lsp_for_vertex(spftree, vertex); if (!lsp) { - zlog_warn("ISIS-Spf: No LSP found for %s", + zlog_warn("ISIS-SPF: No LSP found for %s", isis_format_id(vertex->N.id, sizeof(vertex->N.id))); continue; @@ -1248,6 +1446,23 @@ static void isis_spf_loop(struct isis_spftree *spftree, isis_spf_process_lsp(spftree, lsp, vertex->d_N, vertex->depth, root_sysid, vertex); } + + /* Generate routes once the SPT is formed. */ + for (ALL_QUEUE_ELEMENTS_RO(&spftree->paths, node, vertex)) { + /* New-style TLVs take precedence over the old-style TLVs. */ + switch (vertex->type) { + case VTYPE_IPREACH_INTERNAL: + case VTYPE_IPREACH_EXTERNAL: + if (isis_find_vertex(&spftree->paths, &vertex->N, + VTYPE_IPREACH_TE)) + continue; + break; + default: + break; + } + + spf_path_process(spftree, vertex); + } } struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area, @@ -1301,7 +1516,7 @@ void isis_run_spf(struct isis_spftree *spftree) root_lsp = isis_root_system_lsp(spftree->lspdb, spftree->sysid); if (root_lsp == NULL) { - zlog_err("ISIS-Spf: could not find own l%d LSP!", + zlog_err("ISIS-SPF: could not find own l%d LSP!", spftree->level); return; } @@ -1343,7 +1558,7 @@ void isis_run_spf(struct isis_spftree *spftree) */ if (!isis_vertex_queue_count(&spftree->tents) && (IS_DEBUG_SPF_EVENTS)) { - zlog_warn("ISIS-Spf: TENT is empty SPF-root:%s", + zlog_warn("ISIS-SPF: TENT is empty SPF-root:%s", print_sys_hostname(spftree->sysid)); } @@ -1356,28 +1571,48 @@ void isis_run_spf(struct isis_spftree *spftree) + (time_end.tv_usec - time_start.tv_usec); } +static void isis_run_spf_with_protection(struct isis_area *area, + struct isis_spftree *spftree) +{ + /* Run forward SPF locally. */ + memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN); + isis_run_spf(spftree); + + /* Run LFA protection if configured. */ + if (area->lfa_protected_links[spftree->level - 1] > 0) + isis_spf_run_lfa(area, spftree); +} + void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees) { if (area->is_type == IS_LEVEL_1) { - isis_route_verify_table(area, trees[0]->route_table); + isis_route_verify_table(area, trees[0]->route_table, + trees[0]->route_table_backup); } else if (area->is_type == IS_LEVEL_2) { - isis_route_verify_table(area, trees[1]->route_table); + isis_route_verify_table(area, trees[1]->route_table, + trees[1]->route_table_backup); } else { isis_route_verify_merge(area, trees[0]->route_table, - trees[1]->route_table); + trees[0]->route_table_backup, + trees[1]->route_table, + trees[1]->route_table_backup); } } void isis_spf_invalidate_routes(struct isis_spftree *tree) { isis_route_invalidate_table(tree->area, tree->route_table); + + /* Delete backup routes. */ + route_table_finish(tree->route_table_backup); + tree->route_table_backup = srcdest_table_init(); + tree->route_table_backup->cleanup = isis_route_node_cleanup; } static int isis_run_spf_cb(struct thread *thread) { struct isis_spf_run *run = THREAD_ARG(thread); struct isis_area *area = run->area; - struct isis_spftree *spftree; int level = run->level; XFREE(MTYPE_ISIS_SPF_RUN, run); @@ -1390,32 +1625,25 @@ static int isis_run_spf_cb(struct thread *thread) return ISIS_WARNING; } + isis_area_delete_backup_adj_sids(area, level); isis_area_invalidate_routes(area, level); if (IS_DEBUG_SPF_EVENTS) - zlog_debug("ISIS-Spf (%s) L%d SPF needed, periodic SPF", + zlog_debug("ISIS-SPF (%s) L%d SPF needed, periodic SPF", area->area_tag, level); - if (area->ip_circuits) { - spftree = area->spftree[SPFTREE_IPV4][level - 1]; - memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN); - isis_run_spf(spftree); - } - if (area->ipv6_circuits) { - spftree = area->spftree[SPFTREE_IPV6][level - 1]; - memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN); - isis_run_spf(spftree); - } - if (area->ipv6_circuits && isis_area_ipv6_dstsrc_enabled(area)) { - spftree = area->spftree[SPFTREE_DSTSRC][level - 1]; - memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN); - isis_run_spf(spftree); - } + if (area->ip_circuits) + isis_run_spf_with_protection( + area, area->spftree[SPFTREE_IPV4][level - 1]); + if (area->ipv6_circuits) + isis_run_spf_with_protection( + area, area->spftree[SPFTREE_IPV6][level - 1]); + if (area->ipv6_circuits && isis_area_ipv6_dstsrc_enabled(area)) + isis_run_spf_with_protection( + area, area->spftree[SPFTREE_DSTSRC][level - 1]); isis_area_verify_routes(area); - isis_area_verify_sr(area); - /* walk all circuits and reset any spf specific flags */ struct listnode *node; struct isis_circuit *circuit; @@ -1452,7 +1680,7 @@ int _isis_spf_schedule(struct isis_area *area, int level, if (IS_DEBUG_SPF_EVENTS) { zlog_debug( - "ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago Caller: %s %s:%d", + "ISIS-SPF (%s) L%d SPF schedule called, lastrun %d sec ago Caller: %s %s:%d", area->area_tag, level, diff, func, file, line); } @@ -1487,7 +1715,7 @@ int _isis_spf_schedule(struct isis_area *area, int level, if (area->bfd_force_spf_refresh) { zlog_debug( - "ISIS-Spf (%s) L%d SPF scheduled immediately due to BFD 'down' message", + "ISIS-SPF (%s) L%d SPF scheduled immediately due to BFD 'down' message", area->area_tag, level); area->bfd_force_spf_refresh = false; } @@ -1499,7 +1727,7 @@ int _isis_spf_schedule(struct isis_area *area, int level, timer, &area->spf_timer[level - 1]); if (IS_DEBUG_SPF_EVENTS) - zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %ld sec from now", + zlog_debug("ISIS-SPF (%s) L%d SPF scheduled %ld sec from now", area->area_tag, level, timer); return ISIS_OK; @@ -1706,10 +1934,126 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, return CMD_SUCCESS; } -void isis_print_routes(struct vty *vty, struct isis_spftree *spftree) +static void isis_print_route(struct ttable *tt, const struct prefix *prefix, + struct isis_route_info *rinfo, bool prefix_sid, + bool no_adjacencies) { + struct isis_nexthop *nexthop; + struct listnode *node; + bool first = true; + char buf_prefix[BUFSIZ]; + + (void)prefix2str(prefix, buf_prefix, sizeof(buf_prefix)); + for (ALL_LIST_ELEMENTS_RO(rinfo->nexthops, node, nexthop)) { + struct interface *ifp; + char buf_iface[BUFSIZ]; + char buf_nhop[BUFSIZ]; + + if (!no_adjacencies) { + inet_ntop(nexthop->family, &nexthop->ip, buf_nhop, + sizeof(buf_nhop)); + ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); + if (ifp) + strlcpy(buf_iface, ifp->name, + sizeof(buf_iface)); + else + snprintf(buf_iface, sizeof(buf_iface), + "ifindex %u", nexthop->ifindex); + } else { + strlcpy(buf_nhop, print_sys_hostname(nexthop->sysid), + sizeof(buf_nhop)); + strlcpy(buf_iface, "-", sizeof(buf_iface)); + } + + if (prefix_sid) { + char buf_sid[BUFSIZ] = {}; + char buf_lblop[BUFSIZ] = {}; + + if (nexthop->sr.present) { + snprintf(buf_sid, sizeof(buf_sid), "%u", + nexthop->sr.sid.value); + sr_op2str(buf_lblop, sizeof(buf_lblop), + rinfo->sr.label, nexthop->sr.label); + } else { + strlcpy(buf_sid, "-", sizeof(buf_sid)); + strlcpy(buf_lblop, "-", sizeof(buf_lblop)); + } + + if (first) { + ttable_add_row(tt, "%s|%u|%s|%s|%s|%s", + buf_prefix, rinfo->cost, + buf_iface, buf_nhop, buf_sid, + buf_lblop); + first = false; + } else + ttable_add_row(tt, "||%s|%s|%s|%s", buf_iface, + buf_nhop, buf_sid, buf_lblop); + } else { + char buf_labels[BUFSIZ] = {}; + + if (nexthop->label_stack) { + for (int i = 0; + i < nexthop->label_stack->num_labels; + i++) { + char buf_label[BUFSIZ]; + + label2str( + nexthop->label_stack->label[i], + buf_label, sizeof(buf_label)); + if (i != 0) + strlcat(buf_labels, "/", + sizeof(buf_labels)); + strlcat(buf_labels, buf_label, + sizeof(buf_labels)); + } + } else if (nexthop->sr.present) + label2str(nexthop->sr.label, buf_labels, + sizeof(buf_labels)); + else + strlcpy(buf_labels, "-", sizeof(buf_labels)); + + if (first) { + ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix, + rinfo->cost, buf_iface, buf_nhop, + buf_labels); + first = false; + } else + ttable_add_row(tt, "||%s|%s|%s", buf_iface, + buf_nhop, buf_labels); + } + } + if (list_isempty(rinfo->nexthops)) { + if (prefix_sid) { + char buf_sid[BUFSIZ] = {}; + char buf_lblop[BUFSIZ] = {}; + + if (rinfo->sr.present) { + snprintf(buf_sid, sizeof(buf_sid), "%u", + rinfo->sr.sid.value); + sr_op2str(buf_lblop, sizeof(buf_lblop), + rinfo->sr.label, + MPLS_LABEL_IMPLICIT_NULL); + } else { + strlcpy(buf_sid, "-", sizeof(buf_sid)); + strlcpy(buf_lblop, "-", sizeof(buf_lblop)); + } + + ttable_add_row(tt, "%s|%u|%s|%s|%s|%s", buf_prefix, + rinfo->cost, "-", "-", buf_sid, + buf_lblop); + } else + ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix, + rinfo->cost, "-", "-", "-"); + } +} + +void isis_print_routes(struct vty *vty, struct isis_spftree *spftree, + bool prefix_sid, bool backup) +{ + struct route_table *route_table; struct ttable *tt; struct route_node *rn; + bool no_adjacencies = false; const char *tree_id_text = NULL; if (!spftree) @@ -1735,65 +2079,28 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree) /* Prepare table. */ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); - ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|Label(s)"); + if (prefix_sid) + ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|SID|Label Op."); + else + ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|Label(s)"); tt->style.cell.rpad = 2; tt->style.corner = '+'; ttable_restyle(tt); ttable_rowseps(tt, 0, BOTTOM, true, '-'); - for (rn = route_top(spftree->route_table); rn; rn = route_next(rn)) { + if (CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) + no_adjacencies = true; + + route_table = + (backup) ? spftree->route_table_backup : spftree->route_table; + for (rn = route_top(route_table); rn; rn = route_next(rn)) { struct isis_route_info *rinfo; - struct isis_nexthop *nexthop; - struct listnode *node; - bool first = true; - char buf_prefix[BUFSIZ]; rinfo = rn->info; if (!rinfo) continue; - (void)prefix2str(&rn->p, buf_prefix, sizeof(buf_prefix)); - for (ALL_LIST_ELEMENTS_RO(rinfo->nexthops, node, nexthop)) { - struct interface *ifp; - char buf_iface[BUFSIZ]; - char buf_nhop[BUFSIZ]; - char buf_labels[BUFSIZ] = {}; - - if (!CHECK_FLAG(spftree->flags, - F_SPFTREE_NO_ADJACENCIES)) { - inet_ntop(nexthop->family, &nexthop->ip, - buf_nhop, sizeof(buf_nhop)); - ifp = if_lookup_by_index(nexthop->ifindex, - VRF_DEFAULT); - if (ifp) - strlcpy(buf_iface, ifp->name, - sizeof(buf_iface)); - else - snprintf(buf_iface, sizeof(buf_iface), - "ifindex %u", - nexthop->ifindex); - } else { - strlcpy(buf_nhop, - print_sys_hostname(nexthop->sysid), - sizeof(buf_nhop)); - strlcpy(buf_iface, "-", sizeof(buf_iface)); - } - - if (nexthop->sr.label != MPLS_INVALID_LABEL) - label2str(nexthop->sr.label, buf_labels, - sizeof(buf_labels)); - else - strlcpy(buf_labels, "-", sizeof(buf_labels)); - - if (first) { - ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix, - rinfo->cost, buf_iface, buf_nhop, - buf_labels); - first = false; - } else - ttable_add_row(tt, "||%s|%s|%s", buf_iface, - buf_nhop, buf_labels); - } + isis_print_route(tt, &rn->p, rinfo, prefix_sid, no_adjacencies); } /* Dump the generated table. */ @@ -1808,7 +2115,8 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree) } static void show_isis_route_common(struct vty *vty, int levels, - struct isis *isis) + struct isis *isis, bool prefix_sid, + bool backup) { struct listnode *node; struct isis_area *area; @@ -1827,17 +2135,20 @@ static void show_isis_route_common(struct vty *vty, int levels, if (area->ip_circuits > 0) { isis_print_routes( vty, - area->spftree[SPFTREE_IPV4][level - 1]); + area->spftree[SPFTREE_IPV4][level - 1], + prefix_sid, backup); } if (area->ipv6_circuits > 0) { isis_print_routes( vty, - area->spftree[SPFTREE_IPV6][level - 1]); + area->spftree[SPFTREE_IPV6][level - 1], + prefix_sid, backup); } if (isis_area_ipv6_dstsrc_enabled(area)) { isis_print_routes(vty, area->spftree[SPFTREE_DSTSRC] - [level - 1]); + [level - 1], + prefix_sid, backup); } } } @@ -1849,20 +2160,23 @@ DEFUN(show_isis_route, show_isis_route_cmd, #ifndef FABRICD " [<level-1|level-2>]" #endif - , + " [<prefix-sid|backup>]", SHOW_STR PROTO_HELP VRF_FULL_CMD_HELP_STR "IS-IS routing table\n" #ifndef FABRICD "level-1 routes\n" "level-2 routes\n" #endif -) + "Show Prefix-SID information\n" + "Show backup routes\n") { int levels; struct isis *isis; struct listnode *node; const char *vrf_name = VRF_DEFAULT_NAME; bool all_vrf = false; + bool prefix_sid = false; + bool backup = false; int idx = 0; if (argv_find(argv, argc, "level-1", &idx)) @@ -1878,15 +2192,22 @@ DEFUN(show_isis_route, show_isis_route_cmd, } ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf); + if (argv_find(argv, argc, "prefix-sid", &idx)) + prefix_sid = true; + if (argv_find(argv, argc, "backup", &idx)) + backup = true; + if (vrf_name) { if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - show_isis_route_common(vty, levels, isis); + show_isis_route_common(vty, levels, isis, + prefix_sid, backup); return CMD_SUCCESS; } isis = isis_lookup_by_vrfname(vrf_name); if (isis != NULL) - show_isis_route_common(vty, levels, isis); + show_isis_route_common(vty, levels, isis, prefix_sid, + backup); } return CMD_SUCCESS; diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h index b2dc23496f..15d3ff9272 100644 --- a/isisd/isis_spf.h +++ b/isisd/isis_spf.h @@ -24,11 +24,14 @@ #ifndef _ZEBRA_ISIS_SPF_H #define _ZEBRA_ISIS_SPF_H +#include "isisd/isis_lfa.h" + struct isis_spftree; enum spf_type { SPF_TYPE_FORWARD = 1, SPF_TYPE_REVERSE, + SPF_TYPE_TI_LFA, }; struct isis_spf_adj { @@ -56,17 +59,21 @@ void isis_spf_verify_routes(struct isis_area *area, void isis_spftree_del(struct isis_spftree *spftree); void spftree_area_init(struct isis_area *area); void spftree_area_del(struct isis_area *area); +struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb, + const uint8_t *sysid); #define isis_spf_schedule(area, level) \ _isis_spf_schedule((area), (level), __func__, \ __FILE__, __LINE__) int _isis_spf_schedule(struct isis_area *area, int level, const char *func, const char *file, int line); void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree); -void isis_print_routes(struct vty *vty, struct isis_spftree *spftree); +void isis_print_routes(struct vty *vty, struct isis_spftree *spftree, + bool prefix_sid, bool backup); void isis_spf_init(void); void isis_spf_print(struct isis_spftree *spftree, struct vty *vty); void isis_run_spf(struct isis_spftree *spftree); struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area, uint8_t *sysid, struct isis_spftree *spftree); + #endif /* _ZEBRA_ISIS_SPF_H */ diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h index 1e61bf0f48..e999f96539 100644 --- a/isisd/isis_spf_private.h +++ b/isisd/isis_spf_private.h @@ -52,6 +52,7 @@ struct prefix_pair { struct isis_vertex_adj { struct isis_spf_adj *sadj; + struct isis_sr_psid_info sr; struct mpls_label_stack *label_stack; }; @@ -62,7 +63,10 @@ struct isis_vertex { enum vertextype type; union { uint8_t id[ISIS_SYS_ID_LEN + 1]; - struct prefix_pair ip; + struct { + struct prefix_pair p; + struct isis_sr_psid_info sr; + } ip; } N; uint32_t d_N; /* d(N) Distance from this IS */ uint16_t depth; /* The depth in the imaginary tree */ @@ -91,8 +95,8 @@ static unsigned isis_vertex_queue_hash_key(const void *vp) if (VTYPE_IP(vertex->type)) { uint32_t key; - key = prefix_hash_key(&vertex->N.ip.dest); - key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key); + key = prefix_hash_key(&vertex->N.ip.p.dest); + key = jhash_1word(prefix_hash_key(&vertex->N.ip.p.src), key); return key; } @@ -108,11 +112,12 @@ static bool isis_vertex_queue_hash_cmp(const void *a, const void *b) return false; if (VTYPE_IP(va->type)) { - if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest)) + if (prefix_cmp(&va->N.ip.p.dest, &vb->N.ip.p.dest)) return false; - return prefix_cmp((const struct prefix *)&va->N.ip.src, - (const struct prefix *)&vb->N.ip.src) == 0; + return prefix_cmp((const struct prefix *)&va->N.ip.p.src, + (const struct prefix *)&vb->N.ip.p.src) + == 0; } return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0; @@ -306,8 +311,10 @@ struct isis_spftree { struct isis_vertex_queue paths; /* the SPT */ struct isis_vertex_queue tents; /* TENT */ struct route_table *route_table; + struct route_table *route_table_backup; struct lspdb_head *lspdb; /* link-state db */ struct list *sadj_list; + struct isis_spf_nodes adj_nodes; struct isis_area *area; /* back pointer to area */ unsigned int runcount; /* number of runs since uptime */ time_t last_run_timestamp; /* last run timestamp as wall time for display */ @@ -320,7 +327,20 @@ struct isis_spftree { int family; int level; enum spf_tree_id tree_id; - bool hopcount_metric; + struct { + /* Original pre-failure local SPTs. */ + struct { + struct isis_spftree *spftree; + struct isis_spftree *spftree_reverse; + } old; + + /* Protected resource. */ + struct lfa_protected_resource protected_resource; + + /* P-space and Q-space. */ + struct isis_spf_nodes p_space; + struct isis_spf_nodes q_space; + } lfa; uint8_t flags; }; #define F_SPFTREE_HOPCOUNT_METRIC 0x01 @@ -336,7 +356,7 @@ static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id, if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) { memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1); } else if (VTYPE_IP(vtype)) { - memcpy(&vertex->N.ip, id, sizeof(vertex->N.ip)); + memcpy(&vertex->N.ip.p, id, sizeof(vertex->N.ip.p)); } else { flog_err(EC_LIB_DEVELOPMENT, "Unknown Vertex Type"); } @@ -373,6 +393,7 @@ static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree, } #define VID2STR_BUFFER SRCDEST2STR_BUFFER -const char *vid2string(struct isis_vertex *vertex, char *buff, int size); +const char *vtype2string(enum vertextype vtype); +const char *vid2string(const struct isis_vertex *vertex, char *buff, int size); #endif diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index d05afaa630..89fa2018b9 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -31,6 +31,7 @@ #include "memory.h" #include "prefix.h" #include "table.h" +#include "srcdest_table.h" #include "vty.h" #include "zclient.h" #include "lib/lib_errors.h" @@ -50,63 +51,158 @@ /* Local variables and functions */ DEFINE_MTYPE_STATIC(ISISD, ISIS_SR_INFO, "ISIS segment routing information") -static void sr_prefix_uninstall(struct sr_prefix *srp); -static void sr_prefix_reinstall(struct sr_prefix *srp, bool make_before_break); static void sr_local_block_delete(struct isis_area *area); static int sr_local_block_init(struct isis_area *area); static void sr_adj_sid_update(struct sr_adjacency *sra, struct sr_local_block *srlb); +static void sr_adj_sid_del(struct sr_adjacency *sra); /* --- RB-Tree Management functions ----------------------------------------- */ /** - * SR Prefix comparison for RB-Tree. + * Configured SR Prefix comparison for RB-Tree. * * @param a First SR prefix * @param b Second SR prefix * * @return -1 (a < b), 0 (a == b) or +1 (a > b) */ -static inline int sr_prefix_sid_compare(const struct sr_prefix *a, - const struct sr_prefix *b) +static inline int sr_prefix_sid_cfg_compare(const struct sr_prefix_cfg *a, + const struct sr_prefix_cfg *b) { return prefix_cmp(&a->prefix, &b->prefix); } -DECLARE_RBTREE_UNIQ(srdb_node_prefix, struct sr_prefix, node_entry, - sr_prefix_sid_compare) -DECLARE_RBTREE_UNIQ(srdb_area_prefix, struct sr_prefix, area_entry, - sr_prefix_sid_compare) +DECLARE_RBTREE_UNIQ(srdb_prefix_cfg, struct sr_prefix_cfg, entry, + sr_prefix_sid_cfg_compare) /** - * Configured SR Prefix comparison for RB-Tree. + * Find SRGB associated to a System ID. * - * @param a First SR prefix - * @param b Second SR prefix + * @param area IS-IS LSP database + * @param sysid System ID to lookup * - * @return -1 (a < b), 0 (a == b) or +1 (a > b) + * @return Pointer to SRGB if found, NULL otherwise */ -static inline int sr_prefix_sid_cfg_compare(const struct sr_prefix_cfg *a, - const struct sr_prefix_cfg *b) +struct isis_sr_block *isis_sr_find_srgb(struct lspdb_head *lspdb, + const uint8_t *sysid) { - return prefix_cmp(&a->prefix, &b->prefix); + struct isis_lsp *lsp; + + lsp = isis_root_system_lsp(lspdb, sysid); + if (!lsp) + return NULL; + + if (!lsp->tlvs->router_cap + || lsp->tlvs->router_cap->srgb.range_size == 0) + return NULL; + + return &lsp->tlvs->router_cap->srgb; } -DECLARE_RBTREE_UNIQ(srdb_prefix_cfg, struct sr_prefix_cfg, entry, - sr_prefix_sid_cfg_compare) /** - * SR Node comparison for RB-Tree. + * Compute input label for the given Prefix-SID. * - * @param a First SR node - * @param b Second SR node + * @param area IS-IS area + * @param psid IS-IS Prefix-SID Sub-TLV + * @param local Indicates whether the Prefix-SID is local or not * - * @return -1 (a < b), 0 (a == b) or +1 (a > b) + * @return MPLS label or MPLS_INVALID_LABEL in case of SRGB overflow */ -static inline int sr_node_compare(const struct sr_node *a, - const struct sr_node *b) +mpls_label_t sr_prefix_in_label(struct isis_area *area, + struct isis_prefix_sid *psid, bool local) { - return memcmp(a->sysid, b->sysid, ISIS_SYS_ID_LEN); + /* + * No need to assign a label for local Prefix-SIDs unless the no-PHP + * flag is set. + */ + if (local + && (!CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP) + || CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL))) + return MPLS_INVALID_LABEL; + + /* Return SID value as MPLS label if it is an Absolute SID */ + if (CHECK_FLAG(psid->flags, + ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL)) + return psid->value; + + /* Check that SID index falls inside the SRGB */ + if (psid->value >= (area->srdb.config.srgb_upper_bound + - area->srdb.config.srgb_lower_bound + 1)) { + flog_warn(EC_ISIS_SID_OVERFLOW, + "%s: SID index %u falls outside local SRGB range", + __func__, psid->value); + return MPLS_INVALID_LABEL; + } + + /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */ + return (area->srdb.config.srgb_lower_bound + psid->value); +} + +/** + * Compute output label for the given Prefix-SID. + * + * @param lspdb IS-IS LSP database + * @param family Prefix-SID address family + * @param psid Prefix-SID Sub-TLV + * @param nh_sysid System ID of the nexthop node + * @param last_hop Indicates whether the nexthop node is the last hop + * + * @return MPLS label or MPLS_INVALID_LABEL in case of error + */ +mpls_label_t sr_prefix_out_label(struct lspdb_head *lspdb, int family, + struct isis_prefix_sid *psid, + const uint8_t *nh_sysid, bool last_hop) +{ + struct isis_sr_block *nh_srgb; + + if (last_hop) { + if (!CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP)) + return MPLS_LABEL_IMPLICIT_NULL; + + if (CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL)) { + if (family == AF_INET) + return MPLS_LABEL_IPV4_EXPLICIT_NULL; + else + return MPLS_LABEL_IPV6_EXPLICIT_NULL; + } + /* Fallthrough */ + } + + /* Return SID value as MPLS label if it is an Absolute SID */ + if (CHECK_FLAG(psid->flags, + ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL)) { + /* + * V/L SIDs have local significance, so only adjacent routers + * can use them (RFC8667 section #2.1.1.1) + */ + if (!last_hop) + return MPLS_INVALID_LABEL; + return psid->value; + } + + /* Check that SID index falls inside the SRGB */ + nh_srgb = isis_sr_find_srgb(lspdb, nh_sysid); + if (!nh_srgb) + return MPLS_INVALID_LABEL; + + /* + * Check if the nexthop can handle SR-MPLS encapsulated IPv4 or + * IPv6 packets. + */ + if ((family == AF_INET && !IS_SR_IPV4(nh_srgb)) + || (family == AF_INET6 && !IS_SR_IPV6(nh_srgb))) + return MPLS_INVALID_LABEL; + + if (psid->value >= nh_srgb->range_size) { + flog_warn(EC_ISIS_SID_OVERFLOW, + "%s: SID index %u falls outside remote SRGB range", + __func__, psid->value); + return MPLS_INVALID_LABEL; + } + + /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */ + return (nh_srgb->lower_bound + psid->value); } -DECLARE_RBTREE_UNIQ(srdb_node, struct sr_node, entry, sr_node_compare) /* --- Functions used for Yang model and CLI to configure Segment Routing --- */ @@ -161,8 +257,6 @@ int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound, srdb->config.srgb_upper_bound = upper_bound; if (srdb->enabled) { - struct sr_prefix *srp; - /* then request new SRGB if SR is enabled. */ if (isis_zebra_request_label_range( srdb->config.srgb_lower_bound, @@ -178,14 +272,6 @@ int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound, srdb->config.srgb_lower_bound, srdb->config.srgb_upper_bound); - /* Reinstall local Prefix-SIDs to update their input labels. */ - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { - frr_each (srdb_area_prefix, - &area->srdb.prefix_sids[level - 1], srp) { - sr_prefix_reinstall(srp, false); - } - } - lsp_regenerate_schedule(area, area->is_type, 0); } else if (srdb->config.enabled) { /* Try to enable SR again using the new SRGB. */ @@ -277,7 +363,7 @@ struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area, /* Set the N-flag when appropriate. */ ifp = if_lookup_prefix(prefix, VRF_DEFAULT); - if (ifp && sr_prefix_is_node_sid(ifp, prefix)) + if (ifp && sr_prefix_is_node_sid(ifp, prefix) && !pcfg->n_flag_clear) pcfg->node_sid = true; /* Save prefix-sid configuration. */ @@ -363,978 +449,21 @@ void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, bool external, } } -/* --- Segment Routing Prefix Management functions -------------------------- */ - -/** - * Add Segment Routing Prefix to a given Segment Routing Node. - * - * @param area IS-IS area - * @param srn Segment Routing Node - * @param prefix Prefix to be added - * @param local True if prefix is locally configured, false otherwise - * @param psid Prefix-SID sub-TLVs - * - * @return New Segment Routing Prefix structure - */ -static struct sr_prefix *sr_prefix_add(struct isis_area *area, - struct sr_node *srn, - union prefixconstptr prefix, bool local, - const struct isis_prefix_sid *psid) -{ - struct sr_prefix *srp; - - srp = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*srp)); - prefix_copy(&srp->prefix, prefix.p); - srp->sid = *psid; - srp->input_label = MPLS_INVALID_LABEL; - if (local) { - srp->type = ISIS_SR_PREFIX_LOCAL; - isis_sr_nexthop_reset(&srp->u.local.info); - } else { - srp->type = ISIS_SR_PREFIX_REMOTE; - srp->u.remote.rinfo = NULL; - } - srp->srn = srn; - srdb_node_prefix_add(&srn->prefix_sids, srp); - /* TODO: this might fail if we have Anycast SIDs in the IS-IS area. */ - srdb_area_prefix_add(&area->srdb.prefix_sids[srn->level - 1], srp); - - sr_debug(" |- Added new SR Prefix-SID %pFX %s %u to SR Node %s", - &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index", - srp->sid.value, sysid_print(srn->sysid)); - - return srp; -} - -/** - * Remove given Segment Prefix from given Segment Routing Node. - * Prefix-SID is un-installed first. - * - * @param area IS-IS area - * @param srn Segment Routing Node - * @param srp Segment Routing Prefix - */ -static void sr_prefix_del(struct isis_area *area, struct sr_node *srn, - struct sr_prefix *srp) -{ - sr_debug(" |- Delete SR Prefix-SID %pFX %s %u to SR Node %s", - &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index", - srp->sid.value, sysid_print(srn->sysid)); - - sr_prefix_uninstall(srp); - srdb_node_prefix_del(&srn->prefix_sids, srp); - srdb_area_prefix_del(&area->srdb.prefix_sids[srn->level - 1], srp); - XFREE(MTYPE_ISIS_SR_INFO, srp); -} - -/** - * Find Segment Routing Prefix by Area. - * - * @param area IS-IS area - * @param level IS-IS level - * @param prefix Prefix to lookup - * - * @return Segment Routing Prefix structure if found, NULL otherwise - */ -static struct sr_prefix *sr_prefix_find_by_area(struct isis_area *area, - int level, - union prefixconstptr prefix) -{ - struct sr_prefix srp = {}; - - prefix_copy(&srp.prefix, prefix.p); - return srdb_area_prefix_find(&area->srdb.prefix_sids[level - 1], &srp); -} - -/** - * Find Segment Routing Prefix by Segment Routing Node. - * - * @param srn Segment Routing Node - * @param prefix Prefix to lookup - * - * @return Segment Routing Prefix structure if found, NULL otherwise - */ -static struct sr_prefix *sr_prefix_find_by_node(struct sr_node *srn, - union prefixconstptr prefix) -{ - struct sr_prefix srp = {}; - - prefix_copy(&srp.prefix, prefix.p); - return srdb_node_prefix_find(&srn->prefix_sids, &srp); -} - -/* --- Segment Routing Node Management functions ---------------------------- */ - -/** - * Add Segment Routing Node to the Segment Routing Data Base. - * - * @param area IS-IS area - * @param level IS-IS level - * @param sysid Node System ID - * @param cap Segment Routing Capability sub-TLVs - * - * @return New Segment Routing Node structure - */ -static struct sr_node *sr_node_add(struct isis_area *area, int level, - const uint8_t *sysid) -{ - struct sr_node *srn; - - srn = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*srn)); - srn->level = level; - memcpy(srn->sysid, sysid, ISIS_SYS_ID_LEN); - srn->area = area; - srdb_node_prefix_init(&srn->prefix_sids); - srdb_node_add(&area->srdb.sr_nodes[level - 1], srn); - - sr_debug(" |- Added new SR Node %s", sysid_print(srn->sysid)); - - return srn; -} - -static void sr_node_del(struct isis_area *area, int level, struct sr_node *srn) -/** - * Remove Segment Routing Node from the Segment Routing Data Base. - * All Prefix-SID attached to this Segment Routing Node are removed first. - * - * @param area IS-IS area - * @param level IS-IS level - * @param srn Segment Routing Node to be deleted - */ -{ - - sr_debug(" |- Delete SR Node %s", sysid_print(srn->sysid)); - - /* Remove and uninstall Prefix-SIDs. */ - while (srdb_node_prefix_count(&srn->prefix_sids) > 0) { - struct sr_prefix *srp; - - srp = srdb_node_prefix_first(&srn->prefix_sids); - sr_prefix_del(area, srn, srp); - } - - srdb_node_del(&area->srdb.sr_nodes[level - 1], srn); - XFREE(MTYPE_ISIS_SR_INFO, srn); -} - -/** - * Find Segment Routing Node in the Segment Routing Data Base per system ID. - * - * @param area IS-IS area - * @param level IS-IS level - * @param sysid Node System ID to lookup - * - * @return Segment Routing Node structure if found, NULL otherwise - */ -static struct sr_node *sr_node_find(struct isis_area *area, int level, - const uint8_t *sysid) -{ - struct sr_node srn = {}; - - memcpy(srn.sysid, sysid, ISIS_SYS_ID_LEN); - return srdb_node_find(&area->srdb.sr_nodes[level - 1], &srn); -} - -/** - * Update Segment Routing Node following an SRGB update. This function - * is called when a neighbor SR Node has updated its SRGB. - * - * @param area IS-IS area - * @param level IS-IS level - * @param sysid Segment Routing Node system ID - */ -static void sr_node_srgb_update(struct isis_area *area, int level, - uint8_t *sysid) -{ - struct sr_prefix *srp; - - sr_debug("ISIS-Sr (%s): Update neighbors SR Node with new SRGB", - area->area_tag); - - frr_each (srdb_area_prefix, &area->srdb.prefix_sids[level - 1], srp) { - struct listnode *node; - struct isis_nexthop *nh; - - if (srp->type == ISIS_SR_PREFIX_LOCAL) - continue; - - if (srp->u.remote.rinfo == NULL) - continue; - - for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node, - nh)) { - if (memcmp(nh->sysid, sysid, ISIS_SYS_ID_LEN) != 0) - continue; - - /* - * The Prefix-SID input label hasn't changed. We could - * re-install all Prefix-SID with "Make Before Break" - * option. Zebra layer will update output label(s) by - * adding new entry before removing the old one(s). - */ - sr_prefix_reinstall(srp, true); - break; - } - } -} - -/* --- Segment Routing Nexthop information Management functions ------------- */ - -/** - * Update Segment Routing Nexthop. - * - * @param srnh Segment Routing next hop - * @param label Output MPLS label - */ -void isis_sr_nexthop_update(struct sr_nexthop_info *srnh, mpls_label_t label) -{ - srnh->label = label; - if (srnh->uptime == 0) - srnh->uptime = time(NULL); -} - -/** - * Reset Segment Routing Nexthop. - * - * @param srnh Segment Routing Nexthop - */ -void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh) -{ - srnh->label = MPLS_INVALID_LABEL; - srnh->uptime = 0; -} - -/* --- Segment Routing Prefix-SID Management functions to configure LFIB ---- */ - -/** - * Lookup IS-IS route in the Shortest Path Tree. - * - * @param area IS-IS area - * @param tree_id Shortest Path Tree identifier - * @param srp Segment Routing Prefix to lookup - * - * @return Route Information for this prefix if found, NULL otherwise - */ -static struct isis_route_info *sr_prefix_lookup_route(struct isis_area *area, - enum spf_tree_id tree_id, - struct sr_prefix *srp) -{ - struct route_node *rn; - int level = srp->srn->level; - - rn = route_node_lookup(area->spftree[tree_id][level - 1]->route_table, - &srp->prefix); - if (rn) { - route_unlock_node(rn); - if (rn->info) - return rn->info; - } - - return NULL; -} - -/** - * Compute input label for the given Prefix-SID. - * - * @param srp Segment Routing Prefix - * - * @return MPLS label or MPLS_INVALID_LABEL in case of SRGB overflow - */ -static mpls_label_t sr_prefix_in_label(const struct sr_prefix *srp) -{ - const struct sr_node *srn = srp->srn; - struct isis_area *area = srn->area; - - /* Return SID value as MPLS label if it is an Absolute SID */ - if (CHECK_FLAG(srp->sid.flags, - ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL)) - return srp->sid.value; - - /* Check that SID index falls inside the SRGB */ - if (srp->sid.value >= (area->srdb.config.srgb_upper_bound - - area->srdb.config.srgb_lower_bound + 1)) { - flog_warn(EC_ISIS_SID_OVERFLOW, - "%s: SID index %u falls outside local SRGB range", - __func__, srp->sid.value); - return MPLS_INVALID_LABEL; - } - - /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */ - return (area->srdb.config.srgb_lower_bound + srp->sid.value); -} - -/** - * Compute output label for the given Prefix-SID. - * - * @param srp Segment Routing Prefix - * @param srn_nexthop Segment Routing nexthop node - * @param sysid System ID of the SR node which advertised the Prefix-SID - * - * @return MPLS label or MPLS_INVALID_LABEL in case of error - */ -static mpls_label_t sr_prefix_out_label(const struct sr_prefix *srp, - const struct sr_node *srn_nexthop, - const uint8_t *sysid) -{ - const struct sr_node *srn = srp->srn; - - /* Check if the nexthop SR Node is the last hop? */ - if (memcmp(sysid, srn->sysid, ISIS_SYS_ID_LEN) == 0) { - /* SR-Node doesn't request NO-PHP. Return Implicit NULL label */ - if (!CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_NO_PHP)) - return MPLS_LABEL_IMPLICIT_NULL; - - /* SR-Node requests Implicit NULL Label */ - if (CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_EXPLICIT_NULL)) { - if (srp->prefix.family == AF_INET) - return MPLS_LABEL_IPV4_EXPLICIT_NULL; - else - return MPLS_LABEL_IPV6_EXPLICIT_NULL; - } - /* Fallthrough */ - } - - /* Return SID value as MPLS label if it is an Absolute SID */ - if (CHECK_FLAG(srp->sid.flags, - ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL)) { - /* - * V/L SIDs have local significance, so only adjacent routers - * can use them (RFC8667 section #2.1.1.1) - */ - if (srp->srn != srn_nexthop) - return MPLS_INVALID_LABEL; - return srp->sid.value; - } - - /* Check that SID index falls inside the SRGB */ - if (srp->sid.value >= srn_nexthop->cap.srgb.range_size) { - flog_warn(EC_ISIS_SID_OVERFLOW, - "%s: SID index %u falls outside remote SRGB range", - __func__, srp->sid.value); - return MPLS_INVALID_LABEL; - } - - /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */ - return (srn_nexthop->cap.srgb.lower_bound + srp->sid.value); -} - -/** - * Process local Prefix-SID and install it if possible. Input label is - * computed before installing it in LFIB. - * - * @param srp Segment Routing Prefix - * - * @return 0 on success, -1 otherwise - */ -static int sr_prefix_install_local(struct sr_prefix *srp) -{ - mpls_label_t input_label; - const struct sr_node *srn = srp->srn; - - /* - * No need to install Label for local Prefix-SID unless the - * no-PHP option is configured. - */ - if (!CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_NO_PHP) - || CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_EXPLICIT_NULL)) - return -1; - - sr_debug(" |- Installing Prefix-SID %pFX %s %u (%s) with nexthop self", - &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index", - srp->sid.value, circuit_t2string(srn->level)); - - /* Compute input label and check that is valid. */ - input_label = sr_prefix_in_label(srp); - if (input_label == MPLS_INVALID_LABEL) - return -1; - - /* Update internal state. */ - srp->input_label = input_label; - isis_sr_nexthop_update(&srp->u.local.info, MPLS_LABEL_IMPLICIT_NULL); - - /* Install Prefix-SID in the forwarding plane. */ - isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_REPLACE, srp); - - return 0; -} - -/** - * Process remote Prefix-SID and install it if possible. Input and Output - * labels are computed before installing them in LFIB. - * - * @param srp Segment Routing Prefix - * - * @return 0 on success, -1 otherwise - */ -static int sr_prefix_install_remote(struct sr_prefix *srp) -{ - const struct sr_node *srn = srp->srn; - struct isis_area *area = srn->area; - enum spf_tree_id tree_id; - struct listnode *node; - struct isis_nexthop *nexthop; - mpls_label_t input_label; - size_t nexthop_num = 0; - - /* Lookup to associated IS-IS route. */ - tree_id = (srp->prefix.family == AF_INET) ? SPFTREE_IPV4 : SPFTREE_IPV6; - srp->u.remote.rinfo = sr_prefix_lookup_route(area, tree_id, srp); - if (!srp->u.remote.rinfo) - /* SPF hasn't converged for this route yet. */ - return -1; - - /* Compute input label and check that is valid. */ - input_label = sr_prefix_in_label(srp); - if (input_label == MPLS_INVALID_LABEL) - return -1; - - sr_debug(" |- Installing Prefix-SID %pFX %s %u (%s)", &srp->prefix, - IS_SID_VALUE(srp->sid.flags) ? "label" : "index", - srp->sid.value, circuit_t2string(srn->level)); - - /* Process all SPF nexthops */ - for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node, - nexthop)) { - struct sr_node *srn_nexthop; - mpls_label_t output_label; - - /* Check if the nexthop advertised a SRGB. */ - srn_nexthop = sr_node_find(area, srn->level, nexthop->sysid); - if (!srn_nexthop) - goto next; - - /* - * Check if the nexthop can handle SR-MPLS encapsulated IPv4 or - * IPv6 packets. - */ - if ((nexthop->family == AF_INET - && !IS_SR_IPV4(srn_nexthop->cap.srgb)) - || (nexthop->family == AF_INET6 - && !IS_SR_IPV6(srn_nexthop->cap.srgb))) - goto next; - - /* Compute output label and check if it is valid */ - output_label = - sr_prefix_out_label(srp, srn_nexthop, nexthop->sysid); - if (output_label == MPLS_INVALID_LABEL) - goto next; - - if (IS_DEBUG_SR) { - static char buf[INET6_ADDRSTRLEN]; - - inet_ntop(nexthop->family, &nexthop->ip, buf, - sizeof(buf)); - zlog_debug(" |- nexthop %s label %u", buf, - output_label); - } - - isis_sr_nexthop_update(&nexthop->sr, output_label); - nexthop_num++; - continue; - next: - isis_sr_nexthop_reset(&nexthop->sr); - } - - /* Check that we found at least one valid nexthop */ - if (nexthop_num == 0) { - sr_debug(" |- no valid nexthops"); - return -1; - } - - /* Update internal state. */ - srp->input_label = input_label; - - /* Install Prefix-SID in the forwarding plane. */ - isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_REPLACE, srp); - - return 0; -} - -/** - * Process local or remote Prefix-SID and install it if possible. - * - * @param srp Segment Routing Prefix - */ -static void sr_prefix_install(struct sr_prefix *srp) -{ - const struct sr_node *srn = srp->srn; - struct isis_area *area = srn->area; - int ret; - - sr_debug("ISIS-Sr (%s): Install Prefix-SID %pFX %s %u", area->area_tag, - &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index", - srp->sid.value); - - /* L1 routes are preferred over the L2 ones. */ - if (area->is_type == IS_LEVEL_1_AND_2) { - struct sr_prefix *srp_l1, *srp_l2; - - switch (srn->level) { - case ISIS_LEVEL1: - srp_l2 = sr_prefix_find_by_area(area, ISIS_LEVEL2, - &srp->prefix); - if (srp_l2) - sr_prefix_uninstall(srp_l2); - break; - case ISIS_LEVEL2: - srp_l1 = sr_prefix_find_by_area(area, ISIS_LEVEL1, - &srp->prefix); - if (srp_l1) - return; - break; - default: - break; - } - } - - /* Install corresponding LFIB entry */ - if (srp->type == ISIS_SR_PREFIX_LOCAL) - ret = sr_prefix_install_local(srp); - else - ret = sr_prefix_install_remote(srp); - if (ret != 0) - sr_prefix_uninstall(srp); -} - -/** - * Uninstall local or remote Prefix-SID. - * - * @param srp Segment Routing Prefix - */ -static void sr_prefix_uninstall(struct sr_prefix *srp) -{ - struct listnode *node; - struct isis_nexthop *nexthop; - - /* Check that Input Label is valid */ - if (srp->input_label == MPLS_INVALID_LABEL) - return; - - sr_debug("ISIS-Sr: Un-install Prefix-SID %pFX %s %u", &srp->prefix, - IS_SID_VALUE(srp->sid.flags) ? "label" : "index", - srp->sid.value); - - /* Uninstall Prefix-SID from the forwarding plane. */ - isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_DELETE, srp); - - /* Reset internal state. */ - srp->input_label = MPLS_INVALID_LABEL; - switch (srp->type) { - case ISIS_SR_PREFIX_LOCAL: - isis_sr_nexthop_reset(&srp->u.local.info); - break; - case ISIS_SR_PREFIX_REMOTE: - if (srp->u.remote.rinfo) { - for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, - node, nexthop)) - isis_sr_nexthop_reset(&nexthop->sr); - } - break; - } -} - /** - * Reinstall local or remote Prefix-SID. - * - * @param srp Segment Routing Prefix - */ -static inline void sr_prefix_reinstall(struct sr_prefix *srp, - bool make_before_break) -{ - /* - * Make Before Break can be used only when we know for sure that - * the Prefix-SID input label hasn't changed. Otherwise we need to - * uninstall the Prefix-SID first using the old input label before - * reinstalling it. - */ - if (!make_before_break) - sr_prefix_uninstall(srp); - - /* New input label is computed in sr_prefix_install() function */ - sr_prefix_install(srp); -} - -/* --- IS-IS LSP Parse functions -------------------------------------------- */ - -/** - * Compare Router Capabilities. Only Flags, SRGB and Algorithm are used for the - * comparison. MSD and SRLB modification must not trigger and SR-Prefix update. - * - * @param r1 First Router Capabilities to compare - * @param r2 Second Router Capabilities to compare - * @return 0 if r1 and r2 are equal or -1 otherwise - */ -static int router_cap_cmp(const struct isis_router_cap *r1, - const struct isis_router_cap *r2) -{ - if (r1->flags == r2->flags - && r1->srgb.lower_bound == r2->srgb.lower_bound - && r1->srgb.range_size == r2->srgb.range_size - && r1->algo[0] == r2->algo[0]) - return 0; - else - return -1; -} - -/** - * Parse all SR-related information from the given Router Capabilities TLV. - * - * @param area IS-IS area - * @param level IS-IS level - * @param sysid System ID of the LSP - * @param router_cap Router Capability subTLVs - * - * @return Segment Routing Node structure for this System ID - */ -static struct sr_node * -parse_router_cap_tlv(struct isis_area *area, int level, const uint8_t *sysid, - const struct isis_router_cap *router_cap) -{ - struct sr_node *srn; - - if (!router_cap || router_cap->srgb.range_size == 0) - return NULL; - - sr_debug("ISIS-Sr (%s): Parse Router Capability TLV", area->area_tag); - - srn = sr_node_find(area, level, sysid); - if (srn) { - if (router_cap_cmp(&srn->cap, router_cap) != 0) { - srn->state = SRDB_STATE_MODIFIED; - } else - srn->state = SRDB_STATE_UNCHANGED; - sr_debug(" |- Found %s SR Node %s", - srn->state == SRDB_STATE_MODIFIED ? "Modified" - : "Unchanged", - sysid_print(srn->sysid)); - } else { - srn = sr_node_add(area, level, sysid); - srn->state = SRDB_STATE_NEW; - } - - /* - * Update Router Capabilities in any case as SRLB or MSD - * modification are not take into account for comparison. - */ - srn->cap = *router_cap; - - return srn; -} - -/** - * Parse list of Prefix-SID Sub-TLVs. - * - * @param srn Segment Routing Node - * @param prefix Prefix to be parsed - * @param local True if prefix comes from own LSP, false otherwise - * @param prefix_sids Prefix SID subTLVs - */ -static void parse_prefix_sid_subtlvs(struct sr_node *srn, - union prefixconstptr prefix, bool local, - struct isis_item_list *prefix_sids) -{ - struct isis_area *area = srn->area; - struct isis_item *i; - - sr_debug("ISIS-Sr (%s): Parse Prefix SID TLV", area->area_tag); - - /* Parse list of Prefix SID subTLVs */ - for (i = prefix_sids->head; i; i = i->next) { - struct isis_prefix_sid *psid = (struct isis_prefix_sid *)i; - struct sr_prefix *srp; - - /* Only SPF algorithm is supported right now */ - if (psid->algorithm != SR_ALGORITHM_SPF) - continue; - - /* Compute corresponding Segment Routing Prefix */ - srp = sr_prefix_find_by_node(srn, prefix); - if (srp) { - if (srp->sid.flags != psid->flags - || srp->sid.algorithm != psid->algorithm - || srp->sid.value != psid->value) { - srp->sid = *psid; - srp->state = SRDB_STATE_MODIFIED; - } else if (srp->state == SRDB_STATE_VALIDATED) - srp->state = SRDB_STATE_UNCHANGED; - sr_debug(" |- Found %s Prefix-SID %pFX", - srp->state == SRDB_STATE_MODIFIED - ? "Modified" - : "Unchanged", - &srp->prefix); - - } else { - srp = sr_prefix_add(area, srn, prefix, local, psid); - srp->state = SRDB_STATE_NEW; - } - /* - * Stop the Prefix-SID iteration since we only support the SPF - * algorithm for now. - */ - break; - } -} - -/** - * Parse all SR-related information from the given LSP. - * - * @param area IS-IS area - * @param level IS-IS level - * @param srn Segment Routing Node - * @param lsp IS-IS LSP - */ -static void parse_lsp(struct isis_area *area, int level, struct sr_node **srn, - struct isis_lsp *lsp) -{ - struct isis_item_list *items; - struct isis_item *i; - bool local = lsp->own_lsp; - - /* Check LSP sequence number */ - if (lsp->hdr.seqno == 0) { - zlog_warn("%s: lsp with 0 seq_num - ignore", __func__); - return; - } - - sr_debug("ISIS-Sr (%s): Parse LSP from node %s", area->area_tag, - sysid_print(lsp->hdr.lsp_id)); - - /* Parse the Router Capability TLV. */ - if (*srn == NULL) { - *srn = parse_router_cap_tlv(area, level, lsp->hdr.lsp_id, - lsp->tlvs->router_cap); - if (!*srn) - return; - } - - /* Parse the Extended IP Reachability TLV. */ - items = &lsp->tlvs->extended_ip_reach; - for (i = items->head; i; i = i->next) { - struct isis_extended_ip_reach *ir; - - ir = (struct isis_extended_ip_reach *)i; - if (!ir->subtlvs) - continue; - - parse_prefix_sid_subtlvs(*srn, &ir->prefix, local, - &ir->subtlvs->prefix_sids); - } - - /* Parse Multi Topology Reachable IPv6 Prefixes TLV. */ - items = isis_lookup_mt_items(&lsp->tlvs->mt_ipv6_reach, - ISIS_MT_IPV6_UNICAST); - for (i = items ? items->head : NULL; i; i = i->next) { - struct isis_ipv6_reach *ir; - - ir = (struct isis_ipv6_reach *)i; - if (!ir->subtlvs) - continue; - - parse_prefix_sid_subtlvs(*srn, &ir->prefix, local, - &ir->subtlvs->prefix_sids); - } -} - -/** - * Parse all SR-related information from the entire LSPDB. - * - * @param area IS-IS area - */ -static void parse_lspdb(struct isis_area *area) -{ - struct isis_lsp *lsp; - - sr_debug("ISIS-Sr (%s): Parse LSP Data Base", area->area_tag); - - /* Process all LSP from Level 1 & 2 */ - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { - frr_each (lspdb, &area->lspdb[level - 1], lsp) { - struct isis_lsp *frag; - struct listnode *node; - struct sr_node *srn = NULL; - - /* Skip Pseudo ID LSP and LSP without TLVs */ - if (LSP_PSEUDO_ID(lsp->hdr.lsp_id)) - continue; - if (!lsp->tlvs) - continue; - - /* Parse LSP, then fragment */ - parse_lsp(area, level, &srn, lsp); - for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) - parse_lsp(area, level, &srn, frag); - } - } -} - -/** - * Process any new/deleted/modified Prefix-SID in the LSPDB. - * - * @param srn Segment Routing Node - * @param srp Segment Routing Prefix - */ -static void process_prefix_changes(struct sr_node *srn, struct sr_prefix *srp) -{ - struct isis_area *area = srn->area; - - /* Install/reinstall/uninstall Prefix-SID if necessary. */ - switch (srp->state) { - case SRDB_STATE_NEW: - sr_debug("ISIS-Sr (%s): Created Prefix-SID %pFX for SR node %s", - area->area_tag, &srp->prefix, sysid_print(srn->sysid)); - sr_prefix_install(srp); - break; - case SRDB_STATE_MODIFIED: - sr_debug( - "ISIS-Sr (%s): Modified Prefix-SID %pFX for SR node %s", - area->area_tag, &srp->prefix, sysid_print(srn->sysid)); - sr_prefix_reinstall(srp, false); - break; - case SRDB_STATE_UNCHANGED: - break; - default: - sr_debug("ISIS-Sr (%s): Removed Prefix-SID %pFX for SR node %s", - area->area_tag, &srp->prefix, sysid_print(srn->sysid)); - sr_prefix_del(area, srn, srp); - return; - } - - /* Validate SRDB State for next LSPDB parsing */ - srp->state = SRDB_STATE_VALIDATED; -} - -/** - * Process any new/deleted/modified SRGB in the LSPDB. + * Delete all backup Adj-SIDs. * * @param area IS-IS area * @param level IS-IS level - * @param srn Segment Routing Node */ -static void process_node_changes(struct isis_area *area, int level, - struct sr_node *srn) +void isis_area_delete_backup_adj_sids(struct isis_area *area, int level) { - struct sr_prefix *srp; - uint8_t sysid[ISIS_SYS_ID_LEN]; - bool adjacent; - - memcpy(sysid, srn->sysid, sizeof(sysid)); - - /* - * If an neighbor router's SRGB was changed or created, then reinstall - * all Prefix-SIDs from all nodes that use this neighbor as nexthop. - */ - adjacent = !!isis_adj_find(area, level, sysid); - switch (srn->state) { - case SRDB_STATE_NEW: - case SRDB_STATE_MODIFIED: - sr_debug("ISIS-Sr (%s): Create/Update SR node %s", - area->area_tag, sysid_print(srn->sysid)); - if (adjacent) - sr_node_srgb_update(area, level, sysid); - break; - case SRDB_STATE_UNCHANGED: - break; - default: - /* SR capabilities have been removed. Delete SR-Node */ - sr_debug("ISIS-Sr (%s): Remove SR node %s", area->area_tag, - sysid_print(srn->sysid)); - - sr_node_del(area, level, srn); - /* and Update remaining Prefix-SID from all remaining SR Node */ - if (adjacent) - sr_node_srgb_update(area, level, sysid); - return; - } - - /* Validate SRDB State for next LSPDB parsing */ - srn->state = SRDB_STATE_VALIDATED; - - /* Finally, process all Prefix-SID of this SR Node */ - frr_each_safe (srdb_node_prefix, &srn->prefix_sids, srp) - process_prefix_changes(srn, srp); -} - -/** - * Parse and process all SR-related Sub-TLVs after running the SPF algorithm. - * - * @param area IS-IS area - */ -void isis_area_verify_sr(struct isis_area *area) -{ - struct sr_node *srn; - - if (!area->srdb.enabled) - return; - - /* Parse LSPDB to detect new/deleted/modified SR (sub-)TLVs. */ - parse_lspdb(area); - - /* Process possible SR-related changes in the LDPSB. */ - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { - frr_each_safe (srdb_node, &area->srdb.sr_nodes[level - 1], srn) - process_node_changes(area, level, srn); - } -} - -/** - * Once a route is updated in the SPT, reinstall or uninstall its corresponding - * Prefix-SID (if any). - * - * @param area IS-IS area - * @param prefix Prefix to be updated - * @param route_info New Route Information - * - * @return 0 - */ -static int sr_route_update(struct isis_area *area, struct prefix *prefix, - struct isis_route_info *route_info) -{ - struct sr_prefix *srp; - - if (!area->srdb.enabled) - return 0; - - sr_debug("ISIS-Sr (%s): Update route for prefix %pFX", area->area_tag, - prefix); - - /* Lookup to Segment Routing Prefix for this prefix */ - switch (area->is_type) { - case IS_LEVEL_1: - srp = sr_prefix_find_by_area(area, ISIS_LEVEL1, prefix); - break; - case IS_LEVEL_2: - srp = sr_prefix_find_by_area(area, ISIS_LEVEL2, prefix); - break; - case IS_LEVEL_1_AND_2: - srp = sr_prefix_find_by_area(area, ISIS_LEVEL1, prefix); - if (!srp) - srp = sr_prefix_find_by_area(area, ISIS_LEVEL2, prefix); - break; - default: - flog_err(EC_LIB_DEVELOPMENT, "%s: unknown area level", - __func__); - exit(1); - } - - /* Skip NULL or local Segment Routing Prefix */ - if (!srp || srp->type == ISIS_SR_PREFIX_LOCAL) - return 0; - - /* Install or unintall Prefix-SID if route is Active or not */ - if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) { - /* - * The Prefix-SID input label hasn't changed. We could use the - * "Make Before Break" option. Zebra layer will update output - * label by adding new label(s) before removing old one(s). - */ - sr_prefix_reinstall(srp, true); - srp->u.remote.rinfo = route_info; - } else { - sr_prefix_uninstall(srp); - srp->u.remote.rinfo = NULL; - } + struct sr_adjacency *sra; + struct listnode *node, *nnode; - return 0; + for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra)) + if (sra->type == ISIS_SR_LAN_BACKUP + && (sra->adj->level & level)) + sr_adj_sid_del(sra); } /* --- Segment Routing Local Block management functions --------------------- */ @@ -1499,12 +628,13 @@ static int sr_local_block_release_label(struct sr_local_block *srlb, /** * Add new local Adjacency-SID. * - * @param adj IS-IS Adjacency - * @param family Inet Family (IPv4 or IPv6) - * @param backup True to initialize backup Adjacency SID + * @param adj IS-IS Adjacency + * @param family Inet Family (IPv4 or IPv6) + * @param backup True to initialize backup Adjacency SID + * @param nexthops List of backup nexthops (for backup Adj-SIDs only) */ -static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, - bool backup) +void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup, + struct list *nexthops) { struct isis_circuit *circuit = adj->circuit; struct isis_area *area = circuit->area; @@ -1555,9 +685,25 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, sra = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*sra)); sra->type = backup ? ISIS_SR_LAN_BACKUP : ISIS_SR_ADJ_NORMAL; + sra->input_label = input_label; sra->nexthop.family = family; sra->nexthop.address = nexthop; - sra->nexthop.label = input_label; + + if (backup && nexthops) { + struct isis_vertex_adj *vadj; + struct listnode *node; + + sra->backup_nexthops = list_new(); + for (ALL_LIST_ELEMENTS_RO(nexthops, node, vadj)) { + struct isis_adjacency *adj = vadj->sadj->adj; + struct mpls_label_stack *label_stack; + + label_stack = vadj->label_stack; + adjinfo2nexthop(family, sra->backup_nexthops, adj, NULL, + label_stack); + } + } + switch (circuit->circ_type) { /* LAN Adjacency-SID for Broadcast interface section #2.2.2 */ case CIRCUIT_T_BROADCAST: @@ -1603,8 +749,7 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, */ static void sr_adj_sid_add(struct isis_adjacency *adj, int family) { - sr_adj_sid_add_single(adj, family, false); - sr_adj_sid_add_single(adj, family, true); + sr_adj_sid_add_single(adj, family, false, NULL); } static void sr_adj_sid_update(struct sr_adjacency *sra, @@ -1616,16 +761,16 @@ static void sr_adj_sid_update(struct sr_adjacency *sra, isis_zebra_send_adjacency_sid(ZEBRA_MPLS_LABELS_DELETE, sra); /* Got new label in the new SRLB */ - sra->nexthop.label = sr_local_block_request_label(srlb); - if (sra->nexthop.label == MPLS_INVALID_LABEL) + sra->input_label = sr_local_block_request_label(srlb); + if (sra->input_label == MPLS_INVALID_LABEL) return; switch (circuit->circ_type) { case CIRCUIT_T_BROADCAST: - sra->u.ladj_sid->sid = sra->nexthop.label; + sra->u.ladj_sid->sid = sra->input_label; break; case CIRCUIT_T_P2P: - sra->u.adj_sid->sid = sra->nexthop.label; + sra->u.adj_sid->sid = sra->input_label; break; default: flog_warn(EC_LIB_DEVELOPMENT, "%s: unexpected circuit type: %u", @@ -1669,6 +814,12 @@ static void sr_adj_sid_del(struct sr_adjacency *sra) exit(1); } + if (sra->type == ISIS_SR_LAN_BACKUP && sra->backup_nexthops) { + sra->backup_nexthops->del = + (void (*)(void *))isis_nexthop_delete; + list_delete(&sra->backup_nexthops); + } + /* Remove Adjacency-SID from the SRDB */ listnode_delete(area->srdb.adj_sids, sra); listnode_delete(sra->adj->adj_sids, sra); @@ -1676,6 +827,26 @@ static void sr_adj_sid_del(struct sr_adjacency *sra) } /** + * Lookup Segment Routing Adj-SID by family and type. + * + * @param adj IS-IS Adjacency + * @param family Inet Family (IPv4 or IPv6) + * @param type Adjacency SID type + */ +struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj, + int family, enum sr_adj_type type) +{ + struct sr_adjacency *sra; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(adj->adj_sids, node, sra)) + if (sra->nexthop.family == family && sra->type == type) + return sra; + + return NULL; +} + +/** * Remove all Adjacency-SIDs associated to an adjacency that is going down. * * @param adj IS-IS Adjacency @@ -1778,7 +949,7 @@ static int sr_if_new_hook(struct interface *ifp) continue; if (sr_prefix_is_node_sid(ifp, &pcfg->prefix) - && !pcfg->node_sid) { + && !pcfg->n_flag_clear) { pcfg->node_sid = true; lsp_regenerate_schedule(area, area->is_type, 0); } @@ -1787,20 +958,18 @@ static int sr_if_new_hook(struct interface *ifp) return 0; } -/* --- Segment Routing Show information functions --------------------------- */ - /** * Show LFIB operation in human readable format. * - * @param buf Buffer to store string output. Must be pre-allocate - * @param size Size of the buffer - * @param label_in Input Label - * @param label_out Output Label + * @param buf Buffer to store string output. Must be pre-allocate + * @param size Size of the buffer + * @param label_in Input Label + * @param label_out Output Label * * @return String containing LFIB operation in human readable format */ -static char *sr_op2str(char *buf, size_t size, mpls_label_t label_in, - mpls_label_t label_out) +char *sr_op2str(char *buf, size_t size, mpls_label_t label_in, + mpls_label_t label_out) { if (size < 24) return NULL; @@ -1829,205 +998,6 @@ static char *sr_op2str(char *buf, size_t size, mpls_label_t label_in, } /** - * Show Local Prefix-SID. - * - * @param vty VTY output - * @param tt Table format - * @param area IS-IS area - * @param srp Segment Routing Prefix - */ -static void show_prefix_sid_local(struct vty *vty, struct ttable *tt, - const struct isis_area *area, - const struct sr_prefix *srp) -{ - const struct sr_nexthop_info *srnh = &srp->u.local.info; - char buf_prefix[BUFSIZ]; - char buf_oper[BUFSIZ]; - char buf_iface[BUFSIZ]; - char buf_uptime[BUFSIZ]; - - if (srnh->label != MPLS_INVALID_LABEL) { - struct interface *ifp; - ifp = if_lookup_prefix(&srp->prefix, VRF_DEFAULT); - if (ifp) - strlcpy(buf_iface, ifp->name, sizeof(buf_iface)); - else - snprintf(buf_iface, sizeof(buf_iface), "-"); - log_uptime(srnh->uptime, buf_uptime, sizeof(buf_uptime)); - } else { - snprintf(buf_iface, sizeof(buf_iface), "-"); - snprintf(buf_uptime, sizeof(buf_uptime), "-"); - } - sr_op2str(buf_oper, sizeof(buf_oper), srp->input_label, - MPLS_LABEL_IMPLICIT_NULL); - - ttable_add_row(tt, "%s|%u|%s|-|%s|%s", - prefix2str(&srp->prefix, buf_prefix, sizeof(buf_prefix)), - srp->sid.value, buf_oper, buf_iface, buf_uptime); -} - -/** - * Show Remote Prefix-SID. - * - * @param vty VTY output - * @param tt Table format - * @param area IS-IS area - * @param srp Segment Routing Prefix - */ -static void show_prefix_sid_remote(struct vty *vty, struct ttable *tt, - const struct isis_area *area, - const struct sr_prefix *srp) -{ - struct isis_nexthop *nexthop; - struct listnode *node; - char buf_prefix[BUFSIZ]; - char buf_oper[BUFSIZ]; - char buf_nhop[BUFSIZ]; - char buf_iface[BUFSIZ]; - char buf_uptime[BUFSIZ]; - bool first = true; - - (void)prefix2str(&srp->prefix, buf_prefix, sizeof(buf_prefix)); - - if (!srp->u.remote.rinfo) { - ttable_add_row(tt, "%s|%u|%s|-|-|-", buf_prefix, srp->sid.value, - sr_op2str(buf_oper, sizeof(buf_oper), - srp->input_label, - MPLS_LABEL_IMPLICIT_NULL)); - return; - } - - for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node, - nexthop)) { - struct interface *ifp; - - inet_ntop(nexthop->family, &nexthop->ip, buf_nhop, - sizeof(buf_nhop)); - ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); - if (ifp) - strlcpy(buf_iface, ifp->name, sizeof(buf_iface)); - else - snprintf(buf_iface, sizeof(buf_iface), "ifindex %u", - nexthop->ifindex); - if (nexthop->sr.label == MPLS_INVALID_LABEL) - snprintf(buf_uptime, sizeof(buf_uptime), "-"); - else - log_uptime(nexthop->sr.uptime, buf_uptime, - sizeof(buf_uptime)); - sr_op2str(buf_oper, sizeof(buf_oper), srp->input_label, - nexthop->sr.label); - - if (first) - ttable_add_row(tt, "%s|%u|%s|%s|%s|%s", buf_prefix, - srp->sid.value, buf_oper, buf_nhop, - buf_iface, buf_uptime); - else - ttable_add_row(tt, "|||%s|%s|%s|%s", buf_oper, buf_nhop, - buf_iface, buf_uptime); - first = false; - } -} - -/** - * Show Prefix-SIDs. - * - * @param vty VTY output - * @param area IS-IS area - * @param level IS-IS level - */ -static void show_prefix_sids(struct vty *vty, struct isis_area *area, int level) -{ - struct sr_prefix *srp; - struct ttable *tt; - - if (srdb_area_prefix_count(&area->srdb.prefix_sids[level - 1]) == 0) - return; - - vty_out(vty, " IS-IS %s Prefix-SIDs:\n\n", circuit_t2string(level)); - - /* Prepare table. */ - tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); - ttable_add_row(tt, "Prefix|SID|Label Op.|Nexthop|Interface|Uptime"); - tt->style.cell.rpad = 2; - tt->style.corner = '+'; - ttable_restyle(tt); - ttable_rowseps(tt, 0, BOTTOM, true, '-'); - - /* Process all Prefix-SID from the SRDB */ - frr_each (srdb_area_prefix, &area->srdb.prefix_sids[level - 1], srp) { - switch (srp->type) { - case ISIS_SR_PREFIX_LOCAL: - show_prefix_sid_local(vty, tt, area, srp); - break; - case ISIS_SR_PREFIX_REMOTE: - show_prefix_sid_remote(vty, tt, area, srp); - break; - } - } - - /* Dump the generated table. */ - if (tt->nrows > 1) { - char *table; - - table = ttable_dump(tt, "\n"); - vty_out(vty, "%s\n", table); - XFREE(MTYPE_TMP, table); - } - ttable_del(tt); -} - -/** - * Declaration of new show commands. - */ -DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd, - "show isis [vrf <NAME|all>] segment-routing prefix-sids", - SHOW_STR PROTO_HELP VRF_CMD_HELP_STR - "All VRFs\n" - "Segment-Routing\n" - "Segment-Routing Prefix-SIDs\n") -{ - struct listnode *node, *inode; - struct isis_area *area; - struct isis *isis = NULL; - const char *vrf_name = VRF_DEFAULT_NAME; - bool all_vrf = false; - int idx_vrf = 0; - - ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, - area)) { - vty_out(vty, "Area %s:\n", - area->area_tag ? area->area_tag - : "null"); - for (int level = ISIS_LEVEL1; - level <= ISIS_LEVELS; level++) - show_prefix_sids(vty, area, - level); - } - } - return 0; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, - area)) { - vty_out(vty, "Area %s:\n", - area->area_tag ? area->area_tag - : "null"); - for (int level = ISIS_LEVEL1; - level <= ISIS_LEVELS; level++) - show_prefix_sids(vty, area, level); - } - } - } - - return CMD_SUCCESS; -} - -/** * Show Segment Routing Node. * * @param vty VTY output @@ -2036,13 +1006,10 @@ DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd, */ static void show_node(struct vty *vty, struct isis_area *area, int level) { - struct sr_node *srn; + struct isis_lsp *lsp; struct ttable *tt; - if (srdb_area_prefix_count(&area->srdb.prefix_sids[level - 1]) == 0) - return; - - vty_out(vty, " IS-IS %s SR-Node:\n\n", circuit_t2string(level)); + vty_out(vty, " IS-IS %s SR-Nodes:\n\n", circuit_t2string(level)); /* Prepare table. */ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); @@ -2052,19 +1019,23 @@ static void show_node(struct vty *vty, struct isis_area *area, int level) ttable_restyle(tt); ttable_rowseps(tt, 0, BOTTOM, true, '-'); - /* Process all SR-Node from the SRDB */ - frr_each (srdb_node, &area->srdb.sr_nodes[level - 1], srn) { + frr_each (lspdb, &area->lspdb[level - 1], lsp) { + struct isis_router_cap *cap; + + if (!lsp->tlvs) + continue; + cap = lsp->tlvs->router_cap; + if (!cap) + continue; + ttable_add_row( tt, "%s|%u - %u|%u - %u|%s|%u", - sysid_print(srn->sysid), - srn->cap.srgb.lower_bound, - srn->cap.srgb.lower_bound + srn->cap.srgb.range_size - - 1, - srn->cap.srlb.lower_bound, - srn->cap.srlb.lower_bound + srn->cap.srlb.range_size - - 1, - srn->cap.algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF", - srn->cap.msd); + sysid_print(lsp->hdr.lsp_id), cap->srgb.lower_bound, + cap->srgb.lower_bound + cap->srgb.range_size - 1, + cap->srlb.lower_bound, + cap->srlb.lower_bound + cap->srlb.range_size - 1, + cap->algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF", + cap->msd); } /* Dump the generated table. */ @@ -2102,7 +1073,6 @@ DEFUN(show_sr_node, show_sr_node_cmd, return CMD_SUCCESS; } - /* --- IS-IS Segment Routing Management function ---------------------------- */ /** @@ -2202,22 +1172,12 @@ void isis_sr_stop(struct isis_area *area) area->area_tag); /* Disable any re-attempt to connect to Label Manager */ - THREAD_TIMER_OFF(srdb->t_start_lm); + thread_cancel(&srdb->t_start_lm); /* Uninstall all local Adjacency-SIDs. */ for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra)) sr_adj_sid_del(sra); - /* Uninstall all Prefix-SIDs from all SR Node. */ - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { - while (srdb_node_count(&srdb->sr_nodes[level - 1]) > 0) { - struct sr_node *srn; - - srn = srdb_node_first(&srdb->sr_nodes[level - 1]); - sr_node_del(area, level, srn); - } - } - /* Release SRGB if active. */ if (srdb->srgb_active) { isis_zebra_release_label_range(srdb->config.srgb_lower_bound, @@ -2250,11 +1210,6 @@ void isis_sr_area_init(struct isis_area *area) memset(srdb, 0, sizeof(*srdb)); srdb->adj_sids = list_new(); - for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { - srdb_node_init(&srdb->sr_nodes[level - 1]); - srdb_area_prefix_init(&srdb->prefix_sids[level - 1]); - } - /* Pull defaults from the YANG module. */ #ifndef FABRICD srdb->config.enabled = yang_get_default_bool("%s/enabled", ISIS_SR); @@ -2304,14 +1259,12 @@ void isis_sr_area_term(struct isis_area *area) */ void isis_sr_init(void) { - install_element(VIEW_NODE, &show_sr_prefix_sids_cmd); install_element(VIEW_NODE, &show_sr_node_cmd); /* Register hooks. */ hook_register(isis_adj_state_change_hook, sr_adj_state_change); hook_register(isis_adj_ip_enabled_hook, sr_adj_ip_enabled); hook_register(isis_adj_ip_disabled_hook, sr_adj_ip_disabled); - hook_register(isis_route_update_hook, sr_route_update); hook_register(isis_if_new_hook, sr_if_new_hook); } @@ -2324,6 +1277,5 @@ void isis_sr_term(void) hook_unregister(isis_adj_state_change_hook, sr_adj_state_change); hook_unregister(isis_adj_ip_enabled_hook, sr_adj_ip_enabled); hook_unregister(isis_adj_ip_disabled_hook, sr_adj_ip_disabled); - hook_unregister(isis_route_update_hook, sr_route_update); hook_unregister(isis_if_new_hook, sr_if_new_hook); } diff --git a/isisd/isis_sr.h b/isisd/isis_sr.h index 4379a1dcba..b012dfb00a 100644 --- a/isisd/isis_sr.h +++ b/isisd/isis_sr.h @@ -57,11 +57,25 @@ #define SRLB_UPPER_BOUND 15999 /* Segment Routing Data Base (SRDB) RB-Tree structure */ -PREDECL_RBTREE_UNIQ(srdb_node) -PREDECL_RBTREE_UNIQ(srdb_node_prefix) -PREDECL_RBTREE_UNIQ(srdb_area_prefix) PREDECL_RBTREE_UNIQ(srdb_prefix_cfg) +/* + * Segment Routing Prefix-SID information. + * + * This structure is intended to be embedded inside other structures that + * might or might not contain Prefix-SID information. + */ +struct isis_sr_psid_info { + /* Prefix-SID Sub-TLV information. */ + struct isis_prefix_sid sid; + + /* Resolved input/output label. */ + mpls_label_t label; + + /* Indicates whether the Prefix-SID is present or not. */ + bool present; +}; + /* Segment Routing Local Block allocation */ struct sr_local_block { bool active; @@ -84,13 +98,18 @@ struct sr_adjacency { /* Adjacency type. */ enum sr_adj_type type; + /* Adjacency-SID input label. */ + mpls_label_t input_label; + /* Adjacency-SID nexthop information. */ struct { int family; union g_addr address; - mpls_label_t label; } nexthop; + /* Adjacency-SID TI-LFA backup nexthops. */ + struct list *backup_nexthops; + /* (LAN-)Adjacency-SID Sub-TLV. */ union { struct isis_adj_sid *adj_sid; @@ -101,85 +120,6 @@ struct sr_adjacency { struct isis_adjacency *adj; }; -/* Segment Routing Prefix-SID type. */ -enum sr_prefix_type { - ISIS_SR_PREFIX_LOCAL = 0, - ISIS_SR_PREFIX_REMOTE, -}; - -/* Segment Routing Nexthop Information. */ -struct sr_nexthop_info { - mpls_label_t label; - time_t uptime; -}; - -/* State of Object (SR-Node and SR-Prefix) stored in SRDB */ -enum srdb_state { - SRDB_STATE_VALIDATED = 0, - SRDB_STATE_NEW, - SRDB_STATE_MODIFIED, - SRDB_STATE_UNCHANGED -}; - -/* Segment Routing Prefix-SID. */ -struct sr_prefix { - /* SRDB RB-tree entries. */ - struct srdb_node_prefix_item node_entry; - struct srdb_area_prefix_item area_entry; - - /* IP prefix. */ - struct prefix prefix; - - /* SID value, algorithm and flags subTLVs. */ - struct isis_prefix_sid sid; - - /* Input label value. */ - mpls_label_t input_label; - - /* Prefix-SID type. */ - enum sr_prefix_type type; - union { - struct { - /* Information about this local Prefix-SID. */ - struct sr_nexthop_info info; - } local; - struct { - /* Route associated to this remote Prefix-SID. */ - struct isis_route_info *rinfo; - } remote; - } u; - - /* Backpointer to Segment Routing node. */ - struct sr_node *srn; - - /* SR-Prefix State used while the LSPDB is being parsed. */ - enum srdb_state state; -}; - -/* Segment Routing node. */ -struct sr_node { - /* SRDB RB-tree entry. */ - struct srdb_node_item entry; - - /* IS-IS level: ISIS_LEVEL1 or ISIS_LEVEL2. */ - int level; - - /* IS-IS node identifier. */ - uint8_t sysid[ISIS_SYS_ID_LEN]; - - /* Segment Routing node capabilities (SRGB, SR Algorithms) subTLVs. */ - struct isis_router_cap cap; - - /* List of Prefix-SIDs advertised by this node. */ - struct srdb_node_prefix_head prefix_sids; - - /* Backpointer to IS-IS area. */ - struct isis_area *area; - - /* SR-Node State used while the LSPDB is being parsed. */ - enum srdb_state state; -}; - /* SID type. NOTE: these values must be in sync with the YANG module. */ enum sr_sid_value_type { SR_SID_VALUE_TYPE_INDEX = 0, @@ -212,6 +152,9 @@ struct sr_prefix_cfg { /* SID last hop behavior. */ enum sr_last_hop_behavior last_hop_behavior; + /* Indicates whether the node flag must be explicitly unset. */ + bool n_flag_clear; + /* Does this Prefix-SID refer to a loopback address (Node-SID)? */ bool node_sid; @@ -230,12 +173,6 @@ struct isis_sr_db { /* List of local Adjacency-SIDs. */ struct list *adj_sids; - /* Segment Routing Node information per IS-IS level. */ - struct srdb_node_head sr_nodes[ISIS_LEVELS]; - - /* Segment Routing Prefix-SIDs per IS-IS level. */ - struct srdb_area_prefix_head prefix_sids[ISIS_LEVELS]; - /* Management of SRLB & SRGB allocation */ struct sr_local_block srlb; bool srgb_active; @@ -262,6 +199,14 @@ struct isis_sr_db { }; /* Prototypes. */ +extern struct isis_sr_block *isis_sr_find_srgb(struct lspdb_head *lspdb, + const uint8_t *sysid); +extern mpls_label_t sr_prefix_in_label(struct isis_area *area, + struct isis_prefix_sid *psid, + bool local); +extern mpls_label_t sr_prefix_out_label(struct lspdb_head *lspdb, int family, + struct isis_prefix_sid *psid, + const uint8_t *nh_sysid, bool last_hop); extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound, uint32_t upper_bound); extern int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound, @@ -274,10 +219,14 @@ isis_sr_cfg_prefix_find(struct isis_area *area, union prefixconstptr prefix); extern void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, bool external, struct isis_prefix_sid *psid); -extern void isis_sr_nexthop_update(struct sr_nexthop_info *srnh, - mpls_label_t label); -extern void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh); -extern void isis_area_verify_sr(struct isis_area *area); +extern void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, + bool backup, struct list *nexthops); +extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj, + int family, + enum sr_adj_type type); +extern void isis_area_delete_backup_adj_sids(struct isis_area *area, int level); +extern char *sr_op2str(char *buf, size_t size, mpls_label_t label_in, + mpls_label_t label_out); extern int isis_sr_start(struct isis_area *area); extern void isis_sr_stop(struct isis_area *area); extern void isis_sr_area_init(struct isis_area *area); diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 87c4428155..8daa2b36bf 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -336,10 +336,8 @@ DEFUN(show_isis_mpls_te_router, if (ntohs(area->mta->router_id.s_addr) != 0) vty_out(vty, - " MPLS-TE Router-Address: %s\n", - inet_ntoa( - area->mta - ->router_id)); + " MPLS-TE Router-Address: %pI4\n", + &area->mta->router_id); else vty_out(vty, " N/A\n"); } @@ -357,9 +355,8 @@ DEFUN(show_isis_mpls_te_router, vty_out(vty, "Area %s:\n", area->area_tag); if (ntohs(area->mta->router_id.s_addr) != 0) vty_out(vty, - " MPLS-TE Router-Address: %s\n", - inet_ntoa( - area->mta->router_id)); + " MPLS-TE Router-Address: %pI4\n", + &area->mta->router_id); else vty_out(vty, " N/A\n"); } @@ -394,11 +391,11 @@ static void show_ext_sub(struct vty *vty, char *name, ext->remote_llri); } if (IS_SUBTLV(ext, EXT_LOCAL_ADDR)) - sbuf_push(&buf, 4, "Local Interface IP Address(es): %s\n", - inet_ntoa(ext->local_addr)); + sbuf_push(&buf, 4, "Local Interface IP Address(es): %pI4\n", + &ext->local_addr); if (IS_SUBTLV(ext, EXT_NEIGH_ADDR)) - sbuf_push(&buf, 4, "Remote Interface IP Address(es): %s\n", - inet_ntoa(ext->neigh_addr)); + sbuf_push(&buf, 4, "Remote Interface IP Address(es): %pI4\n", + &ext->neigh_addr); if (IS_SUBTLV(ext, EXT_LOCAL_ADDR6)) sbuf_push(&buf, 4, "Local Interface IPv6 Address(es): %s\n", inet_ntop(AF_INET6, &ext->local_addr6, ibuf, @@ -432,8 +429,8 @@ static void show_ext_sub(struct vty *vty, char *name, ext->remote_as); if (IS_SUBTLV(ext, EXT_RMT_IP)) sbuf_push(&buf, 4, - "Inter-AS TE Remote ASBR IP address: %s\n", - inet_ntoa(ext->remote_ip)); + "Inter-AS TE Remote ASBR IP address: %pI4\n", + &ext->remote_ip); if (IS_SUBTLV(ext, EXT_DELAY)) sbuf_push(&buf, 4, "%s Average Link Delay: %u (micro-sec)\n", diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index a1f9cc236f..af419961d5 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -209,11 +209,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, exts->remote_llri); } if (IS_SUBTLV(exts, EXT_LOCAL_ADDR)) - sbuf_push(buf, indent, "Local Interface IP Address(es): %s\n", - inet_ntoa(exts->local_addr)); + sbuf_push(buf, indent, "Local Interface IP Address(es): %pI4\n", + &exts->local_addr); if (IS_SUBTLV(exts, EXT_NEIGH_ADDR)) - sbuf_push(buf, indent, "Remote Interface IP Address(es): %s\n", - inet_ntoa(exts->neigh_addr)); + sbuf_push(buf, indent, "Remote Interface IP Address(es): %pI4\n", + &exts->neigh_addr); if (IS_SUBTLV(exts, EXT_LOCAL_ADDR6)) sbuf_push(buf, indent, "Local Interface IPv6 Address(es): %s\n", inet_ntop(AF_INET6, &exts->local_addr6, ibuf, @@ -247,8 +247,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, exts->remote_as); if (IS_SUBTLV(exts, EXT_RMT_IP)) sbuf_push(buf, indent, - "Inter-AS TE Remote ASBR IP address: %s\n", - inet_ntoa(exts->remote_ip)); + "Inter-AS TE Remote ASBR IP address: %pI4\n", + &exts->remote_ip); /* Extended metrics */ if (IS_SUBTLV(exts, EXT_DELAY)) sbuf_push(buf, indent, @@ -2400,11 +2400,11 @@ static int unpack_tlv_threeway_adj(enum isis_tlv_context context, } /* Functions related to TLVs 236/237 IPv6/MT-IPv6 reach */ - static struct isis_item *copy_item_ipv6_reach(struct isis_item *i) { struct isis_ipv6_reach *r = (struct isis_ipv6_reach *)i; struct isis_ipv6_reach *rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + rv->metric = r->metric; rv->down = r->down; rv->external = r->external; @@ -2573,11 +2573,13 @@ out: static struct isis_router_cap *copy_tlv_router_cap( const struct isis_router_cap *router_cap) { - struct isis_router_cap *rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + struct isis_router_cap *rv; if (!router_cap) return NULL; + rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + memcpy(rv, router_cap, sizeof(*rv)); return rv; @@ -2603,8 +2605,8 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap, sbuf_push( buf, indent, " Segment Routing: I:%s V:%s, Global Block Base: %u Range: %u\n", - IS_SR_IPV4(router_cap->srgb) ? "1" : "0", - IS_SR_IPV6(router_cap->srgb) ? "1" : "0", + IS_SR_IPV4(&router_cap->srgb) ? "1" : "0", + IS_SR_IPV6(&router_cap->srgb) ? "1" : "0", router_cap->srgb.lower_bound, router_cap->srgb.range_size); @@ -4412,11 +4414,19 @@ static void tlvs_area_addresses_to_adj(struct isis_tlvs *tlvs, bool *changed) { if (adj->area_address_count != tlvs->area_addresses.count) { + uint32_t oc = adj->area_address_count; + *changed = true; adj->area_address_count = tlvs->area_addresses.count; adj->area_addresses = XREALLOC( MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses, adj->area_address_count * sizeof(*adj->area_addresses)); + + for (; oc < adj->area_address_count; oc++) { + adj->area_addresses[oc].addr_len = 0; + memset(&adj->area_addresses[oc].area_addr, 0, + sizeof(adj->area_addresses[oc].area_addr)); + } } struct isis_area_address *addr = NULL; @@ -4494,11 +4504,18 @@ static void tlvs_ipv4_addresses_to_adj(struct isis_tlvs *tlvs, hook_call(isis_adj_ip_disabled_hook, adj, AF_INET); if (adj->ipv4_address_count != tlvs->ipv4_address.count) { + uint32_t oc = adj->ipv4_address_count; + *changed = true; adj->ipv4_address_count = tlvs->ipv4_address.count; adj->ipv4_addresses = XREALLOC( MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses, adj->ipv4_address_count * sizeof(*adj->ipv4_addresses)); + + for (; oc < adj->ipv4_address_count; oc++) { + memset(&adj->ipv4_addresses[oc], 0, + sizeof(adj->ipv4_addresses[oc])); + } } struct isis_ipv4_address *addr = NULL; @@ -4533,11 +4550,18 @@ static void tlvs_ipv6_addresses_to_adj(struct isis_tlvs *tlvs, hook_call(isis_adj_ip_disabled_hook, adj, AF_INET6); if (adj->ipv6_address_count != tlvs->ipv6_address.count) { + uint32_t oc = adj->ipv6_address_count; + *changed = true; adj->ipv6_address_count = tlvs->ipv6_address.count; adj->ipv6_addresses = XREALLOC( MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses, adj->ipv6_address_count * sizeof(*adj->ipv6_addresses)); + + for (; oc < adj->ipv6_address_count; oc++) { + memset(&adj->ipv6_addresses[oc], 0, + sizeof(adj->ipv6_addresses[oc])); + } } struct isis_ipv6_address *addr = NULL; diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 1c0d97f2c3..54ded8121d 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -138,8 +138,8 @@ struct isis_threeway_adj { /* Segment Routing subTLV's as per RFC8667 */ #define ISIS_SUBTLV_SRGB_FLAG_I 0x80 #define ISIS_SUBTLV_SRGB_FLAG_V 0x40 -#define IS_SR_IPV4(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I) -#define IS_SR_IPV6(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_V) +#define IS_SR_IPV4(srgb) ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_I) +#define IS_SR_IPV6(srgb) ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_V) #define SUBTLV_SR_BLOCK_SIZE 6 #define SUBTLV_RANGE_INDEX_SIZE 10 #define SUBTLV_RANGE_LABEL_SIZE 9 diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c index 1424b55bdc..5c87e39157 100644 --- a/isisd/isis_tx_queue.c +++ b/isisd/isis_tx_queue.c @@ -93,8 +93,7 @@ static void tx_queue_element_free(void *element) { struct isis_tx_queue_entry *e = element; - if (e->retry) - thread_cancel(e->retry); + thread_cancel(&(e->retry)); XFREE(MTYPE_TX_QUEUE_ENTRY, e); } @@ -166,8 +165,7 @@ void _isis_tx_queue_add(struct isis_tx_queue *queue, e->type = type; - if (e->retry) - thread_cancel(e->retry); + thread_cancel(&(e->retry)); thread_add_event(master, tx_queue_send_event, e, 0, &e->retry); e->is_retry = false; @@ -190,8 +188,7 @@ void _isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp, func, file, line); } - if (e->retry) - thread_cancel(e->retry); + thread_cancel(&(e->retry)); hash_release(queue->hash, e); XFREE(MTYPE_TX_QUEUE_ENTRY, e); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 15b51589ae..805ede1e44 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -85,9 +85,8 @@ static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS) static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS) { + struct isis_circuit *circuit; struct connected *c; - struct prefix *p; - char buf[PREFIX2STR_BUFFER]; c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf, vrf_id); @@ -95,29 +94,26 @@ static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS) if (c == NULL) return 0; - p = c->address; - - prefix2str(p, buf, sizeof(buf)); #ifdef EXTREME_DEBUG if (p->family == AF_INET) - zlog_debug("connected IP address %s", buf); + zlog_debug("connected IP address %pFX", c->address); if (p->family == AF_INET6) - zlog_debug("connected IPv6 address %s", buf); + zlog_debug("connected IPv6 address %pFX", c->address); #endif /* EXTREME_DEBUG */ - if (if_is_operative(c->ifp)) - isis_circuit_add_addr(circuit_scan_by_ifp(c->ifp), c); + + if (if_is_operative(c->ifp)) { + circuit = circuit_scan_by_ifp(c->ifp); + if (circuit) + isis_circuit_add_addr(circuit, c); + } return 0; } static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS) { + struct isis_circuit *circuit; struct connected *c; - struct interface *ifp; -#ifdef EXTREME_DEBUG - struct prefix *p; - char buf[PREFIX2STR_BUFFER]; -#endif /* EXTREME_DEBUG */ c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf, vrf_id); @@ -125,20 +121,19 @@ static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS) if (c == NULL) return 0; - ifp = c->ifp; - #ifdef EXTREME_DEBUG - p = c->address; - prefix2str(p, buf, sizeof(buf)); - if (p->family == AF_INET) - zlog_debug("disconnected IP address %s", buf); + zlog_debug("disconnected IP address %pFX", c->address); if (p->family == AF_INET6) - zlog_debug("disconnected IPv6 address %s", buf); + zlog_debug("disconnected IPv6 address %pFX", c->address); #endif /* EXTREME_DEBUG */ - if (if_is_operative(ifp)) - isis_circuit_del_addr(circuit_scan_by_ifp(ifp), c); + if (if_is_operative(c->ifp)) { + circuit = circuit_scan_by_ifp(c->ifp); + if (circuit) + isis_circuit_del_addr(circuit, c); + } + connected_free(&c); return 0; @@ -159,42 +154,27 @@ static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS) return 0; } -void isis_zebra_route_add_route(struct isis *isis, - struct prefix *prefix, - struct prefix_ipv6 *src_p, - struct isis_route_info *route_info) +enum isis_zebra_nexthop_type { + ISIS_NEXTHOP_MAIN = 0, + ISIS_NEXTHOP_BACKUP, +}; + +static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops, + struct zapi_nexthop zapi_nexthops[], + enum isis_zebra_nexthop_type type, + bool mpls_lsp, uint8_t backup_nhs) { - struct zapi_route api; - struct zapi_nexthop *api_nh; struct isis_nexthop *nexthop; struct listnode *node; int count = 0; - if (zclient->sock < 0) - return; - - memset(&api, 0, sizeof(api)); - api.vrf_id = isis->vrf_id; - api.type = PROTO_TYPE; - api.safi = SAFI_UNICAST; - api.prefix = *prefix; - if (src_p && src_p->prefixlen) { - api.src_prefix = *src_p; - SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX); - } - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = route_info->cost; -#if 0 - SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = route_info->depth; -#endif - /* Nexthops */ - for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) { + for (ALL_LIST_ELEMENTS_RO(nexthops, node, nexthop)) { + struct zapi_nexthop *api_nh; + if (count >= MULTIPATH_NUM) break; - api_nh = &api.nexthops[count]; + api_nh = &zapi_nexthops[count]; if (fabricd) SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK); api_nh->vrf_id = isis->vrf_id; @@ -225,11 +205,97 @@ void isis_zebra_route_add_route(struct isis *isis, } api_nh->ifindex = nexthop->ifindex; + + /* Add MPLS label(s). */ + switch (type) { + case ISIS_NEXTHOP_MAIN: + if (nexthop->sr.present) { + api_nh->label_num = 1; + api_nh->labels[0] = nexthop->sr.label; + } else if (mpls_lsp) + /* + * Do not use non-SR enabled nexthops to prevent + * broken LSPs from being formed. + */ + continue; + break; + case ISIS_NEXTHOP_BACKUP: + if (nexthop->label_stack) { + api_nh->label_num = + nexthop->label_stack->num_labels; + memcpy(api_nh->labels, + nexthop->label_stack->label, + sizeof(mpls_label_t) + * api_nh->label_num); + } else if (mpls_lsp) { + /* + * This is necessary because zebra requires + * the nexthops of MPLS LSPs to be labeled. + */ + api_nh->label_num = 1; + api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL; + } + break; + } + + /* Backup nexthop handling. */ + if (backup_nhs) { + SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP); + /* + * If the backup has multiple nexthops, all of them + * protect the same primary nexthop since ECMP routes + * have no backups. + */ + api_nh->backup_num = backup_nhs; + for (int i = 0; i < backup_nhs; i++) + api_nh->backup_idx[i] = i; + } count++; } - if (!count) + + return count; +} + +void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix, + struct prefix_ipv6 *src_p, + struct isis_route_info *route_info) +{ + struct zapi_route api; + int count = 0; + + if (zclient->sock < 0 || list_isempty(route_info->nexthops)) return; + memset(&api, 0, sizeof(api)); + api.vrf_id = isis->vrf_id; + api.type = PROTO_TYPE; + api.safi = SAFI_UNICAST; + api.prefix = *prefix; + if (src_p && src_p->prefixlen) { + api.src_prefix = *src_p; + SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX); + } + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = route_info->cost; + + /* Add backup nexthops first. */ + if (route_info->backup) { + count = isis_zebra_add_nexthops( + isis, route_info->backup->nexthops, api.backup_nexthops, + ISIS_NEXTHOP_BACKUP, false, 0); + if (count > 0) { + SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS); + api.backup_nexthop_num = count; + } + } + + /* Add primary nexthops. */ + count = isis_zebra_add_nexthops(isis, route_info->nexthops, + api.nexthops, ISIS_NEXTHOP_MAIN, false, + count); + if (!count) + return; api.nexthop_num = count; zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); @@ -259,30 +325,39 @@ void isis_zebra_route_del_route(struct isis *isis, } /** - * Install Prefix-SID in the forwarding plane through Zebra. + * Install Prefix-SID label entry in the forwarding plane through Zebra. * - * @param srp Segment Routing Prefix-SID + * @param area IS-IS area + * @param prefix Route prefix + * @param rinfo Route information + * @param psid Prefix-SID information */ -static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp) +void isis_zebra_prefix_sid_install(struct isis_area *area, + struct prefix *prefix, + struct isis_route_info *rinfo, + struct isis_sr_psid_info *psid) { struct zapi_labels zl; - struct zapi_nexthop *znh; - struct listnode *node; - struct isis_nexthop *nexthop; - struct interface *ifp; + int count = 0; + + sr_debug("ISIS-Sr (%s): update label %u for prefix %pFX", + area->area_tag, psid->label, prefix); /* Prepare message. */ memset(&zl, 0, sizeof(zl)); zl.type = ZEBRA_LSP_ISIS_SR; - zl.local_label = srp->input_label; + zl.local_label = psid->label; + + /* Local routes don't have any nexthop and require special handling. */ + if (list_isempty(rinfo->nexthops)) { + struct zapi_nexthop *znh; + struct interface *ifp; - switch (srp->type) { - case ISIS_SR_PREFIX_LOCAL: ifp = if_lookup_by_name("lo", VRF_DEFAULT); if (!ifp) { zlog_warn( "%s: couldn't install Prefix-SID %pFX: loopback interface not found", - __func__, &srp->prefix); + __func__, prefix); return; } @@ -291,32 +366,26 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp) znh->ifindex = ifp->ifindex; znh->label_num = 1; znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL; - break; - case ISIS_SR_PREFIX_REMOTE: - /* Update route in the RIB too. */ - SET_FLAG(zl.message, ZAPI_LABELS_FTN); - zl.route.prefix = srp->prefix; - zl.route.type = ZEBRA_ROUTE_ISIS; - zl.route.instance = 0; - - for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node, - nexthop)) { - if (nexthop->sr.label == MPLS_INVALID_LABEL) - continue; - - if (zl.nexthop_num >= MULTIPATH_NUM) - break; - - znh = &zl.nexthops[zl.nexthop_num++]; - znh->type = (srp->prefix.family == AF_INET) - ? NEXTHOP_TYPE_IPV4_IFINDEX - : NEXTHOP_TYPE_IPV6_IFINDEX; - znh->gate = nexthop->ip; - znh->ifindex = nexthop->ifindex; - znh->label_num = 1; - znh->labels[0] = nexthop->sr.label; + } else { + /* Add backup nexthops first. */ + if (rinfo->backup) { + count = isis_zebra_add_nexthops( + area->isis, rinfo->backup->nexthops, + zl.backup_nexthops, ISIS_NEXTHOP_BACKUP, true, + 0); + if (count > 0) { + SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS); + zl.backup_nexthop_num = count; + } } - break; + + /* Add primary nexthops. */ + count = isis_zebra_add_nexthops(area->isis, rinfo->nexthops, + zl.nexthops, ISIS_NEXTHOP_MAIN, + true, count); + if (!count) + return; + zl.nexthop_num = count; } /* Send message to zebra. */ @@ -324,58 +393,33 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp) } /** - * Uninstall Prefix-SID from the forwarding plane through Zebra. + * Uninstall Prefix-SID label entry from the forwarding plane through Zebra. * - * @param srp Segment Routing Prefix-SID + * @param area IS-IS area + * @param prefix Route prefix + * @param rinfo Route information + * @param psid Prefix-SID information */ -static void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp) +void isis_zebra_prefix_sid_uninstall(struct isis_area *area, + struct prefix *prefix, + struct isis_route_info *rinfo, + struct isis_sr_psid_info *psid) { struct zapi_labels zl; + sr_debug("ISIS-Sr (%s): delete label %u for prefix %pFX", + area->area_tag, psid->label, prefix); + /* Prepare message. */ memset(&zl, 0, sizeof(zl)); zl.type = ZEBRA_LSP_ISIS_SR; - zl.local_label = srp->input_label; - - if (srp->type == ISIS_SR_PREFIX_REMOTE) { - /* Update route in the RIB too. */ - SET_FLAG(zl.message, ZAPI_LABELS_FTN); - zl.route.prefix = srp->prefix; - zl.route.type = ZEBRA_ROUTE_ISIS; - zl.route.instance = 0; - } + zl.local_label = psid->label; /* Send message to zebra. */ (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl); } /** - * Send Prefix-SID to ZEBRA for installation or deletion. - * - * @param cmd ZEBRA_MPLS_LABELS_REPLACE or ZEBRA_ROUTE_DELETE - * @param srp Segment Routing Prefix-SID - */ -void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp) -{ - - if (cmd != ZEBRA_MPLS_LABELS_REPLACE - && cmd != ZEBRA_MPLS_LABELS_DELETE) { - flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command", - __func__); - return; - } - - sr_debug(" |- %s label %u for prefix %pFX", - cmd == ZEBRA_MPLS_LABELS_REPLACE ? "Update" : "Delete", - srp->input_label, &srp->prefix); - - if (cmd == ZEBRA_MPLS_LABELS_REPLACE) - isis_zebra_prefix_install_prefix_sid(srp); - else - isis_zebra_uninstall_prefix_sid(srp); -} - -/** * Send (LAN)-Adjacency-SID to ZEBRA for installation or deletion. * * @param cmd ZEBRA_MPLS_LABELS_ADD or ZEBRA_ROUTE_DELETE @@ -383,6 +427,7 @@ void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp) */ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra) { + struct isis *isis = sra->adj->circuit->area->isis; struct zapi_labels zl; struct zapi_nexthop *znh; @@ -394,11 +439,11 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra) sr_debug(" |- %s label %u for interface %s", cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete", - sra->nexthop.label, sra->adj->circuit->interface->name); + sra->input_label, sra->adj->circuit->interface->name); memset(&zl, 0, sizeof(zl)); zl.type = ZEBRA_LSP_ISIS_SR; - zl.local_label = sra->nexthop.label; + zl.local_label = sra->input_label; zl.nexthop_num = 1; znh = &zl.nexthops[0]; znh->gate = sra->nexthop.address; @@ -409,6 +454,24 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra) znh->label_num = 1; znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL; + /* Set backup nexthops. */ + if (sra->type == ISIS_SR_LAN_BACKUP) { + int count; + + count = isis_zebra_add_nexthops(isis, sra->backup_nexthops, + zl.backup_nexthops, + ISIS_NEXTHOP_BACKUP, true, 0); + if (count > 0) { + SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS); + zl.backup_nexthop_num = count; + + SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP); + znh->backup_num = count; + for (int i = 0; i < count; i++) + znh->backup_idx[i] = i; + } + } + (void)zebra_send_mpls_labels(zclient, cmd, &zl); } diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index 768919ff46..c5c52a6bc6 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -37,7 +37,6 @@ void isis_zebra_init(struct thread_master *master, int instance); void isis_zebra_stop(void); struct isis_route_info; -struct sr_prefix; struct sr_adjacency; void isis_zebra_route_add_route(struct isis *isis, @@ -48,7 +47,14 @@ void isis_zebra_route_del_route(struct isis *isis, struct prefix *prefix, struct prefix_ipv6 *src_p, struct isis_route_info *route_info); -void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp); +void isis_zebra_prefix_sid_install(struct isis_area *area, + struct prefix *prefix, + struct isis_route_info *rinfo, + struct isis_sr_psid_info *psid); +void isis_zebra_prefix_sid_uninstall(struct isis_area *area, + struct prefix *prefix, + struct isis_route_info *rinfo, + struct isis_sr_psid_info *psid); void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra); int isis_distribute_list_update(int routetype); void isis_zebra_redistribute_set(afi_t afi, int type); diff --git a/isisd/isisd.c b/isisd/isisd.c index 8d73c0571d..057ede0e38 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -77,6 +77,7 @@ unsigned long debug_bfd; unsigned long debug_tx_queue; unsigned long debug_sr; unsigned long debug_ldp_sync; +unsigned long debug_tilfa; DEFINE_QOBJ_TYPE(isis_area) @@ -441,8 +442,8 @@ void isis_area_destroy(struct isis_area *area) spftree_area_del(area); - THREAD_TIMER_OFF(area->spf_timer[0]); - THREAD_TIMER_OFF(area->spf_timer[1]); + thread_cancel(&area->spf_timer[0]); + thread_cancel(&area->spf_timer[1]); spf_backoff_free(area->spf_delay_ietf[0]); spf_backoff_free(area->spf_delay_ietf[1]); @@ -456,9 +457,9 @@ void isis_area_destroy(struct isis_area *area) } area->area_addrs = NULL; - THREAD_TIMER_OFF(area->t_tick); - THREAD_TIMER_OFF(area->t_lsp_refresh[0]); - THREAD_TIMER_OFF(area->t_lsp_refresh[1]); + thread_cancel(&area->t_tick); + thread_cancel(&area->t_lsp_refresh[0]); + thread_cancel(&area->t_lsp_refresh[1]); thread_cancel_event(master, area); @@ -582,6 +583,8 @@ void isis_finish(struct isis *isis) isis_vrf_unlink(isis, vrf); } + list_delete(&isis->area_list); + list_delete(&isis->init_circ_list); XFREE(MTYPE_ISIS, isis); } @@ -1191,6 +1194,8 @@ void print_debug(struct vty *vty, int flags, int onoff) if (flags & DEBUG_SR) vty_out(vty, "IS-IS Segment Routing events debugging is %s\n", onoffs); + if (flags & DEBUG_TILFA) + vty_out(vty, "IS-IS TI-LFA events debugging is %s\n", onoffs); if (flags & DEBUG_UPDATE_PACKETS) vty_out(vty, "IS-IS Update related packet debugging is %s\n", onoffs); @@ -1285,6 +1290,10 @@ static int config_write_debug(struct vty *vty) vty_out(vty, "debug " PROTO_NAME " sr-events\n"); write++; } + if (IS_DEBUG_TILFA) { + vty_out(vty, "debug " PROTO_NAME " ti-lfa\n"); + write++; + } if (IS_DEBUG_UPDATE_PACKETS) { vty_out(vty, "debug " PROTO_NAME " update-packets\n"); write++; @@ -1515,6 +1524,33 @@ DEFUN (no_debug_isis_srevents, return CMD_SUCCESS; } +DEFUN (debug_isis_tilfa, + debug_isis_tilfa_cmd, + "debug " PROTO_NAME " ti-lfa", + DEBUG_STR + PROTO_HELP + "IS-IS TI-LFA Events\n") +{ + debug_tilfa |= DEBUG_TILFA; + print_debug(vty, DEBUG_TILFA, 1); + + return CMD_SUCCESS; +} + +DEFUN (no_debug_isis_tilfa, + no_debug_isis_tilfa_cmd, + "no debug " PROTO_NAME " ti-lfa", + NO_STR + UNDEBUG_STR + PROTO_HELP + "IS-IS TI-LFA Events\n") +{ + debug_tilfa &= ~DEBUG_TILFA; + print_debug(vty, DEBUG_TILFA, 0); + + return CMD_SUCCESS; +} + DEFUN (debug_isis_rtevents, debug_isis_rtevents_cmd, "debug " PROTO_NAME " route-events", @@ -2339,12 +2375,12 @@ static void area_resign_level(struct isis_area *area, int level) } } - THREAD_TIMER_OFF(area->spf_timer[level - 1]); + thread_cancel(&area->spf_timer[level - 1]); sched_debug( "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.", area->area_tag, level); - THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]); + thread_cancel(&area->t_lsp_refresh[level - 1]); area->lsp_regenerate_pending[level - 1] = 0; } @@ -2848,6 +2884,8 @@ void isis_init(void) install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd); install_element(ENABLE_NODE, &debug_isis_srevents_cmd); install_element(ENABLE_NODE, &no_debug_isis_srevents_cmd); + install_element(ENABLE_NODE, &debug_isis_tilfa_cmd); + install_element(ENABLE_NODE, &no_debug_isis_tilfa_cmd); install_element(ENABLE_NODE, &debug_isis_rtevents_cmd); install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd); install_element(ENABLE_NODE, &debug_isis_events_cmd); @@ -2877,6 +2915,8 @@ void isis_init(void) install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd); install_element(CONFIG_NODE, &debug_isis_srevents_cmd); install_element(CONFIG_NODE, &no_debug_isis_srevents_cmd); + install_element(CONFIG_NODE, &debug_isis_tilfa_cmd); + install_element(CONFIG_NODE, &no_debug_isis_tilfa_cmd); install_element(CONFIG_NODE, &debug_isis_rtevents_cmd); install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd); install_element(CONFIG_NODE, &debug_isis_events_cmd); diff --git a/isisd/isisd.h b/isisd/isisd.h index d8df6eead9..921df4d7ef 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -188,6 +188,8 @@ struct isis_area { struct isis_sr_db srdb; int ipv6_circuits; bool purge_originator; + /* Fast Re-Route information. */ + size_t lfa_protected_links[ISIS_LEVELS]; /* Counters */ uint32_t circuit_state_changes; struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT] @@ -278,6 +280,7 @@ extern unsigned long debug_bfd; extern unsigned long debug_tx_queue; extern unsigned long debug_sr; extern unsigned long debug_ldp_sync; +extern unsigned long debug_tilfa; #define DEBUG_ADJ_PACKETS (1<<0) #define DEBUG_SNP_PACKETS (1<<1) @@ -292,7 +295,8 @@ extern unsigned long debug_ldp_sync; #define DEBUG_BFD (1<<10) #define DEBUG_TX_QUEUE (1<<11) #define DEBUG_SR (1<<12) -#define DEBUG_LDP_SYNC (1 << 13) +#define DEBUG_LDP_SYNC (1<<13) +#define DEBUG_TILFA (1<<14) /* Debug related macro. */ #define IS_DEBUG_ADJ_PACKETS (debug_adj_pkt & DEBUG_ADJ_PACKETS) @@ -309,6 +313,7 @@ extern unsigned long debug_ldp_sync; #define IS_DEBUG_TX_QUEUE (debug_tx_queue & DEBUG_TX_QUEUE) #define IS_DEBUG_SR (debug_sr & DEBUG_SR) #define IS_DEBUG_LDP_SYNC (debug_ldp_sync & DEBUG_LDP_SYNC) +#define IS_DEBUG_TILFA (debug_tilfa & DEBUG_TILFA) #define lsp_debug(...) \ do { \ diff --git a/isisd/subdir.am b/isisd/subdir.am index 1d59592626..4be4efc118 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -52,6 +52,7 @@ noinst_HEADERS += \ isisd/isis_events.h \ isisd/isis_flags.h \ isisd/isis_ldp_sync.h \ + isisd/isis_lfa.h \ isisd/isis_lsp.h \ isisd/isis_memory.h \ isisd/isis_misc.h \ @@ -86,6 +87,7 @@ LIBISIS_SOURCES = \ isisd/isis_events.c \ isisd/isis_flags.c \ isisd/isis_ldp_sync.c \ + isisd/isis_lfa.c \ isisd/isis_lsp.c \ isisd/isis_memory.c \ isisd/isis_misc.c \ diff --git a/ldpd/accept.c b/ldpd/accept.c index 323558d7fd..9bba0f5ddd 100644 --- a/ldpd/accept.c +++ b/ldpd/accept.c @@ -74,7 +74,7 @@ accept_del(int fd) LIST_FOREACH(av, &accept_queue.queue, entry) if (av->fd == fd) { log_debug("%s: %d removed from queue", __func__, fd); - THREAD_READ_OFF(av->ev); + thread_cancel(&av->ev); LIST_REMOVE(av, entry); free(av); return; @@ -95,7 +95,7 @@ accept_unpause(void) { if (accept_queue.evt != NULL) { log_debug(__func__); - THREAD_TIMER_OFF(accept_queue.evt); + thread_cancel(&accept_queue.evt); accept_arm(); } } @@ -115,7 +115,7 @@ accept_unarm(void) { struct accept_ev *av; LIST_FOREACH(av, &accept_queue.queue, entry) - THREAD_READ_OFF(av->ev); + thread_cancel(&av->ev); } static int diff --git a/ldpd/address.c b/ldpd/address.c index 74a3f5a309..c3e27357b5 100644 --- a/ldpd/address.c +++ b/ldpd/address.c @@ -410,8 +410,8 @@ static void log_msg_address(int out, uint16_t msg_type, struct nbr *nbr, int af, union ldpd_addr *addr) { - debug_msg(out, "%s: lsr-id %s, address %s", msg_name(msg_type), - inet_ntoa(nbr->id), log_addr(af, addr)); + debug_msg(out, "%s: lsr-id %pI4, address %s", msg_name(msg_type), + &nbr->id, log_addr(af, addr)); } static void @@ -419,7 +419,7 @@ log_msg_mac_withdrawal(int out, struct nbr *nbr, uint8_t *mac) { char buf[ETHER_ADDR_STRLEN]; - debug_msg(out, "mac withdrawal: lsr-id %s, mac %s", inet_ntoa(nbr->id), + debug_msg(out, "mac withdrawal: lsr-id %pI4, mac %s", &nbr->id, (mac) ? prefix_mac2str((struct ethaddr *)mac, buf, sizeof(buf)) : "wildcard"); } diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c index 4e09a6c4c9..795a41491c 100644 --- a/ldpd/adjacency.c +++ b/ldpd/adjacency.c @@ -84,7 +84,7 @@ adj_new(struct in_addr lsr_id, struct hello_source *source, { struct adj *adj; - log_debug("%s: lsr-id %s, %s", __func__, inet_ntoa(lsr_id), + log_debug("%s: lsr-id %pI4, %s", __func__, &lsr_id, log_hello_src(source)); if ((adj = calloc(1, sizeof(*adj))) == NULL) @@ -114,7 +114,7 @@ adj_del(struct adj *adj, uint32_t notif_status) { struct nbr *nbr = adj->nbr; - log_debug("%s: lsr-id %s, %s (%s)", __func__, inet_ntoa(adj->lsr_id), + log_debug("%s: lsr-id %pI4, %s (%s)", __func__, &adj->lsr_id, log_hello_src(&adj->source), af_name(adj_get_af(adj))); adj_stop_itimer(adj); @@ -179,7 +179,7 @@ adj_itimer(struct thread *thread) adj->inactivity_timer = NULL; - log_debug("%s: lsr-id %s", __func__, inet_ntoa(adj->lsr_id)); + log_debug("%s: lsr-id %pI4", __func__, &adj->lsr_id); if (adj->source.type == HELLO_TARGETED) { if (!(adj->source.target->flags & F_TNBR_CONFIGURED) && @@ -198,7 +198,7 @@ adj_itimer(struct thread *thread) void adj_start_itimer(struct adj *adj) { - THREAD_TIMER_OFF(adj->inactivity_timer); + thread_cancel(&adj->inactivity_timer); adj->inactivity_timer = NULL; thread_add_timer(master, adj_itimer, adj, adj->holdtime, &adj->inactivity_timer); @@ -207,7 +207,7 @@ adj_start_itimer(struct adj *adj) void adj_stop_itimer(struct adj *adj) { - THREAD_TIMER_OFF(adj->inactivity_timer); + thread_cancel(&adj->inactivity_timer); } /* targeted neighbors */ @@ -359,7 +359,7 @@ tnbr_hello_timer(struct thread *thread) static void tnbr_start_hello_timer(struct tnbr *tnbr) { - THREAD_TIMER_OFF(tnbr->hello_timer); + thread_cancel(&tnbr->hello_timer); tnbr->hello_timer = NULL; thread_add_timer(master, tnbr_hello_timer, tnbr, tnbr_get_hello_interval(tnbr), &tnbr->hello_timer); @@ -368,7 +368,7 @@ tnbr_start_hello_timer(struct tnbr *tnbr) static void tnbr_stop_hello_timer(struct tnbr *tnbr) { - THREAD_TIMER_OFF(tnbr->hello_timer); + thread_cancel(&tnbr->hello_timer); } struct ctl_adj * diff --git a/ldpd/control.c b/ldpd/control.c index 6554f0a6f1..3b77765952 100644 --- a/ldpd/control.c +++ b/ldpd/control.c @@ -183,8 +183,8 @@ control_close(int fd) msgbuf_clear(&c->iev.ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); - THREAD_READ_OFF(c->iev.ev_read); - THREAD_WRITE_OFF(c->iev.ev_write); + thread_cancel(&c->iev.ev_read); + thread_cancel(&c->iev.ev_write); close(c->iev.ibuf.fd); accept_unpause(); free(c); diff --git a/ldpd/hello.c b/ldpd/hello.c index caf63c13d7..327cb32434 100644 --- a/ldpd/hello.c +++ b/ldpd/hello.c @@ -179,24 +179,24 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, r = tlv_decode_hello_prms(buf, len, &holdtime, &flags); if (r == -1) { - log_debug("%s: lsr-id %s: failed to decode params", __func__, - inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: failed to decode params", __func__, + &lsr_id); return; } /* safety checks */ if (holdtime != 0 && holdtime < MIN_HOLDTIME) { - log_debug("%s: lsr-id %s: invalid hello holdtime (%u)", - __func__, inet_ntoa(lsr_id), holdtime); + log_debug("%s: lsr-id %pI4: invalid hello holdtime (%u)", + __func__, &lsr_id, holdtime); return; } if (multicast && (flags & F_HELLO_TARGETED)) { - log_debug("%s: lsr-id %s: multicast targeted hello", __func__, - inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: multicast targeted hello", __func__, + &lsr_id); return; } if (!multicast && !((flags & F_HELLO_TARGETED))) { - log_debug("%s: lsr-id %s: unicast link hello", __func__, - inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: unicast link hello", __func__, + &lsr_id); return; } buf += r; @@ -205,13 +205,13 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, r = tlv_decode_opt_hello_prms(buf, len, &tlvs_rcvd, af, &trans_addr, &conf_seqnum, &trans_pref); if (r == -1) { - log_debug("%s: lsr-id %s: failed to decode optional params", - __func__, inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: failed to decode optional params", + __func__, &lsr_id); return; } if (r != len) { - log_debug("%s: lsr-id %s: unexpected data in message", - __func__, inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: unexpected data in message", + __func__, &lsr_id); return; } ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0; @@ -220,8 +220,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, if (!(tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)) trans_addr = *src; if (bad_addr(af, &trans_addr)) { - log_debug("%s: lsr-id %s: invalid transport address %s", - __func__, inet_ntoa(lsr_id), log_addr(af, &trans_addr)); + log_debug("%s: lsr-id %pI4: invalid transport address %s", + __func__, &lsr_id, log_addr(af, &trans_addr)); return; } if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&trans_addr.v6)) { @@ -234,7 +234,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, * check)". */ if (flags & F_HELLO_TARGETED) { - log_debug("%s: lsr-id %s: invalid targeted hello transport address %s", __func__, inet_ntoa(lsr_id), + log_debug("%s: lsr-id %pI4: invalid targeted hello transport address %s", __func__, &lsr_id, log_addr(af, &trans_addr)); return; } @@ -249,8 +249,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, * targeted LDP Hello packet's source or destination addresses". */ if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&src->v6)) { - log_debug("%s: lsr-id %s: targeted hello with link-local source address", __func__, - inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: targeted hello with link-local source address", __func__, + &lsr_id); return; } @@ -290,8 +290,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, source.link.src_addr = *src; } - debug_hello_recv("%s lsr-id %s transport-address %s holdtime %u%s", - log_hello_src(&source), inet_ntoa(lsr_id), log_addr(af, &trans_addr), + debug_hello_recv("%s lsr-id %pI4 transport-address %s holdtime %u%s", + log_hello_src(&source), &lsr_id, log_addr(af, &trans_addr), holdtime, (ds_tlv) ? " (dual stack TLV present)" : ""); adj = adj_find(lsr_id, &source); @@ -316,7 +316,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, * send a fatal Notification message with status code of * 'Transport Connection Mismatch' and reset the session". */ - log_debug("%s: lsr-id %s: remote transport preference does not match the local preference", __func__, inet_ntoa(lsr_id)); + log_debug("%s: lsr-id %pI4: remote transport preference does not match the local preference", __func__, &lsr_id); if (nbr) session_shutdown(nbr, S_TRANS_MISMTCH, msg->id, msg->type); @@ -356,7 +356,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, if (nbr && nbr->af == af && (ldp_addrcmp(af, &nbr->raddr, &trans_addr) || nbr->raddr_scope != scope_id)) { - log_warnx("%s: lsr-id %s: hello packet advertising a different transport address", __func__, inet_ntoa(lsr_id)); + log_warnx("%s: lsr-id %pI4: hello packet advertising a different transport address", __func__, &lsr_id); if (adj) adj_del(adj, S_SHUTDOWN); return; @@ -364,8 +364,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af, if (nbr == NULL) { nbrt = nbr_find_addr(af, &trans_addr); if (nbrt) { - log_debug("%s: transport address %s is already being used by lsr-id %s", __func__, log_addr(af, - &trans_addr), inet_ntoa(nbrt->id)); + log_debug("%s: transport address %s is already being used by lsr-id %pI4", __func__, log_addr(af, + &trans_addr), &nbrt->id); if (adj) adj_del(adj, S_SHUTDOWN); return; diff --git a/ldpd/init.c b/ldpd/init.c index 30b78315f9..d394fb08ea 100644 --- a/ldpd/init.c +++ b/ldpd/init.c @@ -35,7 +35,7 @@ send_init(struct nbr *nbr) uint16_t size; int err = 0; - debug_msg_send("initialization: lsr-id %s", inet_ntoa(nbr->id)); + debug_msg_send("initialization: lsr-id %pI4", &nbr->id); size = LDP_HDR_SIZE + LDP_MSG_SIZE + SESS_PRMS_SIZE + CAP_TLV_DYNAMIC_SIZE + CAP_TLV_TWCARD_SIZE + CAP_TLV_UNOTIF_SIZE; @@ -65,7 +65,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) uint16_t max_pdu_len; int caps_rcvd = 0; - debug_msg_recv("initialization: lsr-id %s", inet_ntoa(nbr->id)); + debug_msg_recv("initialization: lsr-id %pI4", &nbr->id); memcpy(&msg, buf, sizeof(msg)); buf += LDP_MSG_SIZE; @@ -146,8 +146,8 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) nbr->flags |= F_NBR_CAP_DYNAMIC; - log_debug("%s: lsr-id %s announced the Dynamic Capability Announcement capability", __func__, - inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4 announced the Dynamic Capability Announcement capability", __func__, + &nbr->id); break; case TLV_TYPE_TWCARD_CAP: if (tlv_len != CAP_TLV_TWCARD_LEN) { @@ -165,7 +165,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) nbr->flags |= F_NBR_CAP_TWCARD; - log_debug("%s: lsr-id %s announced the Typed Wildcard FEC capability", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4 announced the Typed Wildcard FEC capability", __func__, &nbr->id); break; case TLV_TYPE_UNOTIF_CAP: if (tlv_len != CAP_TLV_UNOTIF_LEN) { @@ -183,8 +183,8 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len) nbr->flags |= F_NBR_CAP_UNOTIF; - log_debug("%s: lsr-id %s announced the Unrecognized Notification capability", __func__, - inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4 announced the Unrecognized Notification capability", __func__, + &nbr->id); break; default: if (!(ntohs(tlv.type) & UNKNOWN_FLAG)) @@ -222,7 +222,7 @@ send_capability(struct nbr *nbr, uint16_t capability, int enable) uint16_t size; int err = 0; - log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4", __func__, &nbr->id); size = LDP_HDR_SIZE + LDP_MSG_SIZE + CAP_TLV_DYNAMIC_SIZE; if ((buf = ibuf_open(size)) == NULL) @@ -268,7 +268,7 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len) int enable = 0; int caps_rcvd = 0; - log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4", __func__, &nbr->id); memcpy(&msg, buf, sizeof(msg)); buf += LDP_MSG_SIZE; @@ -318,7 +318,7 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len) else nbr->flags &= ~F_NBR_CAP_TWCARD; - log_debug("%s: lsr-id %s %s the Typed Wildcard FEC capability", __func__, inet_ntoa(nbr->id), + log_debug("%s: lsr-id %pI4 %s the Typed Wildcard FEC capability", __func__, &nbr->id, (enable) ? "announced" : "withdrew"); break; case TLV_TYPE_UNOTIF_CAP: @@ -342,8 +342,8 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len) else nbr->flags &= ~F_NBR_CAP_UNOTIF; - log_debug("%s: lsr-id %s %s the Unrecognized Notification capability", __func__, - inet_ntoa(nbr->id), (enable) ? "announced" : + log_debug("%s: lsr-id %pI4 %s the Unrecognized Notification capability", __func__, + &nbr->id, (enable) ? "announced" : "withdrew"); break; case TLV_TYPE_DYNAMIC_CAP: diff --git a/ldpd/interface.c b/ldpd/interface.c index bc8f26bc58..3e9f2fa991 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -470,7 +470,7 @@ if_hello_timer(struct thread *thread) static void if_start_hello_timer(struct iface_af *ia) { - THREAD_TIMER_OFF(ia->hello_timer); + thread_cancel(&ia->hello_timer); ia->hello_timer = NULL; thread_add_timer(master, if_hello_timer, ia, if_get_hello_interval(ia), &ia->hello_timer); @@ -479,7 +479,7 @@ if_start_hello_timer(struct iface_af *ia) static void if_stop_hello_timer(struct iface_af *ia) { - THREAD_TIMER_OFF(ia->hello_timer); + thread_cancel(&ia->hello_timer); } struct ctl_iface * @@ -578,15 +578,15 @@ if_join_ipv4_group(struct iface *iface, struct in_addr *addr) { struct in_addr if_addr; - log_debug("%s: interface %s addr %s", __func__, iface->name, - inet_ntoa(*addr)); + log_debug("%s: interface %s addr %pI4", __func__, iface->name, + addr); if_addr.s_addr = if_get_ipv4_addr(iface); if (setsockopt_ipv4_multicast(global.ipv4.ldp_disc_socket, IP_ADD_MEMBERSHIP, if_addr, addr->s_addr, iface->ifindex) < 0) { - log_warn("%s: error IP_ADD_MEMBERSHIP, interface %s address %s", - __func__, iface->name, inet_ntoa(*addr)); + log_warn("%s: error IP_ADD_MEMBERSHIP, interface %s address %pI4", + __func__, iface->name, addr); return (-1); } return (0); @@ -597,14 +597,14 @@ if_leave_ipv4_group(struct iface *iface, struct in_addr *addr) { struct in_addr if_addr; - log_debug("%s: interface %s addr %s", __func__, iface->name, - inet_ntoa(*addr)); + log_debug("%s: interface %s addr %pI4", __func__, iface->name, + addr); if_addr.s_addr = if_get_ipv4_addr(iface); if (setsockopt_ipv4_multicast(global.ipv4.ldp_disc_socket, IP_DROP_MEMBERSHIP, if_addr, addr->s_addr, iface->ifindex) < 0) { - log_warn("%s: error IP_DROP_MEMBERSHIP, interface %s address %s", __func__, iface->name, inet_ntoa(*addr)); + log_warn("%s: error IP_DROP_MEMBERSHIP, interface %s address %pI4", __func__, iface->name, addr); return (-1); } @@ -753,8 +753,7 @@ static void start_wait_for_ldp_sync_timer(struct iface *iface) if (iface->ldp_sync.wait_for_sync_timer) return; - THREAD_TIMER_OFF(iface->ldp_sync.wait_for_sync_timer); - iface->ldp_sync.wait_for_sync_timer = NULL; + THREAD_OFF(iface->ldp_sync.wait_for_sync_timer); thread_add_timer(master, iface_wait_for_ldp_sync_timer, iface, if_get_wait_for_sync_interval(), &iface->ldp_sync.wait_for_sync_timer); @@ -762,8 +761,7 @@ static void start_wait_for_ldp_sync_timer(struct iface *iface) static void stop_wait_for_ldp_sync_timer(struct iface *iface) { - THREAD_TIMER_OFF(iface->ldp_sync.wait_for_sync_timer); - iface->ldp_sync.wait_for_sync_timer = NULL; + THREAD_OFF(iface->ldp_sync.wait_for_sync_timer); } static int @@ -828,14 +826,14 @@ ldp_sync_fsm_adj_event(struct adj *adj, enum ldp_sync_event event) } debug_evt_ldp_sync("%s: event %s, " - "adj iface %s (%d) lsr-id %s " - "source address %s transport address %s", - __func__, ldp_sync_event_names[event], - adj->source.link.ia->iface->name, - adj->source.link.ia->iface->ifindex, - inet_ntoa(adj->lsr_id), - log_addr(adj_get_af(adj), &adj->source.link.src_addr), - log_addr(adj_get_af(adj), &adj->trans_addr)); + "adj iface %s (%d) lsr-id %pI4 " + "source address %s transport address %s", + __func__, ldp_sync_event_names[event], + adj->source.link.ia->iface->name, + adj->source.link.ia->iface->ifindex, + &adj->lsr_id, + log_addr(adj_get_af(adj), &adj->source.link.src_addr), + log_addr(adj_get_af(adj), &adj->trans_addr)); return ldp_sync_fsm(iface, event); } @@ -861,9 +859,9 @@ ldp_sync_fsm_nbr_event(struct nbr *nbr, enum ldp_sync_event event) */ continue; - debug_evt_ldp_sync("%s: event %s, iface %s, lsr-id %s", + debug_evt_ldp_sync("%s: event %s, iface %s, lsr-id %pI4", __func__, ldp_sync_event_names[event], - iface->name, inet_ntoa(nbr->id)); + iface->name, &nbr->id); ldp_sync_fsm(iface, event); } diff --git a/ldpd/keepalive.c b/ldpd/keepalive.c index ba5f223316..b03127109f 100644 --- a/ldpd/keepalive.c +++ b/ldpd/keepalive.c @@ -37,7 +37,7 @@ send_keepalive(struct nbr *nbr) size -= LDP_HDR_SIZE; gen_msg_hdr(buf, MSG_TYPE_KEEPALIVE, size); - debug_kalive_send("keepalive: lsr-id %s", inet_ntoa(nbr->id)); + debug_kalive_send("keepalive: lsr-id %pI4", &nbr->id); evbuf_enqueue(&nbr->tcp->wbuf, buf); nbr->stats.kalive_sent++; @@ -54,7 +54,7 @@ recv_keepalive(struct nbr *nbr, char *buf, uint16_t len) return (-1); } - debug_kalive_recv("keepalive: lsr-id %s", inet_ntoa(nbr->id)); + debug_kalive_recv("keepalive: lsr-id %pI4", &nbr->id); if (nbr->state != NBR_STA_OPER) nbr_fsm(nbr, NBR_EVT_KEEPALIVE_RCVD); diff --git a/ldpd/labelmapping.c b/ldpd/labelmapping.c index a656626356..cee9d527e8 100644 --- a/ldpd/labelmapping.c +++ b/ldpd/labelmapping.c @@ -910,6 +910,6 @@ tlv_decode_fec_elm(struct nbr *nbr, struct ldp_msg *msg, char *buf, static void log_msg_mapping(int out, uint16_t msg_type, struct nbr *nbr, struct map *map) { - debug_msg(out, "%s: lsr-id %s, fec %s, label %s", msg_name(msg_type), - inet_ntoa(nbr->id), log_map(map), log_label(map->label)); + debug_msg(out, "%s: lsr-id %pI4, fec %s, label %s", msg_name(msg_type), + &nbr->id, log_map(map), log_label(map->label)); } diff --git a/ldpd/lde.c b/ldpd/lde.c index df64f908ea..67b695150e 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -415,8 +415,8 @@ lde_dispatch_imsg(struct thread *thread) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handlers and exit */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); lde_shutdown(); } @@ -661,8 +661,8 @@ lde_dispatch_parent(struct thread *thread) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handlers and exit */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); lde_shutdown(); } diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index bed276c7b1..9db931677d 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -1060,7 +1060,7 @@ lde_gc_timer(struct thread *thread) void lde_gc_start_timer(void) { - THREAD_TIMER_OFF(gc_timer); + thread_cancel(&gc_timer); gc_timer = NULL; thread_add_timer(master, lde_gc_timer, NULL, LDE_GC_INTERVAL, &gc_timer); @@ -1069,5 +1069,5 @@ lde_gc_start_timer(void) void lde_gc_stop_timer(void) { - THREAD_TIMER_OFF(gc_timer); + thread_cancel(&gc_timer); } diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index c217cfc78a..d21e3c0409 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -255,7 +255,7 @@ ldp_config_write(struct vty *vty) vty_out (vty, "mpls ldp\n"); if (ldpd_conf->rtr_id.s_addr != INADDR_ANY) - vty_out(vty, " router-id %s\n", inet_ntoa(ldpd_conf->rtr_id)); + vty_out(vty, " router-id %pI4\n", &ldpd_conf->rtr_id); if (ldpd_conf->lhello_holdtime != LINK_DFLT_HOLDTIME && ldpd_conf->lhello_holdtime != 0) @@ -292,20 +292,20 @@ ldp_config_write(struct vty *vty) RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) { if (nbrp->flags & F_NBRP_KEEPALIVE) - vty_out (vty, " neighbor %s session holdtime %u\n", - inet_ntoa(nbrp->lsr_id),nbrp->keepalive); + vty_out (vty, " neighbor %pI4 session holdtime %u\n", + &nbrp->lsr_id,nbrp->keepalive); if (nbrp->flags & F_NBRP_GTSM) { if (nbrp->gtsm_enabled) - vty_out (vty, " neighbor %s ttl-security hops %u\n", inet_ntoa(nbrp->lsr_id), + vty_out (vty, " neighbor %pI4 ttl-security hops %u\n", &nbrp->lsr_id, nbrp->gtsm_hops); else - vty_out (vty, " neighbor %s ttl-security disable\n",inet_ntoa(nbrp->lsr_id)); + vty_out (vty, " neighbor %pI4 ttl-security disable\n",&nbrp->lsr_id); } if (nbrp->auth.method == AUTH_MD5SIG) - vty_out (vty, " neighbor %s password %s\n", - inet_ntoa(nbrp->lsr_id),nbrp->auth.md5key); + vty_out (vty, " neighbor %pI4 password %s\n", + &nbrp->lsr_id,nbrp->auth.md5key); } ldp_af_config_write(vty, AF_INET, ldpd_conf, &ldpd_conf->ipv4); @@ -326,7 +326,7 @@ ldp_l2vpn_pw_config_write(struct vty *vty, struct l2vpn_pw *pw) vty_out (vty, " member pseudowire %s\n", pw->ifname); if (pw->lsr_id.s_addr != INADDR_ANY) - vty_out (vty, " neighbor lsr-id %s\n",inet_ntoa(pw->lsr_id)); + vty_out (vty, " neighbor lsr-id %pI4\n",&pw->lsr_id); else missing_lsrid = 1; diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index 609598a768..09b820e3f6 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -19,6 +19,7 @@ #include <zebra.h> #include <sys/un.h> +#include "lib/printfrr.h" #include "ldpd.h" #include "ldpe.h" @@ -237,8 +238,8 @@ show_ldp_sync_msg(struct vty *vty, struct imsg *imsg, } if (iface->peer_ldp_id.s_addr) - vty_out (vty, " Peer LDP Identifier: %s:0\n", - inet_ntoa(iface->peer_ldp_id)); + vty_out (vty, " Peer LDP Identifier: %pI4:0\n", + &iface->peer_ldp_id); break; case IMSG_CTL_END: @@ -256,6 +257,7 @@ show_ldp_sync_msg_json(struct imsg *imsg, struct show_params *params, { struct ctl_ldp_sync *iface; json_object *json_iface; + char buf[PREFIX_STRLEN]; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_LDP_SYNC: @@ -278,7 +280,8 @@ show_ldp_sync_msg_json(struct imsg *imsg, struct show_params *params, json_object_string_add(json_iface, "peerLdpId", iface->peer_ldp_id.s_addr ? - inet_ntoa(iface->peer_ldp_id) : ""); + inet_ntop(AF_INET, &iface->peer_ldp_id, buf, sizeof(buf)) : + ""); json_object_object_add(json, iface->name, json_iface); break; @@ -305,8 +308,7 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg, if (params->family != AF_UNSPEC && params->family != adj->af) break; - vty_out(vty, "%-4s %-15s ", af_name(adj->af), - inet_ntoa(adj->id)); + vty_out(vty, "%-4s %-15pI4 ", af_name(adj->af), &adj->id); switch(adj->type) { case HELLO_LINK: vty_out(vty, "%-8s %-15s ", "Link", adj->ifname); @@ -336,8 +338,8 @@ show_discovery_detail_adj(struct vty *vty, char *buffer, struct ctl_adj *adj) { size_t buflen = strlen(buffer); - snprintf(buffer + buflen, LDPBUFSIZ - buflen, - " LSR Id: %s:0\n", inet_ntoa(adj->id)); + snprintfrr(buffer + buflen, LDPBUFSIZ - buflen, + " LSR Id: %pI4:0\n", &adj->id); buflen = strlen(buffer); snprintf(buffer + buflen, LDPBUFSIZ - buflen, " Source address: %s\n", @@ -419,7 +421,7 @@ show_discovery_detail_msg(struct vty *vty, struct imsg *imsg, case IMSG_CTL_END: rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf); vty_out (vty, "Local:\n"); - vty_out (vty, " LSR Id: %s:0\n",inet_ntoa(rtr_id)); + vty_out (vty, " LSR Id: %pI4:0\n",&rtr_id); if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED) vty_out (vty, " Transport Address (IPv4): %s\n", log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr)); @@ -445,6 +447,7 @@ show_discovery_msg_json(struct imsg *imsg, struct show_params *params, json_object *json) { struct ctl_adj *adj; + char buf[PREFIX_STRLEN]; json_object *json_array; json_object *json_adj; @@ -465,7 +468,8 @@ show_discovery_msg_json(struct imsg *imsg, struct show_params *params, json_object_string_add(json_adj, "addressFamily", af_name(adj->af)); json_object_string_add(json_adj, "neighborId", - inet_ntoa(adj->id)); + inet_ntop(AF_INET, &adj->id, buf, + sizeof(buf))); switch(adj->type) { case HELLO_LINK: json_object_string_add(json_adj, "type", "link"); @@ -494,6 +498,7 @@ show_discovery_msg_json(struct imsg *imsg, struct show_params *params, static void show_discovery_detail_adj_json(json_object *json, struct ctl_adj *adj) { + char buf[PREFIX_STRLEN]; json_object *json_adj; json_object *json_array; @@ -504,7 +509,8 @@ show_discovery_detail_adj_json(json_object *json, struct ctl_adj *adj) } json_adj = json_object_new_object(); - json_object_string_add(json_adj, "lsrId", inet_ntoa(adj->id)); + json_object_string_add(json_adj, "lsrId", inet_ntop(AF_INET, &adj->id, + buf, sizeof(buf))); json_object_string_add(json_adj, "sourceAddress", log_addr(adj->af, &adj->src_addr)); json_object_string_add(json_adj, "transportAddress", log_addr(adj->af, @@ -526,6 +532,7 @@ show_discovery_detail_msg_json(struct imsg *imsg, struct show_params *params, struct ctl_disc_tnbr *tnbr; struct in_addr rtr_id; union ldpd_addr *trans_addr; + char buf[PREFIX_STRLEN]; json_object *json_interface; json_object *json_target; static json_object *json_interfaces; @@ -535,7 +542,9 @@ show_discovery_detail_msg_json(struct imsg *imsg, struct show_params *params, switch (imsg->hdr.type) { case IMSG_CTL_SHOW_DISCOVERY: rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf); - json_object_string_add(json, "lsrId", inet_ntoa(rtr_id)); + json_object_string_add(json, "lsrId", + inet_ntop(AF_INET, &rtr_id, buf, + sizeof(buf))); if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED) json_object_string_add(json, "transportAddressIPv4", log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr)); @@ -612,9 +621,9 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) addr = log_addr(nbr->af, &nbr->raddr); - vty_out(vty, "%-4s %-15s %-11s %-15s", - af_name(nbr->af), inet_ntoa(nbr->id), - nbr_state_name(nbr->nbr_state), addr); + vty_out(vty, "%-4s %-15pI4 %-11s %-15s", + af_name(nbr->af), &nbr->id, + nbr_state_name(nbr->nbr_state), addr); if (strlen(addr) > 15) vty_out(vty, "\n%48s", " "); vty_out (vty, " %8s\n", log_time(nbr->uptime)); @@ -662,8 +671,8 @@ show_nbr_detail_msg(struct vty *vty, struct imsg *imsg, v4adjs_buffer[0] = '\0'; v6adjs_buffer[0] = '\0'; - vty_out (vty, "Peer LDP Identifier: %s:0\n", - inet_ntoa(nbr->id)); + vty_out (vty, "Peer LDP Identifier: %pI4:0\n", + &nbr->id); vty_out (vty, " TCP connection: %s:%u - %s:%u\n", log_addr(nbr->af, &nbr->laddr), ntohs(nbr->lport), log_addr(nbr->af, &nbr->raddr),ntohs(nbr->rport)); @@ -740,6 +749,7 @@ show_nbr_msg_json(struct imsg *imsg, struct show_params *params, json_object *json) { struct ctl_nbr *nbr; + char buf[PREFIX_STRLEN]; json_object *json_array; json_object *json_nbr; @@ -757,7 +767,8 @@ show_nbr_msg_json(struct imsg *imsg, struct show_params *params, json_object_string_add(json_nbr, "addressFamily", af_name(nbr->af)); json_object_string_add(json_nbr, "neighborId", - inet_ntoa(nbr->id)); + inet_ntop(AF_INET, &nbr->id, buf, + sizeof(buf))); json_object_string_add(json_nbr, "state", nbr_state_name(nbr->nbr_state)); json_object_string_add(json_nbr, "transportAddress", @@ -803,6 +814,7 @@ show_nbr_detail_msg_json(struct imsg *imsg, struct show_params *params, struct ctl_nbr *nbr; struct ldp_stats *stats; struct ctl_adj *adj; + char buf[PREFIX_STRLEN]; json_object *json_nbr; json_object *json_array; json_object *json_counter; @@ -815,9 +827,12 @@ show_nbr_detail_msg_json(struct imsg *imsg, struct show_params *params, nbr = imsg->data; json_nbr = json_object_new_object(); - json_object_object_add(json, inet_ntoa(nbr->id), json_nbr); - - json_object_string_add(json_nbr, "peerId", inet_ntoa(nbr->id)); + json_object_object_add(json, + inet_ntop(AF_INET, &nbr->id, buf, + sizeof(buf)), json_nbr); + json_object_string_add(json_nbr, "peerId", + inet_ntop(AF_INET, &nbr->id, buf, + sizeof(buf))); json_object_string_add(json_nbr, "tcpLocalAddress", log_addr(nbr->af, &nbr->laddr)); json_object_int_add(json_nbr, "tcpLocalPort", @@ -998,8 +1013,8 @@ show_nbr_capabilities_msg(struct vty *vty, struct imsg *imsg, struct show_params if (nbr->nbr_state != NBR_STA_OPER) break; - vty_out (vty, "Peer LDP Identifier: %s:0\n", - inet_ntoa(nbr->id)); + vty_out (vty, "Peer LDP Identifier: %pI4:0\n", + &nbr->id); show_nbr_capabilities(vty, nbr); vty_out (vty, "\n"); break; @@ -1079,6 +1094,7 @@ show_nbr_capabilities_msg_json(struct imsg *imsg, struct show_params *params, json_object *json) { struct ctl_nbr *nbr; + char buf[PREFIX_STRLEN]; json_object *json_nbr; switch (imsg->hdr.type) { @@ -1089,7 +1105,8 @@ show_nbr_capabilities_msg_json(struct imsg *imsg, struct show_params *params, break; json_nbr = json_object_new_object(); - json_object_object_add(json, inet_ntoa(nbr->id), json_nbr); + json_object_object_add(json, inet_ntop(AF_INET, &nbr->id, buf, + sizeof(buf)), json_nbr); show_nbr_capabilities_json(nbr, json_nbr); break; case IMSG_CTL_END: @@ -1128,9 +1145,10 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params) vty_out(vty, "%-4s %-20s", af_name(rt->af), dstnet); if (strlen(dstnet) > 20) vty_out(vty, "\n%25s", " "); - vty_out (vty, " %-15s %-11s %-13s %6s\n", inet_ntoa(rt->nexthop), - log_label(rt->local_label), log_label(rt->remote_label), - rt->in_use ? "yes" : "no"); + vty_out (vty, " %-15pI4 %-11s %-13s %6s\n", + &rt->nexthop, log_label(rt->local_label), + log_label(rt->remote_label), + rt->in_use ? "yes" : "no"); break; case IMSG_CTL_END: vty_out (vty, "\n"); @@ -1168,17 +1186,17 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para upstream = 1; buflen = strlen(sent_buffer); - snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen, - "%12s%s:0\n", "", inet_ntoa(rt->nexthop)); + snprintfrr(sent_buffer + buflen, LDPBUFSIZ - buflen, + "%12s%pI4:0\n", "", &rt->nexthop); break; case IMSG_CTL_SHOW_LIB_RCVD: rt = imsg->data; downstream = 1; buflen = strlen(rcvd_buffer); - snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen, - "%12s%s:0, label %s%s\n", "", inet_ntoa(rt->nexthop), - log_label(rt->remote_label), - rt->in_use ? " (in use)" : ""); + snprintfrr(rcvd_buffer + buflen, LDPBUFSIZ - buflen, + "%12s%pI4:0, label %s%s\n", "", &rt->nexthop, + log_label(rt->remote_label), + rt->in_use ? " (in use)" : ""); break; case IMSG_CTL_SHOW_LIB_END: rt = imsg->data; @@ -1217,6 +1235,7 @@ show_lib_msg_json(struct imsg *imsg, struct show_params *params, json_object *json_array; json_object *json_lib_entry; char dstnet[BUFSIZ]; + char buf[PREFIX_STRLEN]; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_LIB_BEGIN: @@ -1240,11 +1259,12 @@ show_lib_msg_json(struct imsg *imsg, struct show_params *params, log_addr(rt->af, &rt->prefix), rt->prefixlen); json_object_string_add(json_lib_entry, "prefix", dstnet); json_object_string_add(json_lib_entry, "neighborId", - inet_ntoa(rt->nexthop)); + inet_ntop(AF_INET, &rt->nexthop, buf, + sizeof(buf))); json_object_string_add(json_lib_entry, "localLabel", - log_label(rt->local_label)); + log_label(rt->local_label)); json_object_string_add(json_lib_entry, "remoteLabel", - log_label(rt->remote_label)); + log_label(rt->remote_label)); json_object_int_add(json_lib_entry, "inUse", rt->in_use); json_object_array_add(json_array, json_lib_entry); @@ -1264,6 +1284,7 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params, { struct ctl_rt *rt = NULL; char dstnet[BUFSIZ]; + char buf[PREFIX_STRLEN]; static json_object *json_lib_entry; static json_object *json_adv_labels; json_object *json_adv_label; @@ -1296,7 +1317,8 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params, json_adv_label = json_object_new_object(); json_object_string_add(json_adv_label, "neighborId", - inet_ntoa(rt->nexthop)); + inet_ntop(AF_INET, &rt->nexthop, buf, + sizeof(buf))); json_object_array_add(json_adv_labels, json_adv_label); break; case IMSG_CTL_SHOW_LIB_RCVD: @@ -1304,9 +1326,10 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params, json_remote_label = json_object_new_object(); json_object_string_add(json_remote_label, "neighborId", - inet_ntoa(rt->nexthop)); + inet_ntop(AF_INET, &rt->nexthop, + buf, sizeof(buf))); json_object_string_add(json_remote_label, "label", - log_label(rt->remote_label)); + log_label(rt->remote_label)); json_object_int_add(json_remote_label, "inUse", rt->in_use); json_object_array_add(json_remote_labels, json_remote_label); break; @@ -1329,8 +1352,8 @@ show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg, case IMSG_CTL_SHOW_L2VPN_BINDING: pw = imsg->data; - vty_out (vty, " Destination Address: %s, VC ID: %u\n", - inet_ntoa(pw->lsr_id), pw->pwid); + vty_out (vty, " Destination Address: %pI4, VC ID: %u\n", + &pw->lsr_id, pw->pwid); /* local binding */ if (pw->local_label != NO_LABEL) { @@ -1371,6 +1394,7 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params, struct ctl_pw *pw; json_object *json_pw; char key_name[64]; + char buf[PREFIX_STRLEN]; switch (imsg->hdr.type) { case IMSG_CTL_SHOW_L2VPN_BINDING: @@ -1378,7 +1402,8 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params, json_pw = json_object_new_object(); json_object_string_add(json_pw, "destination", - inet_ntoa(pw->lsr_id)); + inet_ntop(AF_INET, &pw->lsr_id, buf, + sizeof(buf))); json_object_int_add(json_pw, "vcId", pw->pwid); /* local binding */ @@ -1415,8 +1440,8 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params, json_object_string_add(json_pw, "remoteLabel", "unassigned"); - snprintf(key_name, sizeof(key_name), "%s: %u", - inet_ntoa(pw->lsr_id), pw->pwid); + snprintfrr(key_name, sizeof(key_name), "%pI4: %u", + &pw->lsr_id, pw->pwid); json_object_object_add(json, key_name, json_pw); break; case IMSG_CTL_END: @@ -1437,9 +1462,9 @@ show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg, struct show_params *params case IMSG_CTL_SHOW_L2VPN_PW: pw = imsg->data; - vty_out (vty, "%-9s %-15s %-10u %-16s %-10s\n", pw->ifname, - inet_ntoa(pw->lsr_id), pw->pwid, pw->l2vpn_name, - (pw->status == PW_FORWARDING ? "UP" : "DOWN")); + vty_out (vty, "%-9s %-15pI4 %-10u %-16s %-10s\n", pw->ifname, + &pw->lsr_id, pw->pwid, pw->l2vpn_name, + (pw->status == PW_FORWARDING ? "UP" : "DOWN")); break; case IMSG_CTL_END: vty_out (vty, "\n"); @@ -1456,6 +1481,7 @@ show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params, json_object *json) { struct ctl_pw *pw; + char buf[PREFIX_STRLEN]; json_object *json_pw; switch (imsg->hdr.type) { @@ -1463,7 +1489,9 @@ show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params, pw = imsg->data; json_pw = json_object_new_object(); - json_object_string_add(json_pw, "peerId", inet_ntoa(pw->lsr_id)); + json_object_string_add(json_pw, "peerId", + inet_ntop(AF_INET, &pw->lsr_id, + buf, sizeof(buf))); json_object_int_add(json_pw, "vcId", pw->pwid); json_object_string_add(json_pw, "VpnName", pw->l2vpn_name); if (pw->status == PW_FORWARDING) diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index 16e9adc9d9..3852d8d23b 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -359,7 +359,7 @@ ldp_router_id_update(ZAPI_CALLBACK_ARGS) if (bad_addr_v4(router_id.u.prefix4)) return (0); - debug_zebra_in("router-id update %s", inet_ntoa(router_id.u.prefix4)); + debug_zebra_in("router-id update %pI4", &router_id.u.prefix4); global.rtr_id.s_addr = router_id.u.prefix4.s_addr; main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id, diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 940333f83c..d6da45c862 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -604,8 +604,8 @@ main_dispatch_ldpe(struct thread *thread) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handlers and exit */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); ldpe_pid = 0; if (lde_pid == 0) ldpd_shutdown(); @@ -702,8 +702,8 @@ main_dispatch_lde(struct thread *thread) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handlers and exit */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); lde_pid = 0; if (ldpe_pid == 0) ldpd_shutdown(); @@ -728,8 +728,8 @@ ldp_write_handler(struct thread *thread) fatal("msgbuf_write"); if (n == 0) { /* this pipe is dead, so remove the event handlers */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); return (0); } @@ -816,7 +816,7 @@ evbuf_init(struct evbuf *eb, int fd, int (*handler)(struct thread *), void evbuf_clear(struct evbuf *eb) { - THREAD_WRITE_OFF(eb->ev); + thread_cancel(&eb->ev); msgbuf_clear(&eb->wbuf); eb->wbuf.fd = -1; } diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index d3374a62db..ffc1d17f51 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -208,7 +208,7 @@ ldpe_shutdown(void) #ifdef __OpenBSD__ if (sysdep.no_pfkey == 0) { - THREAD_READ_OFF(pfkey_ev); + thread_cancel(&pfkey_ev); close(global.pfkeysock); } #endif @@ -580,8 +580,8 @@ ldpe_dispatch_main(struct thread *thread) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handlers and exit */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); ldpe_shutdown(); } @@ -719,8 +719,8 @@ ldpe_dispatch_lde(struct thread *thread) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handlers and exit */ - THREAD_READ_OFF(iev->ev_read); - THREAD_WRITE_OFF(iev->ev_write); + thread_cancel(&iev->ev_read); + thread_cancel(&iev->ev_write); ldpe_shutdown(); } @@ -778,14 +778,14 @@ ldpe_close_sockets(int af) af_global = ldp_af_global_get(&global, af); /* discovery socket */ - THREAD_READ_OFF(af_global->disc_ev); + thread_cancel(&af_global->disc_ev); if (af_global->ldp_disc_socket != -1) { close(af_global->ldp_disc_socket); af_global->ldp_disc_socket = -1; } /* extended discovery socket */ - THREAD_READ_OFF(af_global->edisc_ev); + thread_cancel(&af_global->edisc_ev); if (af_global->ldp_edisc_socket != -1) { close(af_global->ldp_edisc_socket); af_global->ldp_edisc_socket = -1; diff --git a/ldpd/logmsg.c b/ldpd/logmsg.c index 6427d0e13b..ff9294f9d2 100644 --- a/ldpd/logmsg.c +++ b/ldpd/logmsg.c @@ -17,6 +17,7 @@ */ #include <zebra.h> +#include "lib/printfrr.h" #include "mpls.h" @@ -254,10 +255,10 @@ log_fec(const struct fec *fec) return ("???"); break; case FEC_TYPE_PWID: - if (snprintf(buf, sizeof(buf), - "pwid %u (%s) - %s", - fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type), - inet_ntoa(fec->u.pwid.lsr_id)) == -1) + if (snprintfrr(buf, sizeof(buf), + "pwid %u (%s) - %pI4", + fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type), + &fec->u.pwid.lsr_id) == -1) return ("???"); break; default: diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index 236d3eaa58..75deaad2c0 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -143,7 +143,7 @@ nbr_fsm(struct nbr *nbr, enum nbr_event event) if (nbr_fsm_tbl[i].state == -1) { /* event outside of the defined fsm, ignore it. */ - log_warnx("%s: lsr-id %s, event %s not expected in state %s", __func__, inet_ntoa(nbr->id), + log_warnx("%s: lsr-id %pI4, event %s not expected in state %s", __func__, &nbr->id, nbr_event_names[event], nbr_state_name(old_state)); return (0); } @@ -152,10 +152,10 @@ nbr_fsm(struct nbr *nbr, enum nbr_event event) nbr->state = new_state; if (old_state != nbr->state) { - log_debug("%s: event %s resulted in action %s and changing state for lsr-id %s from %s to %s", + log_debug("%s: event %s resulted in action %s and changing state for lsr-id %pI4 from %s to %s", __func__, nbr_event_names[event], nbr_action_names[nbr_fsm_tbl[i].action], - inet_ntoa(nbr->id), nbr_state_name(old_state), + &nbr->id, nbr_state_name(old_state), nbr_state_name(nbr->state)); if (nbr->state == NBR_STA_OPER) { @@ -223,8 +223,8 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr, struct adj *adj; struct pending_conn *pconn; - log_debug("%s: lsr-id %s transport-address %s", __func__, - inet_ntoa(id), log_addr(af, addr)); + log_debug("%s: lsr-id %pI4 transport-address %s", __func__, + &id, log_addr(af, addr)); if ((nbr = calloc(1, sizeof(*nbr))) == NULL) fatal(__func__); @@ -289,7 +289,7 @@ nbr_del(struct nbr *nbr) { struct adj *adj; - log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4", __func__, &nbr->id); nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION); #ifdef __OpenBSD__ @@ -302,7 +302,7 @@ nbr_del(struct nbr *nbr) nbr->auth.method = AUTH_NONE; if (nbr_pending_connect(nbr)) - THREAD_WRITE_OFF(nbr->ev_connect); + thread_cancel(&nbr->ev_connect); nbr_stop_ktimer(nbr); nbr_stop_ktimeout(nbr); nbr_stop_itimeout(nbr); @@ -416,7 +416,7 @@ nbr_start_ktimer(struct nbr *nbr) /* send three keepalives per period */ secs = nbr->keepalive / KEEPALIVE_PER_PERIOD; - THREAD_TIMER_OFF(nbr->keepalive_timer); + thread_cancel(&nbr->keepalive_timer); nbr->keepalive_timer = NULL; thread_add_timer(master, nbr_ktimer, nbr, secs, &nbr->keepalive_timer); } @@ -424,7 +424,7 @@ nbr_start_ktimer(struct nbr *nbr) void nbr_stop_ktimer(struct nbr *nbr) { - THREAD_TIMER_OFF(nbr->keepalive_timer); + thread_cancel(&nbr->keepalive_timer); } /* Keepalive timeout: if the nbr hasn't sent keepalive */ @@ -436,7 +436,7 @@ nbr_ktimeout(struct thread *thread) nbr->keepalive_timeout = NULL; - log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4", __func__, &nbr->id); session_shutdown(nbr, S_KEEPALIVE_TMR, 0, 0); @@ -446,7 +446,7 @@ nbr_ktimeout(struct thread *thread) static void nbr_start_ktimeout(struct nbr *nbr) { - THREAD_TIMER_OFF(nbr->keepalive_timeout); + thread_cancel(&nbr->keepalive_timeout); nbr->keepalive_timeout = NULL; thread_add_timer(master, nbr_ktimeout, nbr, nbr->keepalive, &nbr->keepalive_timeout); @@ -455,7 +455,7 @@ nbr_start_ktimeout(struct nbr *nbr) void nbr_stop_ktimeout(struct nbr *nbr) { - THREAD_TIMER_OFF(nbr->keepalive_timeout); + thread_cancel(&nbr->keepalive_timeout); } /* Session initialization timeout: if nbr got stuck in the initialization FSM */ @@ -465,7 +465,7 @@ nbr_itimeout(struct thread *thread) { struct nbr *nbr = THREAD_ARG(thread); - log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4", __func__, &nbr->id); nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION); @@ -478,7 +478,7 @@ nbr_start_itimeout(struct nbr *nbr) int secs; secs = INIT_FSM_TIMEOUT; - THREAD_TIMER_OFF(nbr->init_timeout); + thread_cancel(&nbr->init_timeout); nbr->init_timeout = NULL; thread_add_timer(master, nbr_itimeout, nbr, secs, &nbr->init_timeout); } @@ -486,7 +486,7 @@ nbr_start_itimeout(struct nbr *nbr) void nbr_stop_itimeout(struct nbr *nbr) { - THREAD_TIMER_OFF(nbr->init_timeout); + thread_cancel(&nbr->init_timeout); } /* Init delay timer: timer to retry to iniziatize session */ @@ -498,7 +498,7 @@ nbr_idtimer(struct thread *thread) nbr->initdelay_timer = NULL; - log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4", __func__, &nbr->id); nbr_establish_connection(nbr); @@ -527,7 +527,7 @@ nbr_start_idtimer(struct nbr *nbr) break; } - THREAD_TIMER_OFF(nbr->initdelay_timer); + thread_cancel(&nbr->initdelay_timer); nbr->initdelay_timer = NULL; thread_add_timer(master, nbr_idtimer, nbr, secs, &nbr->initdelay_timer); @@ -536,7 +536,7 @@ nbr_start_idtimer(struct nbr *nbr) void nbr_stop_idtimer(struct nbr *nbr) { - THREAD_TIMER_OFF(nbr->initdelay_timer); + thread_cancel(&nbr->initdelay_timer); } int @@ -619,12 +619,12 @@ nbr_establish_connection(struct nbr *nbr) if (nbr->af == AF_INET) { if (sock_set_ipv4_tos(nbr->fd, IPTOS_PREC_INTERNETCONTROL) == -1) - log_warn("%s: lsr-id %s, sock_set_ipv4_tos error", - __func__, inet_ntoa(nbr->id)); + log_warn("%s: lsr-id %pI4, sock_set_ipv4_tos error", + __func__, &nbr->id); } else if (nbr->af == AF_INET6) { if (sock_set_ipv6_dscp(nbr->fd, IPTOS_PREC_INTERNETCONTROL) == -1) - log_warn("%s: lsr-id %s, sock_set_ipv6_dscp error", - __func__, inet_ntoa(nbr->id)); + log_warn("%s: lsr-id %pI4, sock_set_ipv6_dscp error", + __func__, &nbr->id); } addr2sa(nbr->af, &nbr->laddr, 0, &local_su); @@ -746,8 +746,8 @@ nbr_gtsm_check(int fd, struct nbr *nbr, struct nbr_params *nbrp) } if (nbr_gtsm_setup(fd, nbr->af, nbrp) == -1) { - log_warnx("%s: error enabling GTSM for lsr-id %s", __func__, - inet_ntoa(nbr->id)); + log_warnx("%s: error enabling GTSM for lsr-id %pI4", __func__, + &nbr->id); return (-1); } diff --git a/ldpd/notification.c b/ldpd/notification.c index 93be9d3cb0..f84e0f893b 100644 --- a/ldpd/notification.c +++ b/ldpd/notification.c @@ -309,13 +309,13 @@ void log_msg_notification(int out, struct nbr *nbr, struct notify_msg *nm) { if (nm->status_code & STATUS_FATAL) { - debug_msg(out, "notification: lsr-id %s, status %s (fatal error)", inet_ntoa(nbr->id), + debug_msg(out, "notification: lsr-id %pI4, status %s (fatal error)", &nbr->id, status_code_name(nm->status_code)); return; } - debug_msg(out, "notification: lsr-id %s, status %s", - inet_ntoa(nbr->id), status_code_name(nm->status_code)); + debug_msg(out, "notification: lsr-id %pI4, status %s", + &nbr->id, status_code_name(nm->status_code)); if (nm->flags & F_NOTIF_FEC) debug_msg(out, "notification: fec %s", log_map(&nm->fec)); if (nm->flags & F_NOTIF_PW_STATUS) diff --git a/ldpd/packet.c b/ldpd/packet.c index 3f73f8cd88..fdcaa79d23 100644 --- a/ldpd/packet.c +++ b/ldpd/packet.c @@ -366,7 +366,7 @@ session_accept(struct thread *thread) return (0); } if (nbr->state != NBR_STA_PRESENT) { - log_debug("%s: lsr-id %s: rejecting additional transport connection", __func__, inet_ntoa(nbr->id)); + log_debug("%s: lsr-id %pI4: rejecting additional transport connection", __func__, &nbr->id); close(newfd); return (0); } @@ -558,8 +558,8 @@ session_read(struct thread *thread) type); break; default: - log_debug("%s: unknown LDP message from nbr %s", - __func__, inet_ntoa(nbr->id)); + log_debug("%s: unknown LDP message from nbr %pI4", + __func__, &nbr->id); if (!(ntohs(msg->type) & UNKNOWN_FLAG)) send_notification(nbr->tcp, S_UNKNOWN_MSG, msg->id, msg->type); @@ -662,7 +662,7 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id, switch (nbr->state) { case NBR_STA_PRESENT: if (nbr_pending_connect(nbr)) - THREAD_WRITE_OFF(nbr->ev_connect); + thread_cancel(&nbr->ev_connect); break; case NBR_STA_INITIAL: case NBR_STA_OPENREC: @@ -680,8 +680,8 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id, void session_close(struct nbr *nbr) { - log_debug("%s: closing session with lsr-id %s", __func__, - inet_ntoa(nbr->id)); + log_debug("%s: closing session with lsr-id %pI4", __func__, + &nbr->id); ldp_sync_fsm_nbr_event(nbr, LDP_SYNC_EVT_SESSION_CLOSE); @@ -762,7 +762,7 @@ tcp_close(struct tcp_conn *tcp) evbuf_clear(&tcp->wbuf); if (tcp->nbr) { - THREAD_READ_OFF(tcp->rev); + thread_cancel(&tcp->rev); free(tcp->rbuf); tcp->nbr->tcp = NULL; } @@ -794,7 +794,7 @@ pending_conn_new(int fd, int af, union ldpd_addr *addr) void pending_conn_del(struct pending_conn *pconn) { - THREAD_TIMER_OFF(pconn->ev_timeout); + thread_cancel(&pconn->ev_timeout); TAILQ_REMOVE(&global.pending_conns, pconn, entry); free(pconn); } diff --git a/lib/agentx.c b/lib/agentx.c index 7c4bdcbe27..603d8d6172 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -107,7 +107,7 @@ static void agentx_events_update(void) struct thread *thr; int fd, thr_fd; - THREAD_OFF(timeout_thr); + thread_cancel(&timeout_thr); FD_ZERO(&fds); snmp_select_info(&maxfd, &fds, &timeout, &block); @@ -130,7 +130,7 @@ static void agentx_events_update(void) if (thr_fd == fd) { struct listnode *nextln = listnextnode(ln); if (!FD_ISSET(fd, &fds)) { - thread_cancel(thr); + thread_cancel(&thr); list_delete_node(events, ln); } ln = nextln; @@ -151,7 +151,8 @@ static void agentx_events_update(void) */ while (ln) { struct listnode *nextln = listnextnode(ln); - thread_cancel(listgetdata(ln)); + thr = listgetdata(ln); + thread_cancel(&thr); list_delete_node(events, ln); ln = nextln; } diff --git a/lib/agg_table.h b/lib/agg_table.h index e98476f1b7..e0c06449ee 100644 --- a/lib/agg_table.h +++ b/lib/agg_table.h @@ -161,6 +161,11 @@ agg_node_get_prefix(const struct agg_node *node) return &node->p; } +static inline unsigned int agg_node_get_lock_count(const struct agg_node *node) +{ + return node->lock; +} + #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pRN" (struct agg_node *) #endif diff --git a/lib/command.c b/lib/command.c index 1e950fe483..7d335e1c36 100644 --- a/lib/command.c +++ b/lib/command.c @@ -139,6 +139,27 @@ static struct cmd_node config_node = { .node_exit = vty_config_node_exit, }; +static bool vty_check_node_for_xpath_decrement(enum node_type target_node, + enum node_type node) +{ + /* bgp afi-safi (`address-family <afi> <safi>`) node + * does not increment xpath_index. + * In order to use (`router bgp`) BGP_NODE's xpath as a base, + * retain xpath_index as 1 upon exiting from + * afi-safi node. + */ + + if (target_node == BGP_NODE + && (node == BGP_IPV4_NODE || node == BGP_IPV6_NODE + || node == BGP_IPV4M_NODE || node == BGP_IPV6M_NODE + || node == BGP_VPNV4_NODE || node == BGP_VPNV6_NODE + || node == BGP_EVPN_NODE || node == BGP_IPV4L_NODE + || node == BGP_IPV6L_NODE )) + return false; + + return true; +} + /* This is called from main when a daemon is invoked with -v or --version. */ void print_version(const char *progname) { @@ -985,7 +1006,9 @@ int cmd_execute_command(vector vline, struct vty *vty, while (vty->node > CONFIG_NODE) { try_node = node_parent(try_node); vty->node = try_node; - if (vty->xpath_index > 0) + if (vty->xpath_index > 0 + && vty_check_node_for_xpath_decrement(try_node, + onode)) vty->xpath_index--; ret = cmd_execute_command_real(vline, FILTER_RELAXED, vty, cmd); @@ -1194,7 +1217,9 @@ int command_config_read_one_line(struct vty *vty, && ret != CMD_SUCCESS && ret != CMD_WARNING && vty->node > CONFIG_NODE) { vty->node = node_parent(vty->node); - if (vty->xpath_index > 0) + if (vty->xpath_index > 0 + && vty_check_node_for_xpath_decrement(vty->node, + saved_node)) vty->xpath_index--; ret = cmd_execute_command_strict(vline, vty, cmd); } @@ -1316,7 +1341,8 @@ void cmd_exit(struct vty *vty) } if (cnode->parent_node) vty->node = cnode->parent_node; - if (vty->xpath_index > 0) + if (vty->xpath_index > 0 + && vty_check_node_for_xpath_decrement(vty->node, cnode->node)) vty->xpath_index--; } diff --git a/lib/command.h b/lib/command.h index dc148a92a8..bb007b0868 100644 --- a/lib/command.h +++ b/lib/command.h @@ -452,6 +452,25 @@ struct cmd_node { #define GR_NEIGHBOR_HELPER_CMD "Graceful Restart Helper command for a neighbor\n" #define NO_GR_NEIGHBOR_HELPER_CMD "Undo Graceful Restart Helper command for a neighbor\n" +/* EVPN help Strings */ +#define EVPN_RT_HELP_STR "EVPN route information\n" +#define EVPN_RT_DIST_HELP_STR "Route Distinguisher\n" +#define EVPN_ASN_IP_HELP_STR "ASN:XX or A.B.C.D:XX\n" +#define EVPN_TYPE_HELP_STR "Specify Route type\n" +#define EVPN_TYPE_1_HELP_STR "EAD (Type-1) route\n" +#define EVPN_TYPE_2_HELP_STR "MAC-IP (Type-2) route\n" +#define EVPN_TYPE_3_HELP_STR "Multicast (Type-3) route\n" +#define EVPN_TYPE_4_HELP_STR "Ethernet Segment (Type-4) route\n" +#define EVPN_TYPE_5_HELP_STR "Prefix (Type-5) route\n" +#define EVPN_TYPE_ALL_LIST "<ead|1|macip|2|multicast|3|es|4|prefix|5>" +#define EVPN_TYPE_ALL_LIST_HELP_STR \ + EVPN_TYPE_1_HELP_STR EVPN_TYPE_1_HELP_STR \ + EVPN_TYPE_2_HELP_STR EVPN_TYPE_2_HELP_STR \ + EVPN_TYPE_3_HELP_STR EVPN_TYPE_3_HELP_STR \ + EVPN_TYPE_4_HELP_STR EVPN_TYPE_4_HELP_STR \ + EVPN_TYPE_5_HELP_STR EVPN_TYPE_5_HELP_STR + + /* Prototypes. */ extern void install_node(struct cmd_node *node); extern void install_default(enum node_type); diff --git a/lib/filter.c b/lib/filter.c index e6add0462b..f5ae9ee2b7 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -576,14 +576,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi) if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any\n"); else { - vty_out(vty, " %s", - inet_ntoa(filter->addr)); + vty_out(vty, " %pI4", &filter->addr); if (filter->addr_mask.s_addr != INADDR_ANY) vty_out(vty, - ", wildcard bits %s", - inet_ntoa( - filter->addr_mask)); + ", wildcard bits %pI4", + &filter->addr_mask); vty_out(vty, "\n"); } } @@ -625,14 +623,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi) if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any\n"); else { - vty_out(vty, " %s", - inet_ntoa(filter->addr)); + vty_out(vty, " %pI4", &filter->addr); if (filter->addr_mask.s_addr != INADDR_ANY) vty_out(vty, - ", wildcard bits %s", - inet_ntoa( - filter->addr_mask)); + ", wildcard bits %pI4", + &filter->addr_mask); vty_out(vty, "\n"); } } @@ -722,29 +718,28 @@ static void config_write_access_cisco(struct vty *vty, struct filter *mfilter) if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any"); else if (filter->addr_mask.s_addr == INADDR_ANY) - vty_out(vty, " host %s", inet_ntoa(filter->addr)); + vty_out(vty, " host %pI4", &filter->addr); else { - vty_out(vty, " %s", inet_ntoa(filter->addr)); - vty_out(vty, " %s", inet_ntoa(filter->addr_mask)); + vty_out(vty, " %pI4", &filter->addr); + vty_out(vty, " %pI4", &filter->addr_mask); } if (filter->mask_mask.s_addr == 0xffffffff) vty_out(vty, " any"); else if (filter->mask_mask.s_addr == INADDR_ANY) - vty_out(vty, " host %s", inet_ntoa(filter->mask)); + vty_out(vty, " host %pI4", &filter->mask); else { - vty_out(vty, " %s", inet_ntoa(filter->mask)); - vty_out(vty, " %s", inet_ntoa(filter->mask_mask)); + vty_out(vty, " %pI4", &filter->mask); + vty_out(vty, " %pI4", &filter->mask_mask); } vty_out(vty, "\n"); } else { if (filter->addr_mask.s_addr == 0xffffffff) vty_out(vty, " any\n"); else { - vty_out(vty, " %s", inet_ntoa(filter->addr)); + vty_out(vty, " %pI4", &filter->addr); if (filter->addr_mask.s_addr != INADDR_ANY) - vty_out(vty, " %s", - inet_ntoa(filter->addr_mask)); + vty_out(vty, " %pI4", &filter->addr_mask); vty_out(vty, "\n"); } } diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 09fc3289ce..a8230f3a9a 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -115,21 +115,6 @@ static int64_t acl_zebra_get_seq(struct access_list *acl, const char *action, } /* - * Helper function to concatenate address with mask in Cisco style. - */ -static void concat_addr_mask_v4(const char *addr, const char *mask, char *dst, - size_t dstlen) -{ - struct in_addr ia; - int plen; - - assert(inet_pton(AF_INET, mask, &ia) == 1); - ia.s_addr = ~ia.s_addr; - plen = ip_masklen(ia); - snprintf(dst, dstlen, "%s/%d", addr, plen); -} - -/* * Helper function to generate a sequence number for legacy commands. */ static int acl_get_seq_cb(const struct lyd_node *dnode, void *arg) @@ -177,7 +162,6 @@ DEFPY_YANG( "Wildcard bits\n") { int64_t sseq; - char ipmask[64]; char xpath[XPATH_MAXLEN]; char xpath_entry[XPATH_MAXLEN + 128]; @@ -203,8 +187,10 @@ DEFPY_YANG( if (host_str != NULL && mask_str == NULL) { nb_cli_enqueue_change(vty, "./host", NB_OP_MODIFY, host_str); } else if (host_str != NULL && mask_str != NULL) { - concat_addr_mask_v4(host_str, mask_str, ipmask, sizeof(ipmask)); - nb_cli_enqueue_change(vty, "./network", NB_OP_MODIFY, ipmask); + nb_cli_enqueue_change(vty, "./network/address", NB_OP_MODIFY, + host_str); + nb_cli_enqueue_change(vty, "./network/mask", NB_OP_MODIFY, + mask_str); } else { nb_cli_enqueue_change(vty, "./source-any", NB_OP_CREATE, NULL); } @@ -285,7 +271,6 @@ DEFPY_YANG( "Any destination host\n") { int64_t sseq; - char ipmask[64], ipmask_dst[64]; char xpath[XPATH_MAXLEN]; char xpath_entry[XPATH_MAXLEN + 128]; @@ -311,9 +296,10 @@ DEFPY_YANG( if (src_str != NULL && src_mask_str == NULL) { nb_cli_enqueue_change(vty, "./host", NB_OP_MODIFY, src_str); } else if (src_str != NULL && src_mask_str != NULL) { - concat_addr_mask_v4(src_str, src_mask_str, ipmask, - sizeof(ipmask)); - nb_cli_enqueue_change(vty, "./network", NB_OP_MODIFY, ipmask); + nb_cli_enqueue_change(vty, "./network/address", NB_OP_MODIFY, + src_str); + nb_cli_enqueue_change(vty, "./network/mask", NB_OP_MODIFY, + src_mask_str); } else { nb_cli_enqueue_change(vty, "./source-any", NB_OP_CREATE, NULL); } @@ -322,10 +308,10 @@ DEFPY_YANG( nb_cli_enqueue_change(vty, "./destination-host", NB_OP_MODIFY, dst_str); } else if (dst_str != NULL && dst_mask_str != NULL) { - concat_addr_mask_v4(dst_str, dst_mask_str, ipmask_dst, - sizeof(ipmask_dst)); - nb_cli_enqueue_change(vty, "./destination-network", - NB_OP_MODIFY, ipmask_dst); + nb_cli_enqueue_change(vty, "./destination-network/address", + NB_OP_MODIFY, dst_str); + nb_cli_enqueue_change(vty, "./destination-network/mask", + NB_OP_MODIFY, dst_mask_str); } else { nb_cli_enqueue_change(vty, "./destination-any", NB_OP_CREATE, NULL); @@ -947,7 +933,7 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode, bool is_exact = false; bool cisco_style = false; bool cisco_extended = false; - struct in_addr mask; + struct in_addr addr, mask; char macstr[PREFIX2STR_BUFFER]; is_any = yang_dnode_exists(dnode, "./any"); @@ -957,11 +943,12 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode, break; if (yang_dnode_exists(dnode, "./host") - || yang_dnode_exists(dnode, "./network") + || yang_dnode_exists(dnode, "./network/address") || yang_dnode_exists(dnode, "./source-any")) { cisco_style = true; if (yang_dnode_exists(dnode, "./destination-host") - || yang_dnode_exists(dnode, "./destination-network") + || yang_dnode_exists( + dnode, "./destination-network/address") || yang_dnode_exists(dnode, "./destination-any")) cisco_extended = true; } else { @@ -998,9 +985,9 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode, vty_out(vty, " ip"); if (yang_dnode_exists(dnode, "./network")) { - yang_dnode_get_prefix(&p, dnode, "./network"); - masklen2ip(p.prefixlen, &mask); - vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask); + yang_dnode_get_ipv4(&addr, dnode, "./network/address"); + yang_dnode_get_ipv4(&mask, dnode, "./network/mask"); + vty_out(vty, " %pI4 %pI4", &addr, &mask); } else if (yang_dnode_exists(dnode, "./host")) { if (cisco_extended) vty_out(vty, " host"); @@ -1018,10 +1005,11 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode, /* Handle destination address. */ if (yang_dnode_exists(dnode, "./destination-network")) { - yang_dnode_get_prefix(&p, dnode, - "./destination-network"); - masklen2ip(p.prefixlen, &mask); - vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask); + yang_dnode_get_ipv4(&addr, dnode, + "./destination-network/address"); + yang_dnode_get_ipv4(&mask, dnode, + "./destination-network/mask"); + vty_out(vty, " %pI4 %pI4", &addr, &mask); } else if (yang_dnode_exists(dnode, "./destination-host")) vty_out(vty, " host %s", yang_dnode_get_string(dnode, diff --git a/lib/filter_nb.c b/lib/filter_nb.c index 8838a48abd..1d522bdbec 100644 --- a/lib/filter_nb.c +++ b/lib/filter_nb.c @@ -32,15 +32,6 @@ #include "lib/routemap.h" /* Helper function. */ -static in_addr_t -ipv4_network_addr(in_addr_t hostaddr, int masklen) -{ - struct in_addr mask; - - masklen2ip(masklen, &mask); - return hostaddr & mask.s_addr; -} - static void acl_notify_route_map(struct access_list *acl, int route_map_event) { switch (route_map_event) { @@ -86,11 +77,11 @@ static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args) /* * Check rule: - * prefix length < ge. + * prefix length <= ge. */ if (yang_dnode_exists(args->dnode, xpath_ge)) { ge = yang_dnode_get_uint8(args->dnode, xpath_ge); - if (p.prefixlen >= ge) + if (p.prefixlen > ge) goto log_and_fail; } @@ -111,7 +102,7 @@ static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args) log_and_fail: snprintfrr( args->errmsg, args->errmsg_len, - "Invalid prefix range for %pFX: Make sure that mask length < ge <= le", + "Invalid prefix range for %pFX: Make sure that mask length <= ge <= le", &p); return NB_ERR_VALIDATION; } @@ -411,14 +402,13 @@ lib_access_list_entry_host_destroy(struct nb_cb_destroy_args *args) } /* - * XPath: /frr-filter:lib/access-list/entry/network + * XPath: /frr-filter:lib/access-list/entry/network/address */ static int -lib_access_list_entry_network_modify(struct nb_cb_modify_args *args) +lib_access_list_entry_network_address_modify(struct nb_cb_modify_args *args) { struct filter_cisco *fc; struct filter *f; - struct prefix p; if (args->event != NB_EV_APPLY) return NB_OK; @@ -426,18 +416,18 @@ lib_access_list_entry_network_modify(struct nb_cb_modify_args *args) f = nb_running_get_entry(args->dnode, NULL, true); f->cisco = 1; fc = &f->u.cfilter; - yang_dnode_get_prefix(&p, args->dnode, NULL); - fc->addr.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen); - masklen2ip(p.prefixlen, &fc->addr_mask); - fc->addr_mask.s_addr = ~fc->addr_mask.s_addr; + yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL); acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED); return NB_OK; } +/* + * XPath: /frr-filter:lib/access-list/entry/network/mask + */ static int -lib_access_list_entry_network_destroy(struct nb_cb_destroy_args *args) +lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args *args) { struct filter_cisco *fc; struct filter *f; @@ -446,10 +436,11 @@ lib_access_list_entry_network_destroy(struct nb_cb_destroy_args *args) return NB_OK; f = nb_running_get_entry(args->dnode, NULL, true); + f->cisco = 1; fc = &f->u.cfilter; - cisco_unset_addr_mask(&fc->addr, &fc->addr_mask); + yang_dnode_get_ipv4(&fc->addr_mask, args->dnode, NULL); - acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED); + acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED); return NB_OK; } @@ -538,14 +529,13 @@ static int lib_access_list_entry_destination_host_destroy( } /* - * XPath: /frr-filter:lib/access-list/entry/destination-network + * XPath: /frr-filter:lib/access-list/entry/destination-network/address */ -static int lib_access_list_entry_destination_network_modify( +static int lib_access_list_entry_destination_network_address_modify( struct nb_cb_modify_args *args) { struct filter_cisco *fc; struct filter *f; - struct prefix p; if (args->event != NB_EV_APPLY) return NB_OK; @@ -553,18 +543,18 @@ static int lib_access_list_entry_destination_network_modify( f = nb_running_get_entry(args->dnode, NULL, true); fc = &f->u.cfilter; fc->extended = 1; - yang_dnode_get_prefix(&p, args->dnode, NULL); - fc->mask.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen); - masklen2ip(p.prefixlen, &fc->mask_mask); - fc->mask_mask.s_addr = ~fc->mask_mask.s_addr; + yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL); acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED); return NB_OK; } -static int lib_access_list_entry_destination_network_destroy( - struct nb_cb_destroy_args *args) +/* + * XPath: /frr-filter:lib/access-list/entry/destination-network/mask + */ +static int lib_access_list_entry_destination_network_mask_modify( + struct nb_cb_modify_args *args) { struct filter_cisco *fc; struct filter *f; @@ -574,10 +564,10 @@ static int lib_access_list_entry_destination_network_destroy( f = nb_running_get_entry(args->dnode, NULL, true); fc = &f->u.cfilter; - fc->extended = 0; - cisco_unset_addr_mask(&fc->mask, &fc->mask_mask); + fc->extended = 1; + yang_dnode_get_ipv4(&fc->mask_mask, args->dnode, NULL); - acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED); + acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED); return NB_OK; } @@ -1100,10 +1090,15 @@ const struct frr_yang_module_info frr_filter_info = { } }, { - .xpath = "/frr-filter:lib/access-list/entry/network", + .xpath = "/frr-filter:lib/access-list/entry/network/address", .cbs = { - .modify = lib_access_list_entry_network_modify, - .destroy = lib_access_list_entry_network_destroy, + .modify = lib_access_list_entry_network_address_modify, + } + }, + { + .xpath = "/frr-filter:lib/access-list/entry/network/mask", + .cbs = { + .modify = lib_access_list_entry_network_mask_modify, } }, { @@ -1121,10 +1116,15 @@ const struct frr_yang_module_info frr_filter_info = { } }, { - .xpath = "/frr-filter:lib/access-list/entry/destination-network", + .xpath = "/frr-filter:lib/access-list/entry/destination-network/address", + .cbs = { + .modify = lib_access_list_entry_destination_network_address_modify, + } + }, + { + .xpath = "/frr-filter:lib/access-list/entry/destination-network/mask", .cbs = { - .modify = lib_access_list_entry_destination_network_modify, - .destroy = lib_access_list_entry_destination_network_destroy, + .modify = lib_access_list_entry_destination_network_mask_modify, } }, { diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index da9594ed80..3f0179fbc1 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -28,6 +28,7 @@ #include "memory.h" #include "linklist.h" #include "zlog.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread") DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives") @@ -167,6 +168,8 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr) sigfillset(&blocksigs); pthread_sigmask(SIG_BLOCK, &blocksigs, &oldsigs); + frrtrace(1, frr_libfrr, frr_pthread_run, fpt->name); + fpt->rcu_thread = rcu_thread_prepare(); ret = pthread_create(&fpt->thread, attr, frr_pthread_inner, fpt); @@ -204,6 +207,8 @@ void frr_pthread_notify_running(struct frr_pthread *fpt) int frr_pthread_stop(struct frr_pthread *fpt, void **result) { + frrtrace(1, frr_libfrr, frr_pthread_stop, fpt->name); + int ret = (*fpt->attr.stop)(fpt, result); memset(&fpt->thread, 0x00, sizeof(fpt->thread)); return ret; diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index 565936a410..cc11d76700 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -190,10 +190,8 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master, cb->read.cancelled = false; if (events & ZMQ_POLLIN) { - if (cb->read.thread) { - thread_cancel(cb->read.thread); - cb->read.thread = NULL; - } + thread_cancel(&cb->read.thread); + funcname_thread_add_event(master, frrzmq_read_msg, cbp, fd, &cb->read.thread, funcname, schedfrom, fromln); @@ -298,10 +296,8 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master, cb->write.cancelled = false; if (events & ZMQ_POLLOUT) { - if (cb->write.thread) { - thread_cancel(cb->write.thread); - cb->write.thread = NULL; - } + thread_cancel(&cb->write.thread); + funcname_thread_add_event(master, frrzmq_write_msg, cbp, fd, &cb->write.thread, funcname, schedfrom, fromln); @@ -317,10 +313,8 @@ void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core) if (!cb || !*cb) return; core->cancelled = true; - if (core->thread) { - thread_cancel(core->thread); - core->thread = NULL; - } + thread_cancel(&core->thread); + if ((*cb)->read.cancelled && !(*cb)->read.thread && (*cb)->write.cancelled && (*cb)->write.thread) XFREE(MTYPE_ZEROMQ_CB, *cb); @@ -344,8 +338,8 @@ void frrzmq_check_events(struct frrzmq_cb **cbp, struct cb_core *core, return; if (events & event && core->thread && !core->cancelled) { struct thread_master *tm = core->thread->master; - thread_cancel(core->thread); - core->thread = NULL; + thread_cancel(&core->thread); + thread_add_event(tm, (event == ZMQ_POLLIN ? frrzmq_read_msg : frrzmq_write_msg), cbp, cb->fd, &core->thread); diff --git a/lib/hash.c b/lib/hash.c index 85982774ac..ed429b77d0 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -29,6 +29,7 @@ #include "command.h" #include "libfrr.h" #include "frr_pthread.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, HASH, "Hash") DEFINE_MTYPE_STATIC(LIB, HASH_BACKET, "Hash Bucket") @@ -138,6 +139,8 @@ static void hash_expand(struct hash *hash) void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *)) { + frrtrace(2, frr_libfrr, hash_get, hash, data); + unsigned int key; unsigned int index; void *newdata; @@ -172,6 +175,8 @@ void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *)) hash->index[index] = bucket; hash->count++; + frrtrace(3, frr_libfrr, hash_insert, hash, data, key); + int oldlen = bucket->next ? bucket->next->len : 0; int newlen = oldlen + 1; @@ -206,7 +211,7 @@ unsigned int string_hash_make(const char *str) void *hash_release(struct hash *hash, void *data) { - void *ret; + void *ret = NULL; unsigned int key; unsigned int index; struct hash_bucket *bucket; @@ -236,11 +241,14 @@ void *hash_release(struct hash *hash, void *data) ret = bucket->data; XFREE(MTYPE_HASH_BACKET, bucket); hash->count--; - return ret; + break; } pp = bucket; } - return NULL; + + frrtrace(3, frr_libfrr, hash_release, hash, data, ret); + + return ret; } void hash_iterate(struct hash *hash, void (*func)(struct hash_bucket *, void *), @@ -826,7 +826,7 @@ DEFUN (show_address, p = ifc->address; if (p->family == AF_INET) - vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + vty_out (vty, "%pFX\n", p); } } return CMD_SUCCESS; @@ -858,7 +858,7 @@ DEFUN (show_address_vrf_all, p = ifc->address; if (p->family == AF_INET) - vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + vty_out (vty, "%pFX\n", p); } } } @@ -929,10 +929,9 @@ connected_log(struct connected *connected, char *str) p = connected->address; vrf = vrf_lookup_by_id(ifp->vrf_id); - snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %s/%d ", + snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %pFX ", str, ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, - prefix_family_str(p), - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + prefix_family_str(p), p); p = connected->destination; if (p) { @@ -949,14 +948,12 @@ nbr_connected_log(struct nbr_connected *connected, char *str) struct prefix *p; struct interface *ifp; char logbuf[BUFSIZ]; - char buf[BUFSIZ]; ifp = connected->ifp; p = connected->address; - snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %s/%d ", str, - ifp->name, prefix_family_str(p), - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %pFX ", str, + ifp->name, prefix_family_str(p), p); zlog_info("%s", logbuf); } @@ -1109,8 +1106,8 @@ ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp) if (rn) { route_unlock_node (rn); - zlog_info ("ifaddr_ipv4_add(): address %s is already added", - inet_ntoa (*ifaddr)); + zlog_info("ifaddr_ipv4_add(): address %pI4 is already added", + ifaddr); return; } rn->info = ifp; @@ -1129,8 +1126,7 @@ ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp) rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p); if (! rn) { - zlog_info ("ifaddr_ipv4_delete(): can't find address %s", - inet_ntoa (*ifaddr)); + zlog_info("%s: can't find address %pI4", __func__, ifaddr); return; } rn->info = NULL; diff --git a/lib/json.c b/lib/json.c index 6bea3982e3..cfba6ea3b6 100644 --- a/lib/json.c +++ b/lib/json.c @@ -39,6 +39,11 @@ bool use_json(const int argc, struct cmd_token *argv[]) return false; } +void json_array_string_add(json_object *json, const char *str) +{ + json_object_array_add(json, json_object_new_string(str)); +} + void json_object_string_add(struct json_object *obj, const char *key, const char *s) { diff --git a/lib/json.h b/lib/json.h index afe0b175da..fe208f4fa9 100644 --- a/lib/json.h +++ b/lib/json.h @@ -57,6 +57,7 @@ extern void json_object_boolean_true_add(struct json_object *obj, const char *key); extern struct json_object *json_object_lock(struct json_object *obj); extern void json_object_free(struct json_object *obj); +extern void json_array_string_add(json_object *json, const char *str); #define JSON_STR "JavaScript Object Notation\n" diff --git a/lib/ldp_sync.c b/lib/ldp_sync.c index 5dd045d88d..c9d7eb37cf 100644 --- a/lib/ldp_sync.c +++ b/lib/ldp_sync.c @@ -79,10 +79,8 @@ bool ldp_sync_if_down(struct ldp_sync_info *ldp_sync_info) * update state */ if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) { - if (ldp_sync_info->t_holddown != NULL) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; - } + THREAD_OFF(ldp_sync_info->t_holddown); + if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP) ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; diff --git a/lib/libfrr_trace.c b/lib/libfrr_trace.c new file mode 100644 index 0000000000..2f300e6ee1 --- /dev/null +++ b/lib/libfrr_trace.c @@ -0,0 +1,4 @@ +#define TRACEPOINT_CREATE_PROBES +#define TRACEPOINT_DEFINE + +#include "libfrr_trace.h" diff --git a/lib/libfrr_trace.h b/lib/libfrr_trace.h new file mode 100644 index 0000000000..7215007ffb --- /dev/null +++ b/lib/libfrr_trace.h @@ -0,0 +1,240 @@ +/* Tracing + * + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(_LIBFRR_TRACE_H_) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define _LIBFRR_TRACE_H_ + +#include "trace.h" + +#ifdef HAVE_LTTNG + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER frr_libfrr + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./libfrr_trace.h" + +#include <lttng/tracepoint.h> + +#include "hash.h" +#include "thread.h" +#include "memory.h" +#include "linklist.h" +#include "table.h" + +/* clang-format off */ + +TRACEPOINT_EVENT( + frr_libfrr, + hash_get, + TP_ARGS(struct hash *, hash, void *, data), + TP_FIELDS( + ctf_string(name, hash->name ? hash->name : "(unnamed)") + ctf_integer(unsigned int, index_size, hash->size) + ctf_integer(unsigned long, item_count, hash->count) + ctf_integer_hex(intptr_t, data_ptr, data) + ) +) + +TRACEPOINT_LOGLEVEL(frr_libfrr, hash_get, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_libfrr, + hash_insert, + TP_ARGS(struct hash *, hash, void *, data, unsigned int, key), + TP_FIELDS( + ctf_string(name, hash->name ? hash->name : "(unnamed)") + ctf_integer(unsigned int, key, hash->size) + ctf_integer(unsigned int, index_size, hash->size) + ctf_integer(unsigned long, item_count, hash->count) + ctf_integer_hex(intptr_t, data_ptr, data) + ) +) + +TRACEPOINT_LOGLEVEL(frr_libfrr, hash_insert, TRACE_INFO) + +TRACEPOINT_EVENT( + frr_libfrr, + hash_release, + TP_ARGS(struct hash *, hash, void *, data, void *, released_item), + TP_FIELDS( + ctf_string(name, hash->name ? hash->name : "(unnamed)") + ctf_integer(unsigned int, index_size, hash->size) + ctf_integer(unsigned long, item_count, hash->count) + ctf_integer_hex(intptr_t, data_ptr, data) + ctf_integer_hex(intptr_t, released_item, data) + ) +) + +TRACEPOINT_LOGLEVEL(frr_libfrr, hash_release, TRACE_INFO) + +#define THREAD_SCHEDULE_ARGS \ + TP_ARGS(struct thread_master *, master, const char *, funcname, \ + const char *, schedfrom, int, fromln, struct thread **, \ + thread_ptr, int, fd, int, val, void *, arg, long, time) + +TRACEPOINT_EVENT_CLASS( + frr_libfrr, + thread_operation, + THREAD_SCHEDULE_ARGS, + TP_FIELDS( + ctf_string(threadmaster_name, master->name) + ctf_string(function_name, funcname ? funcname : "(unknown function)") + ctf_string(scheduled_from, schedfrom ? schedfrom : "(unknown file)") + ctf_integer(int, scheduled_on_line, fromln) + ctf_integer_hex(intptr_t, thread_addr, thread_ptr ? *thread_ptr : NULL) + ctf_integer(int, file_descriptor, fd) + ctf_integer(int, event_value, val) + ctf_integer_hex(intptr_t, argument_ptr, arg) + ctf_integer(long, timer, time) + ) +) + +#define THREAD_OPERATION_TRACEPOINT_INSTANCE(name) \ + TRACEPOINT_EVENT_INSTANCE(frr_libfrr, thread_operation, name, \ + THREAD_SCHEDULE_ARGS) \ + TRACEPOINT_LOGLEVEL(frr_libfrr, name, TRACE_INFO) + +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_timer) +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_event) +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_read) +THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_write) +THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel) +THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel_async) +THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_call) + +TRACEPOINT_EVENT( + frr_libfrr, + frr_pthread_run, + TP_ARGS( + char *, name + ), + TP_FIELDS( + ctf_string(frr_pthread_name, name) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + frr_pthread_stop, + TP_ARGS( + char *, name + ), + TP_FIELDS( + ctf_string(frr_pthread_name, name) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + memalloc, + TP_ARGS( + struct memtype *, mt, void *, ptr, size_t, size + ), + TP_FIELDS( + ctf_string(memtype, mt->name) + ctf_integer(size_t, size, size) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + memfree, + TP_ARGS( + struct memtype *, mt, void *, ptr + ), + TP_FIELDS( + ctf_string(memtype, mt->name) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_add, + TP_ARGS( + struct list *, list, const void *, ptr + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_remove, + TP_ARGS( + struct list *, list, const void *, ptr + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ctf_integer_hex(intptr_t, ptr, ptr) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_delete_node, + TP_ARGS( + struct list *, list, const void *, node + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ctf_integer_hex(intptr_t, node, node) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + list_sort, + TP_ARGS( + struct list *, list + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, list, list) + ctf_integer(unsigned int, count, list->count) + ) +) + +TRACEPOINT_EVENT( + frr_libfrr, + route_node_get, + TP_ARGS( + struct route_table *, table, char *, prefix + ), + TP_FIELDS( + ctf_integer_hex(intptr_t, table, table) + ctf_string(prefix, prefix) + ) +) + +/* clang-format on */ + +#include <lttng/tracepoint-event.h> +#include <lttng/tracelog.h> + +#endif /* HAVE_LTTNG */ + +#endif /* _LIBFRR_TRACE_H_ */ diff --git a/lib/linklist.c b/lib/linklist.c index 84dc6e1419..43c2002231 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -23,6 +23,7 @@ #include "linklist.h" #include "memory.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List") DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node") @@ -66,6 +67,8 @@ static void listnode_free(struct list *list, struct listnode *node) struct listnode *listnode_add(struct list *list, void *val) { + frrtrace(2, frr_libfrr, list_add, list, val); + struct listnode *node; assert(val != NULL); @@ -281,6 +284,8 @@ void listnode_move_to_tail(struct list *l, struct listnode *n) void listnode_delete(struct list *list, const void *val) { + frrtrace(2, frr_libfrr, list_remove, list, val); + struct listnode *node = listnode_lookup(list, val); if (node) @@ -360,6 +365,8 @@ struct listnode *listnode_lookup_nocheck(struct list *list, void *data) void list_delete_node(struct list *list, struct listnode *node) { + frrtrace(2, frr_libfrr, list_delete_node, list, node); + if (node->prev) node->prev->next = node->next; else @@ -374,6 +381,8 @@ void list_delete_node(struct list *list, struct listnode *node) void list_sort(struct list *list, int (*cmp)(const void **, const void **)) { + frrtrace(1, frr_libfrr, list_sort, list); + struct listnode *ln, *nn; int i = -1; void *data; diff --git a/lib/memory.c b/lib/memory.c index 2c902d123b..f715044ea3 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -29,6 +29,7 @@ #include "memory.h" #include "log.h" +#include "libfrr_trace.h" static struct memgroup *mg_first = NULL; struct memgroup **mg_insert = &mg_first; @@ -77,6 +78,8 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr) static inline void mt_count_free(struct memtype *mt, void *ptr) { + frrtrace(2, frr_libfrr, memfree, mt, ptr); + assert(mt->n_alloc); atomic_fetch_sub_explicit(&mt->n_alloc, 1, memory_order_relaxed); @@ -89,6 +92,8 @@ static inline void mt_count_free(struct memtype *mt, void *ptr) static inline void *mt_checkalloc(struct memtype *mt, void *ptr, size_t size) { + frrtrace(3, frr_libfrr, memalloc, mt, ptr, size); + if (__builtin_expect(ptr == NULL, 0)) { if (size) { /* malloc(0) is allowed to return NULL */ diff --git a/lib/nexthop.c b/lib/nexthop.c index 0ea72d03e1..b2fa945690 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -202,43 +202,6 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2) return ret; } -bool nexthop_same_firsthop(const struct nexthop *next1, - const struct nexthop *next2) -{ - /* Map the TYPE_IPx types to TYPE_IPx_IFINDEX */ - int type1 = NEXTHOP_FIRSTHOPTYPE(next1->type); - int type2 = NEXTHOP_FIRSTHOPTYPE(next2->type); - - if (type1 != type2) - return false; - - if (next1->vrf_id != next2->vrf_id) - return false; - - switch (type1) { - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (!IPV4_ADDR_SAME(&next1->gate.ipv4, &next2->gate.ipv4)) - return false; - if (next1->ifindex != next2->ifindex) - return false; - break; - case NEXTHOP_TYPE_IFINDEX: - if (next1->ifindex != next2->ifindex) - return false; - break; - case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&next1->gate.ipv6, &next2->gate.ipv6)) - return false; - if (next1->ifindex != next2->ifindex) - return false; - break; - default: - /* do nothing */ - break; - } - return true; -} - /* * nexthop_type_to_str */ @@ -468,13 +431,13 @@ const char *nexthop2str(const struct nexthop *nexthop, char *str, int size) break; case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - snprintf(str, size, "%s if %u", inet_ntoa(nexthop->gate.ipv4), - nexthop->ifindex); + snprintfrr(str, size, "%pI4 if %u", &nexthop->gate.ipv4, + nexthop->ifindex); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - snprintf(str, size, "%s if %u", inet6_ntoa(nexthop->gate.ipv6), - nexthop->ifindex); + snprintfrr(str, size, "%pI6 if %u", &nexthop->gate.ipv6, + nexthop->ifindex); break; case NEXTHOP_TYPE_BLACKHOLE: snprintf(str, size, "blackhole"); diff --git a/lib/nexthop.h b/lib/nexthop.h index cadcea1f41..f1ad195cf4 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -55,12 +55,6 @@ enum blackhole_type { BLACKHOLE_ADMINPROHIB, }; -/* IPV[46] -> IPV[46]_IFINDEX */ -#define NEXTHOP_FIRSTHOPTYPE(type) \ - ((type) == NEXTHOP_TYPE_IFINDEX || (type) == NEXTHOP_TYPE_BLACKHOLE) \ - ? (type) \ - : ((type) | 1) - enum nh_encap_type { NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */ }; @@ -216,8 +210,6 @@ extern int nexthop_g_addr_cmp(enum nexthop_types_t type, extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type); extern bool nexthop_labels_match(const struct nexthop *nh1, const struct nexthop *nh2); -extern bool nexthop_same_firsthop(const struct nexthop *next1, - const struct nexthop *next2); extern const char *nexthop2str(const struct nexthop *nexthop, char *str, int size); diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 83905abe43..dee98ad8d7 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -481,7 +481,7 @@ void nexthop_group_mark_duplicates(struct nexthop_group *nhg) for (ALL_NEXTHOPS_PTR(nhg, prev)) { if (prev == nexthop) break; - if (nexthop_same_firsthop(nexthop, prev)) { + if (nexthop_same(nexthop, prev)) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE); break; @@ -975,7 +975,6 @@ void nexthop_group_write_nexthop_simple(struct vty *vty, const struct nexthop *nh, char *altifname) { - char buf[100]; char *ifname; vty_out(vty, "nexthop "); @@ -990,19 +989,16 @@ void nexthop_group_write_nexthop_simple(struct vty *vty, vty_out(vty, "%s", ifname); break; case NEXTHOP_TYPE_IPV4: - vty_out(vty, "%s", inet_ntoa(nh->gate.ipv4)); + vty_out(vty, "%pI4", &nh->gate.ipv4); break; case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, "%s %s", inet_ntoa(nh->gate.ipv4), ifname); + vty_out(vty, "%pI4 %s", &nh->gate.ipv4, ifname); break; case NEXTHOP_TYPE_IPV6: - vty_out(vty, "%s", - inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf))); + vty_out(vty, "%pI6", &nh->gate.ipv6); break; case NEXTHOP_TYPE_IPV6_IFINDEX: - vty_out(vty, "%s %s", - inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)), - ifname); + vty_out(vty, "%pI6 %s", &nh->gate.ipv6, ifname); break; case NEXTHOP_TYPE_BLACKHOLE: break; @@ -1056,10 +1052,14 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh) ifindex2ifname(nh->ifindex, nh->vrf_id)); break; case NEXTHOP_TYPE_IPV4: - json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4)); + json_object_string_add( + j, "nexthop", + inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf))); break; case NEXTHOP_TYPE_IPV4_IFINDEX: - json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4)); + json_object_string_add( + j, "nexthop", + inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf))); json_object_string_add(j, "vrfId", ifindex2ifname(nh->ifindex, nh->vrf_id)); break; diff --git a/lib/northbound.c b/lib/northbound.c index 5816c162d8..ecfa2c9d11 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -152,20 +152,22 @@ static int nb_node_del_cb(const struct lys_node *snode, void *arg) struct nb_node *nb_node; nb_node = snode->priv; - lys_set_private(snode, NULL); - XFREE(MTYPE_NB_NODE, nb_node); + if (nb_node) { + lys_set_private(snode, NULL); + XFREE(MTYPE_NB_NODE, nb_node); + } return YANG_ITER_CONTINUE; } void nb_nodes_create(void) { - yang_snodes_iterate_all(nb_node_new_cb, 0, NULL); + yang_snodes_iterate(NULL, nb_node_new_cb, 0, NULL); } void nb_nodes_delete(void) { - yang_snodes_iterate_all(nb_node_del_cb, 0, NULL); + yang_snodes_iterate(NULL, nb_node_del_cb, 0, NULL); } struct nb_node *nb_node_find(const char *xpath) @@ -273,8 +275,10 @@ static int nb_node_validate(const struct lys_node *snode, void *arg) unsigned int *errors = arg; /* Validate callbacks and priority. */ - *errors += nb_node_validate_cbs(nb_node); - *errors += nb_node_validate_priority(nb_node); + if (nb_node) { + *errors += nb_node_validate_cbs(nb_node); + *errors += nb_node_validate_priority(nb_node); + } return YANG_ITER_CONTINUE; } @@ -1142,7 +1146,8 @@ const void *nb_callback_lookup_entry(const struct nb_node *nb_node, } int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, - const struct list *input, struct list *output) + const struct list *input, struct list *output, char *errmsg, + size_t errmsg_len) { struct nb_cb_rpc_args args = {}; @@ -1151,6 +1156,8 @@ int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, args.xpath = xpath; args.input = input; args.output = output; + args.errmsg = errmsg; + args.errmsg_len = errmsg_len; return nb_node->cbs.rpc(&args); } @@ -2229,25 +2236,11 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module) } } -void nb_init(struct thread_master *tm, - const struct frr_yang_module_info *const modules[], - size_t nmodules, bool db_enabled) +void nb_validate_callbacks(void) { unsigned int errors = 0; - /* Load YANG modules. */ - for (size_t i = 0; i < nmodules; i++) - yang_module_load(modules[i]->name); - - /* Create a nb_node for all YANG schema nodes. */ - nb_nodes_create(); - - /* Load northbound callbacks. */ - for (size_t i = 0; i < nmodules; i++) - nb_load_callbacks(modules[i]); - - /* Validate northbound callbacks. */ - yang_snodes_iterate_all(nb_node_validate, 0, &errors); + yang_snodes_iterate(NULL, nb_node_validate, 0, &errors); if (errors > 0) { flog_err( EC_LIB_NB_CBS_VALIDATION, @@ -2255,9 +2248,33 @@ void nb_init(struct thread_master *tm, __func__, errors); exit(1); } +} +void nb_load_module(const struct frr_yang_module_info *module_info) +{ + struct yang_module *module; + + DEBUGD(&nb_dbg_events, "northbound: loading %s.yang", + module_info->name); + + module = yang_module_load(module_info->name); + yang_snodes_iterate(module->info, nb_node_new_cb, 0, NULL); + nb_load_callbacks(module_info); +} + +void nb_init(struct thread_master *tm, + const struct frr_yang_module_info *const modules[], + size_t nmodules, bool db_enabled) +{ nb_db_enabled = db_enabled; + /* Load YANG modules and their corresponding northbound callbacks. */ + for (size_t i = 0; i < nmodules; i++) + nb_load_module(modules[i]); + + /* Validate northbound callbacks. */ + nb_validate_callbacks(); + /* Create an empty running configuration. */ running_config = nb_config_new(NULL); running_config_entries = hash_create(running_config_entry_key_make, diff --git a/lib/northbound.h b/lib/northbound.h index 7b481273cb..3f6e4dc46e 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -258,6 +258,12 @@ struct nb_cb_rpc_args { /* List of output parameters to be populated by the callback. */ struct list *output; + + /* Buffer to store human-readable error message in case of error. */ + char *errmsg; + + /* Size of errmsg. */ + size_t errmsg_len; }; /* @@ -546,7 +552,7 @@ struct nb_node { * from working properly on shared libraries. For those compilers, use a fixed * size array to work around the problem. */ -#define YANG_MODULE_MAX_NODES 1024 +#define YANG_MODULE_MAX_NODES 1400 struct frr_yang_module_info { /* YANG module name. */ @@ -689,7 +695,8 @@ extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node, const void *parent_list_entry, const struct yang_list_keys *keys); extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, - const struct list *input, struct list *output); + const struct list *input, struct list *output, + char *errmsg, size_t errmsg_len); /* * Create a northbound node for all YANG schema nodes. @@ -1231,6 +1238,29 @@ extern const char *nb_err_name(enum nb_error error); extern const char *nb_client_name(enum nb_client client); /* + * Validate all northbound callbacks. + * + * Some errors, like missing callbacks or invalid priorities, are fatal and + * can't be recovered from. Other errors, like unneeded callbacks, are logged + * but otherwise ignored. + * + * Whenever a YANG module is loaded after startup, *all* northbound callbacks + * need to be validated and not only the callbacks from the newly loaded module. + * This is because augmentations can change the properties of the augmented + * module, making mandatory the implementation of additional callbacks. + */ +void nb_validate_callbacks(void); + +/* + * Load a YANG module with its corresponding northbound callbacks. + * + * module_info + * Pointer to structure containing the module name and its northbound + * callbacks. + */ +void nb_load_module(const struct frr_yang_module_info *module_info); + +/* * Initialize the northbound layer. Should be called only once during the * daemon initialization process. * diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 6ce520149a..7048df99fb 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -89,7 +89,7 @@ static int nb_cli_classic_commit(struct vty *vty) static void nb_cli_pending_commit_clear(struct vty *vty) { - THREAD_TIMER_OFF(vty->t_pending_commit); + THREAD_OFF(vty->t_pending_commit); vty->backoff_cmd_count = 0; XFREE(MTYPE_TMP, vty->pending_cmds_buf); vty->pending_cmds_buflen = 0; @@ -154,7 +154,7 @@ static int nb_cli_schedule_command(struct vty *vty) vty->pending_cmds_buflen); /* Schedule the commit operation. */ - THREAD_TIMER_OFF(vty->t_pending_commit); + THREAD_OFF(vty->t_pending_commit); thread_add_timer_msec(master, nb_cli_pending_commit_cb, vty, 100, &vty->t_pending_commit); @@ -284,10 +284,12 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) return CMD_SUCCESS; } -int nb_cli_rpc(const char *xpath, struct list *input, struct list *output) +int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input, + struct list *output) { struct nb_node *nb_node; int ret; + char errmsg[BUFSIZ] = {0}; nb_node = nb_node_find(xpath); if (!nb_node) { @@ -296,18 +298,21 @@ int nb_cli_rpc(const char *xpath, struct list *input, struct list *output) return CMD_WARNING; } - ret = nb_callback_rpc(nb_node, xpath, input, output); + ret = nb_callback_rpc(nb_node, xpath, input, output, errmsg, + sizeof(errmsg)); switch (ret) { case NB_OK: return CMD_SUCCESS; default: + if (strlen(errmsg)) + vty_show_nb_errors(vty, ret, errmsg); return CMD_WARNING; } } void nb_cli_confirmed_commit_clean(struct vty *vty) { - THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout); + thread_cancel(&vty->t_confirmed_commit_timeout); nb_config_free(vty->confirmed_commit_rollback); vty->confirmed_commit_rollback = NULL; } @@ -372,7 +377,7 @@ static int nb_cli_commit(struct vty *vty, bool force, "%% Resetting confirmed-commit timeout to %u minute(s)\n\n", confirmed_timeout); - THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout); + thread_cancel(&vty->t_confirmed_commit_timeout); thread_add_timer(master, nb_cli_confirmed_commit_timeout, vty, confirmed_timeout * 60, diff --git a/lib/northbound_cli.h b/lib/northbound_cli.h index 112d62efda..2290a76b8d 100644 --- a/lib/northbound_cli.h +++ b/lib/northbound_cli.h @@ -75,6 +75,9 @@ extern int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, /* * Execute a YANG RPC or Action. * + * vty + * The vty terminal to dump any error. + * * xpath * XPath of the YANG RPC or Action node. * @@ -90,7 +93,7 @@ extern int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, * Returns: * CMD_SUCCESS on success, CMD_WARNING otherwise. */ -extern int nb_cli_rpc(const char *xpath, struct list *input, +extern int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input, struct list *output); /* diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c index 1f480f3d02..8acba9fd2b 100644 --- a/lib/northbound_confd.c +++ b/lib/northbound_confd.c @@ -550,6 +550,9 @@ static int frr_confd_init_cdb(void) continue; nb_node = snode->priv; + if (!nb_node) + continue; + DEBUGD(&nb_dbg_client_confd, "%s: subscribing to '%s'", __func__, nb_node->xpath); @@ -1068,6 +1071,7 @@ static int frr_confd_action_execute(struct confd_user_info *uinfo, struct yang_data *data; confd_tag_value_t *reply; int ret = CONFD_OK; + char errmsg[BUFSIZ] = {0}; /* Getting the XPath is tricky. */ if (kp) { @@ -1115,7 +1119,9 @@ static int frr_confd_action_execute(struct confd_user_info *uinfo, } /* Execute callback registered for this XPath. */ - if (nb_callback_rpc(nb_node, xpath, input, output) != NB_OK) { + if (nb_callback_rpc(nb_node, xpath, input, output, errmsg, + sizeof(errmsg)) + != NB_OK) { flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s", __func__, xpath); ret = CONFD_ERR; @@ -1186,7 +1192,7 @@ static int frr_confd_subscribe_state(const struct lys_node *snode, void *arg) struct nb_node *nb_node = snode->priv; struct confd_data_cbs *data_cbs = arg; - if (!CHECK_FLAG(snode->flags, LYS_CONFIG_R)) + if (!nb_node || !CHECK_FLAG(snode->flags, LYS_CONFIG_R)) return YANG_ITER_CONTINUE; /* We only need to subscribe to the root of the state subtrees. */ if (snode->parent && CHECK_FLAG(snode->parent->flags, LYS_CONFIG_R)) @@ -1273,7 +1279,7 @@ static int frr_confd_init_dp(const char *program_name) * Iterate over all loaded YANG modules and subscribe to the paths * referent to state data. */ - yang_snodes_iterate_all(frr_confd_subscribe_state, 0, &data_cbs); + yang_snodes_iterate(NULL, frr_confd_subscribe_state, 0, &data_cbs); /* Register notification stream. */ memset(&ncbs, 0, sizeof(ncbs)); @@ -1390,7 +1396,8 @@ static int frr_confd_calculate_snode_hash(const struct lys_node *snode, { struct nb_node *nb_node = snode->priv; - nb_node->confd_hash = confd_str2hash(snode->name); + if (nb_node) + nb_node->confd_hash = confd_str2hash(snode->name); return YANG_ITER_CONTINUE; } @@ -1423,7 +1430,7 @@ static int frr_confd_init(const char *program_name) goto error; } - yang_snodes_iterate_all(frr_confd_calculate_snode_hash, 0, NULL); + yang_snodes_iterate(NULL, frr_confd_calculate_snode_hash, 0, NULL); hook_register(nb_notification_send, frr_confd_notification_send); diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp index f35b4bb31b..abdae993b1 100644 --- a/lib/northbound_grpc.cpp +++ b/lib/northbound_grpc.cpp @@ -962,6 +962,7 @@ class NorthboundImpl struct listnode *node; struct yang_data *data; const char *xpath; + char errmsg[BUFSIZ] = {0}; switch (tag->state) { case CREATE: @@ -1012,7 +1013,7 @@ class NorthboundImpl // Execute callback registered for this XPath. if (nb_callback_rpc(nb_node, xpath, input_list, - output_list) + output_list, errmsg, sizeof(errmsg)) != NB_OK) { flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s", diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c index b5ef040a3f..c027f4de72 100644 --- a/lib/northbound_sysrepo.c +++ b/lib/northbound_sysrepo.c @@ -414,6 +414,7 @@ static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, const char *xpath, struct yang_data *data; size_t cb_output_cnt; int ret = SR_ERR_OK; + char errmsg[BUFSIZ] = {0}; nb_node = nb_node_find(xpath); if (!nb_node) { @@ -436,7 +437,9 @@ static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, const char *xpath, } /* Execute callback registered for this XPath. */ - if (nb_callback_rpc(nb_node, xpath, input, output) != NB_OK) { + if (nb_callback_rpc(nb_node, xpath, input, output, errmsg, + sizeof(errmsg)) + != NB_OK) { flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s", __func__, xpath); ret = SR_ERR_OPERATION_FAILED; @@ -572,6 +575,8 @@ static int frr_sr_subscribe_state(const struct lys_node *snode, void *arg) return YANG_ITER_CONTINUE; nb_node = snode->priv; + if (!nb_node) + return YANG_ITER_CONTINUE; DEBUGD(&nb_dbg_client_sysrepo, "sysrepo: providing data to '%s'", nb_node->xpath); @@ -596,6 +601,8 @@ static int frr_sr_subscribe_rpc(const struct lys_node *snode, void *arg) return YANG_ITER_CONTINUE; nb_node = snode->priv; + if (!nb_node) + return YANG_ITER_CONTINUE; DEBUGD(&nb_dbg_client_sysrepo, "sysrepo: providing RPC to '%s'", nb_node->xpath); @@ -683,10 +690,10 @@ static int frr_sr_init(void) int event_pipe; frr_sr_subscribe_config(module); - yang_snodes_iterate_module(module->info, frr_sr_subscribe_state, - 0, module); - yang_snodes_iterate_module(module->info, frr_sr_subscribe_rpc, - 0, module); + yang_snodes_iterate(module->info, frr_sr_subscribe_state, 0, + module); + yang_snodes_iterate(module->info, frr_sr_subscribe_rpc, 0, + module); /* Watch subscriptions. */ ret = sr_get_event_pipe(module->sr_subscription, &event_pipe); diff --git a/lib/plist.c b/lib/plist.c index 981e86e2ac..4588dfe1d3 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -901,14 +901,11 @@ static void __attribute__((unused)) prefix_list_print(struct prefix_list *plist) printf("any %s\n", prefix_list_type_str(pentry)); else { struct prefix *p; - char buf[BUFSIZ]; p = &pentry->prefix; - printf(" seq %lld %s %s/%d", (long long)pentry->seq, - prefix_list_type_str(pentry), - inet_ntop(p->family, p->u.val, buf, BUFSIZ), - p->prefixlen); + printf(" seq %lld %s %pFX", (long long)pentry->seq, + prefix_list_type_str(pentry), p); if (pentry->ge) printf(" ge %d", pentry->ge); if (pentry->le) @@ -1014,12 +1011,8 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi, vty_out(vty, "any"); else { struct prefix *p = &pentry->prefix; - char buf[BUFSIZ]; - vty_out(vty, "%s/%d", - inet_ntop(p->family, p->u.val, buf, - BUFSIZ), - p->prefixlen); + vty_out(vty, "%pFX", p); if (pentry->ge) vty_out(vty, " ge %d", pentry->ge); @@ -1121,12 +1114,8 @@ static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi, vty_out(vty, "any"); else { struct prefix *pf = &pentry->prefix; - char buf[BUFSIZ]; - vty_out(vty, "%s/%d", - inet_ntop(pf->family, pf->u.val, buf, - BUFSIZ), - pf->prefixlen); + vty_out(vty, "%pFX", pf); if (pentry->ge) vty_out(vty, " ge %d", pentry->ge); @@ -1491,11 +1480,8 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, for (pentry = plist->head; pentry; pentry = pentry->next) { struct prefix *p = &pentry->prefix; char buf_a[BUFSIZ]; - char buf_b[BUFSIZ]; - snprintf(buf_a, sizeof(buf_a), "%s/%d", - inet_ntop(p->family, p->u.val, buf_b, BUFSIZ), - p->prefixlen); + snprintf(buf_a, sizeof(buf_a), "%pFX", p); json_object_int_add(json_list, "seq", pentry->seq); json_object_string_add(json_list, "seqPrefixListType", @@ -1526,13 +1512,9 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, for (pentry = plist->head; pentry; pentry = pentry->next) { struct prefix *p = &pentry->prefix; - char buf[BUFSIZ]; - vty_out(vty, " seq %" PRId64 " %s %s/%d", - pentry->seq, - prefix_list_type_str(pentry), - inet_ntop(p->family, p->u.val, buf, BUFSIZ), - p->prefixlen); + vty_out(vty, " seq %" PRId64 " %s %pFX", pentry->seq, + prefix_list_type_str(pentry), p); if (pentry->ge) vty_out(vty, " ge %d", pentry->ge); diff --git a/lib/prefix.c b/lib/prefix.c index 0a88f9eca6..663a87afde 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -30,6 +30,7 @@ #include "jhash.h" #include "lib_errors.h" #include "printfrr.h" +#include "vxlan.h" DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix") DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec") @@ -909,7 +910,17 @@ int str2prefix(const char *str, struct prefix *p) static const char *prefixevpn_ead2str(const struct prefix_evpn *p, char *str, int size) { - snprintf(str, size, "Unsupported EVPN prefix"); + uint8_t family; + char buf[ESI_STR_LEN]; + char buf1[INET6_ADDRSTRLEN]; + + family = IS_IPADDR_V4(&p->prefix.ead_addr.ip) ? AF_INET : AF_INET6; + snprintf(str, size, "[%d]:[%u]:[%s]:[%d]:[%s]", p->prefix.route_type, + p->prefix.ead_addr.eth_tag, + esi_to_str(&p->prefix.ead_addr.esi, buf, sizeof(buf)), + (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN, + inet_ntop(family, &p->prefix.ead_addr.ip.ipaddr_v4, buf1, + sizeof(buf1))); return str; } @@ -917,27 +928,24 @@ static const char *prefixevpn_macip2str(const struct prefix_evpn *p, char *str, int size) { uint8_t family; - char buf[PREFIX2STR_BUFFER]; - char buf2[ETHER_ADDR_STRLEN]; + char buf1[ETHER_ADDR_STRLEN]; + char buf2[PREFIX2STR_BUFFER]; if (is_evpn_prefix_ipaddr_none(p)) - snprintf(str, size, "[%d]:[%s]/%d", - p->prefix.route_type, - prefix_mac2str(&p->prefix.macip_addr.mac, - buf2, sizeof(buf2)), - p->prefixlen); + snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type, + p->prefix.macip_addr.eth_tag, 8 * ETH_ALEN, + prefix_mac2str(&p->prefix.macip_addr.mac, buf1, + sizeof(buf1))); else { - family = is_evpn_prefix_ipaddr_v4(p) - ? AF_INET - : AF_INET6; - snprintf(str, size, "[%d]:[%s]:[%s]/%d", - p->prefix.route_type, - prefix_mac2str(&p->prefix.macip_addr.mac, - buf2, sizeof(buf2)), - inet_ntop(family, - &p->prefix.macip_addr.ip.ip.addr, - buf, PREFIX2STR_BUFFER), - p->prefixlen); + family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET : AF_INET6; + snprintf(str, size, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]", + p->prefix.route_type, p->prefix.macip_addr.eth_tag, + 8 * ETH_ALEN, + prefix_mac2str(&p->prefix.macip_addr.mac, buf1, + sizeof(buf1)), + family == AF_INET ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN, + inet_ntop(family, &p->prefix.macip_addr.ip.ip.addr, + buf2, PREFIX2STR_BUFFER)); } return str; } @@ -946,28 +954,32 @@ static const char *prefixevpn_imet2str(const struct prefix_evpn *p, char *str, int size) { uint8_t family; - char buf[PREFIX2STR_BUFFER]; + char buf[INET6_ADDRSTRLEN]; + + family = IS_IPADDR_V4(&p->prefix.imet_addr.ip) ? AF_INET : AF_INET6; + snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type, + p->prefix.imet_addr.eth_tag, + (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN, + inet_ntop(family, &p->prefix.imet_addr.ip.ipaddr_v4, buf, + sizeof(buf))); - family = is_evpn_prefix_ipaddr_v4(p) - ? AF_INET - : AF_INET6; - snprintf(str, size, "[%d]:[%s]/%d", p->prefix.route_type, - inet_ntop(family, - &p->prefix.imet_addr.ip.ip.addr, buf, - PREFIX2STR_BUFFER), - p->prefixlen); return str; } static const char *prefixevpn_es2str(const struct prefix_evpn *p, char *str, int size) { + uint8_t family; char buf[ESI_STR_LEN]; + char buf1[INET6_ADDRSTRLEN]; - snprintf(str, size, "[%d]:[%s]:[%s]/%d", p->prefix.route_type, + family = IS_IPADDR_V4(&p->prefix.es_addr.ip) ? AF_INET : AF_INET6; + snprintf(str, size, "[%d]:[%s]:[%d]:[%s]", p->prefix.route_type, esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)), - inet_ntoa(p->prefix.es_addr.ip.ipaddr_v4), - p->prefixlen); + (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN, + inet_ntop(family, &p->prefix.es_addr.ip.ipaddr_v4, buf1, + sizeof(buf1))); + return str; } @@ -975,19 +987,14 @@ static const char *prefixevpn_prefix2str(const struct prefix_evpn *p, char *str, int size) { uint8_t family; - char buf[PREFIX2STR_BUFFER]; + char buf[INET6_ADDRSTRLEN]; - family = is_evpn_prefix_ipaddr_v4(p) - ? AF_INET - : AF_INET6; - snprintf(str, size, "[%d]:[%u]:[%s/%d]/%d", - p->prefix.route_type, + family = IS_IPADDR_V4(&p->prefix.prefix_addr.ip) ? AF_INET : AF_INET6; + snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type, p->prefix.prefix_addr.eth_tag, - inet_ntop(family, - &p->prefix.prefix_addr.ip.ip.addr, buf, - PREFIX2STR_BUFFER), p->prefix.prefix_addr.ip_prefix_length, - p->prefixlen); + inet_ntop(family, &p->prefix.prefix_addr.ip.ipaddr_v4, buf, + sizeof(buf))); return str; } @@ -995,15 +1002,15 @@ static const char *prefixevpn2str(const struct prefix_evpn *p, char *str, int size) { switch (p->prefix.route_type) { - case 1: + case BGP_EVPN_AD_ROUTE: return prefixevpn_ead2str(p, str, size); - case 2: + case BGP_EVPN_MAC_IP_ROUTE: return prefixevpn_macip2str(p, str, size); - case 3: + case BGP_EVPN_IMET_ROUTE: return prefixevpn_imet2str(p, str, size); - case 4: + case BGP_EVPN_ES_ROUTE: return prefixevpn_es2str(p, str, size); - case 5: + case BGP_EVPN_IP_PREFIX_ROUTE: return prefixevpn_prefix2str(p, str, size); default: snprintf(str, size, "Unsupported EVPN prefix"); @@ -1330,6 +1337,29 @@ char *esi_to_str(const esi_t *esi, char *buf, int size) return ptr; } +char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len) +{ + switch (df_alg) { + case EVPN_MH_DF_ALG_SERVICE_CARVING: + snprintf(buf, buf_len, "service-carving"); + break; + + case EVPN_MH_DF_ALG_HRW: + snprintf(buf, buf_len, "HRW"); + break; + + case EVPN_MH_DF_ALG_PREF: + snprintf(buf, buf_len, "preference"); + break; + + default: + snprintf(buf, buf_len, "unknown %u", df_alg); + break; + } + + return buf; +} + printfrr_ext_autoreg_p("EA", printfrr_ea) static ssize_t printfrr_ea(char *buf, size_t bsz, const char *fmt, int prec, const void *ptr) diff --git a/lib/prefix.h b/lib/prefix.h index 471978ed28..d2cabf3104 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -62,6 +62,7 @@ typedef enum { #define EVPN_ETH_TAG_BYTES 4 #define ESI_BYTES 10 #define ESI_STR_LEN (3 * ESI_BYTES) +#define EVPN_DF_ALG_STR_LEN 24 /* Maximum number of VTEPs per-ES - * XXX - temporary limit for allocating strings etc. @@ -515,6 +516,7 @@ extern unsigned prefix_hash_key(const void *pp); extern int str_to_esi(const char *str, esi_t *esi); extern char *esi_to_str(const esi_t *esi, char *buf, int size); +extern char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len); extern void prefix_evpn_hexdump(const struct prefix_evpn *p); static inline int ipv6_martian(struct in6_addr *addr) diff --git a/lib/routemap.c b/lib/routemap.c index fb70860024..0eb54a4794 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -2377,7 +2377,6 @@ route_map_result_t route_map_apply(struct route_map *map, route_map_result_t ret = RMAP_PERMITMATCH; struct route_map_index *index = NULL; struct route_map_rule *set = NULL; - char buf[PREFIX_STRLEN]; bool skip_match_clause = false; if (recursion > RMAP_RECURSION_LIMIT) { @@ -2403,16 +2402,14 @@ route_map_result_t route_map_apply(struct route_map *map, if (index) { if (rmap_debug) zlog_debug( - "Best match route-map: %s, sequence: %d for pfx: %s, result: %s", - map->name, index->pref, - prefix2str(prefix, buf, sizeof(buf)), + "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s", + map->name, index->pref, prefix, route_map_cmd_result_str(match_ret)); } else { if (rmap_debug) zlog_debug( - "No best match sequence for pfx: %s in route-map: %s, result: %s", - prefix2str(prefix, buf, sizeof(buf)), - map->name, + "No best match sequence for pfx: %pFX in route-map: %s, result: %s", + prefix, map->name, route_map_cmd_result_str(match_ret)); /* * No index matches this prefix. Return deny unless, @@ -2437,9 +2434,8 @@ route_map_result_t route_map_apply(struct route_map *map, prefix, type, object); if (rmap_debug) { zlog_debug( - "Route-map: %s, sequence: %d, prefix: %s, result: %s", - map->name, index->pref, - prefix2str(prefix, buf, sizeof(buf)), + "Route-map: %s, sequence: %d, prefix: %pFX, result: %s", + map->name, index->pref, prefix, route_map_cmd_result_str(match_ret)); } } else @@ -2549,12 +2545,10 @@ route_map_result_t route_map_apply(struct route_map *map, } route_map_apply_end: - if (rmap_debug) { - zlog_debug("Route-map: %s, prefix: %s, result: %s", - (map ? map->name : "null"), - prefix2str(prefix, buf, sizeof(buf)), + if (rmap_debug) + zlog_debug("Route-map: %s, prefix: %pFX, result: %s", + (map ? map->name : "null"), prefix, route_map_result_str(ret)); - } return (ret); } @@ -3156,8 +3150,6 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, struct list *rmap_index_list = NULL; struct listnode *ln = NULL, *nln = NULL; struct route_map_index *index = NULL; - struct prefix *p = NULL, *pp = NULL; - char buf[SU_ADDRSTRLEN], pbuf[SU_ADDRSTRLEN]; uint8_t len = 54; vty_out(vty, "%s:\n", frr_protonameinst); @@ -3171,22 +3163,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, "____________________"); for (rn = route_top(rm_pfx_tbl4); rn; rn = route_next(rn)) { - p = &rn->p; - - vty_out(vty, " %s/%d (%d)\n", - inet_ntop(p->family, &p->u.prefix, buf, - SU_ADDRSTRLEN), - p->prefixlen, rn->lock); + vty_out(vty, " %pRN (%d)\n", rn, + route_node_get_lock_count(rn)); vty_out(vty, "(P) "); prn = rn->parent; if (prn) { - pp = &prn->p; - vty_out(vty, "%s/%d\n", - inet_ntop(pp->family, - &pp->u.prefix, pbuf, - SU_ADDRSTRLEN), - pp->prefixlen); + vty_out(vty, "%pRN\n", prn); } vty_out(vty, "\n"); @@ -3215,22 +3198,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, "____________________"); for (rn = route_top(rm_pfx_tbl6); rn; rn = route_next(rn)) { - p = &rn->p; - - vty_out(vty, " %s/%d (%d)\n", - inet_ntop(p->family, &p->u.prefix, buf, - SU_ADDRSTRLEN), - p->prefixlen, rn->lock); + vty_out(vty, " %pRN (%d)\n", rn, + route_node_get_lock_count(rn)); vty_out(vty, "(P) "); prn = rn->parent; if (prn) { - pp = &prn->p; - vty_out(vty, "%s/%d\n", - inet_ntop(pp->family, - &pp->u.prefix, pbuf, - SU_ADDRSTRLEN), - pp->prefixlen); + vty_out(vty, "%pRN\n", prn); } vty_out(vty, "\n"); diff --git a/lib/sigevent.c b/lib/sigevent.c index 04fcc814ef..de9e1f5410 100644 --- a/lib/sigevent.c +++ b/lib/sigevent.c @@ -63,6 +63,33 @@ static void quagga_signal_handler(int signo) sigmaster.caught = 1; } +/* + * Check whether any signals have been received and are pending. This is done + * with the application's key signals blocked. The complete set of signals + * is returned in 'setp', so the caller can restore them when appropriate. + * If there are pending signals, returns 'true', 'false' otherwise. + */ +bool frr_sigevent_check(sigset_t *setp) +{ + sigset_t blocked; + int i; + bool ret; + + sigemptyset(setp); + sigemptyset(&blocked); + + /* Set up mask of application's signals */ + for (i = 0; i < sigmaster.sigc; i++) + sigaddset(&blocked, sigmaster.signals[i].signal); + + pthread_sigmask(SIG_BLOCK, &blocked, setp); + + /* Now that the application's signals are blocked, test. */ + ret = (sigmaster.caught != 0); + + return ret; +} + /* check if signals have been caught and run appropriate handlers */ int quagga_sigevent_process(void) { diff --git a/lib/sigevent.h b/lib/sigevent.h index a0ad88fcaa..4a39b22889 100644 --- a/lib/sigevent.h +++ b/lib/sigevent.h @@ -48,6 +48,15 @@ struct quagga_signal_t { extern void signal_init(struct thread_master *m, int sigc, struct quagga_signal_t *signals); + +/* + * Check whether any signals have been received and are pending. This is done + * with the application's key signals blocked. The complete set of signals + * is returned in 'setp', so the caller can restore them when appropriate. + * If there are pending signals, returns 'true', 'false' otherwise. + */ +bool frr_sigevent_check(sigset_t *setp); + /* check whether there are signals to handle, process any found */ extern int quagga_sigevent_process(void); diff --git a/lib/sockunion.c b/lib/sockunion.c index d77229797c..c999845659 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -587,15 +587,11 @@ static void __attribute__((unused)) sockunion_print(const union sockunion *su) switch (su->sa.sa_family) { case AF_INET: - printf("%s\n", inet_ntoa(su->sin.sin_addr)); + printf("%pI4\n", &su->sin.sin_addr); + break; + case AF_INET6: + printf("%pI6\n", &su->sin6.sin6_addr); break; - case AF_INET6: { - char buf[SU_ADDRSTRLEN]; - - printf("%s\n", inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, - sizeof(buf))); - } break; - #ifdef AF_LINK case AF_LINK: { struct sockaddr_dl *sdl; diff --git a/lib/spf_backoff.c b/lib/spf_backoff.c index 4e74714489..ac6dd29f06 100644 --- a/lib/spf_backoff.c +++ b/lib/spf_backoff.c @@ -110,8 +110,8 @@ void spf_backoff_free(struct spf_backoff *backoff) if (!backoff) return; - THREAD_TIMER_OFF(backoff->t_holddown); - THREAD_TIMER_OFF(backoff->t_timetolearn); + thread_cancel(&backoff->t_holddown); + thread_cancel(&backoff->t_timetolearn); XFREE(MTYPE_SPF_BACKOFF_NAME, backoff->name); XFREE(MTYPE_SPF_BACKOFF, backoff); @@ -121,7 +121,6 @@ static int spf_backoff_timetolearn_elapsed(struct thread *thread) { struct spf_backoff *backoff = THREAD_ARG(thread); - backoff->t_timetolearn = NULL; backoff->state = SPF_BACKOFF_LONG_WAIT; backoff_debug("SPF Back-off(%s) TIMETOLEARN elapsed, move to state %s", backoff->name, spf_backoff_state2str(backoff->state)); @@ -132,8 +131,7 @@ static int spf_backoff_holddown_elapsed(struct thread *thread) { struct spf_backoff *backoff = THREAD_ARG(thread); - backoff->t_holddown = NULL; - THREAD_TIMER_OFF(backoff->t_timetolearn); + THREAD_OFF(backoff->t_timetolearn); timerclear(&backoff->first_event_time); backoff->state = SPF_BACKOFF_QUIET; backoff_debug("SPF Back-off(%s) HOLDDOWN elapsed, move to state %s", @@ -167,7 +165,7 @@ long spf_backoff_schedule(struct spf_backoff *backoff) break; case SPF_BACKOFF_SHORT_WAIT: case SPF_BACKOFF_LONG_WAIT: - THREAD_TIMER_OFF(backoff->t_holddown); + thread_cancel(&backoff->t_holddown); thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed, backoff, backoff->holddown, &backoff->t_holddown); diff --git a/lib/stream.h b/lib/stream.h index 23f85d809b..4f75f121ca 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -386,6 +386,16 @@ static inline const uint8_t *ptr_get_be32(const uint8_t *ptr, uint32_t *out) return ptr + 4; } +static inline uint8_t *ptr_get_be16(uint8_t *ptr, uint16_t *out) +{ + uint16_t tmp; + + memcpy(&tmp, ptr, sizeof(tmp)); + *out = ntohs(tmp); + + return ptr + 2; +} + /* * so Normal stream_getX functions assert. Which is anathema * to keeping a daemon up and running when something goes south diff --git a/lib/subdir.am b/lib/subdir.am index b8bcee139b..ed3c30799d 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -3,7 +3,7 @@ # lib_LTLIBRARIES += lib/libfrr.la lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version -lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(LIBM) +lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST_LIBS) $(LIBM) lib_libfrr_la_SOURCES = \ lib/agg_table.c \ @@ -46,6 +46,7 @@ lib_libfrr_la_SOURCES = \ lib/lib_errors.c \ lib/lib_vty.c \ lib/libfrr.c \ + lib/libfrr_trace.c \ lib/linklist.c \ lib/log.c \ lib/log_filter.c \ @@ -123,6 +124,7 @@ nodist_lib_libfrr_la_SOURCES = \ yang/frr-nexthop.yang.c \ yang/ietf/ietf-routing-types.yang.c \ yang/ietf/ietf-interfaces.yang.c \ + yang/ietf/ietf-bgp-types.yang.c \ yang/frr-module-translator.yang.c \ yang/frr-nexthop.yang.c \ # end @@ -203,6 +205,7 @@ pkginclude_HEADERS += \ lib/lib_errors.h \ lib/lib_vty.h \ lib/libfrr.h \ + lib/libfrr_trace.h \ lib/libospf.h \ lib/linklist.h \ lib/log.h \ @@ -250,6 +253,7 @@ pkginclude_HEADERS += \ lib/table.h \ lib/termtable.h \ lib/thread.h \ + lib/trace.h \ lib/typerb.h \ lib/typesafe.h \ lib/vector.h \ @@ -400,7 +404,7 @@ lib_grammar_sandbox_LDADD = \ lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY lib_clippy_CFLAGS = $(PYTHON_CFLAGS) -lib_clippy_LDADD = $(PYTHON_LIBS) +lib_clippy_LDADD = $(PYTHON_LIBS) $(UST_LIBS) lib_clippy_LDFLAGS = -export-dynamic lib_clippy_SOURCES = \ lib/clippy.c \ @@ -410,6 +414,7 @@ lib_clippy_SOURCES = \ lib/command_py.c \ lib/defun_lex.l \ lib/graph.c \ + lib/libfrr_trace.c \ lib/memory.c \ lib/vector.c \ # end diff --git a/lib/table.c b/lib/table.c index 86347cbacd..89e32182b5 100644 --- a/lib/table.c +++ b/lib/table.c @@ -27,6 +27,7 @@ #include "table.h" #include "memory.h" #include "sockunion.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table") DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node") @@ -119,7 +120,8 @@ static void route_table_free(struct route_table *rt) node = node->parent; tmp_node->table->count--; - tmp_node->lock = 0; /* to cause assert if unlocked after this */ + tmp_node->lock = + 0; /* to cause assert if unlocked after this */ rn_hash_node_del(&rt->hash, tmp_node); route_node_free(rt, tmp_node); @@ -275,6 +277,12 @@ struct route_node *route_node_lookup_maynull(struct route_table *table, struct route_node *route_node_get(struct route_table *table, union prefixconstptr pu) { + if (frrtrace_enabled(frr_libfrr, route_node_get)) { + char buf[PREFIX2STR_BUFFER]; + prefix2str(pu, buf, sizeof(buf)); + frrtrace(2, frr_libfrr, route_node_get, table, buf); + } + struct route_node search; struct prefix *p = &search.p; diff --git a/lib/table.h b/lib/table.h index 9cd9503376..5d620d332b 100644 --- a/lib/table.h +++ b/lib/table.h @@ -262,6 +262,11 @@ static inline void route_unlock_node(struct route_node *node) route_node_delete(node); } +static inline unsigned int route_node_get_lock_count(struct route_node *node) +{ + return node->lock; +} + /* * route_table_iter_next * diff --git a/lib/thread.c b/lib/thread.c index db35a3f031..db53e267f8 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -35,6 +35,7 @@ #include "frratomic.h" #include "frr_pthread.h" #include "lib_errors.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread") DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master") @@ -727,9 +728,13 @@ static void thread_free(struct thread_master *master, struct thread *thread) XFREE(MTYPE_THREAD, thread); } -static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize, - nfds_t count, const struct timeval *timer_wait) +static int fd_poll(struct thread_master *m, const struct timeval *timer_wait, + bool *eintr_p) { + sigset_t origsigs; + unsigned char trash[64]; + nfds_t count = m->handler.copycount; + /* * If timer_wait is null here, that means poll() should block * indefinitely, unless the thread_master has overridden it by setting @@ -760,15 +765,58 @@ static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize, rcu_assert_read_unlocked(); /* add poll pipe poker */ - assert(count + 1 < pfdsize); - pfds[count].fd = m->io_pipe[0]; - pfds[count].events = POLLIN; - pfds[count].revents = 0x00; + assert(count + 1 < m->handler.pfdsize); + m->handler.copy[count].fd = m->io_pipe[0]; + m->handler.copy[count].events = POLLIN; + m->handler.copy[count].revents = 0x00; + + /* We need to deal with a signal-handling race here: we + * don't want to miss a crucial signal, such as SIGTERM or SIGINT, + * that may arrive just before we enter poll(). We will block the + * key signals, then check whether any have arrived - if so, we return + * before calling poll(). If not, we'll re-enable the signals + * in the ppoll() call. + */ + + sigemptyset(&origsigs); + if (m->handle_signals) { + /* Main pthread that handles the app signals */ + if (frr_sigevent_check(&origsigs)) { + /* Signal to process - restore signal mask and return */ + pthread_sigmask(SIG_SETMASK, &origsigs, NULL); + num = -1; + *eintr_p = true; + goto done; + } + } else { + /* Don't make any changes for the non-main pthreads */ + pthread_sigmask(SIG_SETMASK, NULL, &origsigs); + } - num = poll(pfds, count + 1, timeout); +#if defined(HAVE_PPOLL) + struct timespec ts, *tsp; - unsigned char trash[64]; - if (num > 0 && pfds[count].revents != 0 && num--) + if (timeout >= 0) { + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + tsp = &ts; + } else + tsp = NULL; + + num = ppoll(m->handler.copy, count + 1, tsp, &origsigs); + pthread_sigmask(SIG_SETMASK, &origsigs, NULL); +#else + /* Not ideal - there is a race after we restore the signal mask */ + pthread_sigmask(SIG_SETMASK, &origsigs, NULL); + num = poll(m->handler.copy, count + 1, timeout); +#endif + +done: + + if (num < 0 && errno == EINTR) + *eintr_p = true; + + if (num > 0 && m->handler.copy[count].revents != 0 && num--) while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0) ; @@ -787,6 +835,13 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m, struct thread *thread = NULL; struct thread **thread_array; + if (dir == THREAD_READ) + frrtrace(9, frr_libfrr, schedule_read, m, funcname, schedfrom, + fromln, t_ptr, fd, 0, arg, 0); + else + frrtrace(9, frr_libfrr, schedule_write, m, funcname, schedfrom, + fromln, t_ptr, fd, 0, arg, 0); + assert(fd >= 0 && fd < m->fd_limit); frr_with_mutex(&m->mtx) { if (t_ptr && *t_ptr) @@ -861,6 +916,9 @@ funcname_thread_add_timer_timeval(struct thread_master *m, assert(type == THREAD_TIMER); assert(time_relative); + frrtrace(9, frr_libfrr, schedule_timer, m, funcname, schedfrom, fromln, + t_ptr, 0, 0, arg, (long)time_relative->tv_sec); + frr_with_mutex(&m->mtx) { if (t_ptr && *t_ptr) /* thread is already scheduled; don't reschedule */ @@ -939,6 +997,9 @@ struct thread *funcname_thread_add_event(struct thread_master *m, { struct thread *thread = NULL; + frrtrace(9, frr_libfrr, schedule_event, m, funcname, schedfrom, fromln, + t_ptr, 0, val, arg, 0); + assert(m != NULL); frr_with_mutex(&m->mtx) { @@ -1163,19 +1224,30 @@ void thread_cancel_event(struct thread_master *master, void *arg) * * @param thread task to cancel */ -void thread_cancel(struct thread *thread) +void thread_cancel(struct thread **thread) { - struct thread_master *master = thread->master; + struct thread_master *master; + + if (thread == NULL || *thread == NULL) + return; + + master = (*thread)->master; + + frrtrace(9, frr_libfrr, thread_cancel, master, (*thread)->funcname, + (*thread)->schedfrom, (*thread)->schedfrom_line, NULL, (*thread)->u.fd, + (*thread)->u.val, (*thread)->arg, (*thread)->u.sands.tv_sec); assert(master->owner == pthread_self()); frr_with_mutex(&master->mtx) { struct cancel_req *cr = XCALLOC(MTYPE_TMP, sizeof(struct cancel_req)); - cr->thread = thread; + cr->thread = *thread; listnode_add(master->cancel_req, cr); do_thread_cancel(master); } + + *thread = NULL; } /** @@ -1206,6 +1278,17 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread, void *eventobj) { assert(!(thread && eventobj) && (thread || eventobj)); + + if (thread && *thread) + frrtrace(9, frr_libfrr, thread_cancel_async, master, + (*thread)->funcname, (*thread)->schedfrom, + (*thread)->schedfrom_line, NULL, (*thread)->u.fd, + (*thread)->u.val, (*thread)->arg, + (*thread)->u.sands.tv_sec); + else + frrtrace(9, frr_libfrr, thread_cancel_async, master, NULL, NULL, + 0, NULL, 0, 0, eventobj, 0); + assert(master->owner != pthread_self()); frr_with_mutex(&master->mtx) { @@ -1227,6 +1310,9 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread, while (!master->canceled) pthread_cond_wait(&master->cancel_cond, &master->mtx); } + + if (thread) + *thread = NULL; } /* ------------------------------------------------------------------------- */ @@ -1395,7 +1481,7 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) struct timeval zerotime = {0, 0}; struct timeval tv; struct timeval *tw = NULL; - + bool eintr_p = false; int num = 0; do { @@ -1467,14 +1553,14 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) pthread_mutex_unlock(&m->mtx); { - num = fd_poll(m, m->handler.copy, m->handler.pfdsize, - m->handler.copycount, tw); + eintr_p = false; + num = fd_poll(m, tw, &eintr_p); } pthread_mutex_lock(&m->mtx); /* Handle any errors received in poll() */ if (num < 0) { - if (errno == EINTR) { + if (eintr_p) { pthread_mutex_unlock(&m->mtx); /* loop around to signal handler */ continue; @@ -1581,6 +1667,10 @@ void thread_call(struct thread *thread) GETRUSAGE(&before); thread->real = before.real; + frrtrace(9, frr_libfrr, thread_call, thread->master, thread->funcname, + thread->schedfrom, thread->schedfrom_line, NULL, thread->u.fd, + thread->u.val, thread->arg, thread->u.sands.tv_sec); + pthread_setspecific(thread_current, thread); (*thread->func)(thread); pthread_setspecific(thread_current, NULL); @@ -1660,3 +1750,49 @@ void funcname_thread_execute(struct thread_master *m, /* Give back or free thread. */ thread_add_unuse(m, thread); } + +/* Debug signal mask - if 'sigs' is NULL, use current effective mask. */ +void debug_signals(const sigset_t *sigs) +{ + int i, found; + sigset_t tmpsigs; + char buf[300]; + + /* + * We're only looking at the non-realtime signals here, so we need + * some limit value. Platform differences mean at some point we just + * need to pick a reasonable value. + */ +#if defined SIGRTMIN +# define LAST_SIGNAL SIGRTMIN +#else +# define LAST_SIGNAL 32 +#endif + + + if (sigs == NULL) { + sigemptyset(&tmpsigs); + pthread_sigmask(SIG_BLOCK, NULL, &tmpsigs); + sigs = &tmpsigs; + } + + found = 0; + buf[0] = '\0'; + + for (i = 0; i < LAST_SIGNAL; i++) { + char tmp[20]; + + if (sigismember(sigs, i) > 0) { + if (found > 0) + strlcat(buf, ",", sizeof(buf)); + snprintf(tmp, sizeof(tmp), "%d", i); + strlcat(buf, tmp, sizeof(buf)); + found++; + } + } + + if (found == 0) + snprintf(buf, sizeof(buf), "<none>"); + + zlog_debug("%s: %s", __func__, buf); +} diff --git a/lib/thread.h b/lib/thread.h index c22b2105cd..682a17b9f3 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -147,18 +147,15 @@ struct cpu_thread_history { #define THREAD_FD(X) ((X)->u.fd) #define THREAD_VAL(X) ((X)->u.val) -#define THREAD_OFF(thread) \ - do { \ - if (thread) { \ - thread_cancel(thread); \ - thread = NULL; \ - } \ +/* + * Please consider this macro deprecated, and do not use it in new code. + */ +#define THREAD_OFF(thread) \ + do { \ + if ((thread)) \ + thread_cancel(&(thread)); \ } while (0) -#define THREAD_READ_OFF(thread) THREAD_OFF(thread) -#define THREAD_WRITE_OFF(thread) THREAD_OFF(thread) -#define THREAD_TIMER_OFF(thread) THREAD_OFF(thread) - #define debugargdef const char *funcname, const char *schedfrom, int fromln #define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__) @@ -207,7 +204,7 @@ extern void funcname_thread_execute(struct thread_master *, debugargdef); #undef debugargdef -extern void thread_cancel(struct thread *); +extern void thread_cancel(struct thread **event); extern void thread_cancel_async(struct thread_master *, struct thread **, void *); extern void thread_cancel_event(struct thread_master *, void *); @@ -233,6 +230,9 @@ extern pthread_key_t thread_current; extern char *thread_timer_to_hhmmss(char *buf, int buf_size, struct thread *t_timer); +/* Debug signal mask */ +void debug_signals(const sigset_t *sigs); + #ifdef __cplusplus } #endif diff --git a/lib/trace.h b/lib/trace.h new file mode 100644 index 0000000000..73fc10a556 --- /dev/null +++ b/lib/trace.h @@ -0,0 +1,80 @@ +/* Tracing macros + * + * Wraps tracepoint macros for different tracing systems to allow switching + * between them at compile time. + * + * This should not be included directly by source files wishing to provide + * tracepoints. Instead, write a header that defines LTTng tracepoints and + * which includes this header, and include your new header in your source. USDT + * probes do not need tracepoint definitions, but are less capable than LTTng + * tracepoints. + * + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _TRACE_H_ +#define _TRACE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +/* + * Provided here: + * - frrtrace(n, provider, name, ...args...) + * - frrtrace_enabled(provider, name) + * - frrtracelog(level, msg, ...) + * + * Use frrtrace() to define tracepoints. n is the number of arguments; this is + * needed because USDT probe definitions use DTRACE_PROBEn macros, so the + * number of args must be passed in order to expand the correct macro. + * + * frrtrace_enabled() maps to tracepoint_enabled() under LTTng and is always + * true when using USDT. In the future it could be mapped to USDT semaphores + * but this is not implemented at present. + * + * frrtracelog() maps to tracelog() under LTTng and should only be used in zlog + * core code, to propagate zlog messages to LTTng. It expands to nothing + * otherwise. + */ + +#if defined(HAVE_LTTNG) + +#define frrtrace(nargs, provider, name, ...) \ + tracepoint(provider, name, ## __VA_ARGS__) +#define frrtrace_enabled(...) tracepoint_enabled(__VA_ARGS__) +#define frrtracelog(...) tracelog(__VA_ARGS__) + +#elif defined(HAVE_USDT) + +#include "sys/sdt.h" + +#define frrtrace(nargs, provider, name, ...) \ + DTRACE_PROBE##nargs(provider, name, ## __VA_ARGS__) +#define frrtrace_enabled(...) true +#define frrtracelog(...) + +#else + +#define frrtrace(nargs, provider, name, ...) (void)0 +#define frrtrace_enabled(...) false +#define frrtracelog(...) (void)0 + +#endif + +#endif /* _TRACE_H_ */ diff --git a/lib/vxlan.h b/lib/vxlan.h index 69d3939596..62963a6097 100644 --- a/lib/vxlan.h +++ b/lib/vxlan.h @@ -26,6 +26,16 @@ extern "C" { #endif +/* EVPN MH DF election alogorithm */ +#define EVPN_MH_DF_ALG_SERVICE_CARVING 0 +#define EVPN_MH_DF_ALG_HRW 1 +#define EVPN_MH_DF_ALG_PREF 2 + +/* preference range for DF election */ +#define EVPN_MH_DF_PREF_MIN 0 +#define EVPN_MH_DF_PREF_DEFAULT 32767 +#define EVPN_MH_DF_PREF_MAX 65535 + /* VxLAN Network Identifier - 24-bit (RFC 7348) */ typedef uint32_t vni_t; #define VNI_MAX 16777215 /* (2^24 - 1) */ diff --git a/lib/workqueue.c b/lib/workqueue.c index 54090d0d0f..f8e4677220 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -104,7 +104,7 @@ void work_queue_free_and_null(struct work_queue **wqp) struct work_queue *wq = *wqp; if (wq->thread != NULL) - thread_cancel(wq->thread); + thread_cancel(&(wq->thread)); while (!work_queue_empty(wq)) { struct work_queue_item *item = work_queue_last_item(wq); @@ -215,7 +215,7 @@ void workqueue_cmd_init(void) void work_queue_plug(struct work_queue *wq) { if (wq->thread) - thread_cancel(wq->thread); + thread_cancel(&(wq->thread)); wq->thread = NULL; diff --git a/lib/yang.c b/lib/yang.c index 5bf7758e18..c59cb642f0 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -227,40 +227,22 @@ next: return ret; } -int yang_snodes_iterate_module(const struct lys_module *module, - yang_iterate_cb cb, uint16_t flags, void *arg) +int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb, + uint16_t flags, void *arg) { - struct lys_node *snode; - int ret = YANG_ITER_CONTINUE; - - LY_TREE_FOR (module->data, snode) { - ret = yang_snodes_iterate_subtree(snode, module, cb, flags, - arg); - if (ret == YANG_ITER_STOP) - return ret; - } - - for (uint8_t i = 0; i < module->augment_size; i++) { - ret = yang_snodes_iterate_subtree( - (const struct lys_node *)&module->augment[i], module, - cb, flags, arg); - if (ret == YANG_ITER_STOP) - return ret; - } - - return ret; -} - -int yang_snodes_iterate_all(yang_iterate_cb cb, uint16_t flags, void *arg) -{ - struct yang_module *module; + const struct lys_module *module_iter; + uint32_t idx = 0; int ret = YANG_ITER_CONTINUE; - RB_FOREACH (module, yang_modules, &yang_modules) { + idx = ly_ctx_internal_modules_count(ly_native_ctx); + while ((module_iter = ly_ctx_get_module_iter(ly_native_ctx, &idx))) { struct lys_node *snode; - LY_TREE_FOR (module->info->data, snode) { - ret = yang_snodes_iterate_subtree(snode, NULL, cb, + if (!module_iter->implemented) + continue; + + LY_TREE_FOR (module_iter->data, snode) { + ret = yang_snodes_iterate_subtree(snode, module, cb, flags, arg); if (ret == YANG_ITER_STOP) return ret; diff --git a/lib/yang.h b/lib/yang.h index 867ade9676..0cd6a4a6f2 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -186,29 +186,11 @@ extern int yang_snodes_iterate_subtree(const struct lys_node *snode, void *arg); /* - * Iterate over all libyang schema nodes from the given YANG module. + * Iterate over all libyang schema nodes from all loeaded modules of from the + * given YANG module. * * module - * YANG module to operate on. - * - * cb - * Function to call with each schema node. - * - * flags - * YANG_ITER_* flags to control how the iteration is performed. - * - * arg - * Arbitrary argument passed as the second parameter in each call to 'cb'. - * - * Returns: - * The return value of the last called callback. - */ -extern int yang_snodes_iterate_module(const struct lys_module *module, - yang_iterate_cb cb, uint16_t flags, - void *arg); - -/* - * Iterate over all libyang schema nodes from all loaded YANG modules. + * When set, iterate over all nodes of the specified module only. * * cb * Function to call with each schema node. @@ -222,8 +204,8 @@ extern int yang_snodes_iterate_module(const struct lys_module *module, * Returns: * The return value of the last called callback. */ -extern int yang_snodes_iterate_all(yang_iterate_cb cb, uint16_t flags, - void *arg); +extern int yang_snodes_iterate(const struct lys_module *module, + yang_iterate_cb cb, uint16_t flags, void *arg); /* * Build schema path or data path of the schema node. diff --git a/lib/yang_translator.c b/lib/yang_translator.c index 7dbb1f3f1a..1f64675d6a 100644 --- a/lib/yang_translator.c +++ b/lib/yang_translator.c @@ -469,12 +469,12 @@ static unsigned int yang_translator_validate(struct yang_translator *translator) args.errors = 0; for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) { - yang_snodes_iterate_module( - tmodule->module, yang_translator_validate_cb, - YANG_ITER_FILTER_NPCONTAINERS - | YANG_ITER_FILTER_LIST_KEYS - | YANG_ITER_FILTER_INPUT_OUTPUT, - &args); + yang_snodes_iterate(tmodule->module, + yang_translator_validate_cb, + YANG_ITER_FILTER_NPCONTAINERS + | YANG_ITER_FILTER_LIST_KEYS + | YANG_ITER_FILTER_INPUT_OUTPUT, + &args); } if (args.errors) @@ -500,11 +500,11 @@ static unsigned int yang_module_nodes_count(const struct lys_module *module) { unsigned int total = 0; - yang_snodes_iterate_module(module, yang_module_nodes_count_cb, - YANG_ITER_FILTER_NPCONTAINERS - | YANG_ITER_FILTER_LIST_KEYS - | YANG_ITER_FILTER_INPUT_OUTPUT, - &total); + yang_snodes_iterate(module, yang_module_nodes_count_cb, + YANG_ITER_FILTER_NPCONTAINERS + | YANG_ITER_FILTER_LIST_KEYS + | YANG_ITER_FILTER_INPUT_OUTPUT, + &total); return total; } diff --git a/lib/zassert.h b/lib/zassert.h index e50a88f407..e6b254ee8d 100644 --- a/lib/zassert.h +++ b/lib/zassert.h @@ -27,6 +27,8 @@ extern void _zlog_assert_failed(const char *assertion, const char *file, unsigned int line, const char *function) __attribute__((noreturn)); +#undef __ASSERT_FUNCTION + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __ASSERT_FUNCTION __func__ #elif defined(__GNUC__) diff --git a/lib/zclient.c b/lib/zclient.c index 914b02749e..d0144279e5 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1116,13 +1116,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { /* limit the number of nexthops if necessary */ if (api->nexthop_num > MULTIPATH_NUM) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); flog_err( EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: can't encode %u nexthops (maximum is %u)", - __func__, buf, api->nexthop_num, MULTIPATH_NUM); + "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)", + __func__, &api->prefix, api->nexthop_num, + MULTIPATH_NUM); return -1; } @@ -1139,15 +1137,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) /* MPLS labels for BGP-LU or Segment Routing */ if (api_nh->label_num > MPLS_MAX_LABELS) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); - - flog_err(EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: can't encode %u labels (maximum is %u)", - __func__, buf, - api_nh->label_num, - MPLS_MAX_LABELS); + flog_err( + EC_LIB_ZAPI_ENCODE, + "%s: prefix %pFX: can't encode %u labels (maximum is %u)", + __func__, &api->prefix, + api_nh->label_num, MPLS_MAX_LABELS); return -1; } @@ -1162,13 +1156,10 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) { /* limit the number of nexthops if necessary */ if (api->backup_nexthop_num > MULTIPATH_NUM) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); flog_err( EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: can't encode %u backup nexthops (maximum is %u)", - __func__, buf, api->backup_nexthop_num, + "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)", + __func__, &api->prefix, api->backup_nexthop_num, MULTIPATH_NUM); return -1; } @@ -1185,15 +1176,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) /* MPLS labels for BGP-LU or Segment Routing */ if (api_nh->label_num > MPLS_MAX_LABELS) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&api->prefix, buf, sizeof(buf)); - - flog_err(EC_LIB_ZAPI_ENCODE, - "%s: prefix %s: backup: can't encode %u labels (maximum is %u)", - __func__, buf, - api_nh->label_num, - MPLS_MAX_LABELS); + flog_err( + EC_LIB_ZAPI_ENCODE, + "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)", + __func__, &api->prefix, + api_nh->label_num, MPLS_MAX_LABELS); return -1; } @@ -2319,13 +2306,10 @@ struct connected *zebra_interface_address_read(int type, struct stream *s, else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { /* carp interfaces on OpenBSD with 0.0.0.0/0 as * "peer" */ - char buf[PREFIX_STRLEN]; flog_err( EC_LIB_ZAPI_ENCODE, - "warning: interface %s address %s with peer flag set, but no peer address!", - ifp->name, - prefix2str(ifc->address, buf, - sizeof(buf))); + "warning: interface %s address %pFX with peer flag set, but no peer address!", + ifp->name, ifc->address); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } } diff --git a/lib/zclient.h b/lib/zclient.h index 959a101395..80dca3fc56 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -690,6 +690,12 @@ zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note) * to allocate past 0x80 */ +/* Zebra ES VTEP flags (ZEBRA_REMOTE_ES_VTEP_ADD) */ +/* ESR has been rxed from the VTEP. Only VTEPs that have advertised the + * Type-4 route can participate in DF election. + */ +#define ZAPI_ES_VTEP_FLAG_ESR_RXED (1 << 0) + enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 }; struct zclient_options { diff --git a/lib/zlog.c b/lib/zlog.c index 8dfd20371b..e77feec5f2 100644 --- a/lib/zlog.c +++ b/lib/zlog.c @@ -52,6 +52,7 @@ #include "printfrr.h" #include "frrcu.h" #include "zlog.h" +#include "libfrr_trace.h" DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message") DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer") @@ -450,6 +451,34 @@ void vzlog(int prio, const char *fmt, va_list ap) { struct zlog_tls *zlog_tls = zlog_tls_get(); +#ifdef HAVE_LTTNG + va_list copy; + va_copy(copy, ap); + char *msg = vasprintfrr(MTYPE_LOG_MESSAGE, fmt, copy); + + switch (prio) { + case LOG_ERR: + frrtracelog(TRACE_ERR, msg); + break; + case LOG_WARNING: + frrtracelog(TRACE_WARNING, msg); + break; + case LOG_DEBUG: + frrtracelog(TRACE_DEBUG, msg); + break; + case LOG_NOTICE: + frrtracelog(TRACE_DEBUG, msg); + break; + case LOG_INFO: + default: + frrtracelog(TRACE_INFO, msg); + break; + } + + va_end(copy); + XFREE(MTYPE_LOG_MESSAGE, msg); +#endif + if (zlog_tls) vzlog_tls(zlog_tls, prio, fmt, ap); else diff --git a/nhrpd/README.nhrpd b/nhrpd/README.nhrpd index 569b3f4463..8bb5f69bea 100644 --- a/nhrpd/README.nhrpd +++ b/nhrpd/README.nhrpd @@ -126,7 +126,8 @@ Integration with strongSwan Contrary to opennhrp, Quagga/NHRP has tight integration with IKE daemon. Currently strongSwan is supported using the VICI protocol. strongSwan -is connected using UNIX socket (hardcoded now as /var/run/charon.vici). +is connected using UNIX socket (default /var/run/charon.vici use configure +argument --with-vici-socket= to change). Thus nhrpd needs to be run as user that can open that file. Currently, you will need patched strongSwan. The working tree is at: diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c index cf338a0876..309f733526 100644 --- a/nhrpd/netlink_arp.c +++ b/nhrpd/netlink_arp.c @@ -257,7 +257,7 @@ static int netlink_log_recv(struct thread *t) void netlink_set_nflog_group(int nlgroup) { if (netlink_log_fd >= 0) { - THREAD_OFF(netlink_log_thread); + thread_cancel(&netlink_log_thread); close(netlink_log_fd); netlink_log_fd = -1; } diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index 1e576fc5ac..0ed2371eb0 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -220,8 +220,8 @@ static void nhrp_interface_update_address(struct interface *ifp, afi_t afi, /* On NHRP interfaces a host prefix is required */ if (best && if_ad->configured && best->address->prefixlen != 8 * prefix_blen(best->address)) { - zlog_notice("%s: %s is not a host prefix", ifp->name, - prefix2str(best->address, buf, sizeof(buf))); + zlog_notice("%s: %pFX is not a host prefix", ifp->name, + best->address); best = NULL; } @@ -335,14 +335,13 @@ int nhrp_ifp_down(struct interface *ifp) int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS) { struct connected *ifc; - char buf[PREFIX_STRLEN]; ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id); if (ifc == NULL) return 0; - debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %s", ifc->ifp->name, - prefix2str(ifc->address, buf, sizeof(buf))); + debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %pFX", ifc->ifp->name, + ifc->address); nhrp_interface_update_address( ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0); @@ -353,14 +352,13 @@ int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS) int nhrp_interface_address_delete(ZAPI_CALLBACK_ARGS) { struct connected *ifc; - char buf[PREFIX_STRLEN]; ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id); if (ifc == NULL) return 0; - debugf(NHRP_DEBUG_IF, "if-addr-del: %s: %s", ifc->ifp->name, - prefix2str(ifc->address, buf, sizeof(buf))); + debugf(NHRP_DEBUG_IF, "if-addr-del: %s: %pFX", ifc->ifp->name, + ifc->address); nhrp_interface_update_address( ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0); diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index 8509cedcee..085cab347f 100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c @@ -137,7 +137,7 @@ static void nhrp_reg_peer_notify(struct notifier_block *n, unsigned long cmd) debugf(NHRP_DEBUG_COMMON, "NHS: Flush timer for %s", sockunion2str(&r->peer->vc->remote.nbma, buf, sizeof(buf))); - THREAD_TIMER_OFF(r->t_register); + THREAD_OFF(r->t_register); thread_add_timer_msec(master, nhrp_reg_send_req, r, 10, &r->t_register); break; diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 0c5513b892..2bc2d91597 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -166,14 +166,13 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, } if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) { - char buf[2][PREFIX_STRLEN]; + char buf[PREFIX_STRLEN]; - prefix2str(&api.prefix, buf[0], sizeof(buf[0])); zlog_debug( - "Zebra send: route %s %s nexthop %s metric %u count %d dev %s", - add ? "add" : "del", buf[0], + "Zebra send: route %s %pFX nexthop %s metric %u count %d dev %s", + add ? "add" : "del", &api.prefix, nexthop ? inet_ntop(api.prefix.family, &api_nh->gate, - buf[1], sizeof(buf[1])) + buf, sizeof(buf)) : "<onlink>", api.metric, api.nexthop_num, ifp ? ifp->name : "none"); } @@ -188,7 +187,7 @@ int nhrp_route_read(ZAPI_CALLBACK_ARGS) struct zapi_nexthop *api_nh; struct interface *ifp = NULL; union sockunion nexthop_addr; - char buf[2][PREFIX_STRLEN]; + char buf[PREFIX_STRLEN]; int added; if (zapi_route_decode(zclient->ibuf, &api) < 0) @@ -221,10 +220,9 @@ int nhrp_route_read(ZAPI_CALLBACK_ARGS) } added = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD); - debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %s via %s dev %s", - added ? "add" : "del", - prefix2str(&api.prefix, buf[0], sizeof(buf[0])), - sockunion2str(&nexthop_addr, buf[1], sizeof(buf[1])), + debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %pFX via %s dev %s", + added ? "add" : "del", &api.prefix, + sockunion2str(&nexthop_addr, buf, sizeof(buf)), ifp ? ifp->name : "(none)"); nhrp_route_update_zebra(&api.prefix, &nexthop_addr, ifp); @@ -240,7 +238,6 @@ int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p, struct route_info *ri; struct prefix lookup; afi_t afi = family2afi(sockunion_family(addr)); - char buf[PREFIX_STRLEN]; sockunion2hostprefix(addr, &lookup); @@ -250,8 +247,7 @@ int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p, ri = rn->info; if (ri->nhrp_ifp) { - debugf(NHRP_DEBUG_ROUTE, "lookup %s: nhrp_if=%s", - prefix2str(&lookup, buf, sizeof(buf)), + debugf(NHRP_DEBUG_ROUTE, "lookup %pFX: nhrp_if=%s", &lookup, ri->nhrp_ifp->name); if (via) @@ -259,9 +255,8 @@ int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p, if (ifp) *ifp = ri->nhrp_ifp; } else { - debugf(NHRP_DEBUG_ROUTE, "lookup %s: zebra route dev %s", - prefix2str(&lookup, buf, sizeof(buf)), - ri->ifp ? ri->ifp->name : "(none)"); + debugf(NHRP_DEBUG_ROUTE, "lookup %pFX: zebra route dev %s", + &lookup, ri->ifp ? ri->ifp->name : "(none)"); if (via) *via = ri->via; diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 1c2b2b28f2..9a6f77334f 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -28,11 +28,9 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s); static void nhrp_shortcut_check_use(struct nhrp_shortcut *s) { - char buf[PREFIX_STRLEN]; - if (s->expiring && s->cache && s->cache->used) { - debugf(NHRP_DEBUG_ROUTE, "Shortcut %s used and expiring", - prefix2str(s->p, buf, sizeof(buf))); + debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX used and expiring", + s->p); nhrp_shortcut_send_resolution_req(s); } } @@ -53,8 +51,6 @@ static int nhrp_shortcut_do_expire(struct thread *t) static void nhrp_shortcut_cache_notify(struct notifier_block *n, unsigned long cmd) { - char buf[PREFIX_STRLEN]; - struct nhrp_shortcut *s = container_of(n, struct nhrp_shortcut, cache_notifier); @@ -62,9 +58,8 @@ static void nhrp_shortcut_cache_notify(struct notifier_block *n, case NOTIFY_CACHE_UP: if (!s->route_installed) { debugf(NHRP_DEBUG_ROUTE, - "Shortcut: route install %s nh (unspec) dev %s", - prefix2str(s->p, buf, sizeof(buf)), - s->cache->ifp->name); + "Shortcut: route install %pFX nh (unspec) dev %s", + s->p, s->cache->ifp->name); nhrp_route_announce(1, s->type, s->p, s->cache->ifp, NULL, 0); @@ -152,13 +147,11 @@ static void nhrp_shortcut_delete(struct nhrp_shortcut *s) { struct route_node *rn; afi_t afi = family2afi(PREFIX_FAMILY(s->p)); - char buf[PREFIX_STRLEN]; THREAD_OFF(s->t_timer); nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid); - debugf(NHRP_DEBUG_ROUTE, "Shortcut %s purged", - prefix2str(s->p, buf, sizeof(buf))); + debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX purged", s->p); nhrp_shortcut_update_binding(s, NHRP_CACHE_INVALID, NULL, 0); @@ -184,7 +177,6 @@ static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p) { struct nhrp_shortcut *s; struct route_node *rn; - char buf[PREFIX_STRLEN]; afi_t afi = family2afi(PREFIX_FAMILY(p)); if (!shortcut_rib[afi]) @@ -197,8 +189,7 @@ static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p) s->type = NHRP_CACHE_INVALID; s->p = &rn->p; - debugf(NHRP_DEBUG_ROUTE, "Shortcut %s created", - prefix2str(s->p, buf, sizeof(buf))); + debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX created", s->p); } else { s = rn->info; route_unlock_node(rn); @@ -219,7 +210,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, union sockunion *proto, cie_proto, *nbma, cie_nbma, nat_nbma; struct prefix prefix, route_prefix; struct zbuf extpl; - char bufp[PREFIX_STRLEN], buf[4][SU_ADDRSTRLEN]; + char buf[4][SU_ADDRSTRLEN]; int holding_time = pp->if_ad->holdtime; nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid); @@ -287,9 +278,8 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, } debugf(NHRP_DEBUG_COMMON, - "Shortcut: %s is at proto %s dst_proto %s cie-nbma %s nat-nbma %s cie-holdtime %d", - prefix2str(&prefix, bufp, sizeof(bufp)), - sockunion2str(proto, buf[0], sizeof(buf[0])), + "Shortcut: %pFX is at proto %s dst_proto %s cie-nbma %s nat-nbma %s cie-holdtime %d", + &prefix, sockunion2str(proto, buf[0], sizeof(buf[0])), sockunion2str(&pp->dst_proto, buf[1], sizeof(buf[1])), sockunion2str(&cie_nbma, buf[2], sizeof(buf[2])), sockunion2str(&nat_nbma, buf[3], sizeof(buf[3])), diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index fe681b4052..27b7bece48 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -1109,11 +1109,12 @@ void nhrp_config_init(void) access_list_init(); /* global commands */ - install_element(VIEW_NODE, &show_debugging_nhrp_cmd); install_element(VIEW_NODE, &show_ip_nhrp_cmd); install_element(VIEW_NODE, &show_dmvpn_cmd); install_element(ENABLE_NODE, &clear_nhrp_cmd); + install_element(ENABLE_NODE, &show_debugging_nhrp_cmd); + install_element(ENABLE_NODE, &debug_nhrp_cmd); install_element(ENABLE_NODE, &no_debug_nhrp_cmd); diff --git a/nhrpd/vici.c b/nhrpd/vici.c index 2dc05a4aa7..86554f53dc 100644 --- a/nhrpd/vici.c +++ b/nhrpd/vici.c @@ -478,7 +478,7 @@ static int vici_reconnect(struct thread *t) if (vici->fd >= 0) return 0; - fd = sock_open_unix("/var/run/charon.vici"); + fd = sock_open_unix(VICI_SOCKET); if (fd < 0) { debugf(NHRP_DEBUG_VICI, "%s: failure connecting VICI socket: %s", __func__, diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 6fe3a289ce..f087289df6 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -82,10 +82,10 @@ static int ospf6_abr_nexthops_belong_to_area(struct ospf6_route *route, static void ospf6_abr_delete_route(struct ospf6_route *range, struct ospf6_route *summary, struct ospf6_route_table *summary_table, - struct ospf6_lsa *old) + struct ospf6_lsa *old, struct ospf6 *ospf6) { if (summary) { - ospf6_route_remove(summary, summary_table); + ospf6_route_remove(summary, summary_table, ospf6); } if (old && !OSPF6_LSA_IS_MAXAGE(old)) @@ -117,7 +117,7 @@ void ospf6_abr_disable_area(struct ospf6_area *area) area->ospf6->router_id, area->lsdb); if (old) ospf6_lsa_purge(old); - ospf6_route_remove(ro, area->summary_prefix); + ospf6_route_remove(ro, area->summary_prefix, area->ospf6); } /* Withdraw all summary router-routes previously originated */ @@ -128,7 +128,7 @@ void ospf6_abr_disable_area(struct ospf6_area *area) area->ospf6->router_id, area->lsdb); if (old) ospf6_lsa_purge(old); - ospf6_route_remove(ro, area->summary_router); + ospf6_route_remove(ro, area->summary_router, area->ospf6); } /* Schedule Router-LSA for each area (ABR status may change) */ @@ -153,7 +153,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, struct ospf6_inter_router_lsa *router_lsa; struct ospf6_route_table *summary_table = NULL; uint16_t type; - char buf[PREFIX2STR_BUFFER]; int is_debug = 0; /* Only destination type network, range or ASBR are considered */ @@ -196,12 +195,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (route->type == OSPF6_DEST_TYPE_ROUTER) { if (ADV_ROUTER_IN_PREFIX(&route->prefix) == area->ospf6->router_id) { - inet_ntop(AF_INET, - &(ADV_ROUTER_IN_PREFIX(&route->prefix)), buf, - sizeof(buf)); zlog_debug( - "%s: Skipping ASBR announcement for ABR (%s)", - __func__, buf); + "%s: Skipping ASBR announcement for ABR (%pFX)", + __func__, + &ADV_ROUTER_IN_PREFIX(&route->prefix)); return 0; } } @@ -210,11 +207,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE(INTER_ROUTER)) { is_debug++; - inet_ntop(AF_INET, - &(ADV_ROUTER_IN_PREFIX(&route->prefix)), buf, - sizeof(buf)); - zlog_debug("Originating summary in area %s for ASBR %s", - area->name, buf); + zlog_debug( + "Originating summary in area %s for ASBR %pFX", + area->name, + &ADV_ROUTER_IN_PREFIX(&route->prefix)); } summary_table = area->summary_router; } else { @@ -226,16 +222,13 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, route->path.origin.type == htons(OSPF6_LSTYPE_INTER_PREFIX)) { if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST)) { - if (is_debug) { - inet_ntop(AF_INET, - &(ADV_ROUTER_IN_PREFIX( - &route->prefix)), buf, - sizeof(buf)); + if (is_debug) zlog_debug( - "%s: route %s with cost %u is not best, ignore.", - __func__, buf, + "%s: route %pFX with cost %u is not best, ignore.", + __func__, + &ADV_ROUTER_IN_PREFIX( + &route->prefix), route->path.cost); - } return 0; } } @@ -243,23 +236,19 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (route->path.origin.type == htons(OSPF6_LSTYPE_INTRA_PREFIX)) { if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST)) { - if (is_debug) { - prefix2str(&route->prefix, buf, - sizeof(buf)); + if (is_debug) zlog_debug( - "%s: intra-prefix route %s with cost %u is not best, ignore.", - __func__, buf, + "%s: intra-prefix route %pFX with cost %u is not best, ignore.", + __func__, &route->prefix, route->path.cost); - } return 0; } } - if (is_debug) { - prefix2str(&route->prefix, buf, sizeof(buf)); - zlog_debug("Originating summary in area %s for %s cost %u", - area->name, buf, route->path.cost); - } + if (is_debug) + zlog_debug( + "Originating summary in area %s for %pFX cost %u", + area->name, &route->prefix, route->path.cost); summary_table = area->summary_prefix; } @@ -284,10 +273,11 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, "The range is not active. withdraw"); ospf6_abr_delete_route(route, summary, - summary_table, old); + summary_table, old, + area->ospf6); } } else if (old) { - ospf6_route_remove(summary, summary_table); + ospf6_route_remove(summary, summary_table, area->ospf6); ospf6_lsa_purge(old); } return 0; @@ -298,7 +288,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, zlog_debug( "Area has been stubbed, purge Inter-Router LSA"); - ospf6_abr_delete_route(route, summary, summary_table, old); + ospf6_abr_delete_route(route, summary, summary_table, old, + area->ospf6); return 0; } @@ -307,7 +298,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (is_debug) zlog_debug("Area has been stubbed, purge prefix LSA"); - ospf6_abr_delete_route(route, summary, summary_table, old); + ospf6_abr_delete_route(route, summary, summary_table, old, + area->ospf6); return 0; } @@ -343,7 +335,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, zlog_debug( "This is the secondary path to the ASBR, ignore"); ospf6_abr_delete_route(route, summary, summary_table, - old); + old, area->ospf6); return 0; } @@ -369,13 +361,12 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (range && !CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE) && (route->path.area_id != OSPF_AREA_BACKBONE || !IS_AREA_TRANSIT(area))) { - if (is_debug) { - prefix2str(&range->prefix, buf, sizeof(buf)); - zlog_debug("Suppressed by range %s of area %s", - buf, route_area->name); - } + if (is_debug) + zlog_debug( + "Suppressed by range %pFX of area %s", + &range->prefix, route_area->name); ospf6_abr_delete_route(route, summary, summary_table, - old); + old, area->ospf6); return 0; } } @@ -388,7 +379,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, zlog_debug( "This is the range with DoNotAdvertise set. ignore"); ospf6_abr_delete_route(route, summary, summary_table, - old); + old, area->ospf6); return 0; } @@ -397,7 +388,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (is_debug) zlog_debug("The range is not active. withdraw"); ospf6_abr_delete_route(route, summary, summary_table, - old); + old, area->ospf6); return 0; } } @@ -411,15 +402,11 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (EXPORT_LIST(area)) if (access_list_apply(EXPORT_LIST(area), &route->prefix) == FILTER_DENY) { - if (is_debug) { - inet_ntop(AF_INET, - &(ADV_ROUTER_IN_PREFIX( - &route->prefix)), - buf, sizeof(buf)); + if (is_debug) zlog_debug( - "prefix %s was denied by export list", - buf); - } + "prefix %pFX was denied by export list", + &ADV_ROUTER_IN_PREFIX( + &route->prefix)); return 0; } } @@ -428,15 +415,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, if (PREFIX_LIST_OUT(area)) if (prefix_list_apply(PREFIX_LIST_OUT(area), &route->prefix) != PREFIX_PERMIT) { - if (is_debug) { - inet_ntop( - AF_INET, - &(ADV_ROUTER_IN_PREFIX(&route->prefix)), - buf, sizeof(buf)); + if (is_debug) zlog_debug( - "prefix %s was denied by filter-list out", - buf); - } + "prefix %pFX was denied by filter-list out", + &ADV_ROUTER_IN_PREFIX(&route->prefix)); return 0; } @@ -458,7 +440,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, summary->path.origin.type, summary->path.origin.adv_router, area->lsdb); } - summary = ospf6_route_add(summary, summary_table); + summary = ospf6_route_add(summary, summary_table, area->ospf6); } else { summary->type = route->type; monotime(&summary->changed); @@ -597,7 +579,8 @@ ospf6_abr_range_summary_needs_update(struct ospf6_route *range, uint32_t cost) return (redo_summary); } -static void ospf6_abr_range_update(struct ospf6_route *range) +static void ospf6_abr_range_update(struct ospf6_route *range, + struct ospf6 *ospf6) { uint32_t cost = 0; struct listnode *node, *nnode; @@ -636,7 +619,7 @@ static void ospf6_abr_range_update(struct ospf6_route *range) if (IS_OSPF6_DEBUG_ABR) zlog_debug("Add discard route"); - ospf6_zebra_add_discard(range); + ospf6_zebra_add_discard(range, ospf6); } } else { /* Summary removed or no summary generated as no @@ -646,18 +629,19 @@ static void ospf6_abr_range_update(struct ospf6_route *range) if (IS_OSPF6_DEBUG_ABR) zlog_debug("Delete discard route"); - ospf6_zebra_delete_discard(range); + ospf6_zebra_delete_discard(range, ospf6); } } } } -void ospf6_abr_originate_summary(struct ospf6_route *route) +void ospf6_abr_originate_summary(struct ospf6_route *route, struct ospf6 *ospf6) { struct listnode *node, *nnode; struct ospf6_area *oa; struct ospf6_route *range = NULL; + if (route->type == OSPF6_DEST_TYPE_NETWORK) { oa = ospf6_area_lookup(route->path.area_id, ospf6); if (!oa) { @@ -668,7 +652,7 @@ void ospf6_abr_originate_summary(struct ospf6_route *route) range = ospf6_route_lookup_bestmatch(&route->prefix, oa->range_table); if (range) { - ospf6_abr_range_update(range); + ospf6_abr_range_update(range, ospf6); } } @@ -695,7 +679,7 @@ void ospf6_abr_defaults_to_stub(struct ospf6 *o) def->path.subtype = OSPF6_PATH_SUBTYPE_DEFAULT_RT; def->path.area_id = o->backbone->area_id; - for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) { + for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) { if (!IS_AREA_STUB(oa)) { /* withdraw defaults when an area switches from stub to * non-stub */ @@ -725,7 +709,8 @@ void ospf6_abr_defaults_to_stub(struct ospf6 *o) void ospf6_abr_old_path_update(struct ospf6_route *old_route, struct ospf6_route *route, - struct ospf6_route_table *table) + struct ospf6_route_table *table, + struct ospf6 *ospf6) { struct ospf6_path *o_path = NULL; struct listnode *anode, *anext; @@ -772,7 +757,7 @@ void ospf6_abr_old_path_update(struct ospf6_route *old_route, : 0); if (table->hook_add) - (*table->hook_add)(old_route); + (*table->hook_add)(old_route, ospf6); if (old_route->path.origin.id == route->path.origin.id && old_route->path.origin.adv_router == @@ -789,16 +774,15 @@ void ospf6_abr_old_path_update(struct ospf6_route *old_route, } } -void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, - struct ospf6_route *old, - struct ospf6_route_table *table) +void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old, + struct ospf6_route_table *table, + struct ospf6 *ospf6) { if (listcount(old->paths) > 1) { struct listnode *anode, *anext, *nnode, *rnode, *rnext; struct ospf6_path *o_path; struct ospf6_nexthop *nh, *rnh; bool nh_updated = false; - char buf[PREFIX2STR_BUFFER]; for (ALL_LIST_ELEMENTS(old->paths, anode, anext, o_path)) { if (o_path->origin.adv_router != lsa->header->adv_router @@ -820,19 +804,16 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, if (nh_updated) { if (listcount(old->paths)) { - if (IS_OSPF6_DEBUG_ABR || - IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX)) { - prefix2str(&old->prefix, buf, - sizeof(buf)); - zlog_debug("%s: old %s updated nh %u", - __func__, buf, + if (IS_OSPF6_DEBUG_ABR + || IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX)) + zlog_debug("%s: old %pFX updated nh %u", + __func__, &old->prefix, old->nh_list ? listcount( old->nh_list) : 0); - } if (table->hook_add) - (*table->hook_add)(old); + (*table->hook_add)(old, ospf6); if ((old->path.origin.id == lsa->header->id) && (old->path.origin.adv_router @@ -849,11 +830,10 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, h_path->origin.adv_router; } } else - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, ospf6); } } else - ospf6_route_remove(old, table); - + ospf6_route_remove(old, table, ospf6); } /* RFC 2328 16.2. Calculating the inter-area routes */ @@ -968,7 +948,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) if (is_debug) zlog_debug("cost is LS_INFINITY, ignore"); if (old) - ospf6_abr_old_route_remove(lsa, old, table); + ospf6_abr_old_route_remove(lsa, old, table, oa->ospf6); return; } if (OSPF6_LSA_IS_MAXAGE(lsa)) { @@ -976,7 +956,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) zlog_debug("%s: LSA %s is MaxAge, ignore", __func__, lsa->name); if (old) - ospf6_abr_old_route_remove(lsa, old, table); + ospf6_abr_old_route_remove(lsa, old, table, oa->ospf6); return; } @@ -986,7 +966,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) zlog_debug("LSA %s is self-originated, ignore", lsa->name); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); return; } @@ -1002,7 +982,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) zlog_debug( "Prefix is equal to address range, ignore"); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); return; } @@ -1013,7 +993,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) if (is_debug) zlog_debug("Prefix has NU/LA bit set, ignore"); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); return; } } @@ -1026,7 +1006,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) if (is_debug) zlog_debug("Prefix has NU/LA bit set, ignore"); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); return; } @@ -1040,7 +1020,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) "Ignorning Inter-Router LSA for an ABR (%s)", buf); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); return; } @@ -1068,7 +1048,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) zlog_debug( "%s: remove old entry: %s %p ", __func__, buf, (void *)old); - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); } } return; @@ -1087,7 +1067,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) zlog_debug( "Prefix was denied by import-list"); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, + oa->ospf6); return; } } @@ -1099,7 +1080,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) if (is_debug) zlog_debug("Prefix was denied by prefix-list"); if (old) - ospf6_route_remove(old, table); + ospf6_route_remove(old, table, oa->ospf6); return; } } @@ -1140,13 +1121,11 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) continue; if ((ospf6_route_cmp(route, old_route) != 0)) { - if (is_debug) { - prefix2str(&prefix, buf, sizeof(buf)); + if (is_debug) zlog_debug( - "%s: old %p %s cost %u new route cost %u are not same", - __func__, (void *)old_route, buf, + "%s: old %p %pFX cost %u new route cost %u are not same", + __func__, (void *)old_route, &prefix, old_route->path.cost, route->path.cost); - } /* Check new route's adv. router is same in one of * the paths with differed cost, if so remove the @@ -1154,7 +1133,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) */ if (listcount(old_route->paths) > 1) ospf6_abr_old_path_update(old_route, route, - table); + table, oa->ospf6); continue; } @@ -1222,7 +1201,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) * For Inter-Router trigger summary update */ if (table->hook_add) - (*table->hook_add)(old_route); + (*table->hook_add)(old_route, oa->ospf6); /* Delete new route */ ospf6_route_delete(route); @@ -1241,23 +1220,19 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) path = ospf6_path_dup(&route->path); ospf6_copy_nexthops(path->nh_list, abr_entry->nh_list); listnode_add_sort(route->paths, path); - /* ospf6_ia_add_nw_route (table, &prefix, route); */ - ospf6_route_add(route, table); + ospf6_route_add(route, table, oa->ospf6); } } -void ospf6_abr_examin_brouter(uint32_t router_id) +void ospf6_abr_examin_brouter(uint32_t router_id, struct ospf6_route *route, + struct ospf6 *ospf6) { struct ospf6_lsa *lsa; struct ospf6_area *oa; uint16_t type; - if (ospf6_is_router_abr(ospf6)) - oa = ospf6->backbone; - else - oa = listgetdata(listhead(ospf6->area_list)); - + oa = ospf6_area_lookup(route->path.area_id, ospf6); /* * It is possible to designate a non backbone * area first. If that is the case safely @@ -1298,7 +1273,7 @@ void ospf6_abr_prefix_resummarize(struct ospf6 *o) for (route = ospf6_route_head(o->route_table); route; route = ospf6_route_next(route)) - ospf6_abr_originate_summary(route); + ospf6_abr_originate_summary(route, o); if (IS_OSPF6_DEBUG_ABR) zlog_debug("Finished re-examining Inter-Prefix Summaries"); diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h index e40d155037..8ad51a4f82 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -64,11 +64,14 @@ extern void ospf6_abr_disable_area(struct ospf6_area *oa); extern int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, struct ospf6_area *area); -extern void ospf6_abr_originate_summary(struct ospf6_route *route); +extern void ospf6_abr_originate_summary(struct ospf6_route *route, + struct ospf6 *ospf6); extern void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa); extern void ospf6_abr_defaults_to_stub(struct ospf6 *); -extern void ospf6_abr_examin_brouter(uint32_t router_id); +extern void ospf6_abr_examin_brouter(uint32_t router_id, + struct ospf6_route *route, + struct ospf6 *ospf6); extern void ospf6_abr_reimport(struct ospf6_area *oa); extern void ospf6_abr_range_reset_cost(struct ospf6 *ospf6); extern void ospf6_abr_prefix_resummarize(struct ospf6 *ospf6); @@ -78,10 +81,12 @@ extern void install_element_ospf6_debug_abr(void); extern int ospf6_abr_config_write(struct vty *vty); extern void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old, - struct ospf6_route_table *table); + struct ospf6_route_table *table, + struct ospf6 *ospf6); extern void ospf6_abr_old_path_update(struct ospf6_route *old_route, struct ospf6_route *route, - struct ospf6_route_table *table); + struct ospf6_route_table *table, + struct ospf6 *ospf6); extern void ospf6_abr_init(void); #endif /*OSPF6_ABR_H*/ diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 713ce26ecb..e98764cd26 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -115,21 +115,23 @@ static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa *lsa) } } -static void ospf6_area_route_hook_add(struct ospf6_route *route) +static void ospf6_area_route_hook_add(struct ospf6_route *route, + struct ospf6 *ospf6) { struct ospf6_route *copy; copy = ospf6_route_copy(route); - ospf6_route_add(copy, ospf6->route_table); + ospf6_route_add(copy, ospf6->route_table, ospf6); } -static void ospf6_area_route_hook_remove(struct ospf6_route *route) +static void ospf6_area_route_hook_remove(struct ospf6_route *route, + struct ospf6 *ospf6) { struct ospf6_route *copy; copy = ospf6_route_lookup_identical(route, ospf6->route_table); if (copy) - ospf6_route_remove(copy, ospf6->route_table); + ospf6_route_remove(copy, ospf6->route_table, ospf6); } static void ospf6_area_stub_update(struct ospf6_area *area) @@ -282,13 +284,13 @@ void ospf6_area_delete(struct ospf6_area *oa) ospf6_lsdb_delete(oa->lsdb_self); ospf6_lsdb_delete(oa->temp_router_lsa_lsdb); - ospf6_spf_table_finish(oa->spf_table); - ospf6_route_table_delete(oa->spf_table); - ospf6_route_table_delete(oa->route_table); + ospf6_spf_table_finish(oa->spf_table, oa->ospf6); + ospf6_route_table_delete(oa->spf_table, oa->ospf6); + ospf6_route_table_delete(oa->route_table, oa->ospf6); - ospf6_route_table_delete(oa->range_table); - ospf6_route_table_delete(oa->summary_prefix); - ospf6_route_table_delete(oa->summary_router); + ospf6_route_table_delete(oa->range_table, oa->ospf6); + ospf6_route_table_delete(oa->summary_prefix, oa->ospf6); + ospf6_route_table_delete(oa->summary_router, oa->ospf6); listnode_delete(oa->ospf6->area_list, oa); oa->ospf6 = NULL; @@ -297,6 +299,20 @@ void ospf6_area_delete(struct ospf6_area *oa) XFREE(MTYPE_OSPF6_AREA, oa); } +struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id) +{ + struct ospf6_area *oa; + struct listnode *n, *node, *nnode; + struct ospf6 *ospf6; + + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) + if (oa->area_id == area_id) + return oa; + } + return (struct ospf6_area *)NULL; +} + struct ospf6_area *ospf6_area_lookup(uint32_t area_id, struct ospf6 *ospf6) { struct ospf6_area *oa; @@ -335,8 +351,8 @@ void ospf6_area_disable(struct ospf6_area *oa) ospf6_lsdb_remove_all(oa->lsdb); ospf6_lsdb_remove_all(oa->lsdb_self); - ospf6_spf_table_finish(oa->spf_table); - ospf6_route_remove_all(oa->route_table); + ospf6_spf_table_finish(oa->spf_table, oa->ospf6); + ospf6_route_remove_all(oa->route_table, oa->ospf6); THREAD_OFF(oa->thread_router_lsa); THREAD_OFF(oa->thread_intra_prefix_lsa); @@ -401,7 +417,9 @@ DEFUN (area_range, struct ospf6_route *range; uint32_t cost = OSPF_AREA_RANGE_COST_UNSPEC; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6); ret = str2prefix(argv[idx_ipv6_prefixlen]->arg, &prefix); if (ret != 1 || prefix.family != AF_INET6) { @@ -436,7 +454,7 @@ DEFUN (area_range, zlog_debug("%s: for prefix %s, flag = %x", __func__, argv[idx_ipv6_prefixlen]->arg, range->flag); if (range->rnode == NULL) { - ospf6_route_add(range, oa->range_table); + ospf6_route_add(range, oa->range_table, oa->ospf6); } if (ospf6_is_router_abr(ospf6)) { @@ -468,7 +486,9 @@ DEFUN (no_area_range, struct prefix prefix; struct ospf6_route *range, *route; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6); ret = str2prefix(argv[idx_ipv6]->arg, &prefix); if (ret != 1 || prefix.family != AF_INET6) { @@ -488,30 +508,29 @@ DEFUN (no_area_range, SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE); /* Redo summaries if required */ - for (route = ospf6_route_head(ospf6->route_table); route; + for (route = ospf6_route_head(oa->ospf6->route_table); route; route = ospf6_route_next(route)) - ospf6_abr_originate_summary(route); + ospf6_abr_originate_summary(route, oa->ospf6); /* purge the old aggregated summary LSA */ - ospf6_abr_originate_summary(range); + ospf6_abr_originate_summary(range, oa->ospf6); } - ospf6_route_remove(range, oa->range_table); + ospf6_route_remove(range, oa->range_table, oa->ospf6); return CMD_SUCCESS; } -void ospf6_area_config_write(struct vty *vty) +void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6) { struct listnode *node; struct ospf6_area *oa; struct ospf6_route *range; - char buf[PREFIX2STR_BUFFER]; for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { for (range = ospf6_route_head(oa->range_table); range; range = ospf6_route_next(range)) { - prefix2str(&range->prefix, buf, sizeof(buf)); - vty_out(vty, " area %s range %s", oa->name, buf); + vty_out(vty, " area %s range %pFX", oa->name, + &range->prefix); if (CHECK_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE)) { @@ -567,7 +586,9 @@ DEFUN (area_filter_list, struct ospf6_area *area; struct prefix_list *plist; - OSPF6_CMD_AREA_GET(areaid, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(areaid, area, ospf6); plist = prefix_list_lookup(AFI_IP6, plistname); if (strmatch(inout, "in")) { @@ -606,7 +627,8 @@ DEFUN (no_area_filter_list, struct ospf6_area *area; - OSPF6_CMD_AREA_GET(areaid, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + OSPF6_CMD_AREA_GET(areaid, area, ospf6); if (strmatch(inout, "in")) { if (PREFIX_NAME_IN(area)) @@ -630,18 +652,25 @@ DEFUN (no_area_filter_list, void ospf6_area_plist_update(struct prefix_list *plist, int add) { + struct listnode *node, *nnode; struct ospf6_area *oa; struct listnode *n; const char *name = prefix_list_name(plist); + struct ospf6 *ospf6 = NULL; + - if (!ospf6) + if (!om6->ospf6) return; - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { - if (PREFIX_NAME_IN(oa) && !strcmp(PREFIX_NAME_IN(oa), name)) - PREFIX_LIST_IN(oa) = add ? plist : NULL; - if (PREFIX_NAME_OUT(oa) && !strcmp(PREFIX_NAME_OUT(oa), name)) - PREFIX_LIST_OUT(oa) = add ? plist : NULL; + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { + if (PREFIX_NAME_IN(oa) + && !strcmp(PREFIX_NAME_IN(oa), name)) + PREFIX_LIST_IN(oa) = add ? plist : NULL; + if (PREFIX_NAME_OUT(oa) + && !strcmp(PREFIX_NAME_OUT(oa), name)) + PREFIX_LIST_OUT(oa) = add ? plist : NULL; + } } } @@ -659,7 +688,9 @@ DEFUN (area_import_list, struct ospf6_area *area; struct access_list *list; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6); list = access_list_lookup(AFI_IP6, argv[idx_name]->arg); @@ -687,7 +718,9 @@ DEFUN (no_area_import_list, int idx_ipv4 = 2; struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6); IMPORT_LIST(area) = 0; @@ -714,7 +747,9 @@ DEFUN (area_export_list, struct ospf6_area *area; struct access_list *list; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6); list = access_list_lookup(AFI_IP6, argv[idx_name]->arg); @@ -742,7 +777,9 @@ DEFUN (no_area_export_list, int idx_ipv4 = 2; struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6); EXPORT_LIST(area) = 0; @@ -769,9 +806,10 @@ DEFUN (show_ipv6_ospf6_spf_tree, struct ospf6_vertex *root; struct ospf6_route *route; struct prefix prefix; + struct ospf6 *ospf6; - OSPF6_CMD_CHECK_RUNNING(); - + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix); for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { @@ -805,8 +843,11 @@ DEFUN (show_ipv6_ospf6_area_spf_tree, struct ospf6_vertex *root; struct ospf6_route *route; struct prefix prefix; + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); - OSPF6_CMD_CHECK_RUNNING(); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix); @@ -854,8 +895,11 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root, uint32_t router_id; struct ospf6_route_table *spf_table; unsigned char tmp_debug_ospf6_spf = 0; + struct ospf6 *ospf6; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + + OSPF6_CMD_CHECK_RUNNING(ospf6); inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id); ospf6_linkstate_prefix(router_id, htonl(0), &prefix); @@ -880,15 +924,15 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root, route = ospf6_route_lookup(&prefix, spf_table); if (route == NULL) { - ospf6_spf_table_finish(spf_table); - ospf6_route_table_delete(spf_table); + ospf6_spf_table_finish(spf_table, ospf6); + ospf6_route_table_delete(spf_table, ospf6); return CMD_SUCCESS; } root = (struct ospf6_vertex *)route->route_option; ospf6_spf_display_subtree(vty, "", 0, root); - ospf6_spf_table_finish(spf_table); - ospf6_route_table_delete(spf_table); + ospf6_spf_table_finish(spf_table, ospf6); + ospf6_route_table_delete(spf_table, ospf6); return CMD_SUCCESS; } @@ -904,7 +948,9 @@ DEFUN (ospf6_area_stub, int idx_ipv4_number = 1; struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6); if (!ospf6_area_stub_set(ospf6, area)) { vty_out(vty, @@ -929,7 +975,9 @@ DEFUN (ospf6_area_stub_no_summary, int idx_ipv4_number = 1; struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6); if (!ospf6_area_stub_set(ospf6, area)) { vty_out(vty, @@ -954,7 +1002,9 @@ DEFUN (no_ospf6_area_stub, int idx_ipv4_number = 2; struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6); ospf6_area_stub_unset(ospf6, area); ospf6_area_no_summary_unset(ospf6, area); @@ -975,7 +1025,9 @@ DEFUN (no_ospf6_area_stub_no_summary, int idx_ipv4_number = 2; struct ospf6_area *area; - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6); ospf6_area_stub_unset(ospf6, area); ospf6_area_no_summary_unset(ospf6, area); @@ -1010,11 +1062,12 @@ void ospf6_area_interface_delete(struct ospf6_interface *oi) { struct ospf6_area *oa; struct listnode *node, *nnode; + struct ospf6 *ospf6; - if (!ospf6) + if (!om6->ospf6) return; - for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) - if(listnode_lookup(oa->if_list, oi)) - listnode_delete(oa->if_list, oi); - + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) + for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) + if (listnode_lookup(oa->if_list, oi)) + listnode_delete(oa->if_list, oi); } diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index f6287660d6..2097ef6e43 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -117,7 +117,7 @@ struct ospf6_area { #define IS_AREA_TRANSIT(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_TRANSIT)) #define IS_AREA_STUB(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_STUB)) -#define OSPF6_CMD_AREA_GET(str, oa) \ +#define OSPF6_CMD_AREA_GET(str, oa, ospf6) \ { \ char *ep; \ uint32_t area_id = htonl(strtoul(str, &ep, 10)); \ @@ -138,6 +138,7 @@ extern int ospf6_area_cmp(void *va, void *vb); extern struct ospf6_area *ospf6_area_create(uint32_t, struct ospf6 *, int); extern void ospf6_area_delete(struct ospf6_area *); extern struct ospf6_area *ospf6_area_lookup(uint32_t, struct ospf6 *); +extern struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id); extern void ospf6_area_enable(struct ospf6_area *); extern void ospf6_area_disable(struct ospf6_area *); @@ -145,7 +146,7 @@ extern void ospf6_area_disable(struct ospf6_area *); extern void ospf6_area_show(struct vty *, struct ospf6_area *); extern void ospf6_area_plist_update(struct prefix_list *plist, int add); -extern void ospf6_area_config_write(struct vty *vty); +extern void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6); extern void ospf6_area_init(void); struct ospf6_interface; extern void ospf6_area_interface_delete(struct ospf6_interface *oi); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 71ca5afcd2..c053716f26 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -43,6 +43,7 @@ #include "ospf6_interface.h" #include "ospf6_neighbor.h" #include "ospf6_asbr.h" +#include "ospf6_abr.h" #include "ospf6_intra.h" #include "ospf6_flood.h" #include "ospf6d.h" @@ -55,7 +56,8 @@ unsigned char conf_debug_ospf6_asbr = 0; #define ZROUTE_NAME(x) zebra_route_string(x) /* AS External LSA origination */ -static void ospf6_as_external_lsa_originate(struct ospf6_route *route) +static void ospf6_as_external_lsa_originate(struct ospf6_route *route, + struct ospf6 *ospf6) { char buffer[OSPF6_MAX_LSASIZE]; struct ospf6_lsa_header *lsa_header; @@ -63,13 +65,11 @@ static void ospf6_as_external_lsa_originate(struct ospf6_route *route) struct ospf6_external_info *info = route->route_option; struct ospf6_as_external_lsa *as_external_lsa; - char buf[PREFIX2STR_BUFFER]; caddr_t p; - if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE(AS_EXTERNAL)) { - prefix2str(&route->prefix, buf, sizeof(buf)); - zlog_debug("Originate AS-External-LSA for %s", buf); - } + if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE(AS_EXTERNAL)) + zlog_debug("Originate AS-External-LSA for %pFX", + &route->prefix); /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); @@ -165,7 +165,8 @@ int ospf6_orig_as_external_lsa(struct thread *thread) type = htons(OSPF6_LSTYPE_AS_EXTERNAL); adv_router = oi->area->ospf6->router_id; - for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, adv_router, lsa)) { + for (ALL_LSDB_TYPED_ADVRTR(oi->area->ospf6->lsdb, type, adv_router, + lsa)) { if (IS_OSPF6_DEBUG_ASBR) zlog_debug( "%s: Send update of AS-External LSA %s seq 0x%x", @@ -204,14 +205,14 @@ static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa) } void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, - struct ospf6_route *route) + struct ospf6_route *route, + struct ospf6 *ospf6) { struct ospf6_route *old_route; struct ospf6_path *ecmp_path, *o_path = NULL; struct listnode *anode, *anext; struct listnode *nnode, *rnode, *rnext; struct ospf6_nexthop *nh, *rnh; - char buf[PREFIX2STR_BUFFER]; bool route_found = false; /* check for old entry match with new route origin, @@ -284,8 +285,8 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, * nh_list */ if (ospf6->route_table->hook_add) - (*ospf6->route_table->hook_add) - (old_route); + (*ospf6->route_table->hook_add)( + old_route, ospf6); if (old_route->path.origin.id == route->path.origin.id @@ -313,7 +314,7 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, route->path.cost); } ospf6_route_remove(old_route, - ospf6->route_table); + ospf6->route_table, ospf6); } } if (route_updated) @@ -371,11 +372,9 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, listnode_add_sort(old_route->paths, ecmp_path); if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { - prefix2str(&route->prefix, buf, - sizeof(buf)); zlog_debug( - "%s: route %s another path added with nh %u, effective paths %u nh %u", - __func__, buf, + "%s: route %pFX another path added with nh %u, effective paths %u nh %u", + __func__, &route->prefix, listcount(ecmp_path->nh_list), old_route->paths ? listcount( old_route->paths) @@ -401,36 +400,32 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, &o_path->ls_prefix, ospf6->brouter_table); if (asbr_entry == NULL) { - if (IS_OSPF6_DEBUG_EXAMIN( - AS_EXTERNAL)) { - prefix2str(&old_route->prefix, - buf, sizeof(buf)); + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) zlog_debug( - "%s: ls_prfix %s asbr_entry not found.", - __func__, buf); - } + "%s: ls_prfix %pFX asbr_entry not found.", + __func__, + &old_route->prefix); continue; } ospf6_route_merge_nexthops(old_route, asbr_entry); } - if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { - prefix2str(&route->prefix, buf, sizeof(buf)); + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) zlog_debug( - "%s: route %s with effective paths %u nh %u", - __func__, buf, + "%s: route %pFX with effective paths %u nh %u", + __func__, &route->prefix, old_route->paths ? listcount(old_route->paths) : 0, old_route->nh_list ? listcount(old_route->nh_list) : 0); - } /* Update RIB/FIB */ if (ospf6->route_table->hook_add) - (*ospf6->route_table->hook_add)(old_route); + (*ospf6->route_table->hook_add)(old_route, + ospf6); /* Delete the new route its info added to existing * route. @@ -443,17 +438,16 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, if (!route_found) { /* Add new route to existing node in ospf6 route table. */ - ospf6_route_add(route, ospf6->route_table); + ospf6_route_add(route, ospf6->route_table, ospf6); } } -void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) +void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6) { struct ospf6_as_external_lsa *external; struct prefix asbr_id; struct ospf6_route *asbr_entry, *route, *old; struct ospf6_path *path; - char buf[PREFIX2STR_BUFFER]; external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( lsa->header); @@ -484,10 +478,8 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) asbr_entry = ospf6_route_lookup(&asbr_id, ospf6->brouter_table); if (asbr_entry == NULL || !CHECK_FLAG(asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E)) { - if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { - prefix2str(&asbr_id, buf, sizeof(buf)); - zlog_debug("ASBR entry not found: %s", buf); - } + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug("ASBR entry not found: %pFX", &asbr_id); return; } @@ -527,27 +519,25 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) listnode_add_sort(route->paths, path); - if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { - prefix2str(&route->prefix, buf, sizeof(buf)); - zlog_debug("%s: AS-External %u route add %s cost %u(%u) nh %u", - __func__, - (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1) ? 1 - : 2, - buf, route->path.cost, route->path.u.cost_e2, - listcount(route->nh_list)); - } + if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) + zlog_debug( + "%s: AS-External %u route add %pFX cost %u(%u) nh %u", + __func__, + (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1) ? 1 : 2, + &route->prefix, route->path.cost, route->path.u.cost_e2, + listcount(route->nh_list)); old = ospf6_route_lookup(&route->prefix, ospf6->route_table); if (!old) { /* Add the new route to ospf6 instance route table. */ - ospf6_route_add(route, ospf6->route_table); + ospf6_route_add(route, ospf6->route_table, ospf6); } else { /* RFC 2328 16.4 (6) * ECMP: Keep new equal preference path in current * route's path list, update zebra with new effective * list along with addition of ECMP path. */ - ospf6_asbr_update_route_ecmp_path(old, route); + ospf6_asbr_update_route_ecmp_path(old, route, ospf6); } } @@ -557,6 +547,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, struct ospf6_as_external_lsa *external; struct prefix prefix; struct ospf6_route *route, *nroute, *route_to_del; + struct ospf6_area *oa = NULL; + struct ospf6 *ospf6; external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( lsa->header); @@ -564,7 +556,16 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) zlog_debug("Withdraw AS-External route for %s", lsa->name); - if (lsa->header->adv_router == ospf6->router_id) { + ospf6 = ospf6_get_by_lsdb(lsa); + if (ospf6_is_router_abr(ospf6)) + oa = ospf6->backbone; + else + oa = listgetdata(listhead(ospf6->area_list)); + + if (oa == NULL) + return; + + if (lsa->header->adv_router == oa->ospf6->router_id) { if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) zlog_debug("Ignore self-originated AS-External-LSA"); return; @@ -603,7 +604,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, prefix.prefixlen = external->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, external, &external->prefix); - route = ospf6_route_lookup(&prefix, ospf6->route_table); + route = ospf6_route_lookup(&prefix, oa->ospf6->route_table); if (route == NULL) { if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) { zlog_debug("AS-External route %pFX not found", &prefix); @@ -729,9 +730,10 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, /* Update RIB/FIB with effective * nh_list */ - if (ospf6->route_table->hook_add) - (*ospf6->route_table->hook_add) - (route); + if (oa->ospf6->route_table->hook_add) + (*oa->ospf6->route_table + ->hook_add)( + route, oa->ospf6); /* route's primary path is similar * to LSA, replace route's primary @@ -754,8 +756,9 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, h_path->origin.adv_router; } } else { - ospf6_route_remove(route, - ospf6->route_table); + ospf6_route_remove( + route, oa->ospf6->route_table, + oa->ospf6); } } continue; @@ -795,7 +798,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, &route->prefix, route->path.cost, route->path.u.cost_e2, listcount(route->nh_list)); } - ospf6_route_remove(route, ospf6->route_table); + ospf6_route_remove(route, oa->ospf6->route_table, oa->ospf6); } if (route != NULL) ospf6_route_unlock(route); @@ -803,7 +806,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, ospf6_route_delete(route_to_del); } -void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry) +void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry, struct ospf6 *ospf6) { struct ospf6_lsa *lsa; uint16_t type; @@ -821,11 +824,12 @@ void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry) router = ospf6_linkstate_prefix_adv_router(&asbr_entry->prefix); for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa)) { if (!OSPF6_LSA_IS_MAXAGE(lsa)) - ospf6_asbr_lsa_add(lsa); + ospf6_asbr_lsa_add(lsa, ospf6); } } -void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry) +void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry, + struct ospf6 *ospf6) { struct ospf6_lsa *lsa; uint16_t type; @@ -840,8 +844,16 @@ void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry) /* redistribute function */ -static void ospf6_asbr_routemap_set(int type, const char *mapname) +static void ospf6_asbr_routemap_set(int type, const char *mapname, + uint32_t vrf_id) { + struct ospf6 *ospf6 = NULL; + + ospf6 = ospf6_lookup_by_vrf_id(vrf_id); + + if (ospf6 == NULL) + return; + if (ospf6->rmap[type].name) { route_map_counter_decrement(ospf6->rmap[type].map); free(ospf6->rmap[type].name); @@ -851,7 +863,7 @@ static void ospf6_asbr_routemap_set(int type, const char *mapname) route_map_counter_increment(ospf6->rmap[type].map); } -static void ospf6_asbr_routemap_unset(int type) +static void ospf6_asbr_routemap_unset(int type, struct ospf6 *ospf6) { if (ospf6->rmap[type].name) free(ospf6->rmap[type].name); @@ -866,8 +878,10 @@ static int ospf6_asbr_routemap_update_timer(struct thread *thread) { void **arg; int arg_type; + struct ospf6 *ospf6; arg = THREAD_ARG(thread); + ospf6 = (struct ospf6 *)arg[0]; arg_type = (int)(intptr_t)arg[1]; ospf6->t_distribute_update = NULL; @@ -889,7 +903,7 @@ static int ospf6_asbr_routemap_update_timer(struct thread *thread) return 0; } -void ospf6_asbr_distribute_list_update(int type) +void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6) { void **args = NULL; @@ -914,62 +928,75 @@ void ospf6_asbr_distribute_list_update(int type) static void ospf6_asbr_routemap_update(const char *mapname) { int type; + struct listnode *node, *nnode; + struct ospf6 *ospf6 = NULL; - if (ospf6 == NULL) + if (om6 == NULL) return; - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if (ospf6->rmap[type].name) { + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if (ospf6->rmap[type].name == NULL) + continue; ospf6->rmap[type].map = route_map_lookup_by_name( - ospf6->rmap[type].name); + ospf6->rmap[type].name); - if (mapname - && (strcmp(ospf6->rmap[type].name, mapname) == 0)) { - if (ospf6->rmap[type].map) { - if (IS_OSPF6_DEBUG_ASBR) - zlog_debug( + if (mapname == NULL || strcmp(ospf6->rmap[type].name, mapname)) + continue; + if (ospf6->rmap[type].map) { + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug( "%s: route-map %s update, reset redist %s", - __func__, mapname, - ZROUTE_NAME(type)); + __func__, + mapname, + ZROUTE_NAME( + type)); route_map_counter_increment( - ospf6->rmap[type].map); + ospf6->rmap[type].map); - ospf6_asbr_distribute_list_update(type); - } else { - /* - * if the mapname matches a route-map on - * ospf6 but the map doesn't exist, it - * is being deleted. flush and then - * readvertise - */ - if (IS_OSPF6_DEBUG_ASBR) - zlog_debug( + ospf6_asbr_distribute_list_update( + type, ospf6); + } else { + /* + * if the mapname matches a + * route-map on ospf6 but the + * map doesn't exist, it is + * being deleted. flush and then + * readvertise + */ + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug( "%s: route-map %s deleted, reset redist %s", - __func__, mapname, - ZROUTE_NAME(type)); - ospf6_asbr_redistribute_unset( + __func__, + mapname, + ZROUTE_NAME( + type)); + ospf6_asbr_redistribute_unset( type, ospf6->vrf_id); - ospf6_asbr_routemap_set(type, mapname); - ospf6_asbr_redistribute_set( + ospf6_asbr_routemap_set( + type, mapname, + ospf6->vrf_id); + ospf6_asbr_redistribute_set( type, ospf6->vrf_id); - } } - } else - ospf6->rmap[type].map = NULL; + } } } static void ospf6_asbr_routemap_event(const char *name) { int type; + struct listnode *node, *nnode; + struct ospf6 *ospf6; - if (ospf6 == NULL) + if (om6 == NULL) return; - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if ((ospf6->rmap[type].name) - && (strcmp(ospf6->rmap[type].name, name) == 0)) { - ospf6_asbr_distribute_list_update(type); + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + if ((ospf6->rmap[type].name) + && (strcmp(ospf6->rmap[type].name, name) == 0)) + ospf6_asbr_distribute_list_update(type, ospf6); } } } @@ -988,6 +1015,12 @@ static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id) { struct ospf6_route *route; struct ospf6_external_info *info; + struct ospf6 *ospf6 = NULL; + + ospf6 = ospf6_lookup_by_vrf_id(vrf_id); + + if (ospf6 == NULL) + return; ospf6_zebra_no_redistribute(type, vrf_id); @@ -997,18 +1030,19 @@ static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id) if (info->type != type) continue; - ospf6_asbr_redistribute_remove(info->type, 0, &route->prefix); + ospf6_asbr_redistribute_remove(info->type, 0, &route->prefix, + ospf6); } - ospf6_asbr_routemap_unset(type); + ospf6_asbr_routemap_unset(type, ospf6); } /* When an area is unstubified, flood all the external LSAs in the area */ void ospf6_asbr_send_externals_to_area(struct ospf6_area *oa) { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; - for (ALL_LSDB(oa->ospf6->lsdb, lsa)) { + for (ALL_LSDB(oa->ospf6->lsdb, lsa, lsanext)) { if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) { zlog_debug("%s: Flooding AS-External LSA %s", __func__, lsa->name); @@ -1020,7 +1054,8 @@ void ospf6_asbr_send_externals_to_area(struct ospf6_area *oa) void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, struct prefix *prefix, unsigned int nexthop_num, - struct in6_addr *nexthop, route_tag_t tag) + struct in6_addr *nexthop, route_tag_t tag, + struct ospf6 *ospf6) { route_map_result_t ret; struct ospf6_route troute; @@ -1029,7 +1064,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, struct ospf6_external_info *info; struct prefix prefix_id; struct route_node *node; - char pbuf[PREFIX2STR_BUFFER], ibuf[16]; + char ibuf[16]; struct listnode *lnode, *lnnode; struct ospf6_area *oa; @@ -1039,10 +1074,8 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, memset(&troute, 0, sizeof(troute)); memset(&tinfo, 0, sizeof(tinfo)); - if (IS_OSPF6_DEBUG_ASBR) { - prefix2str(prefix, pbuf, sizeof(pbuf)); - zlog_debug("Redistribute %s (%s)", pbuf, ZROUTE_NAME(type)); - } + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("Redistribute %pFX (%s)", prefix, ZROUTE_NAME(type)); /* if route-map was specified but not found, do not advertise */ if (ospf6->rmap[type].name) { @@ -1068,7 +1101,8 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, if (IS_OSPF6_DEBUG_ASBR) zlog_debug("Denied by route-map \"%s\"", ospf6->rmap[type].name); - ospf6_asbr_redistribute_remove(type, ifindex, prefix); + ospf6_asbr_redistribute_remove(type, ifindex, prefix, + ospf6); return; } } @@ -1109,14 +1143,13 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, if (IS_OSPF6_DEBUG_ASBR) { inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); - prefix2str(prefix, pbuf, sizeof(pbuf)); zlog_debug( - "Advertise as AS-External Id:%s prefix %s metric %u", - ibuf, pbuf, match->path.metric_type); + "Advertise as AS-External Id:%s prefix %pFX metric %u", + ibuf, prefix, match->path.metric_type); } match->path.origin.id = htonl(info->id); - ospf6_as_external_lsa_originate(match); + ospf6_as_external_lsa_originate(match, ospf6); return; } @@ -1158,18 +1191,18 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, node = route_node_get(ospf6->external_id_table, &prefix_id); node->info = route; - route = ospf6_route_add(route, ospf6->external_table); + route = ospf6_route_add(route, ospf6->external_table, ospf6); route->route_option = info; if (IS_OSPF6_DEBUG_ASBR) { inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); - prefix2str(prefix, pbuf, sizeof(pbuf)); - zlog_debug("Advertise as AS-External Id:%s prefix %s metric %u", - ibuf, pbuf, route->path.metric_type); + zlog_debug( + "Advertise as AS-External Id:%s prefix %pFX metric %u", + ibuf, prefix, route->path.metric_type); } route->path.origin.id = htonl(info->id); - ospf6_as_external_lsa_originate(route); + ospf6_as_external_lsa_originate(route, ospf6); /* Router-Bit (ASBR Flag) may have to be updated */ for (ALL_LIST_ELEMENTS(ospf6->area_list, lnode, lnnode, oa)) @@ -1177,23 +1210,21 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, } void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, - struct prefix *prefix) + struct prefix *prefix, struct ospf6 *ospf6) { struct ospf6_route *match; struct ospf6_external_info *info = NULL; struct route_node *node; struct ospf6_lsa *lsa; struct prefix prefix_id; - char pbuf[PREFIX2STR_BUFFER], ibuf[16]; + char ibuf[16]; struct listnode *lnode, *lnnode; struct ospf6_area *oa; match = ospf6_route_lookup(prefix, ospf6->external_table); if (match == NULL) { - if (IS_OSPF6_DEBUG_ASBR) { - prefix2str(prefix, pbuf, sizeof(pbuf)); - zlog_debug("No such route %s to withdraw", pbuf); - } + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("No such route %pFX to withdraw", prefix); return; } @@ -1201,17 +1232,14 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, assert(info); if (info->type != type) { - if (IS_OSPF6_DEBUG_ASBR) { - prefix2str(prefix, pbuf, sizeof(pbuf)); - zlog_debug("Original protocol mismatch: %s", pbuf); - } + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("Original protocol mismatch: %pFX", prefix); return; } if (IS_OSPF6_DEBUG_ASBR) { - prefix2str(prefix, pbuf, sizeof(pbuf)); inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); - zlog_debug("Withdraw %s (AS-External Id:%s)", pbuf, ibuf); + zlog_debug("Withdraw %pFX (AS-External Id:%s)", prefix, ibuf); } lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), @@ -1229,7 +1257,7 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, route_unlock_node(node); /* to free the lookup lock */ route_unlock_node(node); /* to free the original lock */ - ospf6_route_remove(match, ospf6->external_table); + ospf6_route_remove(match, ospf6->external_table, ospf6); XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info); /* Router-Bit (ASBR Flag) may have to be updated */ @@ -1245,8 +1273,8 @@ DEFUN (ospf6_redistribute, { int type; - OSPF6_CMD_CHECK_RUNNING(); - + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + OSPF6_CMD_CHECK_RUNNING(ospf6); char *proto = argv[argc - 1]->text; type = proto_redistnum(AFI_IP6, proto); if (type < 0) @@ -1269,7 +1297,8 @@ DEFUN (ospf6_redistribute_routemap, int idx_word = 3; int type; - OSPF6_CMD_CHECK_RUNNING(); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + OSPF6_CMD_CHECK_RUNNING(ospf6); char *proto = argv[idx_protocol]->text; type = proto_redistnum(AFI_IP6, proto); @@ -1277,7 +1306,7 @@ DEFUN (ospf6_redistribute_routemap, return CMD_WARNING_CONFIG_FAILED; ospf6_asbr_redistribute_unset(type, ospf6->vrf_id); - ospf6_asbr_routemap_set(type, argv[idx_word]->arg); + ospf6_asbr_routemap_set(type, argv[idx_word]->arg, ospf6->vrf_id); ospf6_asbr_redistribute_set(type, ospf6->vrf_id); return CMD_SUCCESS; } @@ -1294,7 +1323,9 @@ DEFUN (no_ospf6_redistribute, int idx_protocol = 2; int type; - OSPF6_CMD_CHECK_RUNNING(); + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + + OSPF6_CMD_CHECK_RUNNING(ospf6); char *proto = argv[idx_protocol]->text; type = proto_redistnum(AFI_IP6, proto); @@ -1306,7 +1337,7 @@ DEFUN (no_ospf6_redistribute, return CMD_SUCCESS; } -int ospf6_redistribute_config_write(struct vty *vty) +int ospf6_redistribute_config_write(struct vty *vty, struct ospf6 *ospf6) { int type; @@ -1326,7 +1357,7 @@ int ospf6_redistribute_config_write(struct vty *vty) return 0; } -static void ospf6_redistribute_show_config(struct vty *vty) +static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6) { int type; int nroute[ZEBRA_ROUTE_MAX]; @@ -1823,10 +1854,9 @@ static void ospf6_asbr_external_route_show(struct vty *vty, struct ospf6_route *route) { struct ospf6_external_info *info = route->route_option; - char prefix[PREFIX2STR_BUFFER], id[16], forwarding[64]; + char id[16], forwarding[64]; uint32_t tmp_id; - prefix2str(&route->prefix, prefix, sizeof(prefix)); tmp_id = ntohl(info->id); inet_ntop(AF_INET, &tmp_id, id, sizeof(id)); if (!IN6_IS_ADDR_UNSPECIFIED(&info->forwarding)) @@ -1836,8 +1866,8 @@ static void ospf6_asbr_external_route_show(struct vty *vty, snprintf(forwarding, sizeof(forwarding), ":: (ifindex %d)", ospf6_route_get_first_nh_index(route)); - vty_out(vty, "%c %-32s %-15s type-%d %5lu %s\n", - zebra_route_char(info->type), prefix, id, + vty_out(vty, "%c %-32pFX %-15s type-%d %5lu %s\n", + zebra_route_char(info->type), &route->prefix, id, route->path.metric_type, (unsigned long)(route->path.metric_type == 2 ? route->path.u.cost_e2 @@ -1855,10 +1885,12 @@ DEFUN (show_ipv6_ospf6_redistribute, ) { struct ospf6_route *route; + struct ospf6 *ospf6 = NULL; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); - ospf6_redistribute_show_config(vty); + ospf6_redistribute_show_config(vty, ospf6); for (route = ospf6_route_head(ospf6->external_table); route; route = ospf6_route_next(route)) diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 41b1ac70e9..46c99706ac 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -70,22 +70,26 @@ struct ospf6_as_external_lsa { (E)->bits_metric |= htonl(0x00ffffff) & htonl(C); \ } -extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa); +extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6); extern void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, struct ospf6_route *asbr_entry); -extern void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry); -extern void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry); +extern void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry, + struct ospf6 *ospf6); +extern void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry, + struct ospf6 *ospf6); extern int ospf6_asbr_is_asbr(struct ospf6 *o); extern void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, struct prefix *prefix, unsigned int nexthop_num, struct in6_addr *nexthop, - route_tag_t tag); + route_tag_t tag, struct ospf6 *ospf6); extern void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, - struct prefix *prefix); + struct prefix *prefix, + struct ospf6 *ospf6); -extern int ospf6_redistribute_config_write(struct vty *vty); +extern int ospf6_redistribute_config_write(struct vty *vty, + struct ospf6 *ospf6); extern void ospf6_asbr_init(void); extern void ospf6_asbr_redistribute_reset(vrf_id_t vrf_id); @@ -95,7 +99,8 @@ extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *); extern int config_write_ospf6_debug_asbr(struct vty *vty); extern void install_element_ospf6_debug_asbr(void); extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, - struct ospf6_route *route); -extern void ospf6_asbr_distribute_list_update(int type); + struct ospf6_route *route, + struct ospf6 *ospf6); +extern void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6); #endif /* OSPF6_ASBR_H */ diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index 1b58cd14f6..4e50ab5244 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -204,12 +204,9 @@ static int ospf6_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) if ((ifp == NULL) || (dp.family != AF_INET6)) return 0; - if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&dp, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s bfd destination %s %s", - ifp->name, buf, bfd_get_status_str(status)); - } + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) + zlog_debug("Zebra: interface %s bfd destination %pFX %s", + ifp->name, &dp, bfd_get_status_str(status)); oi = (struct ospf6_interface *)ifp->info; diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index b144c6804e..0662cfd683 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -370,7 +370,7 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, continue; } - if (ospf6->inst_shutdown) { + if (oi->area->ospf6->inst_shutdown) { if (is_debug) zlog_debug( "%s: Send LSA %s (age %d) update now", @@ -486,6 +486,12 @@ static void ospf6_flood_process(struct ospf6_neighbor *from, void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa) { + struct ospf6 *ospf6; + + ospf6 = ospf6_get_by_lsdb(lsa); + if (ospf6 == NULL) + return; + ospf6_flood_process(from, lsa, ospf6); } @@ -555,6 +561,9 @@ static void ospf6_flood_clear_process(struct ospf6_lsa *lsa, void ospf6_flood_clear(struct ospf6_lsa *lsa) { + struct ospf6 *ospf6; + + ospf6 = ospf6_get_by_lsdb(lsa); ospf6_flood_clear_process(lsa, ospf6); } @@ -1001,18 +1010,22 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, * MAXAGEd and not removed.*/ if (OSPF6_LSA_IS_MAXAGE(old) && !OSPF6_LSA_IS_MAXAGE(new)) { - - if (is_debug) - zlog_debug( - "%s: Current copy of LSA %s is MAXAGE, but new has recent Age.", - old->name, __func__); - - ospf6_lsa_purge(old); if (new->header->adv_router - != from->ospf6_if->area->ospf6->router_id) + != from->ospf6_if->area->ospf6->router_id) { + if (is_debug) + zlog_debug( + "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.", + old->name, __PRETTY_FUNCTION__); + ospf6_lsa_purge(old); ospf6_flood(from, new); - - ospf6_install_lsa(new); + ospf6_install_lsa(new); + } else { + if (is_debug) + zlog_debug( + "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, ignoring new.", + old->name, __PRETTY_FUNCTION__); + ospf6_lsa_delete(new); + } return; } diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index fabcc426ea..75917b9d85 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -31,10 +31,10 @@ #include "ospf6_lsa.h" #include "ospf6_lsdb.h" +#include "ospf6_top.h" #include "ospf6_network.h" #include "ospf6_message.h" #include "ospf6_route.h" -#include "ospf6_top.h" #include "ospf6_area.h" #include "ospf6_interface.h" #include "ospf6_neighbor.h" @@ -118,7 +118,7 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi) /* If all else fails, use default OSPF cost */ uint32_t cost; uint32_t bw, refbw; - + struct ospf6 *ospf6; /* interface speed and bw can be 0 in some platforms, * use ospf default bw. If bw is configured then it would * be used. @@ -130,6 +130,7 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi) : OSPF6_INTERFACE_BANDWIDTH; } + ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id); refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH; /* A specifed ip ospf cost overrides a calculated one. */ @@ -259,7 +260,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi) ospf6_lsdb_delete(oi->lsupdate_list); ospf6_lsdb_delete(oi->lsack_list); - ospf6_route_table_delete(oi->route_connected); + ospf6_route_table_delete(oi->route_connected, oi->area->ospf6); /* cut link */ oi->interface->info = NULL; @@ -415,7 +416,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp) return; /* update "route to advertise" interface route table */ - ospf6_route_remove_all(oi->route_connected); + ospf6_route_remove_all(oi->route_connected, oi->area->ospf6); for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) { if (c->address->family != AF_INET6) @@ -436,16 +437,14 @@ void ospf6_interface_connected_route_update(struct interface *ifp) if (oi->plist_name) { struct prefix_list *plist; enum prefix_list_type ret; - char buf[PREFIX2STR_BUFFER]; - prefix2str(c->address, buf, sizeof(buf)); plist = prefix_list_lookup(AFI_IP6, oi->plist_name); ret = prefix_list_apply(plist, (void *)c->address); if (ret == PREFIX_DENY) { if (IS_OSPF6_DEBUG_INTERFACE) zlog_debug( - "%s on %s filtered by prefix-list %s ", - buf, oi->interface->name, + "%pFX on %s filtered by prefix-list %s ", + c->address, oi->interface->name, oi->plist_name); continue; } @@ -461,7 +460,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp) inet_pton(AF_INET6, "::1", &nh_addr); ospf6_route_add_nexthop(route, oi->interface->ifindex, &nh_addr); - ospf6_route_add(route, oi->route_connected); + ospf6_route_add(route, oi->route_connected, oi->area->ospf6); } /* create new Link-LSA */ @@ -474,6 +473,7 @@ static void ospf6_interface_state_change(uint8_t next_state, struct ospf6_interface *oi) { uint8_t prev_state; + struct ospf6 *ospf6; prev_state = oi->state; oi->state = next_state; @@ -489,20 +489,21 @@ static void ospf6_interface_state_change(uint8_t next_state, ospf6_interface_state_str[next_state]); } oi->state_change++; + ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id); if ((prev_state == OSPF6_INTERFACE_DR || prev_state == OSPF6_INTERFACE_BDR) && (next_state != OSPF6_INTERFACE_DR && next_state != OSPF6_INTERFACE_BDR)) ospf6_sso(oi->interface->ifindex, &alldrouters6, - IPV6_LEAVE_GROUP); + IPV6_LEAVE_GROUP, ospf6->fd); if ((prev_state != OSPF6_INTERFACE_DR && prev_state != OSPF6_INTERFACE_BDR) && (next_state == OSPF6_INTERFACE_DR || next_state == OSPF6_INTERFACE_BDR)) ospf6_sso(oi->interface->ifindex, &alldrouters6, - IPV6_JOIN_GROUP); + IPV6_JOIN_GROUP, ospf6->fd); OSPF6_ROUTER_LSA_SCHEDULE(oi->area); if (next_state == OSPF6_INTERFACE_DOWN) { @@ -679,6 +680,7 @@ static uint8_t dr_election(struct ospf6_interface *oi) int interface_up(struct thread *thread) { struct ospf6_interface *oi; + struct ospf6 *ospf6; oi = (struct ospf6_interface *)THREAD_ARG(thread); assert(oi && oi->interface); @@ -749,9 +751,14 @@ int interface_up(struct thread *thread) return 0; } #endif /* __FreeBSD__ */ + if (oi->area->ospf6) + ospf6 = oi->area->ospf6; + else + ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id); /* Join AllSPFRouters */ - if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP) + if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP, + ospf6->fd) < 0) { if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) { zlog_info( @@ -848,6 +855,7 @@ int interface_down(struct thread *thread) struct ospf6_interface *oi; struct listnode *node, *nnode; struct ospf6_neighbor *on; + struct ospf6 *ospf6; oi = (struct ospf6_interface *)THREAD_ARG(thread); assert(oi && oi->interface); @@ -861,11 +869,11 @@ int interface_down(struct thread *thread) /* Stop trying to set socket options. */ THREAD_OFF(oi->thread_sso); - + ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id); /* Leave AllSPFRouters */ if (oi->state > OSPF6_INTERFACE_DOWN) ospf6_sso(oi->interface->ifindex, &allspfrouters6, - IPV6_LEAVE_GROUP); + IPV6_LEAVE_GROUP, ospf6->fd); ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi); @@ -906,7 +914,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) uint8_t default_iftype; struct timeval res, now; char duration[32]; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; default_iftype = ospf6_default_iftype(ifp); @@ -929,16 +937,15 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) { p = c->address; - prefix2str(p, strbuf, sizeof(strbuf)); switch (p->family) { case AF_INET: - vty_out(vty, " inet : %s\n", strbuf); + vty_out(vty, " inet : %pFX\n", p); break; case AF_INET6: - vty_out(vty, " inet6: %s\n", strbuf); + vty_out(vty, " inet6: %pFX\n", p); break; default: - vty_out(vty, " ??? : %s\n", strbuf); + vty_out(vty, " ??? : %pFX\n", p); break; } } @@ -977,7 +984,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", oi->lsupdate_list->count, duration, (oi->thread_send_lsupdate ? "on" : "off")); - for (ALL_LSDB(oi->lsupdate_list, lsa)) + for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); timerclear(&res); @@ -987,7 +994,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp) vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", oi->lsack_list->count, duration, (oi->thread_send_lsack ? "on" : "off")); - for (ALL_LSDB(oi->lsack_list, lsa)) + for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); ospf6_bfd_show_info(vty, oi->bfd_info, 1); return 0; diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index a34f8d3693..f84a7cfe9a 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -147,7 +147,7 @@ static void ospf6_router_lsa_options_set(struct ospf6_area *oa, OSPF6_OPT_CLEAR_ALL(router_lsa->options); memcpy(router_lsa->options, oa->options, 3); - if (ospf6_is_router_abr(ospf6)) + if (ospf6_is_router_abr(oa->ospf6)) SET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B); else UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B); @@ -907,7 +907,6 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread) struct listnode *i, *j; int full_count = 0; unsigned short prefix_num = 0; - char buf[PREFIX2STR_BUFFER]; struct ospf6_route_table *route_advertise; int ls_id = 0; @@ -985,12 +984,10 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread) /* connected prefix to advertise */ for (route = ospf6_route_head(oi->route_connected); route; route = ospf6_route_best_next(route)) { - if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) { - prefix2str(&route->prefix, buf, sizeof(buf)); - zlog_debug(" include %s", buf); - } + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" include %pFX", &route->prefix); ospf6_route_add(ospf6_route_copy(route), - route_advertise); + route_advertise, oa->ospf6); } } @@ -1011,7 +1008,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread) oa->lsdb); } } - ospf6_route_table_delete(route_advertise); + ospf6_route_table_delete(route_advertise, oa->ospf6); return 0; } @@ -1091,7 +1088,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread) op = OSPF6_PREFIX_NEXT(op); } - ospf6_route_table_delete(route_advertise); + ospf6_route_table_delete(route_advertise, oa->ospf6); if (prefix_num == 0) { if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) @@ -1144,7 +1141,6 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread) struct ospf6_link_lsa *link_lsa; char *start, *end, *current; uint16_t type; - char buf[PREFIX2STR_BUFFER]; oi = (struct ospf6_interface *)THREAD_ARG(thread); oi->thread_intra_prefix_lsa = NULL; @@ -1255,12 +1251,11 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread) route->path.area_id = oi->area->area_id; route->path.type = OSPF6_PATH_TYPE_INTRA; - if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) { - prefix2str(&route->prefix, buf, sizeof(buf)); - zlog_debug(" include %s", buf); - } + if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) + zlog_debug(" include %pFX", &route->prefix); - ospf6_route_add(route, route_advertise); + ospf6_route_add(route, route_advertise, + oi->area->ospf6); prefix_num--; } if (current != end && IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) @@ -1282,7 +1277,7 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread) prefix_num++; } - ospf6_route_table_delete(route_advertise); + ospf6_route_table_delete(route_advertise, oi->area->ospf6); if (prefix_num == 0) { if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) @@ -1315,14 +1310,14 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread) return 0; } -static void ospf6_intra_prefix_update_route_origin(struct ospf6_route *oa_route) +static void ospf6_intra_prefix_update_route_origin(struct ospf6_route *oa_route, + struct ospf6 *ospf6) { struct ospf6_path *h_path; struct ospf6_route *g_route, *nroute; /* Update Global ospf6 route path */ - g_route = ospf6_route_lookup(&oa_route->prefix, - ospf6->route_table); + g_route = ospf6_route_lookup(&oa_route->prefix, ospf6->route_table); assert(g_route); @@ -1442,15 +1437,15 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, * nh_list */ if (oa->route_table->hook_add) - (*oa->route_table->hook_add) - (old_route); + (*oa->route_table->hook_add)( + old_route, oa->ospf6); if (old_route->path.origin.id == route->path.origin.id && old_route->path.origin.adv_router == route->path.origin.adv_router) { ospf6_intra_prefix_update_route_origin( - old_route); + old_route, oa->ospf6); } break; } @@ -1464,7 +1459,8 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, } if (oa->route_table->hook_remove) ospf6_route_remove(old_route, - oa->route_table); + oa->route_table, + oa->ospf6); else SET_FLAG(old_route->flag, OSPF6_ROUTE_REMOVE); @@ -1554,11 +1550,9 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, ospf6_linkstate_prefix( o_path->origin.adv_router, o_path->origin.id, &adv_prefix); - prefix2str(&adv_prefix, buf, - sizeof(buf)); zlog_debug( - "%s: adv_router %s lsa not found", - __func__, buf); + "%s: adv_router %pFX lsa not found", + __func__, &adv_prefix); } continue; } @@ -1590,16 +1584,15 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, } } - if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) { - prefix2str(&route->prefix, buf, sizeof(buf)); + if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) zlog_debug( - "%s: route %s %p with final effective paths %u nh%u", - __func__, buf, (void *)old_route, + "%s: route %pFX %p with final effective paths %u nh%u", + __func__, &route->prefix, + (void *)old_route, old_route->paths ? listcount(old_route->paths) : 0, listcount(old_route->nh_list)); - } /* used in intra_route_calculation() to add to * global ospf6 route table. @@ -1608,7 +1601,8 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, SET_FLAG(old_route->flag, OSPF6_ROUTE_ADD); /* Update ospf6 route table and RIB/FIB */ if (oa->route_table->hook_add) - (*oa->route_table->hook_add)(old_route); + (*oa->route_table->hook_add)(old_route, + oa->ospf6); /* Delete the new route its info added to existing * route. */ @@ -1620,7 +1614,7 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, if (!route_found) { /* Add new route to existing node in ospf6 route table. */ - ospf6_route_add(route, oa->route_table); + ospf6_route_add(route, oa->route_table, oa->ospf6); } } @@ -1763,7 +1757,7 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa) listcount(route->paths), listcount(route->nh_list)); } - ospf6_route_add(route, oa->route_table); + ospf6_route_add(route, oa->route_table, oa->ospf6); } prefix_num--; } @@ -1845,7 +1839,7 @@ static void ospf6_intra_prefix_lsa_remove_update_route(struct ospf6_lsa *lsa, * nh_list */ if (oa->route_table->hook_add) - (*oa->route_table->hook_add)(route); + (*oa->route_table->hook_add)(route, oa->ospf6); /* route's primary path is similar * to LSA, replace route's primary @@ -1855,7 +1849,8 @@ static void ospf6_intra_prefix_lsa_remove_update_route(struct ospf6_lsa *lsa, if ((route->path.origin.id == lsa->header->id) && (route->path.origin.adv_router == lsa->header->adv_router)) { - ospf6_intra_prefix_update_route_origin(route); + ospf6_intra_prefix_update_route_origin(route, + oa->ospf6); } } @@ -1937,7 +1932,8 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa) listcount(route->paths), listcount(route->nh_list)); } - ospf6_route_remove(route, oa->route_table); + ospf6_route_remove(route, oa->route_table, + oa->ospf6); } } if (route) @@ -1953,8 +1949,8 @@ void ospf6_intra_route_calculation(struct ospf6_area *oa) struct ospf6_route *route, *nroute; uint16_t type; struct ospf6_lsa *lsa; - void (*hook_add)(struct ospf6_route *) = NULL; - void (*hook_remove)(struct ospf6_route *) = NULL; + void (*hook_add)(struct ospf6_route *, struct ospf6 *) = NULL; + void (*hook_remove)(struct ospf6_route *, struct ospf6 *) = NULL; if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) zlog_debug("Re-examin intra-routes for area %s", oa->name); @@ -1984,15 +1980,15 @@ void ospf6_intra_route_calculation(struct ospf6_area *oa) } if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE)) - ospf6_route_remove(route, oa->route_table); + ospf6_route_remove(route, oa->route_table, oa->ospf6); else if (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD) || CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE)) { if (hook_add) - (*hook_add)(route); + (*hook_add)(route, oa->ospf6); route->flag = 0; } else { /* Redo the summaries as things might have changed */ - ospf6_abr_originate_summary(route); + ospf6_abr_originate_summary(route, oa->ospf6); route->flag = 0; } } @@ -2060,8 +2056,8 @@ static void ospf6_brouter_debug_print(struct ospf6_route *brouter) void ospf6_intra_brouter_calculation(struct ospf6_area *oa) { struct ospf6_route *brouter, *nbrouter, *copy; - void (*hook_add)(struct ospf6_route *) = NULL; - void (*hook_remove)(struct ospf6_route *) = NULL; + void (*hook_add)(struct ospf6_route *, struct ospf6 *) = NULL; + void (*hook_remove)(struct ospf6_route *, struct ospf6 *) = NULL; uint32_t brouter_id; char brouter_name[16]; @@ -2119,7 +2115,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa) copy = ospf6_route_copy(brouter); copy->type = OSPF6_DEST_TYPE_ROUTER; copy->path.area_id = oa->area_id; - ospf6_route_add(copy, oa->ospf6->brouter_table); + ospf6_route_add(copy, oa->ospf6->brouter_table, oa->ospf6); if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id) || IS_OSPF6_DEBUG_ROUTE(MEMORY)) { @@ -2205,7 +2201,8 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa) * removes brouters which are marked for remove. */ oa->intra_brouter_calc = 1; - ospf6_route_remove(brouter, oa->ospf6->brouter_table); + ospf6_route_remove(brouter, oa->ospf6->brouter_table, + oa->ospf6); brouter = NULL; } else if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD) || CHECK_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE)) { @@ -2219,7 +2216,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa) /* newly added */ if (hook_add) - (*hook_add)(brouter); + (*hook_add)(brouter, oa->ospf6); } else { if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID( brouter_id) @@ -2228,7 +2225,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa) zlog_info("brouter %s still exists via area %s", brouter_name, oa->name); /* But re-originate summaries */ - ospf6_abr_originate_summary(brouter); + ospf6_abr_originate_summary(brouter, oa->ospf6); } if (brouter) { diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 9e7479c797..29141ee7f8 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -45,6 +45,27 @@ vector ospf6_lsa_handler_vector; +struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa) +{ + struct ospf6 *ospf6 = NULL; + + switch (OSPF6_LSA_SCOPE(lsa->header->type)) { + case OSPF6_SCOPE_LINKLOCAL: + ospf6 = OSPF6_INTERFACE(lsa->lsdb->data)->area->ospf6; + break; + case OSPF6_SCOPE_AREA: + ospf6 = OSPF6_AREA(lsa->lsdb->data)->ospf6; + break; + case OSPF6_SCOPE_AS: + ospf6 = OSPF6_PROCESS(lsa->lsdb->data); + break; + default: + assert(0); + break; + } + return ospf6; +} + static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa) { uint8_t *start, *end, *current; @@ -601,10 +622,10 @@ struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *lsa) } /* increment reference counter of struct ospf6_lsa */ -void ospf6_lsa_lock(struct ospf6_lsa *lsa) +struct ospf6_lsa *ospf6_lsa_lock(struct ospf6_lsa *lsa) { lsa->lock++; - return; + return lsa; } /* decrement reference counter of struct ospf6_lsa */ @@ -626,6 +647,7 @@ struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *lsa) int ospf6_lsa_expire(struct thread *thread) { struct ospf6_lsa *lsa; + struct ospf6 *ospf6; lsa = (struct ospf6_lsa *)THREAD_ARG(thread); @@ -642,7 +664,7 @@ int ospf6_lsa_expire(struct thread *thread) if (CHECK_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY)) return 0; /* dbexchange will do something ... */ - + ospf6 = ospf6_get_by_lsdb(lsa); /* reinstall lsa */ ospf6_install_lsa(lsa); @@ -703,7 +725,7 @@ int ospf6_lsa_refresh(struct thread *thread) return 0; } -void ospf6_flush_self_originated_lsas_now(void) +void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6) { struct listnode *node; struct ospf6_area *oa; diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index a85d7b0603..814e276796 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -20,6 +20,7 @@ #ifndef OSPF6_LSA_H #define OSPF6_LSA_H +#include "ospf6_top.h" /* Debug option */ #define OSPF6_LSA_DEBUG 0x01 @@ -156,46 +157,36 @@ extern vector ospf6_lsa_handler_vector; /* addr is (struct prefix *) */ #define CONTINUE_IF_ADDRESS_LINKLOCAL(debug, addr) \ if (IN6_IS_ADDR_LINKLOCAL(&(addr)->u.prefix6)) { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str(addr, buf, sizeof(buf)); \ if (debug) \ - zlog_debug("Filter out Linklocal: %s", buf); \ + zlog_debug("Filter out Linklocal: %pFX", addr); \ continue; \ } #define CONTINUE_IF_ADDRESS_UNSPECIFIED(debug, addr) \ if (IN6_IS_ADDR_UNSPECIFIED(&(addr)->u.prefix6)) { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str(addr, buf, sizeof(buf)); \ if (debug) \ - zlog_debug("Filter out Unspecified: %s", buf); \ + zlog_debug("Filter out Unspecified: %pFX", addr); \ continue; \ } #define CONTINUE_IF_ADDRESS_LOOPBACK(debug, addr) \ if (IN6_IS_ADDR_LOOPBACK(&(addr)->u.prefix6)) { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str(addr, buf, sizeof(buf)); \ if (debug) \ - zlog_debug("Filter out Loopback: %s", buf); \ + zlog_debug("Filter out Loopback: %pFX", addr); \ continue; \ } #define CONTINUE_IF_ADDRESS_V4COMPAT(debug, addr) \ if (IN6_IS_ADDR_V4COMPAT(&(addr)->u.prefix6)) { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str(addr, buf, sizeof(buf)); \ if (debug) \ - zlog_debug("Filter out V4Compat: %s", buf); \ + zlog_debug("Filter out V4Compat: %pFX", addr); \ continue; \ } #define CONTINUE_IF_ADDRESS_V4MAPPED(debug, addr) \ if (IN6_IS_ADDR_V4MAPPED(&(addr)->u.prefix6)) { \ - char buf[PREFIX2STR_BUFFER]; \ - prefix2str(addr, buf, sizeof(buf)); \ if (debug) \ - zlog_debug("Filter out V4Mapped: %s", buf); \ + zlog_debug("Filter out V4Mapped: %pFX", addr); \ continue; \ } @@ -226,8 +217,8 @@ ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header); extern void ospf6_lsa_delete(struct ospf6_lsa *lsa); extern struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *); -extern void ospf6_lsa_lock(struct ospf6_lsa *); -extern struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *); +extern struct ospf6_lsa *ospf6_lsa_lock(struct ospf6_lsa *lsa); +extern struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *lsa); extern int ospf6_lsa_expire(struct thread *); extern int ospf6_lsa_refresh(struct thread *); @@ -246,6 +237,6 @@ extern void ospf6_lsa_terminate(void); extern int config_write_ospf6_debug_lsa(struct vty *vty); extern void install_element_ospf6_debug_lsa(void); extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa); -extern void ospf6_flush_self_originated_lsas_now(void); - +extern void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6); +extern struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa); #endif /* OSPF6_LSA_H */ diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index b551dbdfa6..0892863cf1 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -207,11 +207,7 @@ struct ospf6_lsa *ospf6_lsdb_lookup_next(uint16_t type, uint32_t id, ospf6_lsdb_set_key(&key, &adv_router, sizeof(adv_router)); ospf6_lsdb_set_key(&key, &id, sizeof(id)); - { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&key, buf, sizeof(buf)); - zlog_debug("lsdb_lookup_next: key: %s", buf); - } + zlog_debug("lsdb_lookup_next: key: %pFX", &key); node = route_table_get_next(lsdb->table, &key); @@ -298,12 +294,12 @@ struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend, void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb) { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; if (lsdb == NULL) return; - for (ALL_LSDB(lsdb, lsa)) + for (ALL_LSDB(lsdb, lsa, lsanext)) ospf6_lsdb_remove(lsa, lsdb); } @@ -319,9 +315,9 @@ void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa) int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb) { int reschedule = 0; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; - for (ALL_LSDB(lsdb, lsa)) { + for (ALL_LSDB(lsdb, lsa, lsanext)) { if (!OSPF6_LSA_IS_MAXAGE(lsa)) continue; if (lsa->retrans_count != 0) { diff --git a/ospf6d/ospf6_lsdb.h b/ospf6d/ospf6_lsdb.h index 3b32e3ecf6..457e3dc4e4 100644 --- a/ospf6d/ospf6_lsdb.h +++ b/ospf6d/ospf6_lsdb.h @@ -66,11 +66,19 @@ extern struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend, lsa; \ lsa = ospf6_lsdb_next(iterend, lsa) -#define ALL_LSDB(lsdb, lsa) \ +/* + * Since we are locking the lsa in ospf6_lsdb_head + * and then unlocking it in lspf6_lsa_lock, when + * we cache the next pointer we need to increment + * the lock for the lsa so we don't accidently free + * it really early. + */ +#define ALL_LSDB(lsdb, lsa, lsanext) \ const struct route_node *iterend = \ ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa); \ - lsa; \ - lsa = ospf6_lsdb_next(iterend, lsa) + (lsa) != NULL &&ospf6_lsa_lock(lsa) \ + && ((lsanext) = ospf6_lsdb_next(iterend, (lsa)), 1); \ + ospf6_lsa_unlock(lsa), (lsa) = (lsanext) extern void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb); extern void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 182faf0038..4ed6e2a604 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -55,7 +55,7 @@ #define OSPF6_VTY_PORT 2606 /* ospf6d privileges */ -zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND}; +zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN}; struct zebra_privs_t ospf6d_privs = { #if defined(FRR_USER) @@ -68,7 +68,7 @@ struct zebra_privs_t ospf6d_privs = { .vty_group = VTY_GROUP, #endif .caps_p = _caps_p, - .cap_num_p = 2, + .cap_num_p = array_size(_caps_p), .cap_num_i = 0}; /* ospf6d options, we use GNU getopt library. */ @@ -81,27 +81,28 @@ static void __attribute__((noreturn)) ospf6_exit(int status) { struct vrf *vrf; struct interface *ifp; + struct ospf6 *ospf6; + struct listnode *node, *nnode; frr_early_fini(); - if (ospf6) { + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { vrf = vrf_lookup_by_id(ospf6->vrf_id); + ospf6_serv_close(&ospf6->fd); + FOR_ALL_INTERFACES (vrf, ifp) + if (ifp->info != NULL) + ospf6_interface_delete(ifp->info); ospf6_delete(ospf6); ospf6 = NULL; - } else - vrf = vrf_lookup_by_id(VRF_DEFAULT); + } bfd_gbl_exit(); - FOR_ALL_INTERFACES (vrf, ifp) - if (ifp->info != NULL) - ospf6_interface_delete(ifp->info); ospf6_message_terminate(); ospf6_asbr_terminate(); ospf6_lsa_terminate(); - ospf6_serv_close(); /* reverse access_list_init */ access_list_reset(); @@ -216,17 +217,17 @@ int main(int argc, char *argv[], char *envp[]) } /* OSPF6 master init. */ - ospf6_master_init(); + ospf6_master_init(frr_init()); /* thread master */ - master = frr_init(); + master = om6->master; vrf_init(NULL, NULL, NULL, NULL, NULL); access_list_init(); prefix_list_init(); /* initialize ospf6 */ - ospf6_init(); + ospf6_init(master); frr_config_fork(); frr_run(master); diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 4830b38a66..5f9953782c 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -31,10 +31,10 @@ #include "ospf6_proto.h" #include "ospf6_lsa.h" #include "ospf6_lsdb.h" +#include "ospf6_top.h" #include "ospf6_network.h" #include "ospf6_message.h" -#include "ospf6_top.h" #include "ospf6_area.h" #include "ospf6_neighbor.h" #include "ospf6_interface.h" @@ -781,9 +781,9 @@ static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst, oi->db_desc_in++; - if (ntohl(oh->router_id) < ntohl(ospf6->router_id)) + if (ntohl(oh->router_id) < ntohl(oi->area->ospf6->router_id)) ospf6_dbdesc_recv_master(oh, on); - else if (ntohl(ospf6->router_id) < ntohl(oh->router_id)) + else if (ntohl(oi->area->ospf6->router_id) < ntohl(oh->router_id)) ospf6_dbdesc_recv_slave(oh, on); else { if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) @@ -1532,10 +1532,14 @@ int ospf6_receive(struct thread *thread) struct iovec iovector[2]; struct ospf6_interface *oi; struct ospf6_header *oh; + struct ospf6 *ospf6; /* add next read thread */ + ospf6 = THREAD_ARG(thread); sockfd = THREAD_FD(thread); - thread_add_read(master, ospf6_receive, NULL, sockfd, NULL); + + thread_add_read(master, ospf6_receive, ospf6, ospf6->fd, + &ospf6->t_ospf6_receive); /* initialize */ memset(&src, 0, sizeof(src)); @@ -1548,7 +1552,7 @@ int ospf6_receive(struct thread *thread) iovector[1].iov_len = 0; /* receive message */ - len = ospf6_recvmsg(&src, &dst, &ifindex, iovector); + len = ospf6_recvmsg(&src, &dst, &ifindex, iovector, sockfd); if (len > iobuflen) { flog_err(EC_LIB_DEVELOPMENT, "Excess message read"); return 0; @@ -1696,9 +1700,13 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst, } /* send message */ - len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector); - if (len != ntohs(oh->length)) - flog_err(EC_LIB_DEVELOPMENT, "Could not send entire message"); + if (oi->area->ospf6->fd != -1) { + len = ospf6_sendmsg(src, dst, oi->interface->ifindex, iovector, + oi->area->ospf6->fd); + if (len != ntohs(oh->length)) + flog_err(EC_LIB_DEVELOPMENT, + "Could not send entire message"); + } } static uint32_t ospf6_packet_max(struct ospf6_interface *oi) @@ -1784,7 +1792,7 @@ int ospf6_dbdesc_send(struct thread *thread) struct ospf6_header *oh; struct ospf6_dbdesc *dbdesc; uint8_t *p; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; struct in6_addr *dst; on = (struct ospf6_neighbor *)THREAD_ARG(thread); @@ -1825,7 +1833,7 @@ int ospf6_dbdesc_send(struct thread *thread) /* if this is not initial one, set LSA headers in dbdesc */ p = (uint8_t *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc)); if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)) { - for (ALL_LSDB(on->dbdesc_list, lsa)) { + for (ALL_LSDB(on->dbdesc_list, lsa, lsanext)) { ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); @@ -1859,7 +1867,7 @@ int ospf6_dbdesc_send(struct thread *thread) int ospf6_dbdesc_send_newone(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; unsigned int size = 0; on = (struct ospf6_neighbor *)THREAD_ARG(thread); @@ -1869,7 +1877,7 @@ int ospf6_dbdesc_send_newone(struct thread *thread) structure) so that ospf6_send_dbdesc () can send those LSAs */ size = sizeof(struct ospf6_lsa_header) + sizeof(struct ospf6_dbdesc); - for (ALL_LSDB(on->summary_list, lsa)) { + for (ALL_LSDB(on->summary_list, lsa, lsanext)) { if (size + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { ospf6_lsdb_lsa_unlock(lsa); @@ -1900,7 +1908,7 @@ int ospf6_lsreq_send(struct thread *thread) struct ospf6_header *oh; struct ospf6_lsreq_entry *e; uint8_t *p; - struct ospf6_lsa *lsa, *last_req; + struct ospf6_lsa *lsa, *lsanext, *last_req; on = (struct ospf6_neighbor *)THREAD_ARG(thread); on->thread_send_lsreq = (struct thread *)NULL; @@ -1927,7 +1935,7 @@ int ospf6_lsreq_send(struct thread *thread) /* set Request entries in lsreq */ p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header)); - for (ALL_LSDB(on->request_list, lsa)) { + for (ALL_LSDB(on->request_list, lsa, lsanext)) { /* MTU check */ if (p - sendbuf + sizeof(struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if)) { @@ -2012,7 +2020,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) struct ospf6_lsupdate *lsupdate; uint8_t *p; int lsa_cnt; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; on = (struct ospf6_neighbor *)THREAD_ARG(thread); on->thread_send_lsupdate = (struct thread *)NULL; @@ -2037,7 +2045,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) /* lsupdate_list lists those LSA which doesn't need to be retransmitted. remove those from the list */ - for (ALL_LSDB(on->lsupdate_list, lsa)) { + for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) { /* MTU check */ if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) > ospf6_packet_max(on->ospf6_if)) { @@ -2089,7 +2097,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) p = (uint8_t *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); lsa_cnt = 0; - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { /* MTU check */ if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) > ospf6_packet_max(on->ospf6_if)) { @@ -2194,7 +2202,7 @@ int ospf6_lsupdate_send_interface(struct thread *thread) struct ospf6_lsupdate *lsupdate; uint8_t *p; int lsa_cnt; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; oi = (struct ospf6_interface *)THREAD_ARG(thread); oi->thread_send_lsupdate = (struct thread *)NULL; @@ -2220,7 +2228,7 @@ int ospf6_lsupdate_send_interface(struct thread *thread) p = (uint8_t *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); lsa_cnt = 0; - for (ALL_LSDB(oi->lsupdate_list, lsa)) { + for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) { /* MTU check */ if ((p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE(lsa->header))) > ospf6_packet_max(oi)) { @@ -2280,7 +2288,7 @@ int ospf6_lsack_send_neighbor(struct thread *thread) struct ospf6_neighbor *on; struct ospf6_header *oh; uint8_t *p; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; int lsa_cnt = 0; on = (struct ospf6_neighbor *)THREAD_ARG(thread); @@ -2303,7 +2311,7 @@ int ospf6_lsack_send_neighbor(struct thread *thread) p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header)); - for (ALL_LSDB(on->lsack_list, lsa)) { + for (ALL_LSDB(on->lsack_list, lsa, lsanext)) { /* MTU check */ if (p - sendbuf + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { @@ -2358,7 +2366,7 @@ int ospf6_lsack_send_interface(struct thread *thread) struct ospf6_interface *oi; struct ospf6_header *oh; uint8_t *p; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; int lsa_cnt = 0; oi = (struct ospf6_interface *)THREAD_ARG(thread); @@ -2382,7 +2390,7 @@ int ospf6_lsack_send_interface(struct thread *thread) p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header)); - for (ALL_LSDB(oi->lsack_list, lsa)) { + for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) { /* MTU check */ if (p - sendbuf + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(oi)) { diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 92a3c9e1ad..9f13ecffa1 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -118,11 +118,11 @@ struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id, void ospf6_neighbor_delete(struct ospf6_neighbor *on) { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; ospf6_lsdb_remove_all(on->summary_list); ospf6_lsdb_remove_all(on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { ospf6_decrement_retrans_count(lsa); ospf6_lsdb_remove(lsa, on->retrans_list); } @@ -293,7 +293,7 @@ int twoway_received(struct thread *thread) int negotiation_done(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; on = (struct ospf6_neighbor *)THREAD_ARG(thread); assert(on); @@ -307,13 +307,13 @@ int negotiation_done(struct thread *thread) /* clear ls-list */ ospf6_lsdb_remove_all(on->summary_list); ospf6_lsdb_remove_all(on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { ospf6_decrement_retrans_count(lsa); ospf6_lsdb_remove(lsa, on->retrans_list); } /* Interface scoped LSAs */ - for (ALL_LSDB(on->ospf6_if->lsdb, lsa)) { + for (ALL_LSDB(on->ospf6_if->lsdb, lsa, lsanext)) { if (OSPF6_LSA_IS_MAXAGE(lsa)) { ospf6_increment_retrans_count(lsa); ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); @@ -322,7 +322,7 @@ int negotiation_done(struct thread *thread) } /* Area scoped LSAs */ - for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa)) { + for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa, lsanext)) { if (OSPF6_LSA_IS_MAXAGE(lsa)) { ospf6_increment_retrans_count(lsa); ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); @@ -331,7 +331,7 @@ int negotiation_done(struct thread *thread) } /* AS scoped LSAs */ - for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa)) { + for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa, lsanext)) { if (OSPF6_LSA_IS_MAXAGE(lsa)) { ospf6_increment_retrans_count(lsa); ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); @@ -427,7 +427,7 @@ int loading_done(struct thread *thread) int adj_ok(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; on = (struct ospf6_neighbor *)THREAD_ARG(thread); assert(on); @@ -452,7 +452,7 @@ int adj_ok(struct thread *thread) OSPF6_NEIGHBOR_EVENT_ADJ_OK); ospf6_lsdb_remove_all(on->summary_list); ospf6_lsdb_remove_all(on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { ospf6_decrement_retrans_count(lsa); ospf6_lsdb_remove(lsa, on->retrans_list); } @@ -464,7 +464,7 @@ int adj_ok(struct thread *thread) int seqnumber_mismatch(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; on = (struct ospf6_neighbor *)THREAD_ARG(thread); assert(on); @@ -483,7 +483,7 @@ int seqnumber_mismatch(struct thread *thread) ospf6_lsdb_remove_all(on->summary_list); ospf6_lsdb_remove_all(on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { ospf6_decrement_retrans_count(lsa); ospf6_lsdb_remove(lsa, on->retrans_list); } @@ -501,7 +501,7 @@ int seqnumber_mismatch(struct thread *thread) int bad_lsreq(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; on = (struct ospf6_neighbor *)THREAD_ARG(thread); assert(on); @@ -520,7 +520,7 @@ int bad_lsreq(struct thread *thread) ospf6_lsdb_remove_all(on->summary_list); ospf6_lsdb_remove_all(on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { ospf6_decrement_retrans_count(lsa); ospf6_lsdb_remove(lsa, on->retrans_list); } @@ -538,7 +538,7 @@ int bad_lsreq(struct thread *thread) int oneway_received(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; on = (struct ospf6_neighbor *)THREAD_ARG(thread); assert(on); @@ -555,7 +555,7 @@ int oneway_received(struct thread *thread) ospf6_lsdb_remove_all(on->summary_list); ospf6_lsdb_remove_all(on->request_list); - for (ALL_LSDB(on->retrans_list, lsa)) { + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { ospf6_decrement_retrans_count(lsa); ospf6_lsdb_remove(lsa, on->retrans_list); } @@ -685,7 +685,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty, char drouter[16], bdrouter[16]; char linklocal_addr[64], duration[32]; struct timeval now, res; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr, sizeof(linklocal_addr)); @@ -715,15 +715,15 @@ static void ospf6_neighbor_show_detail(struct vty *vty, (unsigned long)ntohl(on->dbdesc_seqnum)); vty_out(vty, " Summary-List: %d LSAs\n", on->summary_list->count); - for (ALL_LSDB(on->summary_list, lsa)) + for (ALL_LSDB(on->summary_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); vty_out(vty, " Request-List: %d LSAs\n", on->request_list->count); - for (ALL_LSDB(on->request_list, lsa)) + for (ALL_LSDB(on->request_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); vty_out(vty, " Retrans-List: %d LSAs\n", on->retrans_list->count); - for (ALL_LSDB(on->retrans_list, lsa)) + for (ALL_LSDB(on->retrans_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); timerclear(&res); @@ -733,7 +733,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty, vty_out(vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n", on->dbdesc_list->count, duration, (on->thread_send_dbdesc ? "on" : "off")); - for (ALL_LSDB(on->dbdesc_list, lsa)) + for (ALL_LSDB(on->dbdesc_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); timerclear(&res); @@ -743,7 +743,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty, vty_out(vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n", on->request_list->count, duration, (on->thread_send_lsreq ? "on" : "off")); - for (ALL_LSDB(on->request_list, lsa)) + for (ALL_LSDB(on->request_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); timerclear(&res); @@ -754,7 +754,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", on->lsupdate_list->count, duration, (on->thread_send_lsupdate ? "on" : "off")); - for (ALL_LSDB(on->lsupdate_list, lsa)) + for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); timerclear(&res); @@ -764,7 +764,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty, vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", on->lsack_list->count, duration, (on->thread_send_lsack ? "on" : "off")); - for (ALL_LSDB(on->lsack_list, lsa)) + for (ALL_LSDB(on->lsack_list, lsa, lsanext)) vty_out(vty, " %s\n", lsa->name); ospf6_bfd_show_info(vty, on->bfd_info, 0); @@ -786,8 +786,11 @@ DEFUN (show_ipv6_ospf6_neighbor, struct ospf6_area *oa; struct listnode *i, *j, *k; void (*showfunc)(struct vty *, struct ospf6_neighbor *); + struct ospf6 *ospf6; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + + OSPF6_CMD_CHECK_RUNNING(ospf6); showfunc = ospf6_neighbor_show; if (argc == 5) { @@ -831,8 +834,10 @@ DEFUN (show_ipv6_ospf6_neighbor_one, struct listnode *i, *j, *k; void (*showfunc)(struct vty *, struct ospf6_neighbor *); uint32_t router_id; + struct ospf6 *ospf6; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); showfunc = ospf6_neighbor_show_detail; if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) { diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c index 9a18680b8b..76f98fecdd 100644 --- a/ospf6d/ospf6_network.c +++ b/ospf6d/ospf6_network.c @@ -26,18 +26,19 @@ #include "sockopt.h" #include "privs.h" #include "lib_errors.h" +#include "vrf.h" #include "libospf.h" #include "ospf6_proto.h" +#include "ospf6_top.h" #include "ospf6_network.h" #include "ospf6d.h" -int ospf6_sock; struct in6_addr allspfrouters6; struct in6_addr alldrouters6; /* setsockopt MulticastLoop to off */ -static void ospf6_reset_mcastloop(void) +static void ospf6_reset_mcastloop(int ospf6_sock) { unsigned int off = 0; if (setsockopt(ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, @@ -47,19 +48,19 @@ static void ospf6_reset_mcastloop(void) safe_strerror(errno)); } -static void ospf6_set_pktinfo(void) +static void ospf6_set_pktinfo(int ospf6_sock) { setsockopt_ipv6_pktinfo(ospf6_sock, 1); } -static void ospf6_set_transport_class(void) +static void ospf6_set_transport_class(int ospf6_sock) { #ifdef IPTOS_PREC_INTERNETCONTROL setsockopt_ipv6_tclass(ospf6_sock, IPTOS_PREC_INTERNETCONTROL); #endif } -static void ospf6_set_checksum(void) +static void ospf6_set_checksum(int ospf6_sock) { int offset = 12; #ifndef DISABLE_IPV6_CHECKSUM @@ -73,21 +74,30 @@ static void ospf6_set_checksum(void) #endif /* DISABLE_IPV6_CHECKSUM */ } -void ospf6_serv_close(void) +void ospf6_serv_close(int *ospf6_sock) { - if (ospf6_sock > 0) { - close(ospf6_sock); - ospf6_sock = -1; + if (*ospf6_sock != -1) { + close(*ospf6_sock); + *ospf6_sock = -1; return; } } /* Make ospf6d's server socket. */ -int ospf6_serv_sock(void) +int ospf6_serv_sock(struct ospf6 *ospf6) { + int ospf6_sock; + + if (ospf6->fd != -1) + return -1; + + if (ospf6->vrf_id == VRF_UNKNOWN) + return -1; + frr_with_privs(&ospf6d_privs) { - ospf6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP); + ospf6_sock = vrf_socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP, + ospf6->vrf_id, ospf6->name); if (ospf6_sock < 0) { zlog_warn("Network: can't create OSPF6 socket."); return -1; @@ -100,11 +110,12 @@ int ospf6_serv_sock(void) #else ospf6_set_reuseaddr(); #endif /*1*/ - ospf6_reset_mcastloop(); - ospf6_set_pktinfo(); - ospf6_set_transport_class(); - ospf6_set_checksum(); + ospf6_reset_mcastloop(ospf6_sock); + ospf6_set_pktinfo(ospf6_sock); + ospf6_set_transport_class(ospf6_sock); + ospf6_set_checksum(ospf6_sock); + ospf6->fd = ospf6_sock; /* setup global in6_addr, allspf6 and alldr6 for later use */ inet_pton(AF_INET6, ALLSPFROUTERS6, &allspfrouters6); inet_pton(AF_INET6, ALLDROUTERS6, &alldrouters6); @@ -113,18 +124,20 @@ int ospf6_serv_sock(void) } /* ospf6 set socket option */ -int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option) +int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option, int sockfd) { struct ipv6_mreq mreq6; int ret; int bufsize = (8 * 1024 * 1024); + if (sockfd == -1) + return -1; + assert(ifindex); mreq6.ipv6mr_interface = ifindex; memcpy(&mreq6.ipv6mr_multiaddr, group, sizeof(struct in6_addr)); - ret = setsockopt(ospf6_sock, IPPROTO_IPV6, option, &mreq6, - sizeof(mreq6)); + ret = setsockopt(sockfd, IPPROTO_IPV6, option, &mreq6, sizeof(mreq6)); if (ret < 0) { flog_err_sys( EC_LIB_SOCKET, @@ -133,8 +146,8 @@ int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option) return ret; } - setsockopt_so_sendbuf(ospf6_sock, bufsize); - setsockopt_so_recvbuf(ospf6_sock, bufsize); + setsockopt_so_sendbuf(sockfd, bufsize); + setsockopt_so_recvbuf(sockfd, bufsize); return 0; } @@ -157,7 +170,7 @@ static int iov_totallen(struct iovec *iov) } int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, - ifindex_t *ifindex, struct iovec *message) + ifindex_t ifindex, struct iovec *message, int ospf6_sock) { int retval; struct msghdr smsghdr; @@ -170,7 +183,6 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, struct sockaddr_in6 dst_sin6; assert(dst); - assert(*ifindex); memset(&cmsgbuf, 0, sizeof(cmsgbuf)); scmsgp = (struct cmsghdr *)&cmsgbuf; @@ -178,7 +190,7 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, memset(&dst_sin6, 0, sizeof(struct sockaddr_in6)); /* source address */ - pktinfo->ipi6_ifindex = *ifindex; + pktinfo->ipi6_ifindex = ifindex; if (src) memcpy(&pktinfo->ipi6_addr, src, sizeof(struct in6_addr)); else @@ -190,7 +202,7 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, dst_sin6.sin6_len = sizeof(struct sockaddr_in6); #endif /*SIN6_LEN*/ memcpy(&dst_sin6.sin6_addr, dst, sizeof(struct in6_addr)); - dst_sin6.sin6_scope_id = *ifindex; + dst_sin6.sin6_scope_id = ifindex; /* send control msg */ scmsgp->cmsg_level = IPPROTO_IPV6; @@ -209,14 +221,15 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, retval = sendmsg(ospf6_sock, &smsghdr, 0); if (retval != iov_totallen(message)) - zlog_warn("sendmsg failed: ifindex: %d: %s (%d)", *ifindex, + zlog_warn("sendmsg failed: source: %pI6 Dest: %pI6 ifindex: %d: %s (%d)", + src, dst, ifindex, safe_strerror(errno), errno); return retval; } int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst, - ifindex_t *ifindex, struct iovec *message) + ifindex_t *ifindex, struct iovec *message, int ospf6_sock) { int retval; struct msghdr rmsghdr; diff --git a/ospf6d/ospf6_network.h b/ospf6d/ospf6_network.h index 7fe6e33ff2..08d8be4445 100644 --- a/ospf6d/ospf6_network.h +++ b/ospf6d/ospf6_network.h @@ -21,17 +21,19 @@ #ifndef OSPF6_NETWORK_H #define OSPF6_NETWORK_H -extern int ospf6_sock; extern struct in6_addr allspfrouters6; extern struct in6_addr alldrouters6; -extern int ospf6_serv_sock(void); -extern void ospf6_serv_close(void); -extern int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option); +extern int ospf6_serv_sock(struct ospf6 *ospf6); +extern void ospf6_serv_close(int *ospf6_sock); +extern int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option, + int sockfd); -extern int ospf6_sendmsg(struct in6_addr *, struct in6_addr *, ifindex_t *, - struct iovec *); -extern int ospf6_recvmsg(struct in6_addr *, struct in6_addr *, ifindex_t *, - struct iovec *); +extern int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst, + ifindex_t ifindex, struct iovec *message, + int ospf6_sock); +extern int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst, + ifindex_t *ifindex, struct iovec *message, + int ospf6_sock); #endif /* OSPF6_NETWORK_H */ diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index a443e4c3ba..2602854f33 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -296,25 +296,24 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, { struct ospf6_nexthop *nh; struct listnode *node; + struct interface *ifp; char buf[64]; int i; if (route) { i = 0; for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { + ifp = if_lookup_by_index_all_vrf(nh->ifindex); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { - const char *ifname; inet_ntop(AF_INET6, &nh->address, buf, sizeof(buf)); - ifname = ifindex2ifname(nh->ifindex, - ospf6->vrf_id); zlog_debug(" nexthop: %s%%%.*s(%d)", buf, - IFNAMSIZ, ifname, nh->ifindex); + IFNAMSIZ, ifp->name, nh->ifindex); } if (i >= entries) return; - nexthops[i].vrf_id = ospf6->vrf_id; + nexthops[i].vrf_id = ifp->vrf_id; nexthops[i].ifindex = nh->ifindex; if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) { nexthops[i].gate.ipv6 = nh->address; @@ -550,7 +549,6 @@ ospf6_route_lookup_bestmatch(struct prefix *prefix, static void route_table_assert(struct ospf6_route_table *table) { struct ospf6_route *prev, *r, *next; - char buf[PREFIX2STR_BUFFER]; unsigned int link_error = 0, num = 0; r = ospf6_route_head(table); @@ -579,10 +577,9 @@ static void route_table_assert(struct ospf6_route_table *table) "Something has gone wrong with ospf6_route_table[%p]", table); zlog_debug("table count = %d, real number = %d", table->count, num); zlog_debug("DUMP START"); - for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) { - prefix2str(&r->prefix, buf, sizeof(buf)); - zlog_info("%p<-[%p]->%p : %s", r->prev, r, r->next, buf); - } + for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) + zlog_info("%p<-[%p]->%p : %pFX", r->prev, r, r->next, + &r->prefix); zlog_debug("DUMP END"); assert(link_error == 0 && num == table->count); @@ -593,7 +590,8 @@ static void route_table_assert(struct ospf6_route_table *table) #endif /*DEBUG*/ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, - struct ospf6_route_table *table) + struct ospf6_route_table *table, + struct ospf6 *ospf6) { struct route_node *node, *nextnode, *prevnode; struct ospf6_route *current = NULL; @@ -702,7 +700,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, ospf6_route_table_assert(table); if (table->hook_add) - (*table->hook_add)(route); + (*table->hook_add)(route, ospf6); return route; } @@ -714,7 +712,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, "%s %p: route add %p cost %u: another path: prev %p, next %p node ref %u", ospf6_route_table_name(table), (void *)table, (void *)route, route->path.cost, (void *)prev, - (void *)next, node->lock); + (void *)next, route_node_get_lock_count(node)); else if (IS_OSPF6_DEBUG_ROUTE(TABLE)) zlog_debug("%s: route add cost %u: another path found", ospf6_route_table_name(table), @@ -757,7 +755,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, SET_FLAG(route->flag, OSPF6_ROUTE_ADD); if (table->hook_add) - (*table->hook_add)(route); + (*table->hook_add)(route, ospf6); return route; } @@ -823,13 +821,13 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, SET_FLAG(route->flag, OSPF6_ROUTE_ADD); if (table->hook_add) - (*table->hook_add)(route); + (*table->hook_add)(route, ospf6); return route; } void ospf6_route_remove(struct ospf6_route *route, - struct ospf6_route_table *table) + struct ospf6_route_table *table, struct ospf6 *ospf6) { struct route_node *node; struct ospf6_route *current; @@ -884,7 +882,7 @@ void ospf6_route_remove(struct ospf6_route *route, /* Note hook_remove may call ospf6_route_remove */ if (table->hook_remove) - (*table->hook_remove)(route); + (*table->hook_remove)(route, ospf6); ospf6_route_unlock(route); } @@ -1004,12 +1002,13 @@ struct ospf6_route *ospf6_route_match_next(struct prefix *prefix, return next; } -void ospf6_route_remove_all(struct ospf6_route_table *table) +void ospf6_route_remove_all(struct ospf6_route_table *table, + struct ospf6 *ospf6) { struct ospf6_route *route; for (route = ospf6_route_head(table); route; route = ospf6_route_next(route)) - ospf6_route_remove(route, table); + ospf6_route_remove(route, table, ospf6); } struct ospf6_route_table *ospf6_route_table_create(int s, int t) @@ -1022,9 +1021,10 @@ struct ospf6_route_table *ospf6_route_table_create(int s, int t) return new; } -void ospf6_route_table_delete(struct ospf6_route_table *table) +void ospf6_route_table_delete(struct ospf6_route_table *table, + struct ospf6 *ospf6) { - ospf6_route_remove_all(table); + ospf6_route_remove_all(table, ospf6); bf_free(table->idspace); route_table_finish(table->table); XFREE(MTYPE_OSPF6_ROUTE, table); @@ -1037,12 +1037,11 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route) int i; char destination[PREFIX2STR_BUFFER], nexthop[64]; char duration[64]; - const char *ifname; struct timeval now, res; struct listnode *node; struct ospf6_nexthop *nh; - if (ospf6 == NULL) { + if (om6->ospf6 == NULL) { vty_out(vty, "OSPFv3 is not running\n"); return; } @@ -1063,35 +1062,34 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route) i = 0; for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { + struct interface *ifp; /* nexthop */ inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop)); - ifname = ifindex2ifname(nh->ifindex, ospf6->vrf_id); - + ifp = if_lookup_by_index_all_vrf(nh->ifindex); if (!i) { vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", (ospf6_route_is_best(route) ? '*' : ' '), OSPF6_DEST_TYPE_SUBSTR(route->type), OSPF6_PATH_TYPE_SUBSTR(route->path.type), - destination, nexthop, IFNAMSIZ, ifname, + destination, nexthop, IFNAMSIZ, ifp->name, duration); i++; } else vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", ' ', - "", "", "", nexthop, IFNAMSIZ, ifname, ""); + "", "", "", nexthop, IFNAMSIZ, ifp->name, ""); } } void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route) { - const char *ifname; - char destination[PREFIX2STR_BUFFER], nexthop[64]; + char destination[PREFIX2STR_BUFFER]; char area_id[16], id[16], adv_router[16], capa[16], options[16]; struct timeval now, res; char duration[64]; struct listnode *node; struct ospf6_nexthop *nh; - if (ospf6 == NULL) { + if (om6->ospf6 == NULL) { vty_out(vty, "OSPFv3 is not running\n"); return; } @@ -1168,10 +1166,11 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route) /* Nexthops */ vty_out(vty, "Nexthop:\n"); for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { + struct interface *ifp; /* nexthop */ - inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop)); - ifname = ifindex2ifname(nh->ifindex, ospf6->vrf_id); - vty_out(vty, " %s %.*s\n", nexthop, IFNAMSIZ, ifname); + + ifp = if_lookup_by_index_all_vrf(nh->ifindex); + vty_out(vty, " %pI6 %.*s\n", &nh->address, IFNAMSIZ, ifp->name); } vty_out(vty, "\n"); } diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index 95ba983e6b..0b984400b5 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -178,6 +178,7 @@ struct ospf6_route { #define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x20 #define OSPF6_ROUTE_WAS_REMOVED 0x40 #define OSPF6_ROUTE_BLACKHOLE_ADDED 0x80 +struct ospf6; struct ospf6_route_table { int scope_type; @@ -192,9 +193,9 @@ struct ospf6_route_table { bitfield_t idspace; /* hooks */ - void (*hook_add)(struct ospf6_route *); + void (*hook_add)(struct ospf6_route *, struct ospf6 *); void (*hook_change)(struct ospf6_route *); - void (*hook_remove)(struct ospf6_route *); + void (*hook_remove)(struct ospf6_route *, struct ospf6 *); }; #define OSPF6_SCOPE_TYPE_NONE 0 @@ -296,7 +297,6 @@ extern int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb); extern void ospf6_route_lock(struct ospf6_route *route); extern void ospf6_route_unlock(struct ospf6_route *route); - extern struct ospf6_route *ospf6_route_lookup(struct prefix *prefix, struct ospf6_route_table *table); extern struct ospf6_route * @@ -307,9 +307,11 @@ ospf6_route_lookup_bestmatch(struct prefix *prefix, struct ospf6_route_table *table); extern struct ospf6_route *ospf6_route_add(struct ospf6_route *route, - struct ospf6_route_table *table); + struct ospf6_route_table *table, + struct ospf6 *ospf6); extern void ospf6_route_remove(struct ospf6_route *route, - struct ospf6_route_table *table); + struct ospf6_route_table *table, + struct ospf6 *ospf6); extern struct ospf6_route *ospf6_route_head(struct ospf6_route_table *table); extern struct ospf6_route *ospf6_route_next(struct ospf6_route *route); @@ -320,9 +322,10 @@ ospf6_route_match_head(struct prefix *prefix, struct ospf6_route_table *table); extern struct ospf6_route *ospf6_route_match_next(struct prefix *prefix, struct ospf6_route *route); -extern void ospf6_route_remove_all(struct ospf6_route_table *); +extern void ospf6_route_remove_all(struct ospf6_route_table *, struct ospf6 *); extern struct ospf6_route_table *ospf6_route_table_create(int s, int t); -extern void ospf6_route_table_delete(struct ospf6_route_table *); +extern void ospf6_route_table_delete(struct ospf6_route_table *, + struct ospf6 *); extern void ospf6_route_dump(struct ospf6_route_table *table); @@ -341,7 +344,6 @@ extern void ospf6_brouter_show(struct vty *vty, struct ospf6_route *route); extern int config_write_ospf6_debug_route(struct vty *vty); extern void install_element_ospf6_debug_route(void); extern void ospf6_route_init(void); -extern void ospf6_clean(void); extern void ospf6_path_free(struct ospf6_path *op); extern struct ospf6_path *ospf6_path_dup(struct ospf6_path *path); extern void ospf6_copy_paths(struct list *dst, struct list *src); diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 57cc055296..3aeba3b609 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -637,8 +637,10 @@ static uint8_t *ospfv3GeneralGroup(struct variable *v, oid *name, { uint16_t sum; uint32_t count; - struct ospf6_lsa *lsa = NULL; + struct ospf6_lsa *lsa = NULL, *lsanext; + struct ospf6 *ospf6; + ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT); /* Check whether the instance identifier is valid */ if (smux_header_generic(v, name, length, exact, var_len, write_method) == MATCH_FAILED) @@ -679,7 +681,7 @@ static uint8_t *ospfv3GeneralGroup(struct variable *v, oid *name, case OSPFv3ASSCOPELSACHECKSUMSUM: if (ospf6) { sum = 0; - for (ALL_LSDB(ospf6->lsdb, lsa)) + for (ALL_LSDB(ospf6->lsdb, lsa, lsanext)) sum += ntohs(lsa->header->checksum); return SNMP_INTEGER(sum); } @@ -733,7 +735,7 @@ static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length, WriteMethod **write_method) { struct ospf6_area *oa, *area = NULL; - struct ospf6_lsa *lsa = NULL; + struct ospf6_lsa *lsa = NULL, *lsanext; uint32_t area_id = 0; uint32_t count; uint16_t sum; @@ -741,6 +743,9 @@ static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length, unsigned int len; char a[16]; struct ospf6_route *ro; + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT); if (ospf6 == NULL) return NULL; @@ -808,7 +813,7 @@ static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length, return SNMP_INTEGER(area->lsdb->count); case OSPFv3AREASCOPELSACKSUMSUM: sum = 0; - for (ALL_LSDB(area->lsdb, lsa)) + for (ALL_LSDB(area->lsdb, lsa, lsanext)) sum += ntohs(lsa->header->checksum); return SNMP_INTEGER(sum); case OSPFv3AREASUMMARY: @@ -850,6 +855,9 @@ static uint8_t *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length, struct interface *iif; struct ospf6_interface *oi = NULL; struct list *ifslist; + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT); if (smux_header_table(v, name, length, exact, var_len, write_method) == MATCH_FAILED) @@ -1044,13 +1052,16 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, ifindex_t ifindex = 0; unsigned int instid = 0; struct ospf6_interface *oi = NULL; - struct ospf6_lsa *lsa = NULL; + struct ospf6_lsa *lsa = NULL, *lsanext; struct interface *iif; struct listnode *i; struct list *ifslist; oid *offset; int offsetlen, len; uint32_t sum; + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT); if (smux_header_table(v, name, length, exact, var_len, write_method) == MATCH_FAILED) @@ -1171,7 +1182,7 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length, return SNMP_INTEGER(oi->lsdb->count); case OSPFv3IFLINKLSACKSUMSUM: sum = 0; - for (ALL_LSDB(oi->lsdb, lsa)) + for (ALL_LSDB(oi->lsdb, lsa, lsanext)) sum += ntohs(lsa->header->checksum); return SNMP_INTEGER(sum); case OSPFv3IFDEMANDNBRPROBE: @@ -1205,6 +1216,9 @@ static uint8_t *ospfv3NbrEntry(struct variable *v, oid *name, size_t *length, struct list *ifslist; oid *offset; int offsetlen, len; + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT); if (smux_header_table(v, name, length, exact, var_len, write_method) == MATCH_FAILED) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index e5eb8d74eb..4dd1d5a462 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -258,7 +258,7 @@ static char *ospf6_lsdesc_backlink(struct ospf6_lsa *lsa, caddr_t lsdesc, } static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, - caddr_t lsdesc) + caddr_t lsdesc, struct ospf6 *ospf6) { int i; ifindex_t ifindex; @@ -316,11 +316,11 @@ static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, } static int ospf6_spf_install(struct ospf6_vertex *v, - struct ospf6_route_table *result_table) + struct ospf6_route_table *result_table, + struct ospf6 *ospf6) { struct ospf6_route *route, *parent_route; struct ospf6_vertex *prev; - char pbuf[PREFIX2STR_BUFFER]; if (IS_OSPF6_DEBUG_SPF(PROCESS)) zlog_debug("SPF install %s (lsa %s) hops %d cost %d", v->name, @@ -335,12 +335,10 @@ static int ospf6_spf_install(struct ospf6_vertex *v, ospf6_vertex_delete(v); return -1; } else if (route && route->path.cost == v->cost) { - if (IS_OSPF6_DEBUG_SPF(PROCESS)) { - prefix2str(&route->prefix, pbuf, sizeof(pbuf)); + if (IS_OSPF6_DEBUG_SPF(PROCESS)) zlog_debug( - " another path found to route %s lsa %s, merge", - pbuf, v->lsa->name); - } + " another path found to route %pFX lsa %s, merge", + &route->prefix, v->lsa->name); ospf6_spf_merge_nexthops_to_route(route, v); prev = (struct ospf6_vertex *)route->route_option; @@ -419,11 +417,12 @@ static int ospf6_spf_install(struct ospf6_vertex *v, listnode_add_sort(v->parent->child_list, v); route->route_option = v; - ospf6_route_add(route, result_table); + ospf6_route_add(route, result_table, ospf6); return 0; } -void ospf6_spf_table_finish(struct ospf6_route_table *result_table) +void ospf6_spf_table_finish(struct ospf6_route_table *result_table, + struct ospf6 *ospf6) { struct ospf6_route *route, *nroute; struct ospf6_vertex *v; @@ -431,7 +430,7 @@ void ospf6_spf_table_finish(struct ospf6_route_table *result_table) nroute = ospf6_route_next(route); v = (struct ospf6_vertex *)route->route_option; ospf6_vertex_delete(v); - ospf6_route_remove(route, result_table); + ospf6_route_remove(route, result_table, ospf6); } } @@ -469,7 +468,7 @@ void ospf6_spf_calculation(uint32_t router_id, struct ospf6_lsa *lsa; struct in6_addr address; - ospf6_spf_table_finish(result_table); + ospf6_spf_table_finish(result_table, oa->ospf6); /* Install the calculating router itself as the root of the SPF tree */ /* construct root vertex */ @@ -498,7 +497,7 @@ void ospf6_spf_calculation(uint32_t router_id, while ((v = vertex_pqueue_pop(&candidate_list))) { /* installing may result in merging or rejecting of the vertex */ - if (ospf6_spf_install(v, result_table) < 0) + if (ospf6_spf_install(v, result_table, oa->ospf6) < 0) continue; /* Skip overloaded routers */ @@ -544,7 +543,7 @@ void ospf6_spf_calculation(uint32_t router_id, w->nh_list, ROUTER_LSDESC_GET_IFID(lsdesc), NULL); else if (w->hops == 1 && v->hops == 0) - ospf6_nexthop_calc(w, v, lsdesc); + ospf6_nexthop_calc(w, v, lsdesc, oa->ospf6); else ospf6_copy_nexthops(w->nh_list, v->nh_list); @@ -915,7 +914,7 @@ int config_write_ospf6_debug_spf(struct vty *vty) return 0; } -void ospf6_spf_config_write(struct vty *vty) +void ospf6_spf_config_write(struct vty *vty, struct ospf6 *ospf6) { if (ospf6->spf_delay != OSPF_SPF_DELAY_DEFAULT @@ -1082,9 +1081,9 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, void ospf6_remove_temp_router_lsa(struct ospf6_area *area) { - struct ospf6_lsa *lsa = NULL; + struct ospf6_lsa *lsa = NULL, *lsanext; - for (ALL_LSDB(area->temp_router_lsa_lsdb, lsa)) { + for (ALL_LSDB(area->temp_router_lsa_lsdb, lsa, lsanext)) { if (IS_OSPF6_DEBUG_SPF(PROCESS)) zlog_debug( "%s Remove LSA %s lsa->lock %u lsdb count %u", diff --git a/ospf6d/ospf6_spf.h b/ospf6d/ospf6_spf.h index a387d40a57..f288f91f57 100644 --- a/ospf6d/ospf6_spf.h +++ b/ospf6d/ospf6_spf.h @@ -139,7 +139,8 @@ static inline unsigned int ospf6_lsremove_to_spf_reason(struct ospf6_lsa *lsa) return (reason); } -extern void ospf6_spf_table_finish(struct ospf6_route_table *result_table); +extern void ospf6_spf_table_finish(struct ospf6_route_table *result_table, + struct ospf6 *ospf6); extern void ospf6_spf_calculation(uint32_t router_id, struct ospf6_route_table *result_table, struct ospf6_area *oa); @@ -148,7 +149,7 @@ extern void ospf6_spf_schedule(struct ospf6 *ospf, unsigned int reason); extern void ospf6_spf_display_subtree(struct vty *vty, const char *prefix, int rest, struct ospf6_vertex *v); -extern void ospf6_spf_config_write(struct vty *vty); +extern void ospf6_spf_config_write(struct vty *vty, struct ospf6 *ospf6); extern int config_write_ospf6_debug_spf(struct vty *vty); extern void install_element_ospf6_debug_spf(void); extern void ospf6_spf_init(void); diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 6f23051dc3..95c72290d0 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -29,6 +29,7 @@ #include "thread.h" #include "command.h" #include "defaults.h" +#include "lib_errors.h" #include "ospf6_proto.h" #include "ospf6_message.h" @@ -41,6 +42,7 @@ #include "ospf6_area.h" #include "ospf6_interface.h" #include "ospf6_neighbor.h" +#include "ospf6_network.h" #include "ospf6_flood.h" #include "ospf6_asbr.h" @@ -57,17 +59,76 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES, ) /* global ospf6d variable */ -struct ospf6 *ospf6; static struct ospf6_master ospf6_master; struct ospf6_master *om6; static void ospf6_disable(struct ospf6 *o); +static void ospf6_add(struct ospf6 *ospf6) +{ + listnode_add(om6->ospf6, ospf6); +} + +static void ospf6_del(struct ospf6 *ospf6) +{ + listnode_delete(om6->ospf6, ospf6); +} + +const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + + return vrf ? vrf->name : "NIL"; +} + +/* Link OSPF instance to VRF. */ +void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf) +{ + ospf6->vrf_id = vrf->vrf_id; + if (vrf->info != (void *)ospf6) + vrf->info = (void *)ospf6; +} + +/* Unlink OSPF instance from VRF. */ +void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf) +{ + if (vrf->info == (void *)ospf6) + vrf->info = NULL; + ospf6->vrf_id = VRF_UNKNOWN; +} + +struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id) +{ + struct vrf *vrf = NULL; + + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + return (vrf->info) ? (struct ospf6 *)vrf->info : NULL; +} + +struct ospf6 *ospf6_lookup_by_vrf_name(const char *name) +{ + struct ospf6 *o = NULL; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) { + if (((o->name == NULL && name == NULL) + || (o->name && name && strcmp(o->name, name) == 0))) + return o; + } + return NULL; +} + + static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa) { + struct ospf6 *ospf6 = NULL; + switch (ntohs(lsa->header->type)) { case OSPF6_LSTYPE_AS_EXTERNAL: - ospf6_asbr_lsa_add(lsa); + ospf6 = ospf6_get_by_lsdb(lsa); + ospf6_asbr_lsa_add(lsa, ospf6); break; default: @@ -87,20 +148,23 @@ static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa) } } -static void ospf6_top_route_hook_add(struct ospf6_route *route) +static void ospf6_top_route_hook_add(struct ospf6_route *route, + struct ospf6 *ospf6) { - ospf6_abr_originate_summary(route); - ospf6_zebra_route_update_add(route); + ospf6_abr_originate_summary(route, ospf6); + ospf6_zebra_route_update_add(route, ospf6); } -static void ospf6_top_route_hook_remove(struct ospf6_route *route) +static void ospf6_top_route_hook_remove(struct ospf6_route *route, + struct ospf6 *ospf6) { route->flag |= OSPF6_ROUTE_REMOVE; - ospf6_abr_originate_summary(route); - ospf6_zebra_route_update_remove(route); + ospf6_abr_originate_summary(route, ospf6); + ospf6_zebra_route_update_remove(route, ospf6); } -static void ospf6_top_brouter_hook_add(struct ospf6_route *route) +static void ospf6_top_brouter_hook_add(struct ospf6_route *route, + struct ospf6 *ospf6) { if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) || IS_OSPF6_DEBUG_BROUTER) { @@ -115,12 +179,14 @@ static void ospf6_top_brouter_hook_add(struct ospf6_route *route) route->path.origin.adv_router, listcount(route->nh_list)); } - ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix)); - ospf6_asbr_lsentry_add(route); - ospf6_abr_originate_summary(route); + ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route, + ospf6); + ospf6_asbr_lsentry_add(route, ospf6); + ospf6_abr_originate_summary(route, ospf6); } -static void ospf6_top_brouter_hook_remove(struct ospf6_route *route) +static void ospf6_top_brouter_hook_remove(struct ospf6_route *route, + struct ospf6 *ospf6) { if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) || IS_OSPF6_DEBUG_BROUTER) { @@ -136,20 +202,34 @@ static void ospf6_top_brouter_hook_remove(struct ospf6_route *route) listcount(route->nh_list)); } route->flag |= OSPF6_ROUTE_REMOVE; - ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix)); - ospf6_asbr_lsentry_remove(route); - ospf6_abr_originate_summary(route); + ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route, + ospf6); + ospf6_asbr_lsentry_remove(route, ospf6); + ospf6_abr_originate_summary(route, ospf6); } -static struct ospf6 *ospf6_create(vrf_id_t vrf_id) +static struct ospf6 *ospf6_create(const char *name) { struct ospf6 *o; + struct vrf *vrf = NULL; o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6)); + vrf = vrf_lookup_by_name(name); + if (vrf) { + o->vrf_id = vrf->vrf_id; + } else + o->vrf_id = VRF_UNKNOWN; + + /* Freed in ospf6_delete */ + o->name = XSTRDUP(MTYPE_OSPF6_TOP, name); + if (vrf) + ospf6_vrf_link(o, vrf); + + ospf6_zebra_vrf_register(o); + /* initialize */ monotime(&o->starttime); - o->vrf_id = vrf_id; o->area_list = list_new(); o->area_list->cmp = ospf6_area_cmp; o->lsdb = ospf6_lsdb_create(o); @@ -183,12 +263,32 @@ static struct ospf6 *ospf6_create(vrf_id_t vrf_id) o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; o->distance_table = route_table_init(); + o->fd = -1; QOBJ_REG(o, ospf6); + /* Make ospf protocol socket. */ + ospf6_serv_sock(o); + return o; } +struct ospf6 *ospf6_instance_create(const char *name) +{ + struct ospf6 *ospf6; + + ospf6 = ospf6_create(name); + if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) + SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); + if (ospf6->router_id == 0) + ospf6_router_id_update(ospf6); + ospf6_add(ospf6); + thread_add_read(master, ospf6_receive, ospf6, ospf6->fd, + &ospf6->t_ospf6_receive); + + return ospf6; +} + void ospf6_delete(struct ospf6 *o) { struct listnode *node, *nnode; @@ -196,8 +296,9 @@ void ospf6_delete(struct ospf6 *o) QOBJ_UNREG(o); - ospf6_flush_self_originated_lsas_now(); - ospf6_disable(ospf6); + ospf6_flush_self_originated_lsas_now(o); + ospf6_disable(o); + ospf6_del(o); for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) ospf6_area_delete(oa); @@ -208,15 +309,16 @@ void ospf6_delete(struct ospf6 *o) ospf6_lsdb_delete(o->lsdb); ospf6_lsdb_delete(o->lsdb_self); - ospf6_route_table_delete(o->route_table); - ospf6_route_table_delete(o->brouter_table); + ospf6_route_table_delete(o->route_table, o); + ospf6_route_table_delete(o->brouter_table, o); - ospf6_route_table_delete(o->external_table); + ospf6_route_table_delete(o->external_table, o); route_table_finish(o->external_id_table); ospf6_distance_reset(o); route_table_finish(o->distance_table); + XFREE(MTYPE_OSPF6_TOP, o->name); XFREE(MTYPE_OSPF6_TOP, o); } @@ -235,21 +337,24 @@ static void ospf6_disable(struct ospf6 *o) ospf6_asbr_redistribute_reset(o->vrf_id); ospf6_lsdb_remove_all(o->lsdb); - ospf6_route_remove_all(o->route_table); - ospf6_route_remove_all(o->brouter_table); + ospf6_route_remove_all(o->route_table, o); + ospf6_route_remove_all(o->brouter_table, o); THREAD_OFF(o->maxage_remover); THREAD_OFF(o->t_spf_calc); THREAD_OFF(o->t_ase_calc); THREAD_OFF(o->t_distribute_update); + THREAD_OFF(o->t_ospf6_receive); } } -void ospf6_master_init(void) +void ospf6_master_init(struct thread_master *master) { memset(&ospf6_master, 0, sizeof(struct ospf6_master)); om6 = &ospf6_master; + om6->ospf6 = list_new(); + om6->master = master; } static int ospf6_maxage_remover(struct thread *thread) @@ -307,7 +412,7 @@ void ospf6_maxage_remove(struct ospf6 *o) &o->maxage_remover); } -void ospf6_router_id_update(void) +void ospf6_router_id_update(struct ospf6 *ospf6) { if (!ospf6) return; @@ -325,14 +430,12 @@ DEFUN_NOSH (router_ospf6, ROUTER_STR OSPF6_STR) { - if (ospf6 == NULL) { - ospf6 = ospf6_create(VRF_DEFAULT); - if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) - SET_FLAG(ospf6->config_flags, - OSPF6_LOG_ADJACENCY_CHANGES); - if (ospf6->router_id == 0) - ospf6_router_id_update(); - } + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + if (ospf6 == NULL) + ospf6 = ospf6_instance_create(VRF_DEFAULT_NAME); + /* set current ospf point. */ VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6); @@ -347,9 +450,13 @@ DEFUN (no_router_ospf6, ROUTER_STR OSPF6_STR) { + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); if (ospf6 == NULL) vty_out(vty, "OSPFv3 is not configured\n"); else { + ospf6_serv_close(&ospf6->fd); ospf6_delete(ospf6); ospf6 = NULL; } @@ -650,13 +757,14 @@ DEFUN (ospf6_interface_area, "OSPF6 area ID in decimal notation\n" ) { - VTY_DECLVAR_CONTEXT(ospf6, o); int idx_ifname = 1; int idx_ipv4 = 3; struct ospf6_area *oa; struct ospf6_interface *oi; struct interface *ifp; + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + /* find/create ospf6 interface */ ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); oi = (struct ospf6_interface *)ifp->info; @@ -669,7 +777,7 @@ DEFUN (ospf6_interface_area, } /* parse Area-ID */ - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6); /* attach interface to area */ listnode_add(oa->if_list, oi); /* sort ?? */ @@ -678,14 +786,14 @@ DEFUN (ospf6_interface_area, SET_FLAG(oa->flag, OSPF6_AREA_ENABLE); /* ospf6 process is currently disabled, not much more to do */ - if (CHECK_FLAG(o->flag, OSPF6_DISABLED)) + if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED)) return CMD_SUCCESS; /* start up */ ospf6_interface_enable(oi); /* If the router is ABR, originate summary routes */ - if (ospf6_is_router_abr(o)) + if (ospf6_is_router_abr(ospf6)) ospf6_abr_enable_area(oa); return CMD_SUCCESS; @@ -761,6 +869,8 @@ DEFUN (ospf6_stub_router_admin, struct listnode *node; struct ospf6_area *oa; + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6); @@ -783,6 +893,7 @@ DEFUN (no_ospf6_stub_router_admin, struct listnode *node; struct ospf6_area *oa; + VTY_DECLVAR_CONTEXT(ospf6, ospf6); if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6); @@ -922,8 +1033,10 @@ DEFUN (show_ipv6_ospf6, IP6_STR OSPF6_STR) { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_show(vty, ospf6); return CMD_SUCCESS; } @@ -944,7 +1057,10 @@ DEFUN (show_ipv6_ospf6_route, "Detailed information\n" "Summary of route table\n") { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); return CMD_SUCCESS; @@ -961,9 +1077,13 @@ DEFUN (show_ipv6_ospf6_route_match, "Display routes which match the specified route\n" "Display routes longer than the specified route\n") { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); + return CMD_SUCCESS; } @@ -979,7 +1099,10 @@ DEFUN (show_ipv6_ospf6_route_match_detail, "Detailed information\n" ) { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); return CMD_SUCCESS; @@ -1000,13 +1123,16 @@ DEFUN (show_ipv6_ospf6_route_type_detail, "Detailed information\n" ) { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); return CMD_SUCCESS; } -static void ospf6_stub_router_config_write(struct vty *vty) +static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6) { if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { vty_out(vty, " stub-router administrative\n"); @@ -1014,7 +1140,7 @@ static void ospf6_stub_router_config_write(struct vty *vty) return; } -static int ospf6_distance_config_write(struct vty *vty) +static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6) { struct route_node *rn; struct ospf6_distance *odistance; @@ -1037,67 +1163,67 @@ static int ospf6_distance_config_write(struct vty *vty) } for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn)) - if ((odistance = rn->info) != NULL) { - char buf[PREFIX_STRLEN]; - - vty_out(vty, " distance %u %s %s\n", - odistance->distance, - prefix2str(&rn->p, buf, sizeof(buf)), + if ((odistance = rn->info) != NULL) + vty_out(vty, " distance %u %pFX %s\n", + odistance->distance, &rn->p, odistance->access_list ? odistance->access_list : ""); - } return 0; } /* OSPF configuration write function. */ static int config_write_ospf6(struct vty *vty) { - char router_id[16]; struct listnode *j, *k; struct ospf6_area *oa; struct ospf6_interface *oi; + struct ospf6 *ospf6; + struct listnode *node, *nnode; /* OSPFv3 configuration. */ - if (ospf6 == NULL) + if (om6 == NULL) return CMD_SUCCESS; - inet_ntop(AF_INET, &ospf6->router_id_static, router_id, - sizeof(router_id)); - vty_out(vty, "router ospf6\n"); - if (ospf6->router_id_static != 0) - vty_out(vty, " ospf6 router-id %s\n", router_id); - - /* log-adjacency-changes flag print. */ - if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { - if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) - vty_out(vty, " log-adjacency-changes detail\n"); - else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES) - vty_out(vty, " log-adjacency-changes\n"); - } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) { - vty_out(vty, " no log-adjacency-changes\n"); - } + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + vty_out(vty, "router ospf6\n"); + if (ospf6->router_id_static != 0) + vty_out(vty, " ospf6 router-id %pI4\n", + &ospf6->router_id_static); + + /* log-adjacency-changes flag print. */ + if (CHECK_FLAG(ospf6->config_flags, + OSPF6_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(ospf6->config_flags, + OSPF6_LOG_ADJACENCY_DETAIL)) + vty_out(vty, " log-adjacency-changes detail\n"); + else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES) + vty_out(vty, " log-adjacency-changes\n"); + } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) { + vty_out(vty, " no log-adjacency-changes\n"); + } - if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH) - vty_out(vty, " auto-cost reference-bandwidth %d\n", - ospf6->ref_bandwidth); - - /* LSA timers print. */ - if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) - vty_out(vty, " timers lsa min-arrival %d\n", - ospf6->lsa_minarrival); - - ospf6_stub_router_config_write(vty); - ospf6_redistribute_config_write(vty); - ospf6_area_config_write(vty); - ospf6_spf_config_write(vty); - ospf6_distance_config_write(vty); - - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) { - for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi)) - vty_out(vty, " interface %s area %s\n", - oi->interface->name, oa->name); + if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH) + vty_out(vty, " auto-cost reference-bandwidth %d\n", + ospf6->ref_bandwidth); + + /* LSA timers print. */ + if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) + vty_out(vty, " timers lsa min-arrival %d\n", + ospf6->lsa_minarrival); + + ospf6_stub_router_config_write(vty, ospf6); + ospf6_redistribute_config_write(vty, ospf6); + ospf6_area_config_write(vty, ospf6); + ospf6_spf_config_write(vty, ospf6); + ospf6_distance_config_write(vty, ospf6); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi)) + vty_out(vty, " interface %s area %s\n", + oi->interface->name, oa->name); + } + vty_out(vty, "!\n"); } - vty_out(vty, "!\n"); return 0; } diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 806b4da1cf..52e1d7ee2b 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -23,9 +23,12 @@ #include "qobj.h" #include "routemap.h" - struct ospf6_master { + /* OSPFv3 instance. */ + struct list *ospf6; + /* OSPFv3 thread master. */ + struct thread_master *master; in_addr_t zebra_router_id; }; @@ -40,6 +43,8 @@ struct ospf6 { /* The relevant vrf_id */ vrf_id_t vrf_id; + char *name; /* VRF name */ + /* my router id */ in_addr_t router_id; @@ -92,11 +97,13 @@ struct ospf6 { struct timeval ts_spf_duration; /* Execution time of last SPF */ unsigned int last_spf_reason; /* Last SPF reason */ + int fd; /* Threads */ struct thread *t_spf_calc; /* SPF calculation timer. */ struct thread *t_ase_calc; /* ASE calculation timer. */ struct thread *maxage_remover; struct thread *t_distribute_update; /* Distirbute update timer. */ + struct thread *t_ospf6_receive; /* OSPF6 receive timer */ uint32_t ref_bandwidth; @@ -124,11 +131,17 @@ extern struct ospf6 *ospf6; extern struct ospf6_master *om6; /* prototypes */ -extern void ospf6_master_init(void); +extern void ospf6_master_init(struct thread_master *master); extern void ospf6_top_init(void); extern void ospf6_delete(struct ospf6 *o); -extern void ospf6_router_id_update(void); +extern void ospf6_router_id_update(struct ospf6 *ospf6); extern void ospf6_maxage_remove(struct ospf6 *o); +extern struct ospf6 *ospf6_instance_create(const char *name); +void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf); +void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf); +struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id); +struct ospf6 *ospf6_lookup_by_vrf_name(const char *name); +const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id); #endif /* OSPF6_TOP_H */ diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 62e0e149b8..b6c712176a 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -39,6 +39,7 @@ #include "ospf6_asbr.h" #include "ospf6_zebra.h" #include "ospf6d.h" +#include "ospf6_area.h" DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance") @@ -47,16 +48,49 @@ unsigned char conf_debug_ospf6_zebra = 0; /* information about zebra. */ struct zclient *zclient = NULL; +void ospf6_zebra_vrf_register(struct ospf6 *ospf6) +{ + if (!zclient || zclient->sock < 0 || !ospf6) + return; + + if (ospf6->vrf_id != VRF_UNKNOWN) { + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { + zlog_debug("%s: Register VRF %s id %u", __func__, + ospf6_vrf_id_to_name(ospf6->vrf_id), + ospf6->vrf_id); + } + zclient_send_reg_requests(zclient, ospf6->vrf_id); + } +} + +void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6) +{ + if (!zclient || zclient->sock < 0 || !ospf6) + return; + + if (ospf6->vrf_id != VRF_DEFAULT && ospf6->vrf_id != VRF_UNKNOWN) { + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { + zlog_debug("%s: De-Register VRF %s id %u to Zebra.", + __func__, + ospf6_vrf_id_to_name(ospf6->vrf_id), + ospf6->vrf_id); + } + /* Deregister for router-id, interfaces, + * redistributed routes. */ + zclient_send_dereg_requests(zclient, ospf6->vrf_id); + } +} + /* Router-id update message from zebra. */ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS) { struct prefix router_id; - struct ospf6 *o = ospf6; + struct ospf6 *o; zebra_router_id_update_read(zclient->ibuf, &router_id); om6->zebra_router_id = router_id.u.prefix4.s_addr; - + o = ospf6_lookup_by_vrf_id(vrf_id); if (o == NULL) return 0; @@ -69,7 +103,7 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS) INET_ADDRSTRLEN)); } - ospf6_router_id_update(); + ospf6_router_id_update(o); return 0; } @@ -99,7 +133,6 @@ void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id) static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS) { struct connected *c; - char buf[128]; c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf, vrf_id); @@ -107,11 +140,9 @@ static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS) return 0; if (IS_OSPF6_DEBUG_ZEBRA(RECV)) - zlog_debug("Zebra Interface address add: %s %5s %s/%d", + zlog_debug("Zebra Interface address add: %s %5s %pFX", c->ifp->name, prefix_family_str(c->address), - inet_ntop(c->address->family, &c->address->u.prefix, - buf, sizeof(buf)), - c->address->prefixlen); + c->address); if (c->address->family == AF_INET6) { ospf6_interface_state_update(c->ifp); @@ -123,7 +154,6 @@ static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS) static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS) { struct connected *c; - char buf[128]; c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf, vrf_id); @@ -131,11 +161,9 @@ static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS) return 0; if (IS_OSPF6_DEBUG_ZEBRA(RECV)) - zlog_debug("Zebra Interface address delete: %s %5s %s/%d", + zlog_debug("Zebra Interface address delete: %s %5s %pFX", c->ifp->name, prefix_family_str(c->address), - inet_ntop(c->address->family, &c->address->u.prefix, - buf, sizeof(buf)), - c->address->prefixlen); + c->address); if (c->address->family == AF_INET6) { ospf6_interface_connected_route_update(c->ifp); @@ -152,6 +180,9 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS) struct zapi_route api; unsigned long ifindex; struct in6_addr *nexthop; + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_id(vrf_id); if (ospf6 == NULL) return 0; @@ -169,25 +200,21 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS) ifindex = api.nexthops[0].ifindex; nexthop = &api.nexthops[0].gate.ipv6; - if (IS_OSPF6_DEBUG_ZEBRA(RECV)) { - char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128]; - - prefix2str(&api.prefix, prefixstr, sizeof(prefixstr)); - inet_ntop(AF_INET6, nexthop, nexthopstr, sizeof(nexthopstr)); - + if (IS_OSPF6_DEBUG_ZEBRA(RECV)) zlog_debug( - "Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %" ROUTE_TAG_PRI, + "Zebra Receive route %s: %s %pFX nexthop %pI6 ifindex %ld tag %" ROUTE_TAG_PRI, (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD ? "add" : "delete"), - zebra_route_string(api.type), prefixstr, nexthopstr, + zebra_route_string(api.type), &api.prefix, nexthop, ifindex, api.tag); - } if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix, - api.nexthop_num, nexthop, api.tag); + api.nexthop_num, nexthop, api.tag, + ospf6); else - ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix); + ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix, + ospf6); return 0; } @@ -222,19 +249,17 @@ DEFUN (show_zebra, #define ADD 0 #define REM 1 -static void ospf6_zebra_route_update(int type, struct ospf6_route *request) +static void ospf6_zebra_route_update(int type, struct ospf6_route *request, + struct ospf6 *ospf6) { struct zapi_route api; - char buf[PREFIX2STR_BUFFER]; int nhcount; int ret = 0; struct prefix *dest; - if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { - prefix2str(&request->prefix, buf, sizeof(buf)); - zlog_debug("Send %s route: %s", - (type == REM ? "remove" : "add"), buf); - } + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug("Send %s route: %pFX", + (type == REM ? "remove" : "add"), &request->prefix); if (zclient->sock < 0) { if (IS_OSPF6_DEBUG_ZEBRA(SEND)) @@ -295,8 +320,8 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) } SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); - api.distance = - ospf6_distance_apply((struct prefix_ipv6 *)dest, request); + api.distance = ospf6_distance_apply((struct prefix_ipv6 *)dest, request, + ospf6); if (type == REM) ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); @@ -312,20 +337,21 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) return; } -void ospf6_zebra_route_update_add(struct ospf6_route *request) +void ospf6_zebra_route_update_add(struct ospf6_route *request, + struct ospf6 *ospf6) { - ospf6_zebra_route_update(ADD, request); + ospf6_zebra_route_update(ADD, request, ospf6); } -void ospf6_zebra_route_update_remove(struct ospf6_route *request) +void ospf6_zebra_route_update_remove(struct ospf6_route *request, + struct ospf6 *ospf6) { - ospf6_zebra_route_update(REM, request); + ospf6_zebra_route_update(REM, request, ospf6); } -void ospf6_zebra_add_discard(struct ospf6_route *request) +void ospf6_zebra_add_discard(struct ospf6_route *request, struct ospf6 *ospf6) { struct zapi_route api; - char buf[INET6_ADDRSTRLEN]; struct prefix *dest = &request->prefix; if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { @@ -339,26 +365,21 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - zlog_debug("Zebra: Route add discard %s/%d", - inet_ntop(AF_INET6, &dest->u.prefix6, buf, - INET6_ADDRSTRLEN), - dest->prefixlen); + zlog_debug("Zebra: Route add discard %pFX", dest); SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); } else { if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug( - "Zebra: Blackhole route present already %s/%d", - inet_ntop(AF_INET6, &dest->u.prefix6, buf, - INET6_ADDRSTRLEN), - dest->prefixlen); + "Zebra: Blackhole route present already %pFX", + dest); } } -void ospf6_zebra_delete_discard(struct ospf6_route *request) +void ospf6_zebra_delete_discard(struct ospf6_route *request, + struct ospf6 *ospf6) { struct zapi_route api; - char buf[INET6_ADDRSTRLEN]; struct prefix *dest = &request->prefix; if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { @@ -372,19 +393,14 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_OSPF6_DEBUG_ZEBRA(SEND)) - zlog_debug("Zebra: Route delete discard %s/%d", - inet_ntop(AF_INET6, &dest->u.prefix6, buf, - INET6_ADDRSTRLEN), - dest->prefixlen); + zlog_debug("Zebra: Route delete discard %pFX", dest); UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED); } else { if (IS_OSPF6_DEBUG_ZEBRA(SEND)) zlog_debug( - "Zebra: Blackhole route already deleted %s/%d", - inet_ntop(AF_INET6, &dest->u.prefix6, buf, - INET6_ADDRSTRLEN), - dest->prefixlen); + "Zebra: Blackhole route already deleted %pFX", + dest); } } @@ -489,7 +505,8 @@ void ospf6_distance_reset(struct ospf6 *o) } } -uint8_t ospf6_distance_apply(struct prefix_ipv6 *p, struct ospf6_route * or) +uint8_t ospf6_distance_apply(struct prefix_ipv6 *p, struct ospf6_route * or, + struct ospf6 *ospf6) { struct ospf6 *o; diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h index d23268303a..5f340924b9 100644 --- a/ospf6d/ospf6_zebra.h +++ b/ospf6d/ospf6_zebra.h @@ -41,21 +41,26 @@ struct ospf6_distance { }; extern struct zclient *zclient; +struct ospf6; -extern void ospf6_zebra_route_update_add(struct ospf6_route *request); -extern void ospf6_zebra_route_update_remove(struct ospf6_route *request); +extern void ospf6_zebra_route_update_add(struct ospf6_route *request, + struct ospf6 *ospf6); +extern void ospf6_zebra_route_update_remove(struct ospf6_route *request, + struct ospf6 *ospf6); extern void ospf6_zebra_redistribute(int, vrf_id_t vrf_id); extern void ospf6_zebra_no_redistribute(int, vrf_id_t vrf_id); #define ospf6_zebra_is_redistribute(type, vrf_id) \ vrf_bitmap_check(zclient->redist[AFI_IP6][type], vrf_id) extern void ospf6_zebra_init(struct thread_master *); -extern void ospf6_zebra_add_discard(struct ospf6_route *request); -extern void ospf6_zebra_delete_discard(struct ospf6_route *request); +extern void ospf6_zebra_add_discard(struct ospf6_route *request, + struct ospf6 *ospf6); +extern void ospf6_zebra_delete_discard(struct ospf6_route *request, + struct ospf6 *ospf6); -struct ospf6; extern void ospf6_distance_reset(struct ospf6 *); -extern uint8_t ospf6_distance_apply(struct prefix_ipv6 *, struct ospf6_route *); +extern uint8_t ospf6_distance_apply(struct prefix_ipv6 *, struct ospf6_route *, + struct ospf6 *); extern int ospf6_distance_set(struct vty *, struct ospf6 *, const char *, const char *, const char *); @@ -64,5 +69,6 @@ extern int ospf6_distance_unset(struct vty *, struct ospf6 *, const char *, extern int config_write_ospf6_debug_zebra(struct vty *vty); extern void install_element_ospf6_debug_zebra(void); - +extern void ospf6_zebra_vrf_register(struct ospf6 *ospf6); +extern void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6); #endif /*OSPF6_ZEBRA_H*/ diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index 17e33902d9..fe519d0a26 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -27,6 +27,7 @@ #include "plist.h" #include "ospf6_proto.h" +#include "ospf6_top.h" #include "ospf6_network.h" #include "ospf6_lsa.h" #include "ospf6_lsdb.h" @@ -34,7 +35,6 @@ #include "ospf6_route.h" #include "ospf6_zebra.h" #include "ospf6_spf.h" -#include "ospf6_top.h" #include "ospf6_area.h" #include "ospf6_interface.h" #include "ospf6_neighbor.h" @@ -168,20 +168,22 @@ DEFUN (show_ipv6_ospf6_database, int idx_level = 4; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); level = parse_show_level(idx_level, argc, argv); - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, NULL, NULL, NULL, oa->lsdb); } - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -190,7 +192,7 @@ DEFUN (show_ipv6_ospf6_database, } vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, NULL, NULL, NULL, o->lsdb); + ospf6_lsdb_show(vty, level, NULL, NULL, NULL, ospf6->lsdb); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -221,19 +223,21 @@ DEFUN (show_ipv6_ospf6_database_type, int idx_level = 5; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); level = parse_show_level(idx_level, argc, argv); switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, NULL, NULL, oa->lsdb); @@ -241,7 +245,7 @@ DEFUN (show_ipv6_ospf6_database_type, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -253,7 +257,7 @@ DEFUN (show_ipv6_ospf6_database_type, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, NULL, NULL, o->lsdb); + ospf6_lsdb_show(vty, level, &type, NULL, NULL, ospf6->lsdb); break; default: @@ -283,24 +287,26 @@ DEFUN (show_ipv6_ospf6_database_id, int idx_level = 6; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint32_t id = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); if (argv[idx_ipv4]->type == IPV4_TKN) inet_pton(AF_INET, argv[idx_ipv4]->arg, &id); level = parse_show_level(idx_level, argc, argv); - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, NULL, &id, NULL, oa->lsdb); } - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -309,7 +315,7 @@ DEFUN (show_ipv6_ospf6_database_id, } vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, NULL, &id, NULL, o->lsdb); + ospf6_lsdb_show(vty, level, NULL, &id, NULL, ospf6->lsdb); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -334,21 +340,23 @@ DEFUN (show_ipv6_ospf6_database_router, int idx_level = 7; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router); level = parse_show_level(idx_level, argc, argv); - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb); } - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -358,7 +366,7 @@ DEFUN (show_ipv6_ospf6_database_router, } vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, ospf6->lsdb); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -379,15 +387,18 @@ DEFUN_HIDDEN (show_ipv6_ospf6_database_aggr_router, uint16_t type = htons(OSPF6_LSTYPE_ROUTER); int idx_ipv4 = 6; struct listnode *i; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_lsdb *lsdb; uint32_t adv_router = 0; + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); + inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router); - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { - if (adv_router == o->router_id) + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { + if (adv_router == ospf6->router_id) lsdb = oa->lsdb_self; else lsdb = oa->lsdb; @@ -435,13 +446,15 @@ DEFUN (show_ipv6_ospf6_database_type_id, int idx_level = 7; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t id = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); inet_pton(AF_INET, argv[idx_ipv4]->arg, &id); @@ -449,14 +462,14 @@ DEFUN (show_ipv6_ospf6_database_type_id, switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, &id, NULL, oa->lsdb); } break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -468,7 +481,7 @@ DEFUN (show_ipv6_ospf6_database_type_id, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, &id, NULL, o->lsdb); + ospf6_lsdb_show(vty, level, &type, &id, NULL, ospf6->lsdb); break; default: @@ -509,21 +522,22 @@ DEFUN (show_ipv6_ospf6_database_type_router, int idx_level = 7; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router); level = parse_show_level(idx_level, argc, argv); switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, oa->lsdb); @@ -531,7 +545,7 @@ DEFUN (show_ipv6_ospf6_database_type_router, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -543,7 +557,8 @@ DEFUN (show_ipv6_ospf6_database_type_router, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, + ospf6->lsdb); break; default: @@ -576,23 +591,24 @@ DEFUN (show_ipv6_ospf6_database_id_router, int idx_level = 7; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint32_t id = 0; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); level = parse_show_level(idx_level, argc, argv); - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb); } - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -602,7 +618,7 @@ DEFUN (show_ipv6_ospf6_database_id_router, } vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, ospf6->lsdb); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -629,23 +645,25 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id, int idx_level = 8; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint32_t id = 0; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); level = parse_show_level(idx_level, argc, argv); - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb); } - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -655,7 +673,7 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id, } vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, ospf6->lsdb); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -688,14 +706,16 @@ DEFUN (show_ipv6_ospf6_database_type_id_router, int idx_level = 7; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t id = 0; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); @@ -704,7 +724,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router, switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, &id, &adv_router, oa->lsdb); @@ -712,7 +732,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -724,7 +744,8 @@ DEFUN (show_ipv6_ospf6_database_type_id_router, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + ospf6->lsdb); break; default: @@ -766,14 +787,16 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id, int idx_level = 9; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t id = 0; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router); @@ -782,7 +805,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id, switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, &id, &adv_router, oa->lsdb); @@ -790,7 +813,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -802,7 +825,8 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + ospf6->lsdb); break; default: @@ -829,21 +853,22 @@ DEFUN (show_ipv6_ospf6_database_self_originated, int idx_level = 5; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); level = parse_show_level(idx_level, argc, argv); - adv_router = o->router_id; + adv_router = ospf6->router_id; - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb); } - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -853,7 +878,7 @@ DEFUN (show_ipv6_ospf6_database_self_originated, } vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, ospf6->lsdb); vty_out(vty, "\n"); return CMD_SUCCESS; @@ -885,22 +910,22 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated, int idx_level = 6; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t adv_router = 0; - OSPF6_CMD_CHECK_RUNNING(); - + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); level = parse_show_level(idx_level, argc, argv); - adv_router = o->router_id; + adv_router = ospf6->router_id; switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, oa->lsdb); @@ -908,7 +933,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -920,7 +945,8 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, + ospf6->lsdb); break; default: @@ -960,23 +986,23 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id, int idx_level = 8; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t adv_router = 0; uint32_t id = 0; - OSPF6_CMD_CHECK_RUNNING(); - + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); level = parse_show_level(idx_level, argc, argv); - adv_router = o->router_id; + adv_router = ospf6->router_id; switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, &id, &adv_router, oa->lsdb); @@ -984,7 +1010,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -996,7 +1022,8 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + ospf6->lsdb); break; default: @@ -1035,23 +1062,23 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated, int idx_level = 7; int level; struct listnode *i, *j; - struct ospf6 *o = ospf6; + struct ospf6 *ospf6; struct ospf6_area *oa; struct ospf6_interface *oi; uint16_t type = 0; uint32_t adv_router = 0; uint32_t id = 0; - OSPF6_CMD_CHECK_RUNNING(); - + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); type = parse_type_spec(idx_lsa, argc, argv); inet_pton(AF_INET, argv[idx_ls_id]->arg, &id); level = parse_show_level(idx_level, argc, argv); - adv_router = o->router_id; + adv_router = ospf6->router_id; switch (OSPF6_LSA_SCOPE(type)) { case OSPF6_SCOPE_AREA: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name); ospf6_lsdb_show(vty, level, &type, &id, &adv_router, oa->lsdb); @@ -1059,7 +1086,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated, break; case OSPF6_SCOPE_LINKLOCAL: - for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) { + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) { for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) { vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name, oa->name); @@ -1071,7 +1098,8 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated, case OSPF6_SCOPE_AS: vty_out(vty, AS_LSDB_TITLE_FORMAT); - ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb); + ospf6_lsdb_show(vty, level, &type, &id, &adv_router, + ospf6->lsdb); break; default: @@ -1097,9 +1125,11 @@ DEFUN (show_ipv6_ospf6_border_routers, uint32_t adv_router; struct ospf6_route *ro; struct prefix prefix; + struct ospf6 *ospf6 = NULL; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); if (argc == 5) { if (strmatch(argv[idx_ipv4]->text, "detail")) { for (ro = ospf6_route_head(ospf6->brouter_table); ro; @@ -1148,9 +1178,10 @@ DEFUN (show_ipv6_ospf6_linkstate, int idx_ipv4 = 5; struct listnode *node; struct ospf6_area *oa; + struct ospf6 *ospf6 = NULL; - OSPF6_CMD_CHECK_RUNNING(); - + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { vty_out(vty, "\n SPF Result in Area %s\n\n", oa->name); ospf6_linkstate_table_show(vty, idx_ipv4, argc, argv, @@ -1174,8 +1205,10 @@ DEFUN (show_ipv6_ospf6_linkstate_detail, int idx_detail = 4; struct listnode *node; struct ospf6_area *oa; + struct ospf6 *ospf6 = NULL; - OSPF6_CMD_CHECK_RUNNING(); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { vty_out(vty, "\n SPF Result in Area %s\n\n", oa->name); @@ -1202,8 +1235,10 @@ static void ospf6_plist_del(struct prefix_list *plist) } /* Install ospf related commands. */ -void ospf6_init(void) +void ospf6_init(struct thread_master *master) { + struct ospf6 *ospf6; + ospf6_top_init(); ospf6_area_init(); ospf6_interface_init(); @@ -1236,7 +1271,7 @@ void ospf6_init(void) install_element_ospf6_clear_interface(); - install_element(VIEW_NODE, &show_debugging_ospf6_cmd); + install_element(ENABLE_NODE, &show_debugging_ospf6_cmd); install_element(VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd); @@ -1268,17 +1303,7 @@ void ospf6_init(void) &show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd); install_element(VIEW_NODE, &show_ipv6_ospf6_database_aggr_router_cmd); - /* Make ospf protocol socket. */ - ospf6_serv_sock(); - thread_add_read(master, ospf6_receive, NULL, ospf6_sock, NULL); -} - -void ospf6_clean(void) -{ - if (!ospf6) - return; - if (ospf6->route_table) - ospf6_route_remove_all(ospf6->route_table); - if (ospf6->brouter_table) - ospf6_route_remove_all(ospf6->brouter_table); + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + if (ospf6 == NULL) + ospf6_instance_create(VRF_DEFAULT_NAME); } diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h index 36f3c2233f..d85ff40f32 100644 --- a/ospf6d/ospf6d.h +++ b/ospf6d/ospf6d.h @@ -88,7 +88,7 @@ extern struct thread_master *master; #define OSPF6_ROUTER_ID_STR "Specify Router-ID\n" #define OSPF6_LS_ID_STR "Specify Link State ID\n" -#define OSPF6_CMD_CHECK_RUNNING() \ +#define OSPF6_CMD_CHECK_RUNNING(ospf6) \ if (ospf6 == NULL) { \ vty_out(vty, "OSPFv3 is not running\n"); \ return CMD_SUCCESS; \ @@ -100,6 +100,6 @@ extern struct zebra_privs_t ospf6d_privs; extern struct route_node *route_prev(struct route_node *node); extern void ospf6_debug(void); -extern void ospf6_init(void); +extern void ospf6_init(struct thread_master *master); #endif /* OSPF6D_H */ diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c index da390e3c70..d4f0dc953c 100644 --- a/ospfclient/ospf_apiclient.c +++ b/ospfclient/ospf_apiclient.c @@ -49,6 +49,7 @@ #include "ospfd/ospf_route.h" #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_api.h" +#include "ospfd/ospf_errors.h" #include "ospf_apiclient.h" @@ -564,15 +565,25 @@ static void ospf_apiclient_handle_lsa_update(struct ospf_apiclient *oclient, { struct msg_lsa_change_notify *cn; struct lsa_header *lsa; - int lsalen; + void *p; + uint16_t lsalen; cn = (struct msg_lsa_change_notify *)STREAM_DATA(msg->s); /* Extract LSA from message */ lsalen = ntohs(cn->data.length); - lsa = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); + if (lsalen > OSPF_MAX_LSA_SIZE) { + flog_warn( + EC_OSPF_LARGE_LSA, + "%s: message received size: %d is greater than a LSA size: %d", + __func__, lsalen, OSPF_MAX_LSA_SIZE); + return; + } + + p = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); - memcpy(lsa, &(cn->data), lsalen); + memcpy(p, &(cn->data), lsalen); + lsa = p; /* Invoke registered update callback function */ if (oclient->update_notify) { @@ -581,7 +592,7 @@ static void ospf_apiclient_handle_lsa_update(struct ospf_apiclient *oclient, } /* free memory allocated by ospf apiclient library */ - XFREE(MTYPE_OSPF_APICLIENT, lsa); + XFREE(MTYPE_OSPF_APICLIENT, p); } static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient, @@ -589,15 +600,25 @@ static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient, { struct msg_lsa_change_notify *cn; struct lsa_header *lsa; - int lsalen; + void *p; + uint16_t lsalen; cn = (struct msg_lsa_change_notify *)STREAM_DATA(msg->s); /* Extract LSA from message */ lsalen = ntohs(cn->data.length); - lsa = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); + if (lsalen > OSPF_MAX_LSA_SIZE) { + flog_warn( + EC_OSPF_LARGE_LSA, + "%s: message received size: %d is greater than a LSA size: %d", + __func__, lsalen, OSPF_MAX_LSA_SIZE); + return; + } + + p = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen); - memcpy(lsa, &(cn->data), lsalen); + memcpy(p, &(cn->data), lsalen); + lsa = p; /* Invoke registered update callback function */ if (oclient->delete_notify) { @@ -606,7 +627,7 @@ static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient, } /* free memory allocated by ospf apiclient library */ - XFREE(MTYPE_OSPF_APICLIENT, lsa); + XFREE(MTYPE_OSPF_APICLIENT, p); } static void ospf_apiclient_msghandle(struct ospf_apiclient *oclient, diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c index f5f994517e..3ca1e132bd 100644 --- a/ospfclient/ospfclient.c +++ b/ospfclient/ospfclient.c @@ -30,6 +30,7 @@ #include "prefix.h" /* needed by ospf_asbr.h */ #include "privs.h" #include "log.h" +#include "lib/printfrr.h" /* work around gcc bug 69981, disable MTYPEs in libospf */ #define _QUAGGA_OSPF_MEMORY_H @@ -186,8 +187,8 @@ static void lsa_update_callback(struct in_addr ifaddr, struct in_addr area_id, struct lsa_header *lsa) { printf("lsa_update_callback: "); - printf("ifaddr: %s ", inet_ntoa(ifaddr)); - printf("area: %s\n", inet_ntoa(area_id)); + printfrr("ifaddr: %pI4 ", &ifaddr); + printfrr("area: %pI4\n", &area_id); printf("is_self_origin: %u\n", is_self_originated); /* It is important to note that lsa_header does indeed include the @@ -211,8 +212,8 @@ static void lsa_delete_callback(struct in_addr ifaddr, struct in_addr area_id, struct lsa_header *lsa) { printf("lsa_delete_callback: "); - printf("ifaddr: %s ", inet_ntoa(ifaddr)); - printf("area: %s\n", inet_ntoa(area_id)); + printf("ifaddr: %pI4 ", &ifaddr); + printf("area: %pI4\n", &area_id); printf("is_self_origin: %u\n", is_self_originated); ospf_lsa_header_dump(lsa); @@ -221,8 +222,8 @@ static void lsa_delete_callback(struct in_addr ifaddr, struct in_addr area_id, static void ready_callback(uint8_t lsa_type, uint8_t opaque_type, struct in_addr addr) { - printf("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n", - lsa_type, opaque_type, inet_ntoa(addr)); + printfrr("ready_callback: lsa_type: %d opaque_type: %d addr=%pI4\n", + lsa_type, opaque_type, &addr); /* Schedule opaque LSA originate in 5 secs */ thread_add_timer(master, lsa_inject, oclient, 5, NULL); @@ -236,20 +237,20 @@ static void ready_callback(uint8_t lsa_type, uint8_t opaque_type, static void new_if_callback(struct in_addr ifaddr, struct in_addr area_id) { - printf("new_if_callback: ifaddr: %s ", inet_ntoa(ifaddr)); - printf("area_id: %s\n", inet_ntoa(area_id)); + printfrr("new_if_callback: ifaddr: %pI4 ", &ifaddr); + printfrr("area_id: %pI4\n", &area_id); } static void del_if_callback(struct in_addr ifaddr) { - printf("new_if_callback: ifaddr: %s\n ", inet_ntoa(ifaddr)); + printfrr("new_if_callback: ifaddr: %pI4\n ", &ifaddr); } static void ism_change_callback(struct in_addr ifaddr, struct in_addr area_id, uint8_t state) { - printf("ism_change: ifaddr: %s ", inet_ntoa(ifaddr)); - printf("area_id: %s\n", inet_ntoa(area_id)); + printfrr("ism_change: ifaddr: %pI4 ", &ifaddr); + printfrr("area_id: %pI4\n", &area_id); printf("state: %d [%s]\n", state, lookup_msg(ospf_ism_state_msg, state, NULL)); } @@ -257,9 +258,9 @@ static void ism_change_callback(struct in_addr ifaddr, struct in_addr area_id, static void nsm_change_callback(struct in_addr ifaddr, struct in_addr nbraddr, struct in_addr router_id, uint8_t state) { - printf("nsm_change: ifaddr: %s ", inet_ntoa(ifaddr)); - printf("nbraddr: %s\n", inet_ntoa(nbraddr)); - printf("router_id: %s\n", inet_ntoa(router_id)); + printfrr("nsm_change: ifaddr: %pI4 ", &ifaddr); + printfrr("nbraddr: %pI4\n", &nbraddr); + printfrr("router_id: %pI4\n", &router_id); printf("state: %d [%s]\n", state, lookup_msg(ospf_nsm_state_msg, state, NULL)); } diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 2131c8ee9d..634418ec5a 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -331,6 +331,7 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area) struct ospf_lsa *lsa; struct router_lsa *rlsa; struct in_addr *best = NULL; + char buf[PREFIX_STRLEN]; LSDB_LOOP (ROUTER_LSDB(area), rn, lsa) { /* sanity checks */ @@ -348,8 +349,8 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area) if (IS_ROUTER_LSA_NT(rlsa)) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_nssa_am_elected: router %s asserts Nt", - inet_ntoa(lsa->data->id)); + "ospf_abr_nssa_am_elected: router %pI4 asserts Nt", + &lsa->data->id); return 0; } @@ -363,7 +364,8 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area) if (IS_DEBUG_OSPF_NSSA) zlog_debug( "ospf_abr_nssa_am_elected: best electable ABR is: %s", - (best) ? inet_ntoa(*best) : "<none>"); + (best) ? inet_ntop(AF_INET, best, buf, sizeof(buf)) : + "<none>"); if (best == NULL) return 1; @@ -390,8 +392,8 @@ static void ospf_abr_nssa_check_status(struct ospf *ospf) if (IS_DEBUG_OSPF(nssa, NSSA)) zlog_debug( - "ospf_abr_nssa_check_status: checking area %s", - inet_ntoa(area->area_id)); + "ospf_abr_nssa_check_status: checking area %pI4", + &area->area_id); if (!IS_OSPF_ABR(area->ospf)) { if (IS_DEBUG_OSPF(nssa, NSSA)) @@ -615,15 +617,15 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa) if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation", - inet_ntoa(lsa->data->id)); + "ospf_abr_translate_nssa(): LSA Id %pI4, P-bit off, NO Translation", + &lsa->data->id); return 1; } if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5", - inet_ntoa(lsa->data->id)); + "ospf_abr_translate_nssa(): LSA Id %pI4, TRANSLATING 7 to 5", + &lsa->data->id); ext7 = (struct as_external_lsa *)(lsa->data); p.prefix = lsa->data->id; @@ -632,37 +634,41 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa) if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): LSA Id %s, Forward address is 0, NO Translation", - inet_ntoa(lsa->data->id)); + "ospf_abr_translate_nssa(): LSA Id %pI4, Forward address is 0, NO Translation", + &lsa->data->id); return 1; } /* try find existing AS-External LSA for this prefix */ - old = ospf_external_info_find_lsa(area->ospf, &p); - if (old) { - /* Do not continue if type 5 LSA not approved */ - if (!CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) { + if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) { + /* if type-7 is removed, remove old translated type-5 lsa */ + if (old) { + UNSET_FLAG(old->flags, OSPF_LSA_APPROVED); if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): LSA Id %s type 5 is not approved", - inet_ntoa(old->data->id)); - return 1; + "ospf_abr_translate_nssa(): remove old translated LSA id %pI4", + &old->data->id); } + /* if type-7 is removed and type-5 does not exist, do not + * originate */ + return 1; + } + if (old && CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): found old translated LSA Id %s, refreshing", - inet_ntoa(old->data->id)); + "ospf_abr_translate_nssa(): found old translated LSA Id %pI4, refreshing", + &old->data->id); /* refresh */ new = ospf_translated_nssa_refresh(area->ospf, lsa, old); if (!new) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): could not refresh translated LSA Id %s", - inet_ntoa(old->data->id)); + "ospf_abr_translate_nssa(): could not refresh translated LSA Id %pI4", + &old->data->id); } } else { /* no existing external route for this LSA Id @@ -672,8 +678,8 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa) if (ospf_translated_nssa_originate(area->ospf, lsa) == NULL) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_translate_nssa(): Could not translate Type-7 for %s to Type-5", - inet_ntoa(lsa->data->id)); + "ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5", + &lsa->data->id); return 1; } } @@ -736,14 +742,10 @@ void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost, lsa = ospf_lsa_refresh(area->ospf, old); if (!lsa) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str((struct prefix *)p, buf, - sizeof(buf)); flog_warn(EC_OSPF_LSA_MISSING, - "%s: Could not refresh %s to %s", - __func__, buf, - inet_ntoa(area->area_id)); + "%s: Could not refresh %pFX to %pI4", + __func__, (struct prefix *)p, + &area->area_id); return; } @@ -758,12 +760,10 @@ void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost, /* This will flood through area. */ if (!lsa) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str((struct prefix *)p, buf, sizeof(buf)); flog_warn(EC_OSPF_LSA_MISSING, - "%s: Could not originate %s to %s", __func__, - buf, inet_ntoa(area->area_id)); + "%s: Could not originate %pFX to %pi4", + __func__, (struct prefix *)p, + &area->area_id); return; } @@ -856,8 +856,8 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p, for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_network(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_network(): looking at area %pI4", + &area->area_id); if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) continue; @@ -868,16 +868,16 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p, if (!ospf_abr_should_accept(p, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_network(): prefix %s/%d was denied by import-list", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_abr_announce_network(): prefix %pFX was denied by import-list", + p); continue; } if (!ospf_abr_plist_in_check(area, or, p)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_network(): prefix %s/%d was denied by prefix-list", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_abr_announce_network(): prefix %pFX was denied by prefix-list", + p); continue; } @@ -885,16 +885,16 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p, && area->no_summary) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_network(): area %s is stub and no_summary", - inet_ntoa(area->area_id)); + "ospf_abr_announce_network(): area %pI4 is stub and no_summary", + &area->area_id); continue; } if (or->path_type == OSPF_PATH_INTER_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_network(): this is inter-area route to %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_abr_announce_network(): this is inter-area route to %pFX", + p); if (!OSPF_IS_AREA_BACKBONE(area)) ospf_abr_announce_network_to_area(p, or->cost, @@ -904,8 +904,8 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p, if (or->path_type == OSPF_PATH_INTRA_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_network(): this is intra-area route to %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_abr_announce_network(): this is intra-area route to %pFX", + p); if ((range = ospf_area_range_match(or_area, p)) && !ospf_area_is_transit(area)) ospf_abr_update_aggregate(range, or, area); @@ -964,8 +964,8 @@ static void ospf_abr_process_nssa_translates(struct ospf *ospf) if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_process_nssa_translates(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_process_nssa_translates(): looking at area %pI4", + &area->area_id); LSDB_LOOP (NSSA_LSDB(area), rn, lsa) ospf_abr_translate_nssa(area, lsa); @@ -993,15 +993,15 @@ static void ospf_abr_process_network_rt(struct ospf *ospf, or->u.std.area_id))) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_process_network_rt(): area %s no longer exists", - inet_ntoa(or->u.std.area_id)); + "ospf_abr_process_network_rt(): area %pI4 no longer exists", + &or->u.std.area_id); continue; } if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_process_network_rt(): this is a route to %s/%d", - inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); + "ospf_abr_process_network_rt(): this is a route to %pFX", + &rn->p); if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( @@ -1114,12 +1114,10 @@ static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, uint32_t cost, } else lsa = ospf_summary_asbr_lsa_originate(p, cost, area); if (!lsa) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str((struct prefix *)p, buf, sizeof(buf)); flog_warn(EC_OSPF_LSA_MISSING, - "%s: Could not refresh/originate %s to %s", - __func__, buf, inet_ntoa(area->area_id)); + "%s: Could not refresh/originate %pFX to %pI4", + __func__, (struct prefix *)p, + &area->area_id); return; } @@ -1153,8 +1151,8 @@ static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p, for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_rtr(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_rtr(): looking at area %pI4", + &area->area_id); if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id)) continue; @@ -1166,24 +1164,24 @@ static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p, if (or->u.std.external_routing == OSPF_AREA_NSSA) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_rtr(): do not generate LSA Type-4 %s from NSSA", - inet_ntoa(p->prefix)); + "ospf_abr_announce_rtr(): do not generate LSA Type-4 %pI4 from NSSA", + &p->prefix); continue; } if (area->external_routing != OSPF_AREA_DEFAULT) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_rtr(): area %s doesn't support external routing", - inet_ntoa(area->area_id)); + "ospf_abr_announce_rtr(): area %pI4 doesn't support external routing", + &area->area_id); continue; } if (or->path_type == OSPF_PATH_INTER_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_rtr(): this is inter-area route to %s", - inet_ntoa(p->prefix)); + "ospf_abr_announce_rtr(): this is inter-area route to %pI4", + &p->prefix); if (!OSPF_IS_AREA_BACKBONE(area)) ospf_abr_announce_rtr_to_area(p, or->cost, area); @@ -1192,8 +1190,8 @@ static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p, if (or->path_type == OSPF_PATH_INTRA_AREA) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_rtr(): this is intra-area route to %s", - inet_ntoa(p->prefix)); + "ospf_abr_announce_rtr(): this is intra-area route to %pI4", + &p->prefix); ospf_abr_announce_rtr_to_area(p, or->cost, area); } } @@ -1224,16 +1222,16 @@ static void ospf_abr_process_router_rt(struct ospf *ospf, if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_process_router_rt(): this is a route to %s", - inet_ntoa(rn->p.u.prefix4)); + "ospf_abr_process_router_rt(): this is a route to %pI4", + &rn->p.u.prefix4); for (ALL_LIST_ELEMENTS(l, node, nnode, or)) { if (!ospf_area_lookup_by_area_id(ospf, or->u.std.area_id)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_process_router_rt(): area %s no longer exists", - inet_ntoa(or->u.std.area_id)); + "ospf_abr_process_router_rt(): area %pI4 no longer exists", + &or->u.std.area_id); continue; } @@ -1314,8 +1312,8 @@ ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */ UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_unapprove_translates(): approved unset on link id %s", - inet_ntoa(lsa->data->id)); + "ospf_abr_unapprove_translates(): approved unset on link id %pI4", + &lsa->data->id); } if (IS_DEBUG_OSPF_NSSA) @@ -1335,14 +1333,14 @@ static void ospf_abr_unapprove_summaries(struct ospf *ospf) for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_unapprove_summaries(): considering area %s", - inet_ntoa(area->area_id)); + "ospf_abr_unapprove_summaries(): considering area %pI4", + &area->area_id); LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa) if (ospf_lsa_is_self_originated(ospf, lsa)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_unapprove_summaries(): approved unset on summary link id %s", - inet_ntoa(lsa->data->id)); + "ospf_abr_unapprove_summaries(): approved unset on summary link id %pI4", + &lsa->data->id); UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); } @@ -1350,8 +1348,8 @@ static void ospf_abr_unapprove_summaries(struct ospf *ospf) if (ospf_lsa_is_self_originated(ospf, lsa)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_unapprove_summaries(): approved unset on asbr-summary link id %s", - inet_ntoa(lsa->data->id)); + "ospf_abr_unapprove_summaries(): approved unset on asbr-summary link id %pI4", + &lsa->data->id); UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED); } } @@ -1396,8 +1394,8 @@ static void ospf_abr_announce_aggregates(struct ospf *ospf) for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_aggregates(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_aggregates(): looking at area %pI4", + &area->area_id); for (rn = route_top(area->ranges); rn; rn = route_next(rn)) if ((range = rn->info)) { @@ -1415,9 +1413,8 @@ static void ospf_abr_announce_aggregates(struct ospf *ospf) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_aggregates(): this is range: %s/%d", - inet_ntoa(p.u.prefix4), - p.prefixlen); + "ospf_abr_announce_aggregates(): this is range: %pFX", + &p); if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) { @@ -1486,8 +1483,8 @@ ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */ if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_send_nssa_aggregates(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_send_nssa_aggregates(): looking at area %pI4", + &area->area_id); for (rn = route_top(area->ranges); rn; rn = route_next(rn)) { if (rn->info == NULL) @@ -1509,8 +1506,8 @@ ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */ if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_abr_send_nssa_aggregates(): this is range: %s/%d", - inet_ntoa(p.prefix), p.prefixlen); + "ospf_abr_send_nssa_aggregates(): this is range: %pFX", + &p); if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) { @@ -1557,8 +1554,8 @@ static void ospf_abr_announce_stub_defaults(struct ospf *ospf) for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_stub_defaults(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_stub_defaults(): looking at area %pI4", + &area->area_id); if ((area->external_routing != OSPF_AREA_STUB) && (area->external_routing != OSPF_AREA_NSSA)) @@ -1569,8 +1566,8 @@ static void ospf_abr_announce_stub_defaults(struct ospf *ospf) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4", + &area->area_id); ospf_abr_announce_network_to_area(&p, area->default_cost, area); } @@ -1584,8 +1581,8 @@ static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf, if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT) && !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) { zlog_info( - "ospf_abr_remove_unapproved_translates(): removing unapproved translates, ID: %s", - inet_ntoa(lsa->data->id)); + "ospf_abr_remove_unapproved_translates(): removing unapproved translates, ID: %pI4", + &lsa->data->id); /* FLUSH THROUGHOUT AS */ ospf_lsa_flush_as(ospf, lsa); @@ -1625,8 +1622,8 @@ static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf) for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_remove_unapproved_summaries(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_abr_remove_unapproved_summaries(): looking at area %pI4", + &area->area_id); LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa) if (ospf_lsa_is_self_originated(ospf, lsa)) diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 73ce606504..c01ecdd1d4 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -317,21 +317,12 @@ void ospf_apiserver_free(struct ospf_apiserver *apiserv) struct listnode *node; /* Cancel read and write threads. */ - if (apiserv->t_sync_read) { - thread_cancel(apiserv->t_sync_read); - } + thread_cancel(&apiserv->t_sync_read); #ifdef USE_ASYNC_READ - if (apiserv->t_async_read) { - thread_cancel(apiserv->t_async_read); - } + thread_cancel(&apiserv->t_async_read); #endif /* USE_ASYNC_READ */ - if (apiserv->t_sync_write) { - thread_cancel(apiserv->t_sync_write); - } - - if (apiserv->t_async_write) { - thread_cancel(apiserv->t_async_write); - } + thread_cancel(&apiserv->t_sync_write); + thread_cancel(&apiserv->t_async_write); /* Unregister all opaque types that application registered and flush opaque LSAs if still in LSDB. */ @@ -387,8 +378,8 @@ int ospf_apiserver_read(struct thread *thread) apiserv->t_sync_read = NULL; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("API: ospf_apiserver_read: Peer: %s/%u", - inet_ntoa(apiserv->peer_sync.sin_addr), + zlog_debug("API: ospf_apiserver_read: Peer: %pI4/%u", + &apiserv->peer_sync.sin_addr, ntohs(apiserv->peer_sync.sin_port)); } #ifdef USE_ASYNC_READ @@ -397,8 +388,8 @@ int ospf_apiserver_read(struct thread *thread) apiserv->t_async_read = NULL; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("API: ospf_apiserver_read: Peer: %s/%u", - inet_ntoa(apiserv->peer_async.sin_addr), + zlog_debug("API: ospf_apiserver_read: Peer: %pI4/%u", + &apiserv->peer_async.sin_addr, ntohs(apiserv->peer_async.sin_port)); } #endif /* USE_ASYNC_READ */ @@ -455,8 +446,8 @@ int ospf_apiserver_sync_write(struct thread *thread) } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("API: ospf_apiserver_sync_write: Peer: %s/%u", - inet_ntoa(apiserv->peer_sync.sin_addr), + zlog_debug("API: ospf_apiserver_sync_write: Peer: %pI4/%u", + &apiserv->peer_sync.sin_addr, ntohs(apiserv->peer_sync.sin_port)); /* Check whether there is really a message in the fifo. */ @@ -519,8 +510,8 @@ int ospf_apiserver_async_write(struct thread *thread) } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("API: ospf_apiserver_async_write: Peer: %s/%u", - inet_ntoa(apiserv->peer_async.sin_addr), + zlog_debug("API: ospf_apiserver_async_write: Peer: %pI4/%u", + &apiserv->peer_async.sin_addr, ntohs(apiserv->peer_async.sin_port)); /* Check whether there is really a message in the fifo. */ @@ -645,8 +636,8 @@ int ospf_apiserver_accept(struct thread *thread) } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("API: ospf_apiserver_accept: New peer: %s/%u", - inet_ntoa(peer_sync.sin_addr), + zlog_debug("API: ospf_apiserver_accept: New peer: %pI4/%u", + &peer_sync.sin_addr, ntohs(peer_sync.sin_port)); /* Create new socket for asynchronous messages. */ @@ -657,8 +648,8 @@ int ospf_apiserver_accept(struct thread *thread) */ if (ntohs(peer_async.sin_port) == ospf_apiserver_getport()) { zlog_warn( - "API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?", - inet_ntoa(peer_async.sin_addr), + "API: ospf_apiserver_accept: Peer(%pI4/%u): Invalid async port number?", + &peer_async.sin_addr, ntohs(peer_async.sin_port)); close(new_sync_sock); return -1; @@ -1409,8 +1400,8 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area, options |= OSPF_OPTION_O; /* Don't forget to set option bit */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Creating an Opaque-LSA instance", - protolsa->type, inet_ntoa(protolsa->id)); + zlog_debug("LSA[Type%d:%pI4]: Creating an Opaque-LSA instance", + protolsa->type, &protolsa->id); } /* Set opaque-LSA header fields. */ @@ -1510,8 +1501,8 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv, case OSPF_OPAQUE_LINK_LSA: oi = ospf_apiserver_if_lookup_by_addr(omsg->ifaddr); if (!oi) { - zlog_warn("apiserver_originate: unknown interface %s", - inet_ntoa(omsg->ifaddr)); + zlog_warn("apiserver_originate: unknown interface %pI4", + &omsg->ifaddr); rc = OSPF_API_NOSUCHINTERFACE; goto out; } @@ -1521,8 +1512,8 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv, case OSPF_OPAQUE_AREA_LSA: area = ospf_area_lookup_by_area_id(ospf, omsg->area_id); if (!area) { - zlog_warn("apiserver_originate: unknown area %s", - inet_ntoa(omsg->area_id)); + zlog_warn("apiserver_originate: unknown area %pI4", + &omsg->area_id); rc = OSPF_API_NOSUCHAREA; goto out; } @@ -1791,8 +1782,8 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa) /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Refresh Opaque LSA", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: Refresh Opaque LSA", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1829,8 +1820,8 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv, case OSPF_OPAQUE_AREA_LSA: area = ospf_area_lookup_by_area_id(ospf, dmsg->area_id); if (!area) { - zlog_warn("ospf_apiserver_lsa_delete: unknown area %s", - inet_ntoa(dmsg->area_id)); + zlog_warn("ospf_apiserver_lsa_delete: unknown area %pI4", + &dmsg->area_id); rc = OSPF_API_NOSUCHAREA; goto out; } @@ -1872,8 +1863,8 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv, old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id); if (!old) { zlog_warn( - "ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB", - dmsg->lsa_type, inet_ntoa(id)); + "ospf_apiserver_lsa_delete: LSA[Type%d:%pI4] not in LSDB", + dmsg->lsa_type, &id); rc = OSPF_API_NOSUCHLSA; goto out; } diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 8fb6402c7e..94fa1b5b44 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -42,7 +42,7 @@ #include "ospfd/ospf_route.h" #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_dump.h" - +#include "ospfd/ospf_errors.h" /* Remove external route. */ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p) @@ -53,8 +53,7 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p) rn = route_node_lookup(ospf->old_external_route, (struct prefix *)p); if (rn) if ((or = rn->info)) { - zlog_info("Route[%s/%d]: external path deleted", - inet_ntoa(p->prefix), p->prefixlen); + zlog_info("Route[%pFX]: external path deleted", p); /* Remove route from zebra. */ if (or->type == OSPF_DESTINATION_NETWORK) @@ -69,8 +68,7 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p) return; } - zlog_info("Route[%s/%d]: no such external path", inet_ntoa(p->prefix), - p->prefixlen); + zlog_info("Route[%pFX]: no such external path", p); } /* Add an External info for AS-external-LSA. */ @@ -82,6 +80,7 @@ struct external_info *ospf_external_info_new(uint8_t type, new = XCALLOC(MTYPE_OSPF_EXTERNAL_INFO, sizeof(struct external_info)); new->type = type; new->instance = instance; + new->to_be_processed = 0; ospf_reset_route_map_set_values(&new->route_map_set); return new; @@ -133,13 +132,12 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance, } inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, - INET6_BUFSIZ); + sizeof(inetbuf)); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "Redistribute[%s][%d][%u]: %s/%d discarding old info with NH %s.", + "Redistribute[%s][%d][%u]: %pFX discarding old info with NH %s.", ospf_redist_string(type), instance, - ospf->vrf_id, inet_ntoa(p.prefix), - p.prefixlen, inetbuf); + ospf->vrf_id, &p, inetbuf); XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info); } @@ -150,6 +148,7 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance, new->nexthop = nexthop; new->tag = tag; new->orig_tag = tag; + new->aggr_route = NULL; /* we don't unlock rn from the get() because we're attaching the info */ if (rn) @@ -157,11 +156,11 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance, if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, - INET6_BUFSIZ); + sizeof(inetbuf)); zlog_debug( - "Redistribute[%s][%u]: %s/%d external info created, with NH %s", + "Redistribute[%s][%u]: %pFX external info created, with NH %s", ospf_redist_string(type), ospf->vrf_id, - inet_ntoa(p.prefix), p.prefixlen, inetbuf); + &p, inetbuf); } return new; } @@ -292,8 +291,9 @@ void ospf_asbr_nssa_redist_task(struct ospf *ospf) continue; for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - ospf_external_lsa_refresh_type( - ospf, type, red->instance, LSA_REFRESH_FORCE); + ospf_external_lsa_refresh_type(ospf, type, + red->instance, + LSA_REFRESH_IF_CHANGED); } ospf_external_lsa_refresh_default(ospf); @@ -329,3 +329,890 @@ void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type, rn->info = NULL; } } + +/* External Route Aggregator Handlers */ +bool is_valid_summary_addr(struct prefix_ipv4 *p) +{ + /* Default prefix validation*/ + if (p->prefix.s_addr == INADDR_ANY) + return false; + + /*Host route shouldn't be configured as summary addres*/ + if (p->prefixlen == IPV4_MAX_PREFIXLEN) + return false; + + return true; +} +void ospf_asbr_external_aggregator_init(struct ospf *instance) +{ + instance->rt_aggr_tbl = route_table_init(); + + instance->t_external_aggr = NULL; + + instance->aggr_action = 0; + + instance->aggr_delay_interval = OSPF_EXTL_AGGR_DEFAULT_DELAY; +} + +static unsigned int ospf_external_rt_hash_key(const void *data) +{ + const struct external_info *ei = data; + unsigned int key = 0; + + key = prefix_hash_key(&ei->p); + return key; +} + +static bool ospf_external_rt_hash_cmp(const void *d1, const void *d2) +{ + const struct external_info *ei1 = d1; + const struct external_info *ei2 = d2; + + return prefix_same((struct prefix *)&ei1->p, (struct prefix *)&ei2->p); +} + +static struct ospf_external_aggr_rt * +ospf_external_aggregator_new(struct prefix_ipv4 *p) +{ + struct ospf_external_aggr_rt *aggr; + + aggr = (struct ospf_external_aggr_rt *)XCALLOC( + MTYPE_OSPF_EXTERNAL_RT_AGGR, + sizeof(struct ospf_external_aggr_rt)); + + if (!aggr) + return NULL; + + aggr->p.family = p->family; + aggr->p.prefix = p->prefix; + aggr->p.prefixlen = p->prefixlen; + aggr->match_extnl_hash = hash_create(ospf_external_rt_hash_key, + ospf_external_rt_hash_cmp, + "Ospf external route hash"); + return aggr; +} + +static void ospf_aggr_handle_external_info(void *data) +{ + struct external_info *ei = (struct external_info *)data; + struct ospf_external_aggr_rt *aggr = NULL; + struct ospf *ospf = NULL; + struct ospf_lsa *lsa = NULL; + + ei->aggr_route = NULL; + + ei->to_be_processed = true; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Handle extrenal route(%pI4/%d)", __func__, + &ei->p.prefix, ei->p.prefixlen); + + ospf = ospf_lookup_instance(ei->instance); + + assert(ospf); + + if (!ospf_redistribute_check(ospf, ei, NULL)) + return; + + aggr = ospf_external_aggr_match(ospf, &ei->p); + if (aggr) { + (void)ospf_originate_summary_lsa(ospf, aggr, ei); + return; + } + + lsa = ospf_external_info_find_lsa(ospf, &ei->p); + if (lsa) + ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE, 1); + else + (void)ospf_external_lsa_originate(ospf, ei); +} + +static void ospf_aggr_unlink_external_info(void *data) +{ + struct external_info *ei = (struct external_info *)data; + + ei->aggr_route = NULL; + + ei->to_be_processed = true; +} + +void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr) +{ + if (OSPF_EXTERNAL_RT_COUNT(aggr)) + hash_clean(aggr->match_extnl_hash, + (void *)ospf_aggr_unlink_external_info); + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Release the aggregator Address(%pI4/%d)", + __func__, &aggr->p.prefix, aggr->p.prefixlen); + hash_free(aggr->match_extnl_hash); + aggr->match_extnl_hash = NULL; + + XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr); +} + +static void ospf_external_aggr_add(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr) +{ + struct route_node *rn; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Adding Aggregate route to Aggr table (%pI4/%d)", + __func__, &aggr->p.prefix, aggr->p.prefixlen); + rn = route_node_get(ospf->rt_aggr_tbl, (struct prefix *)&aggr->p); + if (rn->info) + route_unlock_node(rn); + else + rn->info = aggr; +} + +static void ospf_external_aggr_delete(struct ospf *ospf, struct route_node *rn) +{ + struct ospf_external_aggr_rt *aggr = rn->info; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Deleting Aggregate route (%pI4/%d)", __func__, + &aggr->p.prefix, aggr->p.prefixlen); + + /* Sent a Max age LSA if it is already originated. */ + if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Flushing Aggregate route (%pI4/%d)", + __func__, &aggr->p.prefix, + aggr->p.prefixlen); + ospf_external_lsa_flush(ospf, 0, &aggr->p, 0); + } + + rn->info = NULL; + route_unlock_node(rn); + route_unlock_node(rn); +} + +struct ospf_external_aggr_rt * +ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p) +{ + struct route_node *rn; + struct ospf_external_aggr_rt *summary_rt = NULL; + + rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p); + if (rn) { + summary_rt = rn->info; + route_unlock_node(rn); + return summary_rt; + } + return NULL; +} + +struct ospf_external_aggr_rt *ospf_external_aggr_match(struct ospf *ospf, + struct prefix_ipv4 *p) +{ + struct route_node *node; + struct ospf_external_aggr_rt *summary_rt = NULL; + + node = route_node_match(ospf->rt_aggr_tbl, (struct prefix *)p); + if (node) { + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + if (node->info) { + struct ospf_external_aggr_rt *ag = node->info; + + zlog_debug( + "%s: Matching aggregator found.prefix:%pI4/%d Aggregator %pI4/%d\n", + __func__, &p->prefix, p->prefixlen, + &ag->p.prefix, ag->p.prefixlen); + } + + summary_rt = node->info; + route_unlock_node(node); + return summary_rt; + } + return NULL; +} + +void ospf_unlink_ei_from_aggr(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + struct external_info *ei) +{ + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Unlinking extrenal route(%pI4/%d) from aggregator(%pI4/%d), external route count:%ld", + __func__, &ei->p.prefix, ei->p.prefixlen, + &aggr->p.prefix, aggr->p.prefixlen, + OSPF_EXTERNAL_RT_COUNT(aggr)); + hash_release(aggr->match_extnl_hash, ei); + ei->aggr_route = NULL; + + /* Flush the aggreagte route if matching + * external route count becomes zero. + */ + if (!OSPF_EXTERNAL_RT_COUNT(aggr) + && CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) { + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Flushing the aggreagte route (%pI4/%d)", + __func__, &aggr->p.prefix, + aggr->p.prefixlen); + + /* Flush the aggregate LSA */ + ospf_external_lsa_flush(ospf, 0, &aggr->p, 0); + + /* Unset the Origination flag */ + UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + } +} + +static void ospf_link_ei_to_aggr(struct ospf_external_aggr_rt *aggr, + struct external_info *ei) +{ + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Linking extrenal route(%pI4/%d) to aggregator(%pI4/%d)", + __func__, &ei->p.prefix, ei->p.prefixlen, + &aggr->p.prefix, aggr->p.prefixlen); + hash_get(aggr->match_extnl_hash, ei, hash_alloc_intern); + ei->aggr_route = aggr; +} + +struct ospf_lsa *ospf_originate_summary_lsa(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + struct external_info *ei) +{ + struct ospf_lsa *lsa; + struct external_info ei_aggr; + struct as_external_lsa *asel; + struct ospf_external_aggr_rt *old_aggr; + route_tag_t tag = 0; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Prepare to originate Summary route(%pI4/%d)", + __func__, &aggr->p.prefix, aggr->p.prefixlen); + + /* This case to handle when the overlapping aggregator address + * is availbe.Best match will be considered.So need to delink + * from old aggregator and link to the new aggr. + */ + if (ei->aggr_route) { + if (ei->aggr_route != aggr) { + old_aggr = ei->aggr_route; + ospf_unlink_ei_from_aggr(ospf, old_aggr, ei); + } + } + + /* Add the external route to hash table */ + ospf_link_ei_to_aggr(aggr, ei); + + lsa = ospf_external_info_find_lsa(ospf, &aggr->p); + /* Dont originate external LSA, + * If it is configured not to advertise. + */ + if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) { + /* If it is already originated as external LSA, + * But, it is configured not to advertise then + * flush the originated external lsa. + */ + if (lsa) + ospf_external_lsa_flush(ospf, 0, &aggr->p, 0); + UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Don't originate the summary address,It is configured to not-advertise.", + __func__); + return NULL; + } + + /* Prepare the extrenal_info for aggregator */ + memset(&ei_aggr, 0, sizeof(struct external_info)); + ei_aggr.p = aggr->p; + ei_aggr.tag = aggr->tag; + ei_aggr.type = 0; + ei_aggr.instance = ospf->instance; + ei_aggr.route_map_set.metric = -1; + ei_aggr.route_map_set.metric_type = -1; + + /* Summary route already originated, + * So, Do nothing. + */ + if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) { + if (!lsa) { + flog_warn(EC_OSPF_LSA_MISSING, + "%s: Could not refresh/originate %pI4/%d", + __func__, &aggr->p.prefix, aggr->p.prefixlen); + return NULL; + } + + asel = (struct as_external_lsa *)lsa->data; + tag = (unsigned long)ntohl(asel->e[0].route_tag); + + /* If tag modified , then re-originate the route + * with modified tag details. + */ + if (tag != ei_aggr.tag) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Route tag changed(old:%d new:%d,So refresh the summary route.(%pI4/%d)", + __func__, tag, ei_aggr.tag, + &aggr->p.prefix, aggr->p.prefixlen); + + ospf_external_lsa_refresh(ospf, lsa, &ei_aggr, + LSA_REFRESH_FORCE, 1); + } + return lsa; + } + + if (lsa && IS_LSA_MAXAGE(lsa)) { + /* This is special case. + * If a summary route need to be originated but where + * summary route already exist in lsdb with maxage, then + * it need to be refreshed. + */ + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: LSA is in MAX-AGE so refreshing LSA(%pI4/%d)", + __PRETTY_FUNCTION__, &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_external_lsa_refresh(ospf, lsa, &ei_aggr, + LSA_REFRESH_FORCE, 1); + SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + return lsa; + } + + /* If the external route prefix same as aggregate route + * and if external route is already originated as TYPE-5 + * then it need to be refreshed and originate bit should + * be set. + */ + if (lsa && prefix_same((struct prefix *)&ei_aggr.p, + (struct prefix *)&ei->p)) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: External route prefix is same as aggr so refreshing LSA(%pI4/%d)", + __PRETTY_FUNCTION__, &aggr->p.prefix, + aggr->p.prefixlen); + ospf_external_lsa_refresh(ospf, lsa, &ei_aggr, + LSA_REFRESH_FORCE, 1); + SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + return lsa; + } + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Originate Summary route(%pI4/%d)", __func__, + &aggr->p.prefix, aggr->p.prefixlen); + + /* Originate summary LSA */ + lsa = ospf_external_lsa_originate(ospf, &ei_aggr); + if (lsa) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Set the origination bit for aggregator", + __func__); + SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + } + + return lsa; +} +void ospf_unset_all_aggr_flag(struct ospf *ospf) +{ + struct route_node *rn = NULL; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("Unset the origination bit for all aggregator"); + + for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + + struct ospf_external_aggr_rt *aggr = rn->info; + + UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + } +} + +static void ospf_delete_all_marked_aggregators(struct ospf *ospf) +{ + struct route_node *rn = NULL; + + /* Loop through all the aggregators, Delete all aggregators + * which are marked as DELETE. Set action to NONE for remaining + * aggregators + */ + for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + + struct ospf_external_aggr_rt *aggr = rn->info; + + if (aggr->action != OSPF_ROUTE_AGGR_DEL) { + aggr->action = OSPF_ROUTE_AGGR_NONE; + continue; + } + ospf_external_aggr_delete(ospf, rn); + ospf_external_aggregator_free(aggr); + } +} + +static void ospf_handle_aggregated_exnl_rt(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + struct external_info *ei) +{ + struct ospf_lsa *lsa; + struct as_external_lsa *al; + struct in_addr mask; + + /* Handling the case where the external route prefix + * and aggregate prefix is same + * If same dont flush the originated external LSA. + */ + if (prefix_same((struct prefix *)&aggr->p, (struct prefix *)&ei->p)) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: External Route prefix same as Aggregator(%pI4/%d), so dont flush.", + __func__, &ei->p.prefix, ei->p.prefixlen); + return; + } + + lsa = ospf_external_info_find_lsa(ospf, &ei->p); + if (lsa) { + al = (struct as_external_lsa *)lsa->data; + masklen2ip(ei->p.prefixlen, &mask); + + if (mask.s_addr != al->mask.s_addr) + return; + + ospf_external_lsa_flush(ospf, ei->type, &ei->p, 0); + } +} + +static void ospf_handle_exnl_rt_after_aggr_del(struct ospf *ospf, + struct external_info *ei) +{ + struct ospf_lsa *lsa; + + /* Process only marked external routes. + * These routes were part of a deleted + * aggregator.So, originate now. + */ + if (!ei->to_be_processed) + return; + + ei->to_be_processed = false; + + lsa = ospf_external_info_find_lsa(ospf, &ei->p); + + if (lsa) + ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE, 0); + else { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Originate external route(%pI4/%d)", + __func__, &ei->p.prefix, ei->p.prefixlen); + + ospf_external_lsa_originate(ospf, ei); + } +} + +static void ospf_handle_external_aggr_add(struct ospf *ospf) +{ + struct external_info *ei; + struct route_node *rn = NULL; + struct route_table *rt = NULL; + int type = 0; + + /* Delete all the aggregators which are marked as + * OSPF_ROUTE_AGGR_DEL. + */ + ospf_delete_all_marked_aggregators(ospf); + + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; + struct ospf_external_aggr_rt *aggr; + + ext_list = ospf->external[type]; + if (!ext_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + rt = ext->external_info; + if (!rt) + continue; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + if (!rn->info) + continue; + + ei = rn->info; + if (is_prefix_default(&ei->p)) + continue; + + /* Check the AS-external-LSA + * should be originated. + */ + if (!ospf_redistribute_check(ospf, ei, NULL)) + continue; + + aggr = ospf_external_aggr_match(ospf, &ei->p); + + /* If matching aggregator found, Add + * the external route reference to the + * aggregator and originate the aggr + * route if it is advertisable. + * flush the external LSA if it is + * already originated for this external + * prefix. + */ + if (aggr) { + ospf_originate_summary_lsa(ospf, aggr, + ei); + + /* All aggregated external rts + * are handled here. + */ + ospf_handle_aggregated_exnl_rt( + ospf, aggr, ei); + continue; + } + + /* External routes which are only out + * of aggregation will be handled here. + */ + ospf_handle_exnl_rt_after_aggr_del(ospf, ei); + } + } + } +} + +static void +ospf_aggr_handle_advertise_change(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + struct external_info *ei_aggr) +{ + struct ospf_lsa *lsa; + + /* Check if advertise option modified. */ + if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) { + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Don't originate the summary address,It is configured to not-advertise.", + __func__); + + if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) { + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: No-advertise,So Flush the Aggregate route(%pI4/%d)", + __func__, &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_external_lsa_flush(ospf, 0, &aggr->p, 0); + + UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + } + return; + } + + if (!CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Now it is advatisable", __func__); + + lsa = ospf_external_info_find_lsa(ospf, &ei_aggr->p); + if (lsa && IS_LSA_MAXAGE(lsa)) { + /* This is special case. + * If a summary route need to be originated but where + * summary route already exist in lsdb with maxage, then + * it need to be refreshed. + */ + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: It is already with Maxage, So refresh it (%pI4/%d)", + __func__, &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_external_lsa_refresh(ospf, lsa, ei_aggr, + LSA_REFRESH_FORCE, 1); + + SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED); + + } else { + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Originate Aggregate LSA (%pI4/%d)", + __func__, &aggr->p.prefix, + aggr->p.prefixlen); + + /* Originate summary LSA */ + lsa = ospf_external_lsa_originate(ospf, ei_aggr); + if (lsa) + SET_FLAG(aggr->flags, + OSPF_EXTERNAL_AGGRT_ORIGINATED); + } + } +} + +static void ospf_handle_external_aggr_update(struct ospf *ospf) +{ + struct route_node *rn = NULL; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Process modified aggregators.\n", __func__); + + for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) { + struct ospf_external_aggr_rt *aggr; + struct ospf_lsa *lsa = NULL; + struct as_external_lsa *asel = NULL; + struct external_info ei_aggr; + route_tag_t tag = 0; + + if (!rn->info) + continue; + + aggr = rn->info; + + if (aggr->action == OSPF_ROUTE_AGGR_DEL) { + aggr->action = OSPF_ROUTE_AGGR_NONE; + ospf_external_aggr_delete(ospf, rn); + + if (OSPF_EXTERNAL_RT_COUNT(aggr)) + hash_clean( + aggr->match_extnl_hash, + (void *)ospf_aggr_handle_external_info); + + hash_free(aggr->match_extnl_hash); + XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr); + + } else if (aggr->action == OSPF_ROUTE_AGGR_MODIFY) { + + aggr->action = OSPF_ROUTE_AGGR_NONE; + + /* Prepare the extrenal_info for aggregator */ + memset(&ei_aggr, 0, sizeof(struct external_info)); + ei_aggr.p = aggr->p; + ei_aggr.tag = aggr->tag; + ei_aggr.type = 0; + ei_aggr.instance = ospf->instance; + ei_aggr.route_map_set.metric = -1; + ei_aggr.route_map_set.metric_type = -1; + + /* Check if tag modified */ + if (CHECK_FLAG(aggr->flags, + OSPF_EXTERNAL_AGGRT_ORIGINATED)) { + lsa = ospf_external_info_find_lsa(ospf, + &ei_aggr.p); + if (!lsa) { + flog_warn(EC_OSPF_LSA_MISSING, + "%s: Could not refresh/originate %pI4/%d", + __func__, &aggr->p.prefix, + aggr->p.prefixlen); + continue; + } + + asel = (struct as_external_lsa *)lsa->data; + tag = (unsigned long)ntohl( + asel->e[0].route_tag); + + /* If tag modified , then re-originate the + * route with modified tag details. + */ + if (tag != ei_aggr.tag) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Route tag changed(old:%d new:%d,So refresh the summary route.(%pI4/%d)", + __func__, tag, + ei_aggr.tag, + &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_external_lsa_refresh( + ospf, lsa, &ei_aggr, + LSA_REFRESH_FORCE, 1); + } + } + + /* Advertise option modified ? + * If so, handled it here. + */ + ospf_aggr_handle_advertise_change(ospf, aggr, &ei_aggr); + } + } +} + +static int ospf_asbr_external_aggr_process(struct thread *thread) +{ + struct ospf *ospf = THREAD_ARG(thread); + int operation = 0; + + ospf->t_external_aggr = NULL; + operation = ospf->aggr_action; + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: operation:%d\n", __func__, operation); + + switch (operation) { + case OSPF_ROUTE_AGGR_ADD: + ospf_handle_external_aggr_add(ospf); + break; + case OSPF_ROUTE_AGGR_DEL: + case OSPF_ROUTE_AGGR_MODIFY: + ospf_handle_external_aggr_update(ospf); + break; + default: + break; + } + + return OSPF_SUCCESS; +} +static void ospf_external_aggr_timer(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + enum ospf_aggr_action_t operation) +{ + aggr->action = operation; + + if (ospf->t_external_aggr) { + if (ospf->aggr_action == OSPF_ROUTE_AGGR_ADD) { + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Not required to retsart timer,set is already added.", + __func__); + return; + } + + if (operation == OSPF_ROUTE_AGGR_ADD) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s, Restarting Aggregator delay timer.", + __func__); + THREAD_OFF(ospf->t_external_aggr); + } + } + + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug("%s: Start Aggregator delay timer %d(in seconds).", + __func__, ospf->aggr_delay_interval); + + ospf->aggr_action = operation; + thread_add_timer(master, ospf_asbr_external_aggr_process, ospf, + ospf->aggr_delay_interval, &ospf->t_external_aggr); +} + +int ospf_asbr_external_aggregator_set(struct ospf *ospf, struct prefix_ipv4 *p, + route_tag_t tag) +{ + struct ospf_external_aggr_rt *aggregator; + + aggregator = ospf_extrenal_aggregator_lookup(ospf, p); + + if (aggregator) { + if (CHECK_FLAG(aggregator->flags, + OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) + UNSET_FLAG(aggregator->flags, + OSPF_EXTERNAL_AGGRT_NO_ADVERTISE); + else if (aggregator->tag == tag) + return OSPF_SUCCESS; + + aggregator->tag = tag; + + ospf_external_aggr_timer(ospf, aggregator, + OSPF_ROUTE_AGGR_MODIFY); + } else { + aggregator = ospf_external_aggregator_new(p); + if (!aggregator) + return OSPF_FAILURE; + + aggregator->tag = tag; + + ospf_external_aggr_add(ospf, aggregator); + ospf_external_aggr_timer(ospf, aggregator, OSPF_ROUTE_AGGR_ADD); + } + + return OSPF_SUCCESS; +} + +int ospf_asbr_external_aggregator_unset(struct ospf *ospf, + struct prefix_ipv4 *p, route_tag_t tag) +{ + struct route_node *rn; + struct ospf_external_aggr_rt *aggr; + + rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p); + if (!rn) + return OSPF_INVALID; + + aggr = rn->info; + + if (tag && (tag != aggr->tag)) + return OSPF_INVALID; + + if (!OSPF_EXTERNAL_RT_COUNT(aggr)) { + ospf_external_aggr_delete(ospf, rn); + ospf_external_aggregator_free(aggr); + return OSPF_SUCCESS; + } + + ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_DEL); + + return OSPF_SUCCESS; +} + +int ospf_asbr_external_rt_no_advertise(struct ospf *ospf, struct prefix_ipv4 *p) +{ + struct ospf_external_aggr_rt *aggr; + route_tag_t tag = 0; + + aggr = ospf_extrenal_aggregator_lookup(ospf, p); + if (aggr) { + if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) + return OSPF_SUCCESS; + + SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE); + + aggr->tag = tag; + + if (!OSPF_EXTERNAL_RT_COUNT(aggr)) + return OSPF_SUCCESS; + + ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_MODIFY); + } else { + aggr = ospf_external_aggregator_new(p); + + if (!aggr) + return OSPF_FAILURE; + + SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE); + ospf_external_aggr_add(ospf, aggr); + ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_ADD); + } + + return OSPF_SUCCESS; +} + +int ospf_asbr_external_rt_advertise(struct ospf *ospf, struct prefix_ipv4 *p) +{ + struct route_node *rn; + struct ospf_external_aggr_rt *aggr; + + rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p); + if (!rn) + return OSPF_INVALID; + + aggr = rn->info; + + if (!CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) + return OSPF_INVALID; + + UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE); + + if (!OSPF_EXTERNAL_RT_COUNT(aggr)) + return OSPF_SUCCESS; + + ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_MODIFY); + return OSPF_SUCCESS; +} + +int ospf_external_aggregator_timer_set(struct ospf *ospf, unsigned int interval) +{ + ospf->aggr_delay_interval = interval; + return OSPF_SUCCESS; +} diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h index ede6c47906..7759d45455 100644 --- a/ospfd/ospf_asbr.h +++ b/ospfd/ospf_asbr.h @@ -50,8 +50,57 @@ struct external_info { route_tag_t orig_tag; struct route_map_set_values route_map_set; -#define ROUTEMAP_METRIC(E) (E)->route_map_set.metric +#define ROUTEMAP_METRIC(E) (E)->route_map_set.metric #define ROUTEMAP_METRIC_TYPE(E) (E)->route_map_set.metric_type + + /* Back pointer to summary address */ + struct ospf_external_aggr_rt *aggr_route; + + /* To identify the routes to be originated + * after a summary address deletion. + */ + bool to_be_processed; +}; + +#define OSPF_EXTL_AGGR_DEFAULT_DELAY 5 + +#define OSPF_EXTERNAL_RT_COUNT(aggr) \ + (((struct ospf_external_aggr_rt *)aggr)->match_extnl_hash->count) + +enum ospf_aggr_action_t { + OSPF_ROUTE_AGGR_NONE = 0, + OSPF_ROUTE_AGGR_ADD, + OSPF_ROUTE_AGGR_DEL, + OSPF_ROUTE_AGGR_MODIFY +}; + +#define OSPF_SUCCESS 1 +#define OSPF_FAILURE 0 +#define OSPF_INVALID -1 + +#define OSPF_EXTERNAL_AGGRT_NO_ADVERTISE 0x1 +#define OSPF_EXTERNAL_AGGRT_ORIGINATED 0x2 + +/* Data structures for external route aggregator */ +struct ospf_external_aggr_rt { + /* Prefix. */ + struct prefix_ipv4 p; + + /* Bit 1 : Dont advertise. + * Bit 2 : Originated as Type-5 + */ + uint8_t flags; + + /* Tag for summary route */ + route_tag_t tag; + + /* Action to be done at the delay + * timer expairy. + */ + enum ospf_aggr_action_t action; + + /* Hash Table of external routes */ + struct hash *match_extnl_hash; }; #define OSPF_ASBR_CHECK_DELAY 30 @@ -81,4 +130,36 @@ extern void ospf_asbr_route_install_lsa(struct ospf_lsa *); extern struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *, struct prefix_ipv4 *p); +/* External Route Aggregator */ +extern void ospf_asbr_external_aggregator_init(struct ospf *instance); +extern void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr); +extern bool is_valid_summary_addr(struct prefix_ipv4 *p); +extern struct ospf_external_aggr_rt * +ospf_external_aggr_match(struct ospf *ospf, struct prefix_ipv4 *p); +extern void ospf_unlink_ei_from_aggr(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + struct external_info *ei); +extern struct ospf_lsa * +ospf_originate_summary_lsa(struct ospf *ospf, + struct ospf_external_aggr_rt *aggr, + struct external_info *ei); +extern int ospf_external_aggregator_timer_set(struct ospf *ospf, + unsigned int interval); +extern void ospf_external_aggrigator_free(struct ospf_external_aggr_rt *aggr); + +extern struct ospf_external_aggr_rt * +ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p); + +void ospf_unset_all_aggr_flag(struct ospf *ospf); + +extern int ospf_asbr_external_aggregator_set(struct ospf *ospf, + struct prefix_ipv4 *p, + route_tag_t tag); +extern int ospf_asbr_external_aggregator_unset(struct ospf *ospf, + struct prefix_ipv4 *p, + route_tag_t tag); +extern int ospf_asbr_external_rt_no_advertise(struct ospf *ospf, + struct prefix_ipv4 *p); +extern int ospf_asbr_external_rt_advertise(struct ospf *ospf, + struct prefix_ipv4 *p); #endif /* _ZEBRA_OSPF_ASBR_H */ diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index d2a30477b0..3606efc76f 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -179,8 +179,8 @@ ospf_ase_calculate_asbr_route (struct ospf *ospf, if (asbr_route == NULL) { if (IS_DEBUG_OSPF (lsa, LSA)) - zlog_debug ("ospf_ase_calculate(): Route to ASBR %s not found", - inet_ntoa (asbr.prefix)); + zlog_debug ("ospf_ase_calculate(): Route to ASBR %pI4 not found", + &asbr.prefix); return NULL; } @@ -283,7 +283,6 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) struct prefix_ipv4 asbr, p; struct route_node *rn; struct ospf_route *new, * or ; - char buf1[INET_ADDRSTRLEN]; int ret; assert(lsa); @@ -301,11 +300,10 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) } if (IS_DEBUG_OSPF(lsa, LSA)) { - snprintf(buf1, sizeof(buf1), "%s", - inet_ntoa(al->header.adv_router)); zlog_debug( - "Route[External]: Calculate AS-external-LSA to %s/%d adv_router %s", - inet_ntoa(al->header.id), ip_masklen(al->mask), buf1); + "Route[External]: Calculate AS-external-LSA to %pI4/%d adv_router %pI4", + &al->header.id, ip_masklen(al->mask), + &al->header.adv_router); } /* (1) If the cost specified by the LSA is LSInfinity, or if the @@ -457,9 +455,8 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) if (!rn || (or = rn->info) == NULL) { if (IS_DEBUG_OSPF(lsa, LSA)) - zlog_debug("Route[External]: Adding a new route %s/%d with paths %u", - inet_ntoa(p.prefix), p.prefixlen, - listcount(asbr_route->paths)); + zlog_debug("Route[External]: Adding a new route %pFX with paths %u", + &p, listcount(asbr_route->paths)); ospf_route_add(ospf->new_external_route, &p, new, asbr_route); @@ -658,8 +655,8 @@ static int ospf_ase_calculate_timer(struct thread *t) for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_ase_calculate_timer(): looking at area %s", - inet_ntoa(area->area_id)); + "ospf_ase_calculate_timer(): looking at area %pI4", + &area->area_id); if (area->external_routing == OSPF_AREA_NSSA) LSDB_LOOP (NSSA_LSDB(area), rn, lsa) diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index d2c5090f2f..4640720952 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -76,9 +76,9 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command) bfd_info = (struct bfd_info *)params->bfd_info; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s", + zlog_debug("%s nbr (%pI4) with BFD. OSPF vrf %s", bfd_get_command_dbg_str(command), - inet_ntoa(nbr->src), + &nbr->src, ospf_vrf_id_to_name(oi->ospf->vrf_id)); cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON); @@ -180,8 +180,8 @@ static int ospf_bfd_nbr_replay(ZAPI_CALLBACK_ARGS) continue; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("Replaying nbr (%s) to BFD", - inet_ntoa(nbr->src)); + zlog_debug("Replaying nbr (%pI4) to BFD", + &nbr->src); ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_UPDATE); @@ -217,12 +217,9 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) if ((ifp == NULL) || (p.family != AF_INET)) return 0; - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&p, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s bfd destination %s %s", - ifp->name, buf, bfd_get_status_str(status)); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: interface %s bfd destination %pFX %s", + ifp->name, &p, bfd_get_status_str(status)); params = IF_DEF_PARAMS(ifp); if (!params->bfd_info) @@ -269,18 +266,18 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) { if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) - zlog_debug("NSM[%s:%s]: BFD Down", + zlog_debug("NSM[%s:%pI4]: BFD Down", IF_NAME(nbr->oi), - inet_ntoa(nbr->address.u.prefix4)); + &nbr->address.u.prefix4); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); } if ((status == BFD_STATUS_UP) && (old_status == BFD_STATUS_DOWN)) { if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) - zlog_debug("NSM[%s:%s]: BFD Up", + zlog_debug("NSM[%s:%pI4]: BFD Up", IF_NAME(nbr->oi), - inet_ntoa(nbr->address.u.prefix4)); + &nbr->address.u.prefix4); } } diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index e8798e023e..e15c9c42c7 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -41,6 +41,9 @@ #include "ospfd/ospf_dump.h" #include "ospfd/ospf_packet.h" #include "ospfd/ospf_network.h" +#ifndef VTYSH_EXTRACT_PL +#include "ospfd/ospf_dump_clippy.c" +#endif /* Configuration debug option variables. */ unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0}; @@ -55,6 +58,7 @@ unsigned long conf_debug_ospf_ext = 0; unsigned long conf_debug_ospf_sr = 0; unsigned long conf_debug_ospf_defaultinfo = 0; unsigned long conf_debug_ospf_ldp_sync = 0; +unsigned long conf_debug_ospf_gr = 0; /* Enable debug option variables -- valid only session. */ unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0}; @@ -69,6 +73,7 @@ unsigned long term_debug_ospf_ext = 0; unsigned long term_debug_ospf_sr = 0; unsigned long term_debug_ospf_defaultinfo; unsigned long term_debug_ospf_ldp_sync; +unsigned long term_debug_ospf_gr = 0; const char *ospf_redist_string(unsigned int route_type) { @@ -237,20 +242,20 @@ static void ospf_packet_hello_dump(struct stream *s, uint16_t length) hello = (struct ospf_hello *)stream_pnt(s); zlog_debug("Hello"); - zlog_debug(" NetworkMask %s", inet_ntoa(hello->network_mask)); + zlog_debug(" NetworkMask %pI4", &hello->network_mask); zlog_debug(" HelloInterval %d", ntohs(hello->hello_interval)); zlog_debug(" Options %d (%s)", hello->options, ospf_options_dump(hello->options)); zlog_debug(" RtrPriority %d", hello->priority); zlog_debug(" RtrDeadInterval %ld", (unsigned long)ntohl(hello->dead_interval)); - zlog_debug(" DRouter %s", inet_ntoa(hello->d_router)); - zlog_debug(" BDRouter %s", inet_ntoa(hello->bd_router)); + zlog_debug(" DRouter %pI4", &hello->d_router); + zlog_debug(" BDRouter %pI4", &hello->bd_router); length -= OSPF_HEADER_SIZE + OSPF_HELLO_MIN_SIZE; zlog_debug(" # Neighbors %d", length / 4); for (i = 0; length > 0; i++, length -= sizeof(struct in_addr)) - zlog_debug(" Neighbor %s", inet_ntoa(hello->neighbors[i])); + zlog_debug(" Neighbor %pI4", &hello->neighbors[i]); } static char *ospf_dd_flags_dump(uint8_t flags, char *buf, size_t size) @@ -287,9 +292,9 @@ static void ospf_router_lsa_dump(struct stream *s, uint16_t length) len = ntohs(rl->header.length) - OSPF_LSA_HEADER_SIZE - 4; for (i = 0; len > 0; i++) { - zlog_debug(" Link ID %s", inet_ntoa(rl->link[i].link_id)); - zlog_debug(" Link Data %s", - inet_ntoa(rl->link[i].link_data)); + zlog_debug(" Link ID %pI4", &rl->link[i].link_id); + zlog_debug(" Link Data %pI4", + &rl->link[i].link_data); zlog_debug(" Type %d", (uint8_t)rl->link[i].type); zlog_debug(" TOS %d", (uint8_t)rl->link[i].tos); zlog_debug(" metric %d", ntohs(rl->link[i].metric)); @@ -312,11 +317,11 @@ static void ospf_network_lsa_dump(struct stream *s, uint16_t length) zlog_debug ("Network-LSA size %d", ntohs (nl->header.length) - OSPF_LSA_HEADER_SIZE); */ - zlog_debug(" Network Mask %s", inet_ntoa(nl->mask)); + zlog_debug(" Network Mask %pI4", &nl->mask); zlog_debug(" # Attached Routers %d", cnt); for (i = 0; i < cnt; i++) - zlog_debug(" Attached Router %s", - inet_ntoa(nl->routers[i])); + zlog_debug(" Attached Router %pI4", + &nl->routers[i]); } static void ospf_summary_lsa_dump(struct stream *s, uint16_t length) @@ -328,7 +333,7 @@ static void ospf_summary_lsa_dump(struct stream *s, uint16_t length) sl = (struct summary_lsa *)stream_pnt(s); zlog_debug(" Summary-LSA"); - zlog_debug(" Network Mask %s", inet_ntoa(sl->mask)); + zlog_debug(" Network Mask %pI4", &sl->mask); size = ntohs(sl->header.length) - OSPF_LSA_HEADER_SIZE - 4; for (i = 0; size > 0; size -= 4, i++) @@ -344,15 +349,15 @@ static void ospf_as_external_lsa_dump(struct stream *s, uint16_t length) al = (struct as_external_lsa *)stream_pnt(s); zlog_debug(" %s", ospf_lsa_type_msg[al->header.type].str); - zlog_debug(" Network Mask %s", inet_ntoa(al->mask)); + zlog_debug(" Network Mask %pI4", &al->mask); size = ntohs(al->header.length) - OSPF_LSA_HEADER_SIZE - 4; for (i = 0; size > 0; size -= 12, i++) { zlog_debug(" bit %s TOS=%d metric %d", IS_EXTERNAL_METRIC(al->e[i].tos) ? "E" : "-", al->e[i].tos & 0x7f, GET_METRIC(al->e[i].metric)); - zlog_debug(" Forwarding address %s", - inet_ntoa(al->e[i].fwd_addr)); + zlog_debug(" Forwarding address %pI4", + &al->e[i].fwd_addr); zlog_debug(" External Route Tag %" ROUTE_TAG_PRI, al->e[i].route_tag); } @@ -422,8 +427,8 @@ static void ospf_packet_ls_req_dump(struct stream *s, uint16_t length) adv_router.s_addr = stream_get_ipv4(s); zlog_debug(" LS type %d", ls_type); - zlog_debug(" Link State ID %s", inet_ntoa(ls_id)); - zlog_debug(" Advertising Router %s", inet_ntoa(adv_router)); + zlog_debug(" Link State ID %pI4", &ls_id); + zlog_debug(" Advertising Router %pI4", &adv_router); } stream_set_getp(s, sp); @@ -514,8 +519,8 @@ static void ospf_header_dump(struct ospf_header *ospfh) zlog_debug(" Type %d (%s)", ospfh->type, lookup_msg(ospf_packet_type_str, ospfh->type, NULL)); zlog_debug(" Packet Len %d", ntohs(ospfh->length)); - zlog_debug(" Router ID %s", inet_ntoa(ospfh->router_id)); - zlog_debug(" Area ID %s", inet_ntoa(ospfh->area_id)); + zlog_debug(" Router ID %pI4", &ospfh->router_id); + zlog_debug(" Area ID %pI4", &ospfh->area_id); zlog_debug(" Checksum 0x%x", ntohs(ospfh->checksum)); zlog_debug(" AuType %s", lookup_msg(ospf_auth_type_str, auth_type, NULL)); @@ -996,6 +1001,8 @@ static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, DEBUG_ON(lsa, LSA_INSTALL); else if (strmatch(argv[arg_base]->text, "refresh")) DEBUG_ON(lsa, LSA_REFRESH); + else if (strmatch(argv[arg_base]->text, "aggregate")) + DEBUG_ON(lsa, EXTNL_LSA_AGGR); } return CMD_SUCCESS; @@ -1013,6 +1020,8 @@ static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, TERM_DEBUG_ON(lsa, LSA_INSTALL); else if (strmatch(argv[arg_base]->text, "refresh")) TERM_DEBUG_ON(lsa, LSA_REFRESH); + else if (strmatch(argv[arg_base]->text, "aggregate")) + TERM_DEBUG_ON(lsa, EXTNL_LSA_AGGR); } return CMD_SUCCESS; @@ -1020,21 +1029,23 @@ static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, DEFUN (debug_ospf_lsa, debug_ospf_lsa_cmd, - "debug ospf lsa [<generate|flooding|install|refresh>]", + "debug ospf lsa [<generate|flooding|install|refresh|aggregate>]", DEBUG_STR OSPF_STR "OSPF Link State Advertisement\n" "LSA Generation\n" "LSA Flooding\n" "LSA Install/Delete\n" - "LSA Refresh\n") + "LSA Refresh\n" + "External LSA Aggregation\n") { return debug_ospf_lsa_common(vty, 3, argc, argv); } DEFUN (debug_ospf_instance_lsa, debug_ospf_instance_lsa_cmd, - "debug ospf (1-65535) lsa [<generate|flooding|install|refresh>]", + "debug ospf (1-65535) lsa " + "[<generate|flooding|install|refresh|aggregate>]", DEBUG_STR OSPF_STR "Instance ID\n" @@ -1042,7 +1053,8 @@ DEFUN (debug_ospf_instance_lsa, "LSA Generation\n" "LSA Flooding\n" "LSA Install/Delete\n" - "LSA Refresh\n") + "LSA Refresh\n" + "External LSA Aggregation\n") { int idx_number = 2; unsigned short instance = 0; @@ -1070,6 +1082,8 @@ static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, DEBUG_OFF(lsa, LSA_INSTALL); else if (strmatch(argv[arg_base]->text, "refresh")) DEBUG_OFF(lsa, LSA_REFRESH); + else if (strmatch(argv[arg_base]->text, "aggregate")) + DEBUG_OFF(lsa, EXTNL_LSA_AGGR); } return CMD_SUCCESS; @@ -1087,6 +1101,8 @@ static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, TERM_DEBUG_OFF(lsa, LSA_INSTALL); else if (strmatch(argv[arg_base]->text, "refresh")) TERM_DEBUG_OFF(lsa, LSA_REFRESH); + else if (strmatch(argv[arg_base]->text, "aggregate")) + TERM_DEBUG_OFF(lsa, EXTNL_LSA_AGGR); } return CMD_SUCCESS; @@ -1094,7 +1110,7 @@ static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc, DEFUN (no_debug_ospf_lsa, no_debug_ospf_lsa_cmd, - "no debug ospf lsa [<generate|flooding|install|refresh>]", + "no debug ospf lsa [<generate|flooding|install|refresh|aggregate>]", NO_STR DEBUG_STR OSPF_STR @@ -1102,14 +1118,16 @@ DEFUN (no_debug_ospf_lsa, "LSA Generation\n" "LSA Flooding\n" "LSA Install/Delete\n" - "LSA Refres\n") + "LSA Refres\n" + "External LSA Aggregation\n") { return no_debug_ospf_lsa_common(vty, 4, argc, argv); } DEFUN (no_debug_ospf_instance_lsa, no_debug_ospf_instance_lsa_cmd, - "no debug ospf (1-65535) lsa [<generate|flooding|install|refresh>]", + "no debug ospf (1-65535) lsa " + "[<generate|flooding|install|refresh|aggregate>]", NO_STR DEBUG_STR OSPF_STR @@ -1118,7 +1136,8 @@ DEFUN (no_debug_ospf_instance_lsa, "LSA Generation\n" "LSA Flooding\n" "LSA Install/Delete\n" - "LSA Refres\n") + "LSA Refres\n" + "External LSA Aggregation\n") { int idx_number = 3; unsigned short instance = 0; @@ -1501,6 +1520,26 @@ DEFUN(no_debug_ospf_ldp_sync, if (vty->node == CONFIG_NODE) CONF_DEBUG_OFF(ldp_sync, LDP_SYNC); TERM_DEBUG_OFF(ldp_sync, LDP_SYNC); + + return CMD_SUCCESS; +} + +DEFPY (debug_ospf_gr, + debug_ospf_gr_cmd, + "[no$no] debug ospf graceful-restart helper", + NO_STR + DEBUG_STR OSPF_STR + "Gracefull restart\n" + "Helper Information\n") +{ + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON(gr, GR_HELPER); + + if (!no) + TERM_DEBUG_ON(gr, GR_HELPER); + else + TERM_DEBUG_OFF(gr, GR_HELPER); + return CMD_SUCCESS; } @@ -1667,6 +1706,10 @@ static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf) if (IS_DEBUG_OSPF(ldp_sync, LDP_SYNC) == OSPF_DEBUG_LDP_SYNC) vty_out(vty, " OSPF ldp-sync debugging is on\n"); + /* Show debug status for GR helper. */ + if (IS_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER) + vty_out(vty, " OSPF Graceful Restart Helper debugging is on\n"); + vty_out(vty, "\n"); return CMD_SUCCESS; @@ -1853,6 +1896,13 @@ static int config_write_debug(struct vty *vty) vty_out(vty, "debug ospf%s ldp-sync\n", str); write = 1; } + + /* debug ospf gr helper */ + if (IS_CONF_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER) { + vty_out(vty, "debug ospf%s graceful-restart helper\n", str); + write = 1; + } + return write; } @@ -1882,6 +1932,7 @@ void ospf_debug_init(void) install_element(ENABLE_NODE, &no_debug_ospf_sr_cmd); install_element(ENABLE_NODE, &no_debug_ospf_default_info_cmd); install_element(ENABLE_NODE, &no_debug_ospf_ldp_sync_cmd); + install_element(ENABLE_NODE, &debug_ospf_gr_cmd); install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd); install_element(ENABLE_NODE, &debug_ospf_packet_cmd); @@ -1922,6 +1973,7 @@ void ospf_debug_init(void) install_element(CONFIG_NODE, &no_debug_ospf_sr_cmd); install_element(CONFIG_NODE, &no_debug_ospf_default_info_cmd); install_element(CONFIG_NODE, &no_debug_ospf_ldp_sync_cmd); + install_element(CONFIG_NODE, &debug_ospf_gr_cmd); install_element(CONFIG_NODE, &debug_ospf_instance_nsm_cmd); install_element(CONFIG_NODE, &debug_ospf_instance_lsa_cmd); diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index faae27e2cf..ea607fef7c 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -49,6 +49,7 @@ #define OSPF_DEBUG_LSA_INSTALL 0x04 #define OSPF_DEBUG_LSA_REFRESH 0x08 #define OSPF_DEBUG_LSA 0x0F +#define OSPF_DEBUG_EXTNL_LSA_AGGR 0x10 #define OSPF_DEBUG_ZEBRA_INTERFACE 0x01 #define OSPF_DEBUG_ZEBRA_REDISTRIBUTE 0x02 @@ -62,6 +63,9 @@ #define OSPF_DEBUG_DEFAULTINFO 0x20 #define OSPF_DEBUG_LDP_SYNC 0x40 +#define OSPF_DEBUG_GR_HELPER 0x01 +#define OSPF_DEBUG_GR 0x03 + /* Macro for setting debug option. */ #define CONF_DEBUG_PACKET_ON(a, b) conf_debug_ospf_packet[a] |= (b) #define CONF_DEBUG_PACKET_OFF(a, b) conf_debug_ospf_packet[a] &= ~(b) @@ -109,6 +113,7 @@ #define IS_DEBUG_OSPF_DEFAULT_INFO IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO) #define IS_DEBUG_OSPF_LDP_SYNC IS_DEBUG_OSPF(ldp_sync, LDP_SYNC) +#define IS_DEBUG_OSPF_GR_HELPER IS_DEBUG_OSPF(gr, GR_HELPER) #define IS_CONF_DEBUG_OSPF_PACKET(a, b) \ (conf_debug_ospf_packet[a] & OSPF_DEBUG_##b) @@ -130,6 +135,7 @@ extern unsigned long term_debug_ospf_ext; extern unsigned long term_debug_ospf_sr; extern unsigned long term_debug_ospf_defaultinfo; extern unsigned long term_debug_ospf_ldp_sync; +extern unsigned long term_debug_ospf_gr; /* Message Strings. */ extern char *ospf_lsa_type_str[]; diff --git a/ospfd/ospf_dump_api.c b/ospfd/ospf_dump_api.c index e24936a473..4b68b006e2 100644 --- a/ospfd/ospf_dump_api.c +++ b/ospfd/ospf_dump_api.c @@ -127,8 +127,8 @@ void ospf_lsa_header_dump(struct lsa_header *lsah) ospf_options_dump(lsah->options)); zlog_debug(" LS type %d (%s)", lsah->type, (lsah->type ? lsah_type : "unknown type")); - zlog_debug(" Link State ID %s", inet_ntoa(lsah->id)); - zlog_debug(" Advertising Router %s", inet_ntoa(lsah->adv_router)); + zlog_debug(" Link State ID %pI4", &lsah->id); + zlog_debug(" Advertising Router %pI4", &lsah->adv_router); zlog_debug(" LS sequence number 0x%lx", (unsigned long)ntohl(lsah->ls_seqnum)); zlog_debug(" LS checksum 0x%x", ntohs(lsah->checksum)); diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index 90dc108c0e..4fa61221a6 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -462,6 +462,10 @@ static void set_rmt_itf_addr(struct ext_itf *exti, struct in_addr rmtif) static void ospf_extended_lsa_delete(struct ext_itf *exti) { + /* Avoid deleting LSA if Extended is not enable */ + if (!OspfEXT.enabled) + return; + /* Process only Active Extended Prefix/Link LSA */ if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE)) return; @@ -755,16 +759,16 @@ static void ospf_ext_ism_change(struct ospf_interface *oi, int old_status) if (oi->type == OSPF_IFTYPE_LOOPBACK) { exti->stype = PREF_SID; exti->type = OPAQUE_TYPE_EXTENDED_PREFIX_LSA; - exti->flags = EXT_LPFLG_LSA_ACTIVE; exti->instance = get_ext_pref_instance_value(); exti->area = oi->area; - osr_debug("EXT (%s): Set Prefix SID to interface %s ", - __func__, oi->ifp->name); - /* Complete SRDB if the interface belongs to a Prefix */ - if (OspfEXT.enabled) + if (OspfEXT.enabled) { + osr_debug("EXT (%s): Set Prefix SID to interface %s ", + __func__, oi->ifp->name); + exti->flags = EXT_LPFLG_LSA_ACTIVE; ospf_sr_update_local_prefix(oi->ifp, oi->address); + } } else { /* Determine if interface is related to Adj. or LAN Adj. SID */ if (oi->state == ISM_DR) @@ -780,9 +784,11 @@ static void ospf_ext_ism_change(struct ospf_interface *oi, int old_status) * Note: Adjacency SID information are completed when ospf * adjacency become up see ospf_ext_link_nsm_change() */ - osr_debug("EXT (%s): Set %sAdjacency SID for interface %s ", - __func__, exti->stype == ADJ_SID ? "" : "LAN-", - oi->ifp->name); + if (OspfEXT.enabled) + osr_debug( + "EXT (%s): Set %sAdjacency SID for interface %s ", + __func__, exti->stype == ADJ_SID ? "" : "LAN-", + oi->ifp->name); } } @@ -817,7 +823,8 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status) } /* Remove Extended Link if Neighbor State goes Down or Deleted */ - if (nbr->state == NSM_Down || nbr->state == NSM_Deleted) { + if (OspfEXT.enabled + && (nbr->state == NSM_Down || nbr->state == NSM_Deleted)) { ospf_ext_link_delete_adj_sid(exti); if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED)) ospf_ext_link_lsa_schedule(exti, FLUSH_THIS_LSA); @@ -1716,8 +1723,8 @@ static uint16_t show_vty_ext_link_rmt_itf_addr(struct vty *vty, top = (struct ext_subtlv_rmt_itf_addr *)tlvh; vty_out(vty, - " Remote Interface Address Sub-TLV: Length %u\n Address: %s\n", - ntohs(top->header.length), inet_ntoa(top->value)); + " Remote Interface Address Sub-TLV: Length %u\n Address: %pI4\n", + ntohs(top->header.length), &top->value); return TLV_SIZE(tlvh); } @@ -1748,9 +1755,9 @@ static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty, (struct ext_subtlv_lan_adj_sid *)tlvh; vty_out(vty, - " LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %s\n\t%s: %u\n", + " LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %pI4\n\t%s: %u\n", ntohs(top->header.length), top->flags, top->mtid, top->weight, - inet_ntoa(top->neighbor_id), + &top->neighbor_id, CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) ? "Label" : "Index", CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) @@ -1778,10 +1785,10 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext) vty_out(vty, " Extended Link TLV: Length %u\n Link Type: 0x%x\n" - " Link ID: %s\n", + " Link ID: %pI4\n", ntohs(top->header.length), top->link_type, - inet_ntoa(top->link_id)); - vty_out(vty, " Link data: %s\n", inet_ntoa(top->link_data)); + &top->link_id); + vty_out(vty, " Link data: %pI4\n", &top->link_data); tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE + EXT_TLV_LINK_SIZE); @@ -1858,9 +1865,9 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext) vty_out(vty, " Extended Prefix TLV: Length %u\n\tRoute Type: %u\n" - "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %s/%u\n", + "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %pI4/%u\n", ntohs(top->header.length), top->route_type, top->af, top->flags, - inet_ntoa(top->address), top->pref_length); + &top->address, top->pref_length); tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE + EXT_TLV_PREFIX_SIZE); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 58afb2b392..cb2b7c2365 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -154,12 +154,15 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf, struct ospf_interface *oi; struct external_info *ei; struct listnode *node; + struct as_external_lsa *al; + struct prefix_ipv4 p; + struct ospf_external_aggr_rt *aggr; if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "%s:LSA[Type%d:%s]: Process self-originated LSA seq 0x%x", + "%s:LSA[Type%d:%pI4]: Process self-originated LSA seq 0x%x", ospf_get_name(ospf), new->data->type, - inet_ntoa(new->data->id), ntohl(new->data->ls_seqnum)); + &new->data->id, ntohl(new->data->ls_seqnum)); /* If we're here, we installed a self-originated LSA that we received from a neighbor, i.e. it's more recent. We must see whether we want @@ -222,12 +225,51 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf, ospf_translated_nssa_refresh(ospf, NULL, new); return; } + + al = (struct as_external_lsa *)new->data; + p.family = AF_INET; + p.prefixlen = ip_masklen(al->mask); + p.prefix = new->data->id; + ei = ospf_external_info_check(ospf, new); - if (ei) + if (ei) { + if (ospf_external_aggr_match(ospf, &ei->p)) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "%s, Matching external aggregate route found for %pI4, so don't refresh it.", + __func__, + &ei->p.prefix); + + /* Aggregated external route shouldn't + * be in LSDB. + */ + if (!IS_LSA_MAXAGE(new)) + ospf_lsa_flush_as(ospf, new); + + return; + } + ospf_external_lsa_refresh(ospf, new, ei, - LSA_REFRESH_FORCE); - else - ospf_lsa_flush_as(ospf, new); + LSA_REFRESH_FORCE, false); + } else { + aggr = (struct ospf_external_aggr_rt *) + ospf_extrenal_aggregator_lookup(ospf, &p); + if (aggr) { + struct external_info ei_aggr; + + memset(&ei_aggr, 0, + sizeof(struct external_info)); + ei_aggr.p = aggr->p; + ei_aggr.tag = aggr->tag; + ei_aggr.instance = ospf->instance; + ei_aggr.route_map_set.metric = -1; + ei_aggr.route_map_set.metric_type = -1; + + ospf_external_lsa_refresh(ospf, new, &ei_aggr, + LSA_REFRESH_FORCE, true); + } else + ospf_lsa_flush_as(ospf, new); + } break; case OSPF_OPAQUE_AREA_LSA: ospf_opaque_lsa_refresh(new); @@ -276,8 +318,8 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr, if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "%s:LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]", - ospf_get_name(ospf), inet_ntoa(nbr->router_id), + "%s:LSA[Flooding]: start, NBR %pI4 (%s), cur(%p), New-LSA[%s]", + ospf_get_name(ospf), &nbr->router_id, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), (void *)current, dump_lsa_key(new)); @@ -337,6 +379,45 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr, SET_FLAG(new->flags, OSPF_LSA_RECEIVED); (void)ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */ + /* Received Grace LSA */ + if (IS_GRACE_LSA(new)) { + + if (IS_LSA_MAXAGE(new)) { + + /* Handling Max age grace LSA.*/ + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Received a maxage GRACE-LSA from router %pI4", + __PRETTY_FUNCTION__, + &new->data->adv_router); + + if (current) { + ospf_process_maxage_grace_lsa(ospf, new, nbr); + } else { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Grace LSA doesn't exist in lsdb, so discarding grace lsa", + __PRETTY_FUNCTION__); + return -1; + } + } else { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Received a GRACE-LSA from router %pI4", + __PRETTY_FUNCTION__, + &new->data->adv_router); + + if (ospf_process_grace_lsa(ospf, new, nbr) + == OSPF_GR_NOT_HELPER) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Not moving to HELPER role, So discarding grace LSA", + __PRETTY_FUNCTION__); + return -1; + } + } + } + /* Install the new LSA in the link state database (replacing the current database copy). This may cause the routing table calculation to be scheduled. In addition, @@ -373,17 +454,21 @@ static int ospf_flood_through_interface(struct ospf_interface *oi, struct ospf_neighbor *onbr; struct route_node *rn; int retx_flag; + char buf[PREFIX_STRLEN]; if (IS_DEBUG_OSPF_EVENT) zlog_debug( "%s:ospf_flood_through_interface(): considering int %s, INBR(%s), LSA[%s] AGE %u", - ospf_get_name(oi->ospf), IF_NAME(oi), inbr ? inet_ntoa(inbr->router_id) : "NULL", + ospf_get_name(oi->ospf), IF_NAME(oi), + inbr ? + inet_ntop(AF_INET, &inbr->router_id, buf, sizeof(buf)) : + "NULL", dump_lsa_key(lsa), ntohs(lsa->data->ls_age)); if (!ospf_if_is_enable(oi)) return 0; - /* Remember if new LSA is aded to a retransmit list. */ + /* Remember if new LSA is added to a retransmit list. */ retx_flag = 0; /* Each of the neighbors attached to this interface are examined, @@ -398,8 +483,8 @@ static int ospf_flood_through_interface(struct ospf_interface *oi, onbr = rn->info; if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_flood_through_interface(): considering nbr %s(%s) (%s)", - inet_ntoa(onbr->router_id), + "ospf_flood_through_interface(): considering nbr %pI4(%s) (%s)", + &onbr->router_id, ospf_get_name(oi->ospf), lookup_msg(ospf_nsm_state_msg, onbr->state, NULL)); @@ -734,9 +819,9 @@ void ospf_ls_request_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) * the common function "ospf_lsdb_add()" -- endo. */ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) - zlog_debug("RqstL(%lu)++, NBR(%s(%s)), LSA[%s]", + zlog_debug("RqstL(%lu)++, NBR(%pI4(%s)), LSA[%s]", ospf_ls_request_count(nbr), - inet_ntoa(nbr->router_id), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); ospf_lsdb_add(&nbr->ls_req, lsa); @@ -761,9 +846,9 @@ void ospf_ls_request_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) } if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ - zlog_debug("RqstL(%lu)--, NBR(%s(%s)), LSA[%s]", + zlog_debug("RqstL(%lu)--, NBR(%pI4(%s)), LSA[%s]", ospf_ls_request_count(nbr), - inet_ntoa(nbr->router_id), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); ospf_lsdb_delete(&nbr->ls_req, lsa); @@ -823,9 +908,9 @@ void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) if (old) { old->retransmit_counter--; if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) - zlog_debug("RXmtL(%lu)--, NBR(%s(%s)), LSA[%s]", + zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]", ospf_ls_retransmit_count(nbr), - inet_ntoa(nbr->router_id), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), dump_lsa_key(old)); ospf_lsdb_delete(&nbr->ls_rxmt, old); @@ -840,9 +925,9 @@ void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) * the common function "ospf_lsdb_add()" -- endo. */ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) - zlog_debug("RXmtL(%lu)++, NBR(%s(%s)), LSA[%s]", + zlog_debug("RXmtL(%lu)++, NBR(%pI4(%s)), LSA[%s]", ospf_ls_retransmit_count(nbr), - inet_ntoa(nbr->router_id), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); ospf_lsdb_add(&nbr->ls_rxmt, lsa); @@ -855,9 +940,9 @@ void ospf_ls_retransmit_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) if (ospf_ls_retransmit_lookup(nbr, lsa)) { lsa->retransmit_counter--; if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ - zlog_debug("RXmtL(%lu)--, NBR(%s(%s)), LSA[%s]", + zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]", ospf_ls_retransmit_count(nbr), - inet_ntoa(nbr->router_id), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); ospf_lsdb_delete(&nbr->ls_rxmt, lsa); @@ -936,7 +1021,7 @@ void ospf_ls_retransmit_delete_nbr_as(struct ospf *ospf, struct ospf_lsa *lsa) /* Sets ls_age to MaxAge and floods throu the area. - When we implement ASE routing, there will be anothe function + When we implement ASE routing, there will be another function flushing an LSA from the whole domain. */ void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area) { @@ -945,8 +1030,8 @@ void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area) retransmissions */ lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: MAXAGE set to LSA %s", __func__, - inet_ntoa(lsa->data->id)); + zlog_debug("%s: MAXAGE set to LSA %pI4", __func__, + &lsa->data->id); monotime(&lsa->tv_recv); lsa->tv_orig = lsa->tv_recv; ospf_flood_through_area(area, NULL, lsa); diff --git a/ospfd/ospf_gr_helper.c b/ospfd/ospf_gr_helper.c new file mode 100644 index 0000000000..9c029a49ba --- /dev/null +++ b/ospfd/ospf_gr_helper.c @@ -0,0 +1,1079 @@ +/* + * OSPF Graceful Restart helper functions. + * + * Copyright (C) 2020-21 Vmware, Inc. + * Rajesh Kumar Girada + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "thread.h" +#include "memory.h" +#include "linklist.h" +#include "prefix.h" +#include "if.h" +#include "table.h" +#include "vty.h" +#include "filter.h" +#include "log.h" +#include "jhash.h" + +#include "ospfd/ospfd.h" +#include "ospfd/ospf_interface.h" +#include "ospfd/ospf_asbr.h" +#include "ospfd/ospf_lsa.h" +#include "ospfd/ospf_lsdb.h" +#include "ospfd/ospf_neighbor.h" +#include "ospfd/ospf_spf.h" +#include "ospfd/ospf_flood.h" +#include "ospfd/ospf_route.h" +#include "ospfd/ospf_zebra.h" +#include "ospfd/ospf_dump.h" +#include "ospfd/ospf_errors.h" +#include "ospfd/ospf_nsm.h" +#include "ospfd/ospf_ism.h" +#include "ospfd/ospf_gr_helper.h" + +static const char * const ospf_exit_reason_desc[] = { + "Unknown reason", + "Helper inprogress", + "Topology Change", + "Grace timer expiry", + "Successful graceful restart", +}; + +static const char * const ospf_restart_reason_desc[] = { + "Unknown restart", + "Software restart", + "Software reload/upgrade", + "Switch to redundant control processor", +}; + +static const char * const ospf_rejected_reason_desc[] = { + "Unknown reason", + "Helper support disabled", + "Neighbour is not in FULL state", + "Supports only planned restart but received unplanned", + "Topo change due to change in lsa rxmt list", + "LSA age is more than Grace interval", +}; + +static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa); +static bool ospf_check_change_in_rxmt_list(struct ospf_neighbor *nbr); + +static unsigned int ospf_enable_rtr_hash_key(const void *data) +{ + const struct advRtr *rtr = data; + + return jhash_1word(rtr->advRtrAddr.s_addr, 0); +} + +static bool ospf_enable_rtr_hash_cmp(const void *d1, const void *d2) +{ + const struct advRtr *rtr1 = (struct advRtr *)d1; + const struct advRtr *rtr2 = (struct advRtr *)d2; + + return (rtr1->advRtrAddr.s_addr == rtr2->advRtrAddr.s_addr); +} + +static void *ospf_enable_rtr_hash_alloc(void *p) +{ + struct advRtr *rid; + + rid = XCALLOC(MTYPE_OSPF_GR_HELPER, sizeof(struct advRtr)); + rid->advRtrAddr.s_addr = ((struct in_addr *)p)->s_addr; + + return rid; +} + +static void ospf_disable_rtr_hash_free(void *rtr) +{ + XFREE(MTYPE_OSPF_GR_HELPER, rtr); +} + +static void ospf_enable_rtr_hash_destroy(struct ospf *ospf) +{ + if (ospf->enable_rtr_list == NULL) + return; + + hash_clean(ospf->enable_rtr_list, ospf_disable_rtr_hash_free); + hash_free(ospf->enable_rtr_list); + ospf->enable_rtr_list = NULL; +} + +/* + * GR exit reason strings + */ +const char *ospf_exit_reason2str(unsigned int reason) +{ + if (reason < array_size(ospf_exit_reason_desc)) + return(ospf_exit_reason_desc[reason]); + else + return "Invalid reason"; +} + +/* + * GR restart reason strings + */ +const char *ospf_restart_reason2str(unsigned int reason) +{ + if (reason < array_size(ospf_restart_reason_desc)) + return(ospf_restart_reason_desc[reason]); + else + return "Invalid reason"; +} + +/* + * GR rejected reason strings + */ +const char *ospf_rejected_reason2str(unsigned int reason) +{ + if (reason < array_size(ospf_rejected_reason_desc)) + return(ospf_rejected_reason_desc[reason]); + else + return "Invalid reason"; +} + +/* + * Initialize GR helper config data structures. + * + * OSPF + * OSPF pointer + * + * Returns: + * Nothing + */ +void ospf_gr_helper_init(struct ospf *ospf) +{ + int rc; + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, GR Helper init.", __PRETTY_FUNCTION__); + + ospf->is_helper_supported = OSPF_GR_FALSE; + ospf->strict_lsa_check = OSPF_GR_TRUE; + ospf->only_planned_restart = OSPF_GR_FALSE; + ospf->supported_grace_time = OSPF_MAX_GRACE_INTERVAL; + ospf->last_exit_reason = OSPF_GR_HELPER_EXIT_NONE; + ospf->active_restarter_cnt = 0; + + ospf->enable_rtr_list = + hash_create(ospf_enable_rtr_hash_key, ospf_enable_rtr_hash_cmp, + "OSPF enable router hash"); + + rc = ospf_register_opaque_functab( + OSPF_OPAQUE_LINK_LSA, OPAQUE_TYPE_GRACE_LSA, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, show_ospf_grace_lsa_info, NULL, NULL, + NULL, NULL); + if (rc != 0) { + flog_warn(EC_OSPF_OPAQUE_REGISTRATION, + "%s: Failed to register Grace LSA functions", + __func__); + } +} + +/* + * De-Initialize GR helper config data structures. + * + * OSPF + * OSPF pointer + * + * Returns: + * Nothing + */ +void ospf_gr_helper_stop(struct ospf *ospf) +{ + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, GR helper deinit.", __PRETTY_FUNCTION__); + + ospf_enable_rtr_hash_destroy(ospf); + + ospf_delete_opaque_functab(OSPF_OPAQUE_LINK_LSA, OPAQUE_TYPE_GRACE_LSA); +} + +/* + * Extracting tlv info from GRACE LSA. + * + * lsa + * ospf grace lsa + * + * Returns: + * interval : grace interval. + * addr : RESTARTER address. + * reason : Restarting reason. + */ +static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa, + uint32_t *interval, + struct in_addr *addr, uint8_t *reason) +{ + struct lsa_header *lsah = NULL; + struct tlv_header *tlvh = NULL; + struct grace_tlv_graceperiod *grace_period; + struct grace_tlv_restart_reason *gr_reason; + struct grace_tlv_restart_addr *restart_addr; + uint16_t length = 0; + int sum = 0; + + lsah = (struct lsa_header *)lsa->data; + + length = ntohs(lsah->length); + + /* Check LSA len */ + if (length <= OSPF_LSA_HEADER_SIZE) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s: Malformed packet: Invalid LSA len:%d", + __func__, length); + return OSPF_GR_FAILURE; + } + + length -= OSPF_LSA_HEADER_SIZE; + + for (tlvh = TLV_HDR_TOP(lsah); sum < length; + tlvh = TLV_HDR_NEXT(tlvh)) { + + /* Check TLV len against overall LSA */ + if (sum + TLV_SIZE(tlvh) > length) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s: Malformed packet: Invalid TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + + switch (ntohs(tlvh->type)) { + case GRACE_PERIOD_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_graceperiod)) { + zlog_debug("%s: Malformed packet: Invalid grace TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + + grace_period = (struct grace_tlv_graceperiod *)tlvh; + *interval = ntohl(grace_period->interval); + sum += TLV_SIZE(tlvh); + + /* Check if grace interval is valid */ + if (*interval > OSPF_MAX_GRACE_INTERVAL + || *interval < OSPF_MIN_GRACE_INTERVAL) + return OSPF_GR_FAILURE; + break; + case RESTART_REASON_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_reason)) { + zlog_debug("%s: Malformed packet: Invalid reason TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + + gr_reason = (struct grace_tlv_restart_reason *)tlvh; + *reason = gr_reason->reason; + sum += TLV_SIZE(tlvh); + + if (*reason >= OSPF_GR_INVALID_REASON_CODE) + return OSPF_GR_FAILURE; + break; + case RESTARTER_IP_ADDR_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_addr)) { + zlog_debug("%s: Malformed packet: Invalid addr TLV len:%zu", + __func__, TLV_SIZE(tlvh)); + return OSPF_GR_FAILURE; + } + + restart_addr = (struct grace_tlv_restart_addr *)tlvh; + addr->s_addr = restart_addr->addr.s_addr; + sum += TLV_SIZE(tlvh); + break; + default: + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Malformed packet.Invalid TLV type:%d", + __PRETTY_FUNCTION__, ntohs(tlvh->type)); + return OSPF_GR_FAILURE; + } + } + + return OSPF_GR_SUCCESS; +} + +/* + * Grace timer expiry handler. + * HELPER aborts its role at grace timer expiry. + * + * thread + * thread pointer + * + * Returns: + * Nothing + */ +static int ospf_handle_grace_timer_expiry(struct thread *thread) +{ + struct ospf_neighbor *nbr = THREAD_ARG(thread); + + nbr->gr_helper_info.t_grace_timer = NULL; + + ospf_gr_helper_exit(nbr, OSPF_GR_HELPER_GRACE_TIMEOUT); + return OSPF_GR_SUCCESS; +} + +/* + * Process Grace LSA.If it is eligible move to HELPER role. + * Ref rfc3623 section 3.1 + * + * ospf + * OSPF pointer. + * + * lsa + * Grace LSA received from RESTARTER. + * + * nbr + * ospf neighbour which requets the router to act as + * HELPER. + * + * Returns: + * status. + * If supported as HELPER : OSPF_GR_HELPER_INPROGRESS + * If Not supported as HELPER : OSPF_GR_HELPER_NONE + */ +int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa, + struct ospf_neighbor *nbr) +{ + struct in_addr restart_addr = {0}; + uint8_t restart_reason = 0; + uint32_t grace_interval = 0; + uint32_t actual_grace_interval = 0; + struct advRtr lookup; + struct ospf_neighbor *restarter = NULL; + struct ospf_interface *oi = nbr->oi; + int ret; + + + /* Extract the grace lsa packet fields */ + ret = ospf_extract_grace_lsa_fields(lsa, &grace_interval, &restart_addr, + &restart_reason); + if (ret != OSPF_GR_SUCCESS) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, Wrong Grace LSA packet.", + __PRETTY_FUNCTION__); + return OSPF_GR_NOT_HELPER; + } + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Grace LSA received from %pI4, grace interval:%u, restartreason :%s", + __PRETTY_FUNCTION__, &restart_addr, + grace_interval, + ospf_restart_reason2str(restart_reason)); + + /* Incase of broadcast links, if RESTARTER is DR_OTHER, + * grace LSA might be received from DR, so need to get + * actual neighbour info , here RESTARTER. + */ + if (oi->type != OSPF_IFTYPE_POINTOPOINT) { + restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restart_addr); + + if (!restarter) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Restarter is not a nbr(%pI4) for this router.", + __PRETTY_FUNCTION__, + &restart_addr); + return OSPF_GR_NOT_HELPER; + } + } else + restarter = nbr; + + /* Verify Helper enabled globally */ + if (!ospf->is_helper_supported) { + /* Verify that Helper support is enabled for the + * current neighbour router-id. + */ + lookup.advRtrAddr.s_addr = restarter->router_id.s_addr; + + if (!hash_lookup(ospf->enable_rtr_list, &lookup)) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, HELPER support is disabled, So not a HELPER", + __PRETTY_FUNCTION__); + restarter->gr_helper_info.rejected_reason = + OSPF_HELPER_SUPPORT_DISABLED; + return OSPF_GR_NOT_HELPER; + } + } + + + /* Check neighbour is in FULL state and + * became a adjacency. + */ + if (!IS_NBR_STATE_FULL(restarter)) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, This Neighbour %pI4 is not in FULL state.", + __PRETTY_FUNCTION__, &restarter->src); + restarter->gr_helper_info.rejected_reason = + OSPF_HELPER_NOT_A_VALID_NEIGHBOUR; + return OSPF_GR_NOT_HELPER; + } + + /* Based on the restart reason from grace lsa + * check the current router is supporting or not + */ + if (ospf->only_planned_restart + && !OSPF_GR_IS_PLANNED_RESTART(restart_reason)) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Router supports only planned restarts but received the GRACE LSA for an unplanned restart.", + __PRETTY_FUNCTION__); + restarter->gr_helper_info.rejected_reason = + OSPF_HELPER_PLANNED_ONLY_RESTART; + return OSPF_GR_NOT_HELPER; + } + + /* Check the retranmission list of this + * neighbour, check any change in lsas. + */ + if (ospf->strict_lsa_check && !ospf_ls_retransmit_isempty(restarter) + && ospf_check_change_in_rxmt_list(restarter)) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Changed LSA in Rxmt list. So not Helper.", + __PRETTY_FUNCTION__); + restarter->gr_helper_info.rejected_reason = + OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST; + return OSPF_GR_NOT_HELPER; + } + + /*LSA age must be less than the grace period */ + if (ntohs(lsa->data->ls_age) >= grace_interval) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Grace LSA age(%d) is more than the graceinterval(%d)", + __PRETTY_FUNCTION__, lsa->data->ls_age, + grace_interval); + restarter->gr_helper_info.rejected_reason = + OSPF_HELPER_LSA_AGE_MORE; + return OSPF_GR_NOT_HELPER; + } + + /* check supported grace period configured + * if configured, use this to start the grace + * timer otherwise use the interval received + * in grace LSA packet. + */ + actual_grace_interval = grace_interval; + if (grace_interval > ospf->supported_grace_time) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Received grace period %d is larger than supported grace %d", + __PRETTY_FUNCTION__, grace_interval, + ospf->supported_grace_time); + actual_grace_interval = ospf->supported_grace_time; + } + + if (OSPF_GR_IS_ACTIVE_HELPER(restarter)) { + if (restarter->gr_helper_info.t_grace_timer) + THREAD_OFF(restarter->gr_helper_info.t_grace_timer); + + if (ospf->active_restarter_cnt > 0) + ospf->active_restarter_cnt--; + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Router is already acting as a HELPER for this nbr,so restart the grace timer", + __PRETTY_FUNCTION__); + } else { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, This Router becomes a HELPER for the neighbour %pI4", + __PRETTY_FUNCTION__, &restarter->src); + } + + /* Became a Helper to the RESTART neighbour. + * Change the helper status. + */ + restarter->gr_helper_info.gr_helper_status = OSPF_GR_ACTIVE_HELPER; + restarter->gr_helper_info.recvd_grace_period = grace_interval; + restarter->gr_helper_info.actual_grace_period = actual_grace_interval; + restarter->gr_helper_info.gr_restart_reason = restart_reason; + restarter->gr_helper_info.rejected_reason = OSPF_HELPER_REJECTED_NONE; + + /* Incremnet the active restarer count */ + ospf->active_restarter_cnt++; + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, Grace timer started.interval:%d", + __PRETTY_FUNCTION__, actual_grace_interval); + + /* Start the grace timer */ + thread_add_timer(master, ospf_handle_grace_timer_expiry, restarter, + actual_grace_interval, + &restarter->gr_helper_info.t_grace_timer); + + return OSPF_GR_ACTIVE_HELPER; +} + +/* + * API to check any change in the neighbor's + * retransmission list. + * + * nbr + * ospf neighbor + * + * Returns: + * TRUE - if any change in the lsa. + * FALSE - no change in the lsas. + */ +static bool ospf_check_change_in_rxmt_list(struct ospf_neighbor *nbr) +{ + struct route_node *rn; + struct ospf_lsa *lsa; + struct route_table *tbl; + + tbl = nbr->ls_rxmt.type[OSPF_ROUTER_LSA].db; + LSDB_LOOP (tbl, rn, lsa) + if (lsa->to_be_acknowledged) + return OSPF_GR_TRUE; + tbl = nbr->ls_rxmt.type[OSPF_NETWORK_LSA].db; + LSDB_LOOP (tbl, rn, lsa) + if (lsa->to_be_acknowledged) + return OSPF_GR_TRUE; + + tbl = nbr->ls_rxmt.type[OSPF_SUMMARY_LSA].db; + LSDB_LOOP (tbl, rn, lsa) + if (lsa->to_be_acknowledged) + return OSPF_GR_TRUE; + + tbl = nbr->ls_rxmt.type[OSPF_ASBR_SUMMARY_LSA].db; + LSDB_LOOP (tbl, rn, lsa) + if (lsa->to_be_acknowledged) + return OSPF_GR_TRUE; + + tbl = nbr->ls_rxmt.type[OSPF_AS_EXTERNAL_LSA].db; + LSDB_LOOP (tbl, rn, lsa) + if (lsa->to_be_acknowledged) + return OSPF_GR_TRUE; + + tbl = nbr->ls_rxmt.type[OSPF_AS_NSSA_LSA].db; + LSDB_LOOP (tbl, rn, lsa) + if (lsa->to_be_acknowledged) + return OSPF_GR_TRUE; + + return OSPF_GR_FALSE; +} + +/* + * Actions to be taken when topo change detected + * HELPER will exit upon topo change. + * + * ospf + * ospf pointer + * lsa + * topo change occured due to this lsa type (1 to 5 and 7) + * + * Returns: + * Nothing + */ +void ospf_helper_handle_topo_chg(struct ospf *ospf, struct ospf_lsa *lsa) +{ + struct listnode *node; + struct ospf_interface *oi; + + if (!ospf->active_restarter_cnt) + return; + + /* Topo change not required to be handled if strict + * LSA check is disbaled for this router. + */ + if (!ospf->strict_lsa_check) + return; + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Topo change detected due to lsa LSID:%pI4 type:%d", + __PRETTY_FUNCTION__, &lsa->data->id, + lsa->data->type); + + lsa->to_be_acknowledged = OSPF_GR_TRUE; + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct route_node *rn = NULL; + + if (ospf_interface_neighbor_count(oi) == 0) + continue; + + /* Ref rfc3623 section 3.2.3.b + * If change due to external LSA and if the area is + * stub, then it is not a topo change. Since Type-5 + * lsas will not be flooded in stub area. + */ + if ((oi->area->external_routing == OSPF_AREA_STUB) + && (lsa->data->type == OSPF_AS_EXTERNAL_LSA)) { + continue; + } + + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + struct ospf_neighbor *nbr = NULL; + + if (!rn->info) + continue; + + nbr = rn->info; + + if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) + ospf_gr_helper_exit(nbr, + OSPF_GR_HELPER_TOPO_CHG); + } + } +} + +/* + * Api to exit from HELPER role to take all actions + * required at exit. + * Ref rfc3623 section 3.2 + * + * ospf + * OSPF pointer. + * + * nbr + * OSPF neighbour for which it is acting as HELPER. + * + * reason + * The reason for exiting from HELPER. + * + * Returns: + * Nothing. + */ +void ospf_gr_helper_exit(struct ospf_neighbor *nbr, + enum ospf_helper_exit_reason reason) +{ + struct ospf_interface *oi = nbr->oi; + struct ospf *ospf = oi->ospf; + + if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) + return; + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s", + __PRETTY_FUNCTION__, &nbr->src, + ospf_exit_reason2str(reason)); + + /* Reset helper status*/ + nbr->gr_helper_info.gr_helper_status = OSPF_GR_NOT_HELPER; + nbr->gr_helper_info.helper_exit_reason = reason; + nbr->gr_helper_info.actual_grace_period = 0; + nbr->gr_helper_info.recvd_grace_period = 0; + nbr->gr_helper_info.gr_restart_reason = 0; + ospf->last_exit_reason = reason; + + if (ospf->active_restarter_cnt <= 0) { + zlog_err( + "OSPF GR-Helper: active_restarter_cnt should be greater than zero here."); + return; + } + /* Decrement active Restarter count */ + ospf->active_restarter_cnt--; + + /* If the exit not triggered due to grace timer + * expairy , stop the grace timer. + */ + if (reason != OSPF_GR_HELPER_GRACE_TIMEOUT) + THREAD_OFF(nbr->gr_helper_info.t_grace_timer); + + /* check exit triggered due to successful completion + * of graceful restart. + * If no, bringdown the neighbour. + */ + if (reason != OSPF_GR_HELPER_COMPLETED) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Failed GR exit, so bringing down the neighbour", + __PRETTY_FUNCTION__); + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr); + } + + /*Recalculate the DR for the network segment */ + ospf_dr_election(oi); + + /* Originate a router LSA */ + ospf_router_lsa_update_area(oi->area); + + /* Originate network lsa if it is an DR in the LAN */ + if (oi->state == ISM_DR) + ospf_network_lsa_update(oi); +} + +/* + * Process Maxage Grace LSA. + * It is a indication for successful completion of GR. + * If router acting as HELPER, It exits from helper role. + * + * ospf + * OSPF pointer. + * + * lsa + * Grace LSA received from RESTARTER. + * + * nbr + * ospf neighbour which requets the router to act as + * HELPER. + * + * Returns: + * Nothing. + */ +void ospf_process_maxage_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa, + struct ospf_neighbor *nbr) +{ + struct in_addr restartAddr = {0}; + uint8_t restartReason = 0; + uint32_t graceInterval = 0; + struct ospf_neighbor *restarter = NULL; + struct ospf_interface *oi = nbr->oi; + int ret; + + /* Extract the grace lsa packet fields */ + ret = ospf_extract_grace_lsa_fields(lsa, &graceInterval, &restartAddr, + &restartReason); + if (ret != OSPF_GR_SUCCESS) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, Wrong Grace LSA packet.", + __PRETTY_FUNCTION__); + return; + } + + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, GraceLSA received for neighbour %pI4", + __PRETTY_FUNCTION__, &restartAddr); + + /* In case of broadcast links, if RESTARTER is DR_OTHER, + * grace LSA might be received from DR, so fetching the + * actual neighbour information using restarter address. + */ + if (oi->type != OSPF_IFTYPE_POINTOPOINT) { + restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restartAddr); + + if (!restarter) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Restarter is not a neighbour for this router.", + __PRETTY_FUNCTION__); + return; + } + } else { + restarter = nbr; + } + + ospf_gr_helper_exit(restarter, OSPF_GR_HELPER_COMPLETED); +} + +/* Configuration handlers */ +/* + * Disable/Enable HELPER support on router level. + * + * ospf + * OSPFpointer. + * + * status + * TRUE/FALSE + * + * Returns: + * Nothing. + */ +void ospf_gr_helper_support_set(struct ospf *ospf, bool support) +{ + struct ospf_interface *oi; + struct listnode *node; + struct advRtr lookup; + + if (ospf->is_helper_supported == support) + return; + + ospf->is_helper_supported = support; + + /* If helper support disabled, cease HELPER role for all + * supporting neighbors. + */ + if (support == OSPF_GR_FALSE) { + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct route_node *rn = NULL; + + if (ospf_interface_neighbor_count(oi) == 0) + continue; + + for (rn = route_top(oi->nbrs); rn; + rn = route_next(rn)) { + struct ospf_neighbor *nbr = NULL; + + if (!rn->info) + continue; + + nbr = rn->info; + + lookup.advRtrAddr.s_addr = + nbr->router_id.s_addr; + /* check if helper support enabled for the + * correspodning routerid.If enabled, dont + * dont exit from helper role. + */ + if (hash_lookup(ospf->enable_rtr_list, &lookup)) + continue; + + if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) + ospf_gr_helper_exit( + nbr, OSPF_GR_HELPER_TOPO_CHG); + } + } + } +} + +/* + * Enable/Disable HELPER support on a specified advertagement + * router. + * + * ospf + * OSPF pointer. + * + * advRtr + * HELPER support for given Advertisement Router. + * + * support + * True - Enable Helper Support. + * False - Disable Helper Support. + * + * Returns: + * Nothing. + */ + +void ospf_gr_helper_support_set_per_routerid(struct ospf *ospf, + struct in_addr *advrtr, + bool support) +{ + struct advRtr temp; + struct advRtr *rtr; + struct ospf_interface *oi; + struct listnode *node; + + temp.advRtrAddr.s_addr = advrtr->s_addr; + + if (support == OSPF_GR_FALSE) { + /*Delete the routerid from the enable router hash table */ + rtr = hash_lookup(ospf->enable_rtr_list, &temp); + + if (rtr) { + hash_release(ospf->enable_rtr_list, rtr); + ospf_disable_rtr_hash_free(rtr); + } + + /* If helper support is enabled globally + * no action is required. + */ + if (ospf->is_helper_supported) + return; + + /* Cease the HELPER role fore neighbours from the + * specified advertisement router. + */ + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct route_node *rn = NULL; + + if (ospf_interface_neighbor_count(oi) == 0) + continue; + + for (rn = route_top(oi->nbrs); rn; + rn = route_next(rn)) { + struct ospf_neighbor *nbr = NULL; + + if (!rn->info) + continue; + + nbr = rn->info; + + if (nbr->router_id.s_addr != advrtr->s_addr) + continue; + + if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) + ospf_gr_helper_exit( + nbr, OSPF_GR_HELPER_TOPO_CHG); + } + } + + } else { + /* Add the routerid to the enable router hash table */ + hash_get(ospf->enable_rtr_list, &temp, + ospf_enable_rtr_hash_alloc); + } +} + +/* + * Api to enable/disable strict lsa check on the HELPER. + * + * ospf + * OSPF pointer. + * + * enabled + * True - disable the lsa check. + * False - enable the strict lsa check. + * + * Returns: + * Nothing. + */ +void ospf_gr_helper_lsa_check_set(struct ospf *ospf, bool enabled) +{ + if (ospf->strict_lsa_check == enabled) + return; + + ospf->strict_lsa_check = enabled; +} + +/* + * Api to set the supported grace interval in this router. + * + * ospf + * OSPF pointer. + * + * interval + * The supported grace interval.. + * + * Returns: + * Nothing. + */ +void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf, + uint32_t interval) +{ + ospf->supported_grace_time = interval; +} + +/* + * Api to set the supported restart reason. + * + * ospf + * OSPF pointer. + * + * planned_only + * True: support only planned restart. + * False: support for planned/unplanned restarts. + * + * Returns: + * Nothing. + */ +void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf, + bool planned_only) +{ + ospf->only_planned_restart = planned_only; +} + +/* + * Api to display the grace LSA information. + * + * vty + * vty pointer. + * lsa + * Grace LSA. + * json + * json object + * + * Returns: + * Nothing. + */ +static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa) +{ + struct lsa_header *lsah = NULL; + struct tlv_header *tlvh = NULL; + struct grace_tlv_graceperiod *gracePeriod; + struct grace_tlv_restart_reason *grReason; + struct grace_tlv_restart_addr *restartAddr; + uint16_t length = 0; + int sum = 0; + + lsah = (struct lsa_header *)lsa->data; + + length = ntohs(lsah->length); + + if (length <= OSPF_LSA_HEADER_SIZE) { + vty_out(vty, "%% Invalid LSA length: %d\n", length); + return; + } + + length -= OSPF_LSA_HEADER_SIZE; + + vty_out(vty, " TLV info:\n"); + + for (tlvh = TLV_HDR_TOP(lsah); sum < length; + tlvh = TLV_HDR_NEXT(tlvh)) { + /* Check TLV len */ + if (sum + TLV_SIZE(tlvh) > length) { + vty_out(vty, "%% Invalid TLV length: %zu\n", + TLV_SIZE(tlvh)); + return; + } + + switch (ntohs(tlvh->type)) { + case GRACE_PERIOD_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_graceperiod)) { + vty_out(vty, + "%% Invalid grace TLV length %zu\n", + TLV_SIZE(tlvh)); + return; + } + + gracePeriod = (struct grace_tlv_graceperiod *)tlvh; + sum += TLV_SIZE(tlvh); + + vty_out(vty, " Grace period:%d\n", + ntohl(gracePeriod->interval)); + break; + case RESTART_REASON_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_reason)) { + vty_out(vty, + "%% Invalid reason TLV length %zu\n", + TLV_SIZE(tlvh)); + return; + } + + grReason = (struct grace_tlv_restart_reason *)tlvh; + sum += TLV_SIZE(tlvh); + + vty_out(vty, " Restart reason:%s\n", + ospf_restart_reason2str(grReason->reason)); + break; + case RESTARTER_IP_ADDR_TYPE: + if (TLV_SIZE(tlvh) < + sizeof(struct grace_tlv_restart_addr)) { + vty_out(vty, + "%% Invalid addr TLV length %zu\n", + TLV_SIZE(tlvh)); + return; + } + + restartAddr = (struct grace_tlv_restart_addr *)tlvh; + sum += TLV_SIZE(tlvh); + + vty_out(vty, " Restarter address:%pI4\n", + &restartAddr->addr); + break; + default: + vty_out(vty, " Unknown TLV type %d\n", + ntohs(tlvh->type)); + + break; + } + } +} diff --git a/ospfd/ospf_gr_helper.h b/ospfd/ospf_gr_helper.h new file mode 100644 index 0000000000..c355bb4f3d --- /dev/null +++ b/ospfd/ospf_gr_helper.h @@ -0,0 +1,179 @@ +/* + * OSPF Graceful Restart helper functions. + * + * Copyright (C) 2020-21 Vmware, Inc. + * Rajesh Kumar Girada + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_OSPF_GR_HELPER_H +#define _ZEBRA_OSPF_GR_HELPER_H + +#define OSPF_GR_NOT_HELPER 0 +#define OSPF_GR_ACTIVE_HELPER 1 + +#define OSPF_GR_HELPER_NO_LSACHECK 0 +#define OSPF_GR_HELPER_LSACHECK 1 + +#define OSPF_MAX_GRACE_INTERVAL 1800 +#define OSPF_MIN_GRACE_INTERVAL 1 + +enum ospf_helper_exit_reason { + OSPF_GR_HELPER_EXIT_NONE = 0, + OSPF_GR_HELPER_INPROGRESS, + OSPF_GR_HELPER_TOPO_CHG, + OSPF_GR_HELPER_GRACE_TIMEOUT, + OSPF_GR_HELPER_COMPLETED +}; + +enum ospf_gr_restart_reason { + OSPF_GR_UNKNOWN_RESTART = 0, + OSPF_GR_SW_RESTART = 1, + OSPF_GR_SW_UPGRADE = 2, + OSPF_GR_SWITCH_REDUNDANT_CARD = 3, + OSPF_GR_INVALID_REASON_CODE = 4 +}; + +enum ospf_gr_helper_rejected_reason { + OSPF_HELPER_REJECTED_NONE, + OSPF_HELPER_SUPPORT_DISABLED, + OSPF_HELPER_NOT_A_VALID_NEIGHBOUR, + OSPF_HELPER_PLANNED_ONLY_RESTART, + OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST, + OSPF_HELPER_LSA_AGE_MORE +}; + +/* Ref RFC3623 appendex-A */ +/* Grace period TLV */ +#define GRACE_PERIOD_TYPE 1 +#define GRACE_PERIOD_LENGTH 4 + +struct grace_tlv_graceperiod { + struct tlv_header header; + uint32_t interval; +}; + +/* Restart reason TLV */ +#define RESTART_REASON_TYPE 2 +#define RESTART_REASON_LENGTH 1 + +struct grace_tlv_restart_reason { + struct tlv_header header; + uint8_t reason; + uint8_t reserved[3]; +}; + +/* Restarter ip address TLV */ +#define RESTARTER_IP_ADDR_TYPE 3 +#define RESTARTER_IP_ADDR_LEN 4 + +struct grace_tlv_restart_addr { + struct tlv_header header; + struct in_addr addr; +}; + +struct ospf_helper_info { + + /* Grace interval received from + * Restarting Router. + */ + uint32_t recvd_grace_period; + + /* Grace interval used for grace + * gracetimer. + */ + uint32_t actual_grace_period; + + /* Grace timer,This Router acts as + * helper until this timer until + * this timer expires*/ + struct thread *t_grace_timer; + + /* Helper status */ + uint32_t gr_helper_status; + + /* Helper exit reason*/ + enum ospf_helper_exit_reason helper_exit_reason; + + /* Planned/Unplanned restart*/ + enum ospf_gr_restart_reason gr_restart_reason; + + /* Helper rejected reason */ + enum ospf_gr_helper_rejected_reason rejected_reason; +}; + +struct advRtr { + struct in_addr advRtrAddr; +}; + +#define OSPF_HELPER_ENABLE_RTR_COUNT(ospf) (ospf->enable_rtr_list->count) + +/* Check for planned restart */ +#define OSPF_GR_IS_PLANNED_RESTART(reason) \ + ((reason == OSPF_GR_SW_RESTART) || (reason == OSPF_GR_SW_UPGRADE)) + +/* Check the router is HELPER for current neighbour */ +#define OSPF_GR_IS_ACTIVE_HELPER(N) \ + ((N)->gr_helper_info.gr_helper_status == OSPF_GR_ACTIVE_HELPER) + +/* Check the LSA is GRACE LSA */ +#define IS_GRACE_LSA(lsa) \ + ((lsa->data->type == OSPF_OPAQUE_LINK_LSA) \ + && (GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr)) \ + == OPAQUE_TYPE_GRACE_LSA)) + +/* Check neighbour is in FULL state */ +#define IS_NBR_STATE_FULL(nbr) (nsm_should_adj(nbr) && (nbr->state == NSM_Full)) + +/* Check neighbour is DR_OTHER and state is 2_WAY */ +#define IS_NBR_STATE_2_WAY_WITH_DROTHER(nbr) \ + ((ospf_get_nbr_ism_role(nbr) == ISM_DROther) \ + && (nbr->state == NSM_TwoWay)) + +#define OSPF_GR_FALSE false +#define OSPF_GR_TRUE true + +#define OSPF_GR_SUCCESS 1 +#define OSPF_GR_FAILURE 0 +#define OSPF_GR_INVALID -1 + +const char *ospf_exit_reason2str(unsigned int reason); +const char *ospf_restart_reason2str(unsigned int reason); +const char *ospf_rejected_reason2str(unsigned int reason); + +extern void ospf_gr_helper_init(struct ospf *ospf); +extern void ospf_gr_helper_stop(struct ospf *ospf); +extern int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa, + struct ospf_neighbor *nbr); +extern void ospf_gr_helper_exit(struct ospf_neighbor *nbr, + enum ospf_helper_exit_reason reason); +extern void ospf_process_maxage_grace_lsa(struct ospf *ospf, + struct ospf_lsa *lsa, + struct ospf_neighbor *nbr); +extern void ospf_helper_handle_topo_chg(struct ospf *ospf, + struct ospf_lsa *lsa); +extern void ospf_gr_helper_support_set(struct ospf *ospf, bool support); +extern void ospf_gr_helper_support_set_per_routerid(struct ospf *ospf, + struct in_addr *rid, + bool support); +extern void ospf_gr_helper_lsa_check_set(struct ospf *ospf, bool lsacheck); +extern void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf, + uint32_t interval); +extern void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf, + bool planned_only); +#endif /* _ZEBRA_OSPF_HELPER_H */ diff --git a/ospfd/ospf_ia.c b/ospfd/ospf_ia.c index 87929e4369..f805899b81 100644 --- a/ospfd/ospf_ia.c +++ b/ospfd/ospf_ia.c @@ -76,8 +76,8 @@ static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt, if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_ia_network_route(): processing summary route to %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_ia_network_route(): processing summary route to %pFX", + p); /* Find a route to the same dest */ if ((rn1 = route_node_lookup(rt, (struct prefix *)p))) { @@ -113,8 +113,8 @@ static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt, else { /* no route */ if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_ia_network_route(): add new route to %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_ia_network_route(): add new route to %pFX", + p); ospf_route_add(rt, p, new_or, abr_or); } } @@ -129,8 +129,8 @@ static void ospf_ia_router_route(struct ospf *ospf, struct route_table *rtrs, int ret; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_ia_router_route(): considering %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + zlog_debug("ospf_ia_router_route(): considering %pFX", p); + /* Find a route to the same dest */ rn = route_node_get(rtrs, (struct prefix *)p); @@ -202,8 +202,8 @@ static int process_summary_lsa(struct ospf_area *area, struct route_table *rt, sl = (struct summary_lsa *)lsa->data; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("process_summary_lsa(): LS ID: %s", - inet_ntoa(sl->header.id)); + zlog_debug("process_summary_lsa(): LS ID: %pI4", + &sl->header.id); metric = GET_METRIC(sl->metric); @@ -524,8 +524,8 @@ static int process_transit_summary_lsa(struct ospf_area *area, sl = (struct summary_lsa *)lsa->data; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("process_transit_summaries(): LS ID: %s", - inet_ntoa(lsa->data->id)); + zlog_debug("process_transit_summaries(): LS ID: %pI4", + &lsa->data->id); metric = GET_METRIC(sl->metric); if (metric == OSPF_LS_INFINITY) { diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 6bfdb1e9e0..e461345fe5 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -535,6 +535,7 @@ static struct ospf_if_params *ospf_new_if_params(void) UNSET_IF_PARAM(oip, auth_simple); UNSET_IF_PARAM(oip, auth_crypt); UNSET_IF_PARAM(oip, auth_type); + UNSET_IF_PARAM(oip, if_area); oip->auth_crypt = list_new(); @@ -579,8 +580,8 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr) && !OSPF_IF_PARAM_CONFIGURED(oip, type) && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple) && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type) - && listcount(oip->auth_crypt) == 0 - && ntohl(oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) { + && !OSPF_IF_PARAM_CONFIGURED(oip, if_area) + && listcount(oip->auth_crypt) == 0) { ospf_del_if_params(oip); rn->info = NULL; route_unlock_node(rn); @@ -796,9 +797,36 @@ int ospf_if_up(struct ospf_interface *oi) int ospf_if_down(struct ospf_interface *oi) { + struct ospf *ospf; + if (oi == NULL) return 0; + ospf = oi->ospf; + + /* Cease the HELPER role for all the neighbours + * of this interface. + */ + if (ospf->is_helper_supported) { + struct route_node *rn = NULL; + + if (ospf_interface_neighbor_count(oi)) { + for (rn = route_top(oi->nbrs); rn; + rn = route_next(rn)) { + struct ospf_neighbor *nbr = NULL; + + if (!rn->info) + continue; + + nbr = rn->info; + + if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) + ospf_gr_helper_exit( + nbr, OSPF_GR_HELPER_TOPO_CHG); + } + } + } + OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown); /* delete position in router LSA */ oi->lsa_pos_beg = 0; @@ -950,17 +978,17 @@ struct ospf_vl_data *ospf_vl_lookup(struct ospf *ospf, struct ospf_area *area, struct listnode *node; if (IS_DEBUG_OSPF_EVENT) { - zlog_debug("%s: Looking for %s", __func__, inet_ntoa(vl_peer)); + zlog_debug("%s: Looking for %pI4", __func__, &vl_peer); if (area) - zlog_debug("%s: in area %s", __func__, - inet_ntoa(area->area_id)); + zlog_debug("%s: in area %pI4", __func__, + &area->area_id); } for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: VL %s, peer %s", __func__, + zlog_debug("%s: VL %s, peer %pI4", __func__, vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->vl_peer)); + &vl_data->vl_peer); if (area && !IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) @@ -1082,9 +1110,9 @@ static int ospf_vl_set_params(struct ospf_area *area, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: %s peer address: %s, cost: %d,%schanged", + zlog_debug("%s: %s peer address: %pI4, cost: %d,%schanged", __func__, vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->peer_addr), voi->output_cost, + &vl_data->peer_addr, voi->output_cost, (changed ? " " : " un")); return changed; @@ -1101,19 +1129,19 @@ void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid, if (IS_DEBUG_OSPF_EVENT) { zlog_debug("ospf_vl_up_check(): Start"); - zlog_debug("ospf_vl_up_check(): Router ID is %s", - inet_ntoa(rid)); - zlog_debug("ospf_vl_up_check(): Area is %s", - inet_ntoa(area->area_id)); + zlog_debug("ospf_vl_up_check(): Router ID is %pI4", + &rid); + zlog_debug("ospf_vl_up_check(): Area is %pI4", + &area->area_id); } for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) { if (IS_DEBUG_OSPF_EVENT) { - zlog_debug("%s: considering VL, %s in area %s", + zlog_debug("%s: considering VL, %s in area %pI4", __func__, vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->vl_area_id)); - zlog_debug("%s: peer ID: %s", __func__, - inet_ntoa(vl_data->vl_peer)); + &vl_data->vl_area_id); + zlog_debug("%s: peer ID: %pI4", __func__, + &vl_data->vl_peer); } if (IPV4_ADDR_SAME(&vl_data->vl_peer, &rid) @@ -1171,8 +1199,8 @@ int ospf_full_virtual_nbrs(struct ospf_area *area) { if (IS_DEBUG_OSPF_EVENT) { zlog_debug( - "counting fully adjacent virtual neighbors in area %s", - inet_ntoa(area->area_id)); + "counting fully adjacent virtual neighbors in area %pI4", + &area->area_id); zlog_debug("there are %d of them", area->full_vls); } @@ -1249,6 +1277,9 @@ void ospf_if_interface(struct interface *ifp) static int ospf_ifp_create(struct interface *ifp) { struct ospf *ospf = NULL; + struct ospf_if_params *params; + struct route_node *rn; + uint32_t count = 0; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) zlog_debug( @@ -1270,6 +1301,19 @@ static int ospf_ifp_create(struct interface *ifp) if (!ospf) return 0; + params = IF_DEF_PARAMS(ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + count++; + + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) + if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) + count++; + + if (count > 0) { + ospf->if_ospf_cli_count += count; + ospf_interface_area_set(ospf, ifp); + } + ospf_if_recalculate_output_cost(ifp); ospf_if_update(ospf, ifp); @@ -1335,7 +1379,10 @@ static int ospf_ifp_down(struct interface *ifp) static int ospf_ifp_destroy(struct interface *ifp) { + struct ospf *ospf; + struct ospf_if_params *params; struct route_node *rn; + uint32_t count = 0; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) zlog_debug( @@ -1346,6 +1393,22 @@ static int ospf_ifp_destroy(struct interface *ifp) hook_call(ospf_if_delete, ifp); + ospf = ospf_lookup_by_vrf_id(ifp->vrf_id); + if (ospf) { + params = IF_DEF_PARAMS(ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + count++; + + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) + if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) + count++; + + if (count > 0) { + ospf->if_ospf_cli_count -= count; + ospf_interface_area_unset(ospf, ifp); + } + } + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) if (rn->info) ospf_if_free((struct ospf_interface *)rn->info); diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 86712c6198..36e97f8779 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -201,7 +201,7 @@ static void ospf_dr_change(struct ospf *ospf, struct route_table *nbrs) } } -static int ospf_dr_election(struct ospf_interface *oi) +int ospf_dr_election(struct ospf_interface *oi) { struct in_addr old_dr, old_bdr; int old_state, new_state; @@ -223,8 +223,8 @@ static int ospf_dr_election(struct ospf_interface *oi) new_state = ospf_ism_state(oi); - zlog_debug("DR-Election[1st]: Backup %s", inet_ntoa(BDR(oi))); - zlog_debug("DR-Election[1st]: DR %s", inet_ntoa(DR(oi))); + zlog_debug("DR-Election[1st]: Backup %pI4", &BDR(oi)); + zlog_debug("DR-Election[1st]: DR %pI4", &DR(oi)); if (new_state != old_state && !(new_state == ISM_DROther && old_state < ISM_DROther)) { @@ -233,8 +233,8 @@ static int ospf_dr_election(struct ospf_interface *oi) new_state = ospf_ism_state(oi); - zlog_debug("DR-Election[2nd]: Backup %s", inet_ntoa(BDR(oi))); - zlog_debug("DR-Election[2nd]: DR %s", inet_ntoa(DR(oi))); + zlog_debug("DR-Election[2nd]: Backup %pI4", &BDR(oi)); + zlog_debug("DR-Election[2nd]: DR %pI4", &DR(oi)); } list_delete(&el_list); diff --git a/ospfd/ospf_ism.h b/ospfd/ospf_ism.h index 8d21403695..c41ba6c843 100644 --- a/ospfd/ospf_ism.h +++ b/ospfd/ospf_ism.h @@ -79,13 +79,7 @@ } while (0) /* Macro for OSPF ISM timer turn off. */ -#define OSPF_ISM_TIMER_OFF(X) \ - do { \ - if (X) { \ - thread_cancel(X); \ - (X) = NULL; \ - } \ - } while (0) +#define OSPF_ISM_TIMER_OFF(X) thread_cancel(&(X)) /* Macro for OSPF schedule event. */ #define OSPF_ISM_EVENT_SCHEDULE(I, E) \ @@ -99,6 +93,7 @@ extern int ospf_ism_event(struct thread *); extern void ism_change_status(struct ospf_interface *, int); extern int ospf_hello_timer(struct thread *thread); +extern int ospf_dr_election(struct ospf_interface *oi); DECLARE_HOOK(ospf_ism_change, (struct ospf_interface * oi, int state, int oldstate), diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index cdb0eae2c4..68792ebcc2 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -99,8 +99,7 @@ int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce) FOR_ALL_INTERFACES (vrf, ifp) ospf_ldp_sync_if_start(ifp, true); - THREAD_TIMER_OFF(ospf->ldp_sync_cmd.t_hello); - ospf->ldp_sync_cmd.t_hello = NULL; + THREAD_OFF(ospf->ldp_sync_cmd.t_hello); ospf->ldp_sync_cmd.sequence = 0; ospf_ldp_sync_hello_timer_add(ospf); @@ -140,7 +139,7 @@ int ospf_ldp_sync_hello_update(struct ldp_igp_sync_hello hello) FOR_ALL_INTERFACES (vrf, ifp) ospf_ldp_sync_if_start(ifp, true); } else { - THREAD_TIMER_OFF(ospf->ldp_sync_cmd.t_hello); + THREAD_OFF(ospf->ldp_sync_cmd.t_hello); ospf_ldp_sync_hello_timer_add(ospf); } ospf->ldp_sync_cmd.sequence = hello.sequence; @@ -249,8 +248,7 @@ void ospf_ldp_sync_if_complete(struct interface *ifp) if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) { if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP) ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP; - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; + THREAD_OFF(ldp_sync_info->t_holddown); ospf_if_recalculate_output_cost(ifp); } } @@ -274,10 +272,7 @@ void ospf_ldp_sync_ldp_fail(struct interface *ifp) if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED && ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) { - if (ldp_sync_info->t_holddown != NULL) { - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; - } + THREAD_OFF(ldp_sync_info->t_holddown); ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP; ospf_if_recalculate_output_cost(ifp); } @@ -340,8 +335,9 @@ void ospf_ldp_sync_if_remove(struct interface *ifp, bool remove) * restore cost */ ols_debug("ldp_sync: Removed from if %s", ifp->name); - if (ldp_sync_info->t_holddown) - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); + + THREAD_OFF(ldp_sync_info->t_holddown); + ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; ospf_if_recalculate_output_cost(ifp); if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG)) @@ -390,7 +386,6 @@ static int ospf_ldp_sync_holddown_timer(struct thread *thread) ldp_sync_info = params->ldp_sync_info; ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP; - ldp_sync_info->t_holddown = NULL; ols_debug("ldp_sync: holddown timer expired for %s state: %s", ifp->name, "Sync achieved"); @@ -440,7 +435,6 @@ static int ospf_ldp_sync_hello_timer(struct thread *thread) */ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); if (ospf) { - ospf->ldp_sync_cmd.t_hello = NULL; vrf = vrf_lookup_by_id(ospf->vrf_id); FOR_ALL_INTERFACES (vrf, ifp) @@ -490,8 +484,8 @@ void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove) UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE); UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN); ospf->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT; - THREAD_TIMER_OFF(ospf->ldp_sync_cmd.t_hello); - ospf->ldp_sync_cmd.t_hello = NULL; + + THREAD_OFF(ospf->ldp_sync_cmd.t_hello); /* turn off LDP-IGP Sync on all OSPF interfaces */ vrf = vrf_lookup_by_id(ospf->vrf_id); @@ -984,8 +978,7 @@ DEFPY (no_mpls_ldp_sync, SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; - THREAD_TIMER_OFF(ldp_sync_info->t_holddown); - ldp_sync_info->t_holddown = NULL; + THREAD_OFF(ldp_sync_info->t_holddown); ospf_if_recalculate_output_cost(ifp); return CMD_SUCCESS; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 8095219146..42fc3288cd 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -98,8 +98,8 @@ int ospf_lsa_refresh_delay(struct ospf_lsa *lsa) if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "LSA[Type%d:%s]: Refresh timer delay %d seconds", - lsa->data->type, inet_ntoa(lsa->data->id), + "LSA[Type%d:%pI4]: Refresh timer delay %d seconds", + lsa->data->type, &lsa->data->id, delay); assert(delay > 0); @@ -164,6 +164,7 @@ struct ospf_lsa *ospf_lsa_new(void) new->tv_orig = new->tv_recv; new->refresh_list = -1; new->vrf_id = VRF_DEFAULT; + new->to_be_acknowledged = 0; return new; } @@ -280,8 +281,8 @@ struct lsa_header *ospf_lsa_data_dup(struct lsa_header *lsah) void ospf_lsa_data_free(struct lsa_header *lsah) { if (IS_DEBUG_OSPF(lsa, LSA)) - zlog_debug("LSA[Type%d:%s]: data freed %p", lsah->type, - inet_ntoa(lsah->id), (void *)lsah); + zlog_debug("LSA[Type%d:%pI4]: data freed %p", lsah->type, + &lsah->id, (void *)lsah); XFREE(MTYPE_OSPF_LSA_DATA, lsah); } @@ -296,8 +297,8 @@ const char *dump_lsa_key(struct ospf_lsa *lsa) if (lsa != NULL && (lsah = lsa->data) != NULL) { char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN]; - strlcpy(id, inet_ntoa(lsah->id), sizeof(id)); - strlcpy(ar, inet_ntoa(lsah->adv_router), sizeof(ar)); + inet_ntop(AF_INET, &lsah->id, id, sizeof(id)); + inet_ntop(AF_INET, &lsah->adv_router, ar, sizeof(ar)); snprintf(buf, sizeof(buf), "Type%d,id(%s),ar(%s)", lsah->type, id, ar); @@ -627,10 +628,8 @@ static int lsa_link_ptomp_set(struct stream **s, struct ospf_interface *oi) cost); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "PointToMultipoint: set link to %s", - inet_ntoa( - oi->address->u - .prefix4)); + "PointToMultipoint: set link to %pI4", + &oi->address->u.prefix4); } return links; @@ -836,8 +835,8 @@ static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area) ospf_flood_through_area(area, NULL, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Originate router-LSA %p", - new->data->type, inet_ntoa(new->data->id), + zlog_debug("LSA[Type%d:%pI4]: Originate router-LSA %p", + new->data->type, &new->data->id, (void *)new); ospf_lsa_header_dump(new->data); } @@ -875,8 +874,8 @@ static struct ospf_lsa *ospf_router_lsa_refresh(struct ospf_lsa *lsa) /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: router-LSA refresh", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: router-LSA refresh", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -928,9 +927,9 @@ int ospf_router_lsa_update(struct ospf *ospf) else if (!IPV4_ADDR_SAME(&lsa->data->id, &ospf->router_id)) { if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "LSA[Type%d:%s]: Refresh router-LSA for Area %s", + "LSA[Type%d:%pI4]: Refresh router-LSA for Area %s", lsa->data->type, - inet_ntoa(lsa->data->id), area_str); + &lsa->data->id, area_str); ospf_refresher_unregister_lsa(ospf, lsa); ospf_lsa_flush_area(lsa, area); ospf_lsa_unlock(&area->router_lsa_self); @@ -1058,8 +1057,8 @@ void ospf_network_lsa_update(struct ospf_interface *oi) ospf_flood_through_area(oi->area, NULL, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Originate network-LSA %p", - new->data->type, inet_ntoa(new->data->id), + zlog_debug("LSA[Type%d:%pI4]: Originate network-LSA %p", + new->data->type, &new->data->id, (void *)new); ospf_lsa_header_dump(new->data); } @@ -1081,8 +1080,8 @@ static struct ospf_lsa *ospf_network_lsa_refresh(struct ospf_lsa *lsa) if (oi == NULL) { if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { zlog_debug( - "LSA[Type%d:%s]: network-LSA refresh: no oi found, ick, ignoring.", - lsa->data->type, inet_ntoa(lsa->data->id)); + "LSA[Type%d:%pI4]: network-LSA refresh: no oi found, ick, ignoring.", + lsa->data->type, &lsa->data->id); ospf_lsa_header_dump(lsa->data); } return NULL; @@ -1111,8 +1110,8 @@ static struct ospf_lsa *ospf_network_lsa_refresh(struct ospf_lsa *lsa) ospf_flood_through_area(area, NULL, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: network-LSA refresh", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: network-LSA refresh", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1230,8 +1229,8 @@ struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p, ospf_flood_through_area(area, NULL, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Originate summary-LSA %p", - new->data->type, inet_ntoa(new->data->id), + zlog_debug("LSA[Type%d:%pI4]: Originate summary-LSA %p", + new->data->type, &new->data->id, (void *)new); ospf_lsa_header_dump(new->data); } @@ -1266,8 +1265,8 @@ static struct ospf_lsa *ospf_summary_lsa_refresh(struct ospf *ospf, /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: summary-LSA refresh", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: summary-LSA refresh", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1373,8 +1372,8 @@ struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p, ospf_flood_through_area(area, NULL, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p", - new->data->type, inet_ntoa(new->data->id), + zlog_debug("LSA[Type%d:%pI4]: Originate summary-ASBR-LSA %p", + new->data->type, &new->data->id, (void *)new); ospf_lsa_header_dump(new->data); } @@ -1407,8 +1406,8 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_refresh(struct ospf *ospf, ospf_flood_through_area(new->area, NULL, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: summary-ASBR-LSA refresh", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: summary-ASBR-LSA refresh", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1757,8 +1756,8 @@ static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf, == NULL) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_nssa_translate_originate(): Could not originate Translated Type-5 for %s", - inet_ntoa(ei.p.prefix)); + "ospf_nssa_translate_originate(): Could not originate Translated Type-5 for %pI4", + &ei.p.prefix); return NULL; } @@ -1791,8 +1790,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_translated_nssa_originate(): Could not translate Type-7, Id %s, to Type-5", - inet_ntoa(type7->data->id)); + "ospf_translated_nssa_originate(): Could not translate Type-7, Id %pI4, to Type-5", + &type7->data->id); return NULL; } @@ -1801,8 +1800,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) { flog_warn( EC_OSPF_LSA_INSTALL_FAILURE, - "ospf_lsa_translated_nssa_originate(): Could not install LSA id %s", - inet_ntoa(type7->data->id)); + "ospf_lsa_translated_nssa_originate(): Could not install LSA id %pI4", + &type7->data->id); return NULL; } @@ -1811,8 +1810,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf, "ospf_translated_nssa_originate(): translated Type 7, installed:"); ospf_lsa_header_dump(new->data); zlog_debug(" Network mask: %d", ip_masklen(extnew->mask)); - zlog_debug(" Forward addr: %s", - inet_ntoa(extnew->e[0].fwd_addr)); + zlog_debug(" Forward addr: %pI4", + &extnew->e[0].fwd_addr); } ospf->lsa_originate_count++; @@ -1877,8 +1876,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, if (!type7) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_translated_nssa_refresh(): no Type-7 found for Type-5 LSA Id %s", - inet_ntoa(type5->data->id)); + "ospf_translated_nssa_refresh(): no Type-7 found for Type-5 LSA Id %pI4", + &type5->data->id); return NULL; } @@ -1886,8 +1885,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, if (type5 == NULL || !CHECK_FLAG(type5->flags, OSPF_LSA_LOCAL_XLT)) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_translated_nssa_refresh(): No translated Type-5 found for Type-7 with Id %s", - inet_ntoa(type7->data->id)); + "ospf_translated_nssa_refresh(): No translated Type-5 found for Type-7 with Id %pI4", + &type7->data->id); return NULL; } @@ -1898,16 +1897,16 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf, if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) { if (IS_DEBUG_OSPF_NSSA) zlog_debug( - "ospf_translated_nssa_refresh(): Could not translate Type-7 for %s to Type-5", - inet_ntoa(type7->data->id)); + "ospf_translated_nssa_refresh(): Could not translate Type-7 for %pI4 to Type-5", + &type7->data->id); return NULL; } if (!(new = ospf_lsa_install(ospf, NULL, new))) { flog_warn( EC_OSPF_LSA_INSTALL_FAILURE, - "ospf_translated_nssa_refresh(): Could not install translated LSA, Id %s", - inet_ntoa(type7->data->id)); + "ospf_translated_nssa_refresh(): Could not install translated LSA, Id %pI4", + &type7->data->id); return NULL; } @@ -1978,16 +1977,12 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf, return NULL; } - /* Check the AS-external-LSA should be originated. */ - if (!ospf_redistribute_check(ospf, ei, NULL)) - return NULL; - /* Create new AS-external-LSA instance. */ if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "LSA[Type5:%s]: Could not originate AS-external-LSA", - inet_ntoa(ei->p.prefix)); + "LSA[Type5:%pI4]: Could not originate AS-external-LSA", + &ei->p.prefix); return NULL; } @@ -2009,8 +2004,8 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf, /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Originate AS-external-LSA %p", - new->data->type, inet_ntoa(new->data->id), + zlog_debug("LSA[Type%d:%pI4]: Originate AS-external-LSA %p", + new->data->type, &new->data->id, (void *)new); ospf_lsa_header_dump(new->data); } @@ -2057,6 +2052,7 @@ static struct external_info *ospf_default_external_info(struct ospf *ospf) void ospf_external_lsa_rid_change(struct ospf *ospf) { struct external_info *ei; + struct ospf_external_aggr_rt *aggr; int type; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { @@ -2088,9 +2084,21 @@ void ospf_external_lsa_rid_change(struct ospf *ospf) (struct prefix_ipv4 *)&ei->p)) continue; - if (!ospf_external_lsa_originate(ospf, ei)) + if (!ospf_redistribute_check(ospf, ei, NULL)) + continue; + + aggr = ospf_external_aggr_match(ospf, &ei->p); + if (aggr) { + if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) + zlog_debug( + "Originate Summary LSA after reset/router-ID change"); + /* Here the LSA is originated as new */ + ospf_originate_summary_lsa(ospf, aggr, + ei); + } else if (!ospf_external_lsa_originate(ospf, + ei)) flog_warn(EC_OSPF_LSA_INSTALL_FAILURE, - "LSA: AS-external-LSA was not originated."); + "LSA: AS-external-LSA was not originated."); } } } @@ -2116,9 +2124,8 @@ void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p) if (!lsa) { if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( - "LSA: There is no such AS-NSSA-LSA %s/%d in LSDB", - inet_ntoa(p->prefix), - p->prefixlen); + "LSA: There is no such AS-NSSA-LSA %pFX in LSDB", + p); continue; } ospf_ls_retransmit_delete_nbr_area(area, lsa); @@ -2138,15 +2145,14 @@ void ospf_external_lsa_flush(struct ospf *ospf, uint8_t type, struct ospf_lsa *lsa; if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) - zlog_debug("LSA: Flushing AS-external-LSA %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + zlog_debug("LSA: Flushing AS-external-LSA %pFX", p); /* First lookup LSA from LSDB. */ if (!(lsa = ospf_external_info_find_lsa(ospf, p))) { if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( - "LSA: There is no such AS-external-LSA %s/%d in LSDB", - inet_ntoa(p->prefix), p->prefixlen); + "LSA: There is no such AS-external-LSA %pFX in LSDB", + p); return; } @@ -2194,8 +2200,9 @@ void ospf_external_lsa_refresh_default(struct ospf *ospf) if (ei && lsa) { if (IS_DEBUG_OSPF_EVENT) zlog_debug("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", - (void *)lsa); - ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE); + (void *)lsa); + ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE, + false); } else if (ei && !lsa) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( @@ -2228,15 +2235,51 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, if (ei) { if (!is_prefix_default(&ei->p)) { struct ospf_lsa *lsa; + struct ospf_external_aggr_rt *aggr; + aggr = ospf_external_aggr_match(ospf, + &ei->p); lsa = ospf_external_info_find_lsa( - ospf, &ei->p); - if (lsa) + ospf, &ei->p); + if (aggr) { + /* Check the AS-external-LSA + * should be originated. + */ + if (!ospf_redistribute_check( + ospf, ei, NULL)) { + + ospf_unlink_ei_from_aggr( + ospf, aggr, ei); + continue; + } + + if (IS_DEBUG_OSPF( + lsa, + EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Send Aggreate LSA (%pFX/%d)", + __func__, + &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_originate_summary_lsa( + ospf, aggr, ei); + + } else if (lsa) { + + if (IS_LSA_MAXAGE(lsa)) + force = LSA_REFRESH_FORCE; + ospf_external_lsa_refresh( - ospf, lsa, ei, force); - else + ospf, lsa, ei, force, + false); + } else { + if (!ospf_redistribute_check( + ospf, ei, NULL)) + continue; ospf_external_lsa_originate( ospf, ei); + } } } } @@ -2246,27 +2289,31 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, /* Refresh AS-external-LSA. */ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa, - struct external_info *ei, int force) + struct external_info *ei, int force, + bool is_aggr) { struct ospf_lsa *new; - int changed; + int changed = 0; /* Check the AS-external-LSA should be originated. */ - if (!ospf_redistribute_check(ospf, ei, &changed)) { - if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) - zlog_debug( - "LSA[Type%d:%s]: Could not be refreshed, redist check fail", - lsa->data->type, inet_ntoa(lsa->data->id)); - ospf_external_lsa_flush(ospf, ei->type, &ei->p, - ei->ifindex /*, ei->nexthop */); - return NULL; - } + if (!is_aggr) + if (!ospf_redistribute_check(ospf, ei, &changed)) { + if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) + zlog_debug( + "LSA[Type%d:%s] Could not be refreshed, redist check fail", + lsa->data->type, + inet_ntoa(lsa->data->id)); + + ospf_external_lsa_flush(ospf, ei->type, &ei->p, + ei->ifindex /*, ei->nexthop */); + return NULL; + } if (!changed && !force) { if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "LSA[Type%d:%s]: Not refreshed, not changed/forced", - lsa->data->type, inet_ntoa(lsa->data->id)); + "LSA[Type%d:%pI4]: Not refreshed, not changed/forced", + lsa->data->type, &lsa->data->id); return NULL; } @@ -2280,8 +2327,8 @@ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf, if (new == NULL) { if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) - zlog_debug("LSA[Type%d:%s]: Could not be refreshed", - lsa->data->type, inet_ntoa(lsa->data->id)); + zlog_debug("LSA[Type%d:%pI4]: Could not be refreshed", + lsa->data->type, &lsa->data->id); return NULL; } @@ -2306,8 +2353,8 @@ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf, /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: AS-external-LSA refresh", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: AS-external-LSA refresh", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -2578,8 +2625,19 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi, /* Do comparision and record if recalc needed. */ rt_recalc = 0; - if (old == NULL || ospf_lsa_different(old, lsa)) + if (old == NULL || ospf_lsa_different(old, lsa)) { + /* Ref rfc3623 section 3.2.3 + * Installing new lsa or change in the existing LSA + * or flushing existing LSA leads to topo change + * and trigger SPF caculation. + * So, router should be aborted from HELPER role + * if it is detected as TOPO change. + */ + if (CHECK_LSA_TYPE_1_TO_5_OR_7(lsa->data->type)) + ospf_helper_handle_topo_chg(ospf, lsa); + rt_recalc = 1; + } /* Sequence number check (Section 14.1 of rfc 2328) @@ -2671,8 +2729,6 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi, /* Debug logs. */ if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) { - char area_str[INET_ADDRSTRLEN]; - switch (lsa->data->type) { case OSPF_AS_EXTERNAL_LSA: case OSPF_OPAQUE_AS_LSA: @@ -2682,13 +2738,11 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi, new->data->type, NULL)); break; default: - strlcpy(area_str, inet_ntoa(new->area->area_id), - sizeof(area_str)); - zlog_debug("LSA[%s]: Install %s to Area %s", + zlog_debug("LSA[%s]: Install %s to Area %pI4", dump_lsa_key(new), lookup_msg(ospf_lsa_type_msg, new->data->type, NULL), - area_str); + &new->area->area_id); break; } } @@ -2699,8 +2753,8 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi, */ if (IS_LSA_MAXAGE(new)) { if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) - zlog_debug("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge", - new->data->type, inet_ntoa(new->data->id), + zlog_debug("LSA[Type%d:%pI4]: Install LSA 0x%p, MaxAge", + new->data->type, &new->data->id, (void *)lsa); ospf_lsa_maxage(ospf, lsa); } @@ -2776,16 +2830,16 @@ static int ospf_maxage_lsa_remover(struct thread *thread) if (IS_LSA_SELF(lsa)) if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( - "LSA[Type%d:%s]: LSA 0x%lx is self-originated: ", + "LSA[Type%d:%pI4]: LSA 0x%lx is self-originated: ", lsa->data->type, - inet_ntoa(lsa->data->id), + &lsa->data->id, (unsigned long)lsa); if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( - "LSA[Type%d:%s]: MaxAge LSA removed from list", + "LSA[Type%d:%pI4]: MaxAge LSA removed from list", lsa->data->type, - inet_ntoa(lsa->data->id)); + &lsa->data->id); if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) { if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) @@ -2802,9 +2856,9 @@ static int ospf_maxage_lsa_remover(struct thread *thread) } else { if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( - "%s: LSA[Type%d:%s]: No associated LSDB!", + "%s: LSA[Type%d:%pI4]: No associated LSDB!", __func__, lsa->data->type, - inet_ntoa(lsa->data->id)); + &lsa->data->id); } } @@ -2861,8 +2915,8 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa) if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) { if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) zlog_debug( - "LSA[Type%d:%s]: %p already exists on MaxAge LSA list", - lsa->data->type, inet_ntoa(lsa->data->id), + "LSA[Type%d:%pI4]: %p already exists on MaxAge LSA list", + lsa->data->type, &lsa->data->id, (void *)lsa); return; } @@ -3097,8 +3151,8 @@ struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area, if (match == NULL) if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA) - zlog_debug("LSA[Type%d:%s]: Lookup by header, NO MATCH", - lsah->type, inet_ntoa(lsah->id)); + zlog_debug("LSA[Type%d:%pI4]: Lookup by header, NO MATCH", + lsah->type, &lsah->id); return match; } @@ -3194,8 +3248,8 @@ int ospf_lsa_flush_schedule(struct ospf *ospf, struct ospf_lsa *lsa) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", - lsa->data->type, inet_ntoa(lsa->data->id)); + "LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH", + lsa->data->type, &lsa->data->id); /* Force given lsa's age to MaxAge. */ lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); @@ -3232,9 +3286,9 @@ void ospf_flush_self_originated_lsas_now(struct ospf *ospf) if ((lsa = area->router_lsa_self) != NULL) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", + "LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH", lsa->data->type, - inet_ntoa(lsa->data->id)); + &lsa->data->id); ospf_refresher_unregister_lsa(ospf, lsa); ospf_lsa_flush_area(lsa, area); @@ -3247,9 +3301,9 @@ void ospf_flush_self_originated_lsas_now(struct ospf *ospf) && oi->state == ISM_DR && oi->full_nbrs > 0) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", + "LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH", lsa->data->type, - inet_ntoa(lsa->data->id)); + &lsa->data->id); ospf_refresher_unregister_lsa( ospf, oi->network_lsa_self); @@ -3351,8 +3405,8 @@ struct in_addr ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb, if (ip_masklen(al->mask) == p->prefixlen) { if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "ospf_lsa_unique_id(): Can't get Link State ID for %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + "ospf_lsa_unique_id(): Can't get Link State ID for %pFX", + p); /* id.s_addr = 0; */ id.s_addr = 0xffffffff; return id; @@ -3368,9 +3422,8 @@ struct in_addr ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb, if (lsa) { if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "ospf_lsa_unique_id(): Can't get Link State ID for %s/%d", - inet_ntoa(p->prefix), - p->prefixlen); + "ospf_lsa_unique_id(): Can't get Link State ID for %pFX", + p); /* id.s_addr = 0; */ id.s_addr = 0xffffffff; return id; @@ -3444,7 +3497,11 @@ void ospf_schedule_lsa_flush_area(struct ospf_area *area, struct ospf_lsa *lsa) struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa) { struct external_info *ei; + struct ospf_external_aggr_rt *aggr; struct ospf_lsa *new = NULL; + struct as_external_lsa *al; + struct prefix_ipv4 p; + assert(CHECK_FLAG(lsa->flags, OSPF_LSA_SELF)); assert(IS_LSA_SELF(lsa)); assert(lsa->lock > 0); @@ -3467,14 +3524,37 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa) /* Translated from NSSA Type-5s are refreshed when * from refresh of Type-7 - do not refresh these directly. */ + + al = (struct as_external_lsa *)lsa->data; + p.family = AF_INET; + p.prefixlen = ip_masklen(al->mask); + p.prefix = lsa->data->id; + if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) break; ei = ospf_external_info_check(ospf, lsa); if (ei) - new = ospf_external_lsa_refresh(ospf, lsa, ei, - LSA_REFRESH_FORCE); - else - ospf_lsa_flush_as(ospf, lsa); + new = ospf_external_lsa_refresh( + ospf, lsa, ei, LSA_REFRESH_FORCE, false); + else { + aggr = (struct ospf_external_aggr_rt *) + ospf_extrenal_aggregator_lookup(ospf, &p); + if (aggr) { + struct external_info ei_aggr; + + memset(&ei_aggr, 0, + sizeof(struct external_info)); + ei_aggr.p = aggr->p; + ei_aggr.tag = aggr->tag; + ei_aggr.instance = ospf->instance; + ei_aggr.route_map_set.metric = -1; + ei_aggr.route_map_set.metric_type = -1; + + ospf_external_lsa_refresh(ospf, lsa, &ei_aggr, + LSA_REFRESH_FORCE, true); + } else + ospf_lsa_flush_as(ospf, lsa); + } break; case OSPF_OPAQUE_LINK_LSA: case OSPF_OPAQUE_AREA_LSA: @@ -3518,8 +3598,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) zlog_debug( - "LSA[Refresh:Type%d:%s]: age %d, added to index %d", - lsa->data->type, inet_ntoa(lsa->data->id), + "LSA[Refresh:Type%d:%pI4]: age %d, added to index %d", + lsa->data->type, &lsa->data->id, LS_AGE(lsa), index); if (!ospf->lsa_refresh_queue.qs[index]) @@ -3531,8 +3611,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) zlog_debug( - "LSA[Refresh:Type%d:%s]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", - lsa->data->type, inet_ntoa(lsa->data->id), + "LSA[Refresh:Type%d:%pI4]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", + lsa->data->type, &lsa->data->id, (void *)lsa, index); } } @@ -3603,9 +3683,9 @@ int ospf_lsa_refresh_walker(struct thread *t) lsa)) { if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) zlog_debug( - "LSA[Refresh:Type%d:%s]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", + "LSA[Refresh:Type%d:%pI4]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa->data->type, - inet_ntoa(lsa->data->id), + &lsa->data->id, (void *)lsa, i); assert(lsa->lock > 0); @@ -3636,3 +3716,34 @@ int ospf_lsa_refresh_walker(struct thread *t) return 0; } + +/* Flush the LSAs for the specific area */ +void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, + int type) +{ + struct ospf_area *area; + struct route_node *rn; + struct ospf_lsa *lsa; + + area = ospf_area_get(ospf, area_id); + + switch (type) { + case OSPF_AS_EXTERNAL_LSA: + if ((area->external_routing == OSPF_AREA_NSSA) || + (area->external_routing == OSPF_AREA_STUB)) { + LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) + if (IS_LSA_SELF(lsa) && + !(CHECK_FLAG(lsa->flags, + OSPF_LSA_LOCAL_XLT))) + ospf_lsa_flush_area(lsa, area); + } + break; + case OSPF_AS_NSSA_LSA: + LSDB_LOOP (NSSA_LSDB(area), rn, lsa) + if (IS_LSA_SELF(lsa)) + ospf_lsa_flush_area(lsa, area); + break; + default: + break; + } +} diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 4033659bff..c5de287948 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -119,6 +119,9 @@ struct ospf_lsa { /* VRF Id */ vrf_id_t vrf_id; + + /*For topo chg detection in HELPER role*/ + bool to_be_acknowledged; }; /* OSPF LSA Link Type. */ @@ -221,6 +224,11 @@ struct as_external_lsa { if (!(T)) \ (T) = thread_add_timer(master, (F), 0, 2) +#define CHECK_LSA_TYPE_1_TO_5_OR_7(type) \ + ((type == OSPF_ROUTER_LSA) || (type == OSPF_NETWORK_LSA) \ + || (type == OSPF_SUMMARY_LSA) || (type == OSPF_ASBR_SUMMARY_LSA) \ + || (type == OSPF_AS_EXTERNAL_LSA) || (type == OSPF_AS_NSSA_LSA)) + /* Prototypes. */ /* XXX: Eek, time functions, similar are in lib/thread.c */ extern struct timeval int2tv(int); @@ -305,7 +313,8 @@ extern void ospf_external_lsa_refresh_type(struct ospf *, uint8_t, unsigned short, int); extern struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *, struct ospf_lsa *, - struct external_info *, int); + struct external_info *, int, + bool aggr); extern struct in_addr ospf_lsa_unique_id(struct ospf *, struct ospf_lsdb *, uint8_t, struct prefix_ipv4 *); extern void ospf_schedule_lsa_flood_area(struct ospf_area *, struct ospf_lsa *); @@ -331,5 +340,6 @@ extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *, struct ospf_lsa *); extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *, struct ospf_lsa *); - +extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id, + int type); #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index c4dc0136ed..ae22cec414 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -56,3 +56,5 @@ DEFINE_MTYPE(OSPFD, OSPF_ROUTER_INFO, "OSPF Router Info parameters") DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters") DEFINE_MTYPE(OSPFD, OSPF_EXT_PARAMS, "OSPF Extended parameters") DEFINE_MTYPE(OSPFD, OSPF_SR_PARAMS, "OSPF Segment Routing parameters") +DEFINE_MTYPE(OSPFD, OSPF_GR_HELPER, "OSPF Graceful Restart Helper") +DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_RT_AGGR, "OSPF External Route Summarisation") diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h index 861de64c25..624b1d3306 100644 --- a/ospfd/ospf_memory.h +++ b/ospfd/ospf_memory.h @@ -55,5 +55,7 @@ DECLARE_MTYPE(OSPF_ROUTER_INFO) DECLARE_MTYPE(OSPF_PCE_PARAMS) DECLARE_MTYPE(OSPF_SR_PARAMS) DECLARE_MTYPE(OSPF_EXT_PARAMS) +DECLARE_MTYPE(OSPF_GR_HELPER) +DECLARE_MTYPE(OSPF_EXTERNAL_RT_AGGR) #endif /* _QUAGGA_OSPF_MEMORY_H */ diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index 46dfc505ef..2fa43923ab 100644 --- a/ospfd/ospf_neighbor.c +++ b/ospfd/ospf_neighbor.c @@ -43,6 +43,7 @@ #include "ospfd/ospf_flood.h" #include "ospfd/ospf_dump.h" #include "ospfd/ospf_bfd.h" +#include "ospfd/ospf_gr_helper.h" /* Fill in the the 'key' as appropriate to retrieve the entry for nbr * from the ospf_interface's nbrs table. Indexed by interface address @@ -99,6 +100,14 @@ struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi) nbr->crypt_seqnum = 0; ospf_bfd_info_nbr_create(oi, nbr); + + /* Initialize GR Helper info*/ + nbr->gr_helper_info.recvd_grace_period = 0; + nbr->gr_helper_info.actual_grace_period = 0; + nbr->gr_helper_info.gr_helper_status = OSPF_GR_NOT_HELPER; + nbr->gr_helper_info.helper_exit_reason = OSPF_GR_HELPER_EXIT_NONE; + nbr->gr_helper_info.gr_restart_reason = OSPF_GR_UNKNOWN_RESTART; + return nbr; } @@ -142,6 +151,8 @@ void ospf_nbr_free(struct ospf_neighbor *nbr) ospf_bfd_info_free(&nbr->bfd_info); + OSPF_NSM_TIMER_OFF(nbr->gr_helper_info.t_grace_timer); + nbr->oi = NULL; XFREE(MTYPE_OSPF_NEIGHBOR, nbr); } @@ -173,8 +184,8 @@ void ospf_nbr_delete(struct ospf_neighbor *nbr) rn->info = NULL; route_unlock_node(rn); } else - zlog_info("Can't find neighbor %s in the interface %s", - inet_ntoa(nbr->src), IF_NAME(oi)); + zlog_info("Can't find neighbor %pI4 in the interface %s", + &nbr->src, IF_NAME(oi)); route_unlock_node(rn); } else { @@ -273,8 +284,8 @@ void ospf_nbr_add_self(struct ospf_interface *oi, struct in_addr router_id) /* There is already pseudo neighbor. */ if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "router_id %s already present in neighbor table. node refcount %u", - inet_ntoa(router_id), rn->lock); + "router_id %pI4 already present in neighbor table. node refcount %u", + &router_id, route_node_get_lock_count(rn)); route_unlock_node(rn); } else rn->info = oi->nbr_self; @@ -390,8 +401,8 @@ void ospf_renegotiate_optional_capabilities(struct ospf *top) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Renegotiate optional capabilities with neighbor(%s)", - inet_ntoa(nbr->router_id)); + "Renegotiate optional capabilities with neighbor(%pI4)", + &nbr->router_id); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); } @@ -448,8 +459,8 @@ static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi, nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("NSM[%s:%s]: start", IF_NAME(oi), - inet_ntoa(nbr->router_id)); + zlog_debug("NSM[%s:%pI4]: start", IF_NAME(oi), + &nbr->router_id); return nbr; } diff --git a/ospfd/ospf_neighbor.h b/ospfd/ospf_neighbor.h index 91dfc7a276..758693e289 100644 --- a/ospfd/ospf_neighbor.h +++ b/ospfd/ospf_neighbor.h @@ -22,6 +22,7 @@ #ifndef _ZEBRA_OSPF_NEIGHBOR_H #define _ZEBRA_OSPF_NEIGHBOR_H +#include <ospfd/ospf_gr_helper.h> #include <ospfd/ospf_packet.h> /* Neighbor Data Structure */ @@ -88,6 +89,9 @@ struct ospf_neighbor { /* BFD information */ void *bfd_info; + + /* ospf graceful restart HELPER info */ + struct ospf_helper_info gr_helper_info; }; /* Macros. */ @@ -113,5 +117,4 @@ extern struct ospf_neighbor *ospf_nbr_lookup_by_addr(struct route_table *, extern struct ospf_neighbor *ospf_nbr_lookup_by_routerid(struct route_table *, struct in_addr *); extern void ospf_renegotiate_optional_capabilities(struct ospf *top); - #endif /* _ZEBRA_OSPF_NEIGHBOR_H */ diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 3a1547978a..00fbdc21a1 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -53,14 +53,14 @@ int ospf_if_add_allspfrouters(struct ospf *top, struct prefix *p, if (ret < 0) flog_err( EC_LIB_SOCKET, - "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?", - top->fd, inet_ntoa(p->u.prefix4), ifindex, + "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); else { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "interface %s [%u] join AllSPFRouters Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); + "interface %pI4 [%u] join AllSPFRouters Multicast group.", + &p->u.prefix4, ifindex); } return ret; @@ -76,14 +76,14 @@ int ospf_if_drop_allspfrouters(struct ospf *top, struct prefix *p, ifindex); if (ret < 0) flog_err(EC_LIB_SOCKET, - "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, + "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); else { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "interface %s [%u] leave AllSPFRouters Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); + "interface %pI4 [%u] leave AllSPFRouters Multicast group.", + &p->u.prefix4, ifindex); } return ret; @@ -101,13 +101,13 @@ int ospf_if_add_alldrouters(struct ospf *top, struct prefix *p, if (ret < 0) flog_err( EC_LIB_SOCKET, - "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllDRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?", - top->fd, inet_ntoa(p->u.prefix4), ifindex, + "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); else zlog_debug( - "interface %s [%u] join AllDRouters Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); + "interface %pI4 [%u] join AllDRouters Multicast group.", + &p->u.prefix4, ifindex); return ret; } @@ -122,13 +122,13 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p, ifindex); if (ret < 0) flog_err(EC_LIB_SOCKET, - "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllDRouters): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, + "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); else zlog_debug( - "interface %s [%u] leave AllDRouters Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); + "interface %pI4 [%u] leave AllDRouters Multicast group.", + &p->u.prefix4, ifindex); return ret; } @@ -161,8 +161,8 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex) ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex); if (ret < 0) flog_err(EC_LIB_SOCKET, - "can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, ifindex %u): %s", - top->fd, inet_ntoa(p->u.prefix4), ifindex, + "can't setsockopt IP_MULTICAST_IF(fd %d, addr %pI4, ifindex %u): %s", + top->fd, &p->u.prefix4, ifindex, safe_strerror(errno)); #endif @@ -201,7 +201,6 @@ int ospf_sock_init(struct ospf *ospf) flog_err(EC_LIB_SOCKET, "Can't set IP_HDRINCL option for fd %d: %s", ospf_sock, safe_strerror(errno)); - close(ospf_sock); break; } #elif defined(IPTOS_PREC_INTERNETCONTROL) @@ -213,7 +212,6 @@ int ospf_sock_init(struct ospf *ospf) flog_err(EC_LIB_SOCKET, "can't set sockopt IP_TOS %d to socket %d: %s", tos, ospf_sock, safe_strerror(errno)); - close(ospf_sock); /* Prevent sd leak. */ break; } #else /* !IPTOS_PREC_INTERNETCONTROL */ diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index dffbfb7d17..26e7855e8c 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -66,11 +66,19 @@ static int ospf_inactivity_timer(struct thread *thread) nbr->t_inactivity = NULL; if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s:%s]: Timer (Inactivity timer expire)", - IF_NAME(nbr->oi), inet_ntoa(nbr->router_id), + zlog_debug("NSM[%s:%pI4:%s]: Timer (Inactivity timer expire)", + IF_NAME(nbr->oi), &nbr->router_id, ospf_get_name(nbr->oi->ospf)); - OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); + /* Dont trigger NSM_InactivityTimer event , if the current + * router acting as HELPER for this neighbour. + */ + if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer); + else if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug( + "%s, Acting as HELPER for this neighbour, So inactivitytimer event will not be fired.", + __PRETTY_FUNCTION__); return 0; } @@ -83,8 +91,8 @@ static int ospf_db_desc_timer(struct thread *thread) nbr->t_db_desc = NULL; if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s:%s]: Timer (DD Retransmit timer expire)", - IF_NAME(nbr->oi), inet_ntoa(nbr->src), + zlog_debug("NSM[%s:%pI4:%s]: Timer (DD Retransmit timer expire)", + IF_NAME(nbr->oi), &nbr->src, ospf_get_name(nbr->oi->ospf)); /* resent last send DD packet. */ @@ -144,7 +152,7 @@ static void nsm_timer_set(struct ospf_neighbor *nbr) /* 10.4 of RFC2328, indicate whether an adjacency is appropriate with * the given neighbour */ -static int nsm_should_adj(struct ospf_neighbor *nbr) +int nsm_should_adj(struct ospf_neighbor *nbr) { struct ospf_interface *oi = nbr->oi; @@ -390,9 +398,9 @@ static int nsm_kill_nbr(struct ospf_neighbor *nbr) if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) zlog_debug( - "NSM[%s:%s:%s]: Down (PollIntervalTimer scheduled)", + "NSM[%s:%pI4:%s]: Down (PollIntervalTimer scheduled)", IF_NAME(nbr->oi), - inet_ntoa(nbr->address.u.prefix4), + &nbr->address.u.prefix4, ospf_get_name(nbr->oi->ospf)); } @@ -589,8 +597,8 @@ static void nsm_notice_state_change(struct ospf_neighbor *nbr, int next_state, { /* Logging change of status. */ if (IS_DEBUG_OSPF(nsm, NSM_STATUS)) - zlog_debug("NSM[%s:%s:%s]: State change %s -> %s (%s)", - IF_NAME(nbr->oi), inet_ntoa(nbr->router_id), + zlog_debug("NSM[%s:%pI4:%s]: State change %s -> %s (%s)", + IF_NAME(nbr->oi), &nbr->router_id, ospf_get_name(nbr->oi->ospf), lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), lookup_msg(ospf_nsm_state_msg, next_state, NULL), @@ -600,8 +608,8 @@ static void nsm_notice_state_change(struct ospf_neighbor *nbr, int next_state, if (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_CHANGES) && (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL) || (next_state == NSM_Full) || (next_state < nbr->state))) - zlog_notice("AdjChg: Nbr %s(%s) on %s: %s -> %s (%s)", - inet_ntoa(nbr->router_id), + zlog_notice("AdjChg: Nbr %pI4(%s) on %s: %s -> %s (%s)", + &nbr->router_id, ospf_get_name(nbr->oi->ospf), IF_NAME(nbr->oi), lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), lookup_msg(ospf_nsm_state_msg, next_state, NULL), @@ -683,13 +691,17 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "%s:[%s:%s], %s -> %s): scheduling new router-LSA origination", - __func__, inet_ntoa(nbr->router_id), + "%s:[%pI4:%s], %s -> %s): scheduling new router-LSA origination", + __func__, &nbr->router_id, ospf_get_name(oi->ospf), lookup_msg(ospf_nsm_state_msg, old_state, NULL), lookup_msg(ospf_nsm_state_msg, state, NULL)); - ospf_router_lsa_update_area(oi->area); + /* Dont originate router LSA if the current + * router is acting as a HELPER for this neighbour. + */ + if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) + ospf_router_lsa_update_area(oi->area); if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { vl_area = ospf_area_lookup_by_area_id( @@ -699,15 +711,21 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) ospf_router_lsa_update_area(vl_area); } - /* Originate network-LSA. */ - if (oi->state == ISM_DR) { - if (oi->network_lsa_self && oi->full_nbrs == 0) { - ospf_lsa_flush_area(oi->network_lsa_self, - oi->area); - ospf_lsa_unlock(&oi->network_lsa_self); - oi->network_lsa_self = NULL; - } else - ospf_network_lsa_update(oi); + /* Dont originate/flush network LSA if the current + * router is acting as a HELPER for this neighbour. + */ + if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) { + /* Originate network-LSA. */ + if (oi->state == ISM_DR) { + if (oi->network_lsa_self + && oi->full_nbrs == 0) { + ospf_lsa_flush_area( + oi->network_lsa_self, oi->area); + ospf_lsa_unlock(&oi->network_lsa_self); + oi->network_lsa_self = NULL; + } else + ospf_network_lsa_update(oi); + } } } @@ -731,10 +749,10 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) OSPF_DD_FLAG_I | OSPF_DD_FLAG_M | OSPF_DD_FLAG_MS; if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "%s: Initializing [DD]: %s with seqnum:%x , flags:%x", + "%s: Initializing [DD]: %pI4 with seqnum:%x , flags:%x", (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME, - inet_ntoa(nbr->router_id), nbr->dd_seqnum, + &nbr->router_id, nbr->dd_seqnum, nbr->dd_flags); ospf_db_desc_send(nbr); } @@ -759,8 +777,8 @@ int ospf_nsm_event(struct thread *thread) event = THREAD_VAL(thread); if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) - zlog_debug("NSM[%s:%s:%s]: %s (%s)", IF_NAME(nbr->oi), - inet_ntoa(nbr->router_id), + zlog_debug("NSM[%s:%pI4:%s]: %s (%s)", IF_NAME(nbr->oi), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), ospf_nsm_event_str[event]); @@ -784,8 +802,8 @@ int ospf_nsm_event(struct thread *thread) */ flog_err( EC_OSPF_FSM_INVALID_STATE, - "NSM[%s:%s:%s]: %s (%s): Warning: action tried to change next_state to %s", - IF_NAME(nbr->oi), inet_ntoa(nbr->router_id), + "NSM[%s:%pI4:%s]: %s (%s): Warning: action tried to change next_state to %s", + IF_NAME(nbr->oi), &nbr->router_id, ospf_get_name(nbr->oi->ospf), lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h index dcfba84d8b..24cf05009c 100644 --- a/ospfd/ospf_nsm.h +++ b/ospfd/ospf_nsm.h @@ -59,13 +59,7 @@ #define OSPF_NSM_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr, (V), &(T)) /* Macro for OSPF NSM timer turn off. */ -#define OSPF_NSM_TIMER_OFF(X) \ - do { \ - if (X) { \ - thread_cancel(X); \ - (X) = NULL; \ - } \ - } while (0) +#define OSPF_NSM_TIMER_OFF(X) thread_cancel(&(X)) /* Macro for OSPF NSM schedule event. */ #define OSPF_NSM_EVENT_SCHEDULE(N, E) \ @@ -81,7 +75,7 @@ extern void ospf_check_nbr_loading(struct ospf_neighbor *); extern int ospf_db_summary_isempty(struct ospf_neighbor *); extern int ospf_db_summary_count(struct ospf_neighbor *); extern void ospf_db_summary_clear(struct ospf_neighbor *); - +extern int nsm_should_adj(struct ospf_neighbor *nbr); DECLARE_HOOK(ospf_nsm_change, (struct ospf_neighbor * on, int state, int oldstate), (on, state, oldstate)) diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 061ada5b16..eb0c4a949a 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -1159,7 +1159,8 @@ void ospf_opaque_config_write_debug(struct vty *vty) return; } -void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa) +void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { struct lsa_header *lsah = lsa->data; uint32_t lsid = ntohl(lsah->id.s_addr); @@ -1169,13 +1170,17 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa) /* Switch output functionality by vty address. */ if (vty != NULL) { - vty_out(vty, " Opaque-Type %u (%s)\n", opaque_type, - ospf_opaque_type_name(opaque_type)); - vty_out(vty, " Opaque-ID 0x%x\n", opaque_id); - - vty_out(vty, " Opaque-Info: %u octets of data%s\n", - ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, - VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)"); + if (!json) { + vty_out(vty, " Opaque-Type %u (%s)\n", opaque_type, + ospf_opaque_type_name(opaque_type)); + vty_out(vty, " Opaque-ID 0x%x\n", opaque_id); + + vty_out(vty, " Opaque-Info: %u octets of data%s\n", + ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, + VALID_OPAQUE_INFO_LEN(lsah) + ? "" + : "(Invalid length?)"); + } } else { zlog_debug(" Opaque-Type %u (%s)", opaque_type, ospf_opaque_type_name(opaque_type)); @@ -1200,7 +1205,7 @@ void ospf_opaque_lsa_dump(struct stream *s, uint16_t length) struct ospf_lsa lsa; lsa.data = (struct lsa_header *)stream_pnt(s); - show_opaque_info_detail(NULL, &lsa); + show_opaque_info_detail(NULL, &lsa, NULL); return; } @@ -1469,8 +1474,8 @@ static int ospf_opaque_type10_lsa_originate(struct thread *t) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s", - inet_ntoa(area->area_id)); + "Timer[Type10-LSA]: Originate Opaque-LSAs for Area %pI4", + &area->area_id); rc = opaque_lsa_originate_callback(ospf_opaque_type10_funclist, area); @@ -1626,8 +1631,8 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa) * LSA from the routing domain. */ if (IS_DEBUG_OSPF_EVENT) - zlog_debug("LSA[Type%d:%s]: Flush stray Opaque-LSA", - lsa->data->type, inet_ntoa(lsa->data->id)); + zlog_debug("LSA[Type%d:%pI4]: Flush stray Opaque-LSA", + lsa->data->type, &lsa->data->id); lsa->data->ls_age = htons(OSPF_LSA_MAXAGE); ospf_lsa_flush(ospf, lsa); @@ -1701,8 +1706,8 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, if ((top = area->ospf) == NULL) { flog_warn( EC_OSPF_LSA, - "ospf_opaque_lsa_reoriginate_schedule: AREA(%s) -> TOP?", - inet_ntoa(area->area_id)); + "ospf_opaque_lsa_reoriginate_schedule: AREA(%pI4) -> TOP?", + &area->area_id); goto out; } if (!list_isempty(ospf_opaque_type10_funclist) @@ -1710,8 +1715,8 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent, && area->t_opaque_lsa_self != NULL) { flog_warn( EC_OSPF_LSA, - "Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%s) has already started", - opaque_type, inet_ntoa(area->area_id)); + "Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%pI4) has already started", + opaque_type, &area->area_id); goto out; } func = ospf_opaque_type10_lsa_reoriginate_timer; @@ -1927,8 +1932,8 @@ static int ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Timer[Type10-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for Area %s", - oipt->opaque_type, inet_ntoa(area->area_id)); + "Timer[Type10-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for Area %pI4", + oipt->opaque_type, &area->area_id); rc = (*functab->lsa_originator)(area); out: diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h index 96155608b2..f02f34c9af 100644 --- a/ospfd/ospf_opaque.h +++ b/ospfd/ospf_opaque.h @@ -24,6 +24,7 @@ #define _ZEBRA_OSPF_OPAQUE_H #include "vty.h" +#include <lib/json.h> #define IS_OPAQUE_LSA(type) \ ((type) == OSPF_OPAQUE_LINK_LSA || (type) == OSPF_OPAQUE_AREA_LSA \ @@ -148,7 +149,8 @@ extern void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_status); extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *ospf); extern void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp); extern void ospf_opaque_config_write_debug(struct vty *vty); -extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa); +extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json); extern void ospf_opaque_lsa_dump(struct stream *s, uint16_t length); extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 61aae695b3..ef39b6c2f6 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -54,6 +54,7 @@ #include "ospfd/ospf_dump.h" #include "ospfd/ospf_errors.h" #include "ospfd/ospf_zebra.h" +#include "ospfd/ospf_gr_helper.h" /* * OSPF Fragmentation / fragmented writes @@ -467,11 +468,7 @@ static int ospf_ls_req_timer(struct thread *thread) void ospf_ls_req_event(struct ospf_neighbor *nbr) { - if (nbr->t_ls_req) { - thread_cancel(nbr->t_ls_req); - nbr->t_ls_req = NULL; - } - nbr->t_ls_req = NULL; + thread_cancel(&nbr->t_ls_req); thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req); } @@ -605,15 +602,15 @@ static void ospf_write_frags(int fd, struct ospf_packet *op, struct ip *iph, if (ret < 0) flog_err( EC_LIB_SOCKET, - "*** ospf_write_frags: sendmsg failed to %s, id %d, off %d, len %d, mtu %u failed with %s", - inet_ntoa(iph->ip_dst), iph->ip_id, iph->ip_off, + "*** ospf_write_frags: sendmsg failed to %pI4, id %d, off %d, len %d, mtu %u failed with %s", + &iph->ip_dst, iph->ip_id, iph->ip_off, iph->ip_len, mtu, safe_strerror(errno)); if (IS_DEBUG_OSPF_PACKET(type - 1, SEND)) { zlog_debug( - "ospf_write_frags: sent id %d, off %d, len %d to %s", + "ospf_write_frags: sent id %d, off %d, len %d to %pI4", iph->ip_id, iph->ip_off, iph->ip_len, - inet_ntoa(iph->ip_dst)); + &iph->ip_dst); } iph->ip_off += offset; @@ -658,8 +655,8 @@ static int ospf_write(struct thread *thread) if (ospf->fd < 0 || ospf->oi_running == 0) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_write failed to send, fd %d, instance %u" - ,ospf->fd, ospf->oi_running); + "ospf_write failed to send, fd %d, instance %u", + ospf->fd, ospf->oi_running); return -1; } @@ -798,15 +795,15 @@ static int ospf_write(struct thread *thread) sockopt_iphdrincl_swab_systoh(&iph); if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_write to %s, id %d, off %d, len %d, interface %s, mtu %u:", - inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, + "ospf_write to %pI4, id %d, off %d, len %d, interface %s, mtu %u:", + &iph.ip_dst, iph.ip_id, iph.ip_off, iph.ip_len, oi->ifp->name, oi->ifp->mtu); if (ret < 0) flog_err( EC_LIB_SOCKET, - "*** sendmsg in ospf_write failed to %s, id %d, off %d, len %d, interface %s, mtu %u: %s", - inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, + "*** sendmsg in ospf_write failed to %pI4, id %d, off %d, len %d, interface %s, mtu %u: %s", + &iph.ip_dst, iph.ip_id, iph.ip_off, iph.ip_len, oi->ifp->name, oi->ifp->mtu, safe_strerror(errno)); @@ -819,9 +816,9 @@ static int ospf_write(struct thread *thread) ospf_packet_dump(op->s); } - zlog_debug("%s sent to [%s] via [%s].", + zlog_debug("%s sent to [%pI4] via [%s].", lookup_msg(ospf_packet_type_str, type, NULL), - inet_ntoa(op->dst), IF_NAME(oi)); + &op->dst, IF_NAME(oi)); if (IS_DEBUG_OSPF_PACKET(type - 1, DETAIL)) zlog_debug( @@ -895,10 +892,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, if (IPV4_ADDR_SAME(&ospfh->router_id, &oi->ospf->router_id)) { if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) { zlog_debug( - "ospf_header[%s/%s]: selforiginated, dropping.", + "ospf_header[%s/%pI4]: selforiginated, dropping.", lookup_msg(ospf_packet_type_str, ospfh->type, NULL), - inet_ntoa(iph->ip_src)); + &iph->ip_src); } return; } @@ -915,8 +912,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, if (oi->address->prefixlen != p.prefixlen) { flog_warn( EC_OSPF_PACKET, - "Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).", - inet_ntoa(ospfh->router_id), IF_NAME(oi), + "Packet %pI4 [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).", + &ospfh->router_id, IF_NAME(oi), (int)oi->address->prefixlen, (int)p.prefixlen); return; } @@ -924,8 +921,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, /* Compare Router Dead Interval. */ if (OSPF_IF_PARAM(oi, v_wait) != ntohl(hello->dead_interval)) { flog_warn(EC_OSPF_PACKET, - "Packet %s [Hello:RECV]: RouterDeadInterval mismatch (expected %u, but received %u).", - inet_ntoa(ospfh->router_id), + "Packet %pI4 [Hello:RECV]: RouterDeadInterval mismatch (expected %u, but received %u).", + &ospfh->router_id, OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval)); return; @@ -937,8 +934,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, != ntohs(hello->hello_interval)) { flog_warn( EC_OSPF_PACKET, - "Packet %s [Hello:RECV]: HelloInterval mismatch (expected %u, but received %u).", - inet_ntoa(ospfh->router_id), + "Packet %pI4 [Hello:RECV]: HelloInterval mismatch (expected %u, but received %u).", + &ospfh->router_id, OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval)); return; @@ -946,8 +943,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s", - inet_ntoa(ospfh->router_id), + zlog_debug("Packet %pI4 [Hello:RECV]: Options %s vrf %s", + &ospfh->router_id, ospf_options_dump(hello->options), ospf_vrf_id_to_name(oi->ospf->vrf_id)); @@ -961,8 +958,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, * relationship. */ flog_warn(EC_OSPF_PACKET, - "Packet %s [Hello:RECV]: T-bit on, drop it.", - inet_ntoa(ospfh->router_id)); + "Packet %pI4 [Hello:RECV]: T-bit on, drop it.", + &ospfh->router_id); return; } #endif /* REJECT_IF_TBIT_ON */ @@ -974,8 +971,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, * the bit should be set in DD packet only. */ flog_warn(EC_OSPF_PACKET, - "Packet %s [Hello:RECV]: O-bit abuse?", - inet_ntoa(ospfh->router_id)); + "Packet %pI4 [Hello:RECV]: O-bit abuse?", + &ospfh->router_id); #ifdef STRICT_OBIT_USAGE_CHECK return; /* Reject this packet. */ #else /* STRICT_OBIT_USAGE_CHECK */ @@ -992,14 +989,14 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, && !CHECK_FLAG(hello->options, OSPF_OPTION_E))) { flog_warn( EC_OSPF_PACKET, - "NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", - inet_ntoa(ospfh->router_id), OPTIONS(oi), + "NSSA-Packet-%pI4[Hello:RECV]: my options: %x, his options %x", + &ospfh->router_id, OPTIONS(oi), hello->options); return; } if (IS_DEBUG_OSPF_NSSA) - zlog_debug("NSSA-Hello:RECV:Packet from %s:", - inet_ntoa(ospfh->router_id)); + zlog_debug("NSSA-Hello:RECV:Packet from %pI4:", + &ospfh->router_id); } else /* The setting of the E-bit found in the Hello Packet's Options field must match this area's ExternalRoutingCapability A @@ -1010,8 +1007,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, != CHECK_FLAG(hello->options, OSPF_OPTION_E)) { flog_warn( EC_OSPF_PACKET, - "Packet %s [Hello:RECV]: my options: %x, his options %x", - inet_ntoa(ospfh->router_id), OPTIONS(oi), + "Packet %pI4 [Hello:RECV]: my options: %x, his options %x", + &ospfh->router_id, OPTIONS(oi), hello->options); return; } @@ -1058,7 +1055,16 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh, OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_TwoWayReceived); nbr->options |= hello->options; } else { - OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_OneWayReceived); + /* If the router is DR_OTHER, RESTARTER will not wait + * until it receives the hello from it if it receives + * from DR and BDR. + * So, helper might receives ONW_WAY hello from + * RESTARTER. So not allowing to change the state if it + * receives one_way hellow when it acts as HELPER for + * that specific neighbor. + */ + if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) + OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_OneWayReceived); /* Set neighbor information. */ nbr->priority = hello->priority; nbr->d_router = hello->d_router; @@ -1137,8 +1143,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, if (IS_OPAQUE_LSA(lsah->type) && !CHECK_FLAG(nbr->options, OSPF_OPTION_O)) { flog_warn(EC_OSPF_PACKET, - "LSA[Type%d:%s]: Opaque capability mismatch?", - lsah->type, inet_ntoa(lsah->id)); + "LSA[Type%d:%pI4]: Opaque capability mismatch?", + lsah->type, &lsah->id); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); return; } @@ -1152,8 +1158,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, if (oi->area->external_routing == OSPF_AREA_STUB) { flog_warn( EC_OSPF_PACKET, - "Packet [DD:RECV]: LSA[Type%d:%s] from %s area.", - lsah->type, inet_ntoa(lsah->id), + "Packet [DD:RECV]: LSA[Type%d:%pI4] from %s area.", + lsah->type, &lsah->id, (oi->area->external_routing == OSPF_AREA_STUB) ? "STUB" @@ -1208,8 +1214,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi, */ if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Packet [DD:RECV]: LSA received Type %d, ID %s is not recent.", - lsah->type, inet_ntoa(lsah->id)); + "Packet [DD:RECV]: LSA received Type %d, ID %pI4 is not recent.", + lsah->type, &lsah->id); ospf_lsa_discard(new); } } @@ -1277,8 +1283,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, nbr = ospf_nbr_lookup(oi, iph, ospfh); if (nbr == NULL) { - flog_warn(EC_OSPF_PACKET, "Packet[DD]: Unknown Neighbor %s", - inet_ntoa(ospfh->router_id)); + flog_warn(EC_OSPF_PACKET, "Packet[DD]: Unknown Neighbor %pI4", + &ospfh->router_id); return; } @@ -1287,8 +1293,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, && (ntohs(dd->mtu) > oi->ifp->mtu)) { flog_warn( EC_OSPF_PACKET, - "Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u", - inet_ntoa(nbr->router_id), ntohs(dd->mtu), IF_NAME(oi), + "Packet[DD]: Neighbor %pI4 MTU %u is larger than [%s]'s MTU %u", + &nbr->router_id, ntohs(dd->mtu), IF_NAME(oi), oi->ifp->mtu); return; } @@ -1314,8 +1320,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, && (!CHECK_FLAG(dd->options, OSPF_OPTION_NP))) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbour %pI4: Has NSSA capability, sends with N bit clear in DD options", + &nbr->router_id); SET_FLAG(dd->options, OSPF_OPTION_NP); } @@ -1325,8 +1331,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, * In Hello protocol, optional capability must have checked * to prevent this T-bit enabled router be my neighbor. */ - flog_warn(EC_OSPF_PACKET, "Packet[DD]: Neighbor %s: T-bit on?", - inet_ntoa(nbr->router_id)); + flog_warn(EC_OSPF_PACKET, "Packet[DD]: Neighbor %pI4: T-bit on?", + &nbr->router_id); return; } #endif /* REJECT_IF_TBIT_ON */ @@ -1346,9 +1352,9 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "%s:Packet[DD]: Neighbor %s state is %s, seq_num:0x%x, local:0x%x", + "%s:Packet[DD]: Neighbor %pI4 state is %s, seq_num:0x%x, local:0x%x", (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME, - inet_ntoa(nbr->router_id), + &nbr->router_id, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), ntohl(dd->dd_seqnum), nbr->dd_seqnum); @@ -1359,8 +1365,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, case NSM_TwoWay: if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "Packet[DD]: Neighbor %s state is %s, packet discarded.", - inet_ntoa(nbr->router_id), + "Packet[DD]: Neighbor %pI4 state is %s, packet discarded.", + &nbr->router_id, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); break; @@ -1382,8 +1388,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "Packet[DD]: Neighbor %s Negotiation done (Slave).", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 Negotiation done (Slave).", + &nbr->router_id); nbr->dd_seqnum = ntohl(dd->dd_seqnum); @@ -1396,8 +1402,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "Packet[DD]: Neighbor %s: Initial DBD from Slave, ignoring.", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4: Initial DBD from Slave, ignoring.", + &nbr->router_id); break; } } @@ -1407,14 +1413,14 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, && IPV4_ADDR_CMP(&nbr->router_id, &oi->ospf->router_id) < 0) { zlog_info( - "Packet[DD]: Neighbor %s Negotiation done (Master).", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 Negotiation done (Master).", + &nbr->router_id); /* Reset I, leaving MS */ UNSET_FLAG(nbr->dd_flags, OSPF_DD_FLAG_I); } else { flog_warn(EC_OSPF_PACKET, - "Packet[DD]: Neighbor %s Negotiation fails.", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 Negotiation fails.", + &nbr->router_id); break; } @@ -1424,8 +1430,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Neighbor[%s] is %sOpaque-capable.", - inet_ntoa(nbr->router_id), + "Neighbor[%pI4] is %sOpaque-capable.", + &nbr->router_id, CHECK_FLAG(nbr->options, OSPF_OPTION_O) ? "" : "NOT "); @@ -1435,8 +1441,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, &nbr->address.u.prefix4)) { flog_warn( EC_OSPF_PACKET, - "DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", - inet_ntoa(nbr->router_id)); + "DR-neighbor[%pI4] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", + &nbr->router_id); /* This situation is undesirable, but not a real * error. */ } @@ -1452,15 +1458,15 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (IS_SET_DD_MS(nbr->dd_flags)) /* Master: discard duplicated DD packet. */ zlog_info( - "Packet[DD] (Master): Neighbor %s packet duplicated.", - inet_ntoa(nbr->router_id)); + "Packet[DD] (Master): Neighbor %pI4 packet duplicated.", + &nbr->router_id); else /* Slave: cause to retransmit the last Database Description. */ { zlog_info( - "Packet[DD] [Slave]: Neighbor %s packet duplicated.", - inet_ntoa(nbr->router_id)); + "Packet[DD] [Slave]: Neighbor %pI4 packet duplicated.", + &nbr->router_id); ospf_db_desc_resend(nbr); } break; @@ -1471,8 +1477,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (IS_SET_DD_MS(dd->flags) != IS_SET_DD_MS(nbr->last_recv.flags)) { flog_warn(EC_OSPF_PACKET, - "Packet[DD]: Neighbor %s MS-bit mismatch.", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 MS-bit mismatch.", + &nbr->router_id); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); if (IS_DEBUG_OSPF_EVENT) zlog_debug( @@ -1483,8 +1489,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* Check initialize bit is set. */ if (IS_SET_DD_I(dd->flags)) { - zlog_info("Packet[DD]: Neighbor %s I-bit set.", - inet_ntoa(nbr->router_id)); + zlog_info("Packet[DD]: Neighbor %pI4 I-bit set.", + &nbr->router_id); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); break; } @@ -1492,8 +1498,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, /* Check DD Options. */ if (dd->options != nbr->options) { flog_warn(EC_OSPF_PACKET, - "Packet[DD]: Neighbor %s options mismatch.", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 options mismatch.", + &nbr->router_id); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); break; } @@ -1505,8 +1511,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, && ntohl(dd->dd_seqnum) != nbr->dd_seqnum + 1)) { flog_warn( EC_OSPF_PACKET, - "Packet[DD]: Neighbor %s sequence number mismatch.", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 sequence number mismatch.", + &nbr->router_id); OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch); break; } @@ -1520,8 +1526,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, if (IS_SET_DD_MS(nbr->dd_flags)) { /* Master should discard duplicate DD packet. */ zlog_info( - "Packet[DD]: Neighbor %s duplicated, packet discarded.", - inet_ntoa(nbr->router_id)); + "Packet[DD]: Neighbor %pI4 duplicated, packet discarded.", + &nbr->router_id); break; } else { if (monotime_since(&nbr->last_send_ts, NULL) @@ -1554,8 +1560,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh, break; default: flog_warn(EC_OSPF_PACKET, - "Packet[DD]: Neighbor %s NSM illegal status %u.", - inet_ntoa(nbr->router_id), nbr->state); + "Packet[DD]: Neighbor %pI4 NSM illegal status %u.", + &nbr->router_id, nbr->state); break; } } @@ -1581,8 +1587,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, nbr = ospf_nbr_lookup(oi, iph, ospfh); if (nbr == NULL) { flog_warn(EC_OSPF_PACKET, - "Link State Request: Unknown Neighbor %s.", - inet_ntoa(ospfh->router_id)); + "Link State Request: Unknown Neighbor %pI4", + &ospfh->router_id); return; } @@ -1594,8 +1600,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh, && nbr->state != NSM_Full) { flog_warn( EC_OSPF_PACKET, - "Link State Request received from %s: Neighbor state is %s, packet discarded.", - inet_ntoa(ospfh->router_id), + "Link State Request received from %pI4: Neighbor state is %s, packet discarded.", + &ospfh->router_id, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); return; } @@ -1702,10 +1708,10 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, * other */ flog_warn( EC_OSPF_PACKET, - "Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s", - sum, lsah->checksum, inet_ntoa(lsah->id), - inet_ntoa(nbr->src), inet_ntoa(nbr->router_id), - inet_ntoa(lsah->adv_router)); + "Link State Update: LSA checksum error %x/%x, ID=%pI4 from: nbr %pI4, router ID %pI4, adv router %pI4", + sum, lsah->checksum, &lsah->id, + &nbr->src, &nbr->router_id, + &lsah->adv_router); continue; } @@ -1737,8 +1743,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, * only. */ flog_warn(EC_OSPF_PACKET, - "LSA[Type%d:%s]: O-bit abuse?", - lsah->type, inet_ntoa(lsah->id)); + "LSA[Type%d:%pI4]: O-bit abuse?", + lsah->type, &lsah->id); continue; } #endif /* STRICT_OBIT_USAGE_CHECK */ @@ -1750,15 +1756,15 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, != OSPF_AREA_DEFAULT) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "LSA[Type%d:%s]: We are a stub, don't take this LSA.", + "LSA[Type%d:%pI4]: We are a stub, don't take this LSA.", lsah->type, - inet_ntoa(lsah->id)); + &lsah->id); continue; } } else if (IS_OPAQUE_LSA(lsah->type)) { flog_warn(EC_OSPF_PACKET, - "LSA[Type%d:%s]: Opaque capability mismatch?", - lsah->type, inet_ntoa(lsah->id)); + "LSA[Type%d:%pI4]: Opaque capability mismatch?", + lsah->type, &lsah->id); continue; } @@ -1786,8 +1792,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr, if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "LSA[Type%d:%s]: %p new LSA created with Link State Update", - lsa->data->type, inet_ntoa(lsa->data->id), + "LSA[Type%d:%pI4]: %p new LSA created with Link State Update", + lsa->data->type, &lsa->data->id, (void *)lsa); listnode_add(lsas, lsa); } @@ -1828,8 +1834,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, nbr = ospf_nbr_lookup(oi, iph, ospfh); if (nbr == NULL) { flog_warn(EC_OSPF_PACKET, - "Link State Update: Unknown Neighbor %s on int: %s", - inet_ntoa(ospfh->router_id), IF_NAME(oi)); + "Link State Update: Unknown Neighbor %pI4 on int: %s", + &ospfh->router_id, IF_NAME(oi)); return; } @@ -1840,8 +1846,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, if (nbr->state < NSM_Exchange) { if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) zlog_debug( - "Link State Update: Neighbor[%s] state %s is less than Exchange", - inet_ntoa(ospfh->router_id), + "Link State Update: Neighbor[%pI4] state %s is less than Exchange", + &ospfh->router_id, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); return; @@ -2231,8 +2237,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, nbr = ospf_nbr_lookup(oi, iph, ospfh); if (nbr == NULL) { flog_warn(EC_OSPF_PACKET, - "Link State Acknowledgment: Unknown Neighbor %s.", - inet_ntoa(ospfh->router_id)); + "Link State Acknowledgment: Unknown Neighbor %pI4", + &ospfh->router_id); return; } @@ -2242,8 +2248,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh, if (nbr->state < NSM_Exchange) { if (IS_DEBUG_OSPF(nsm, NSM_EVENTS)) zlog_debug( - "Link State Acknowledgment: Neighbor[%s] state %s is less than Exchange", - inet_ntoa(ospfh->router_id), + "Link State Acknowledgment: Neighbor[%pI4] state %s is less than Exchange", + &ospfh->router_id, lookup_msg(ospf_nsm_state_msg, nbr->state, NULL)); return; @@ -2475,9 +2481,9 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) flog_warn( EC_OSPF_PACKET, - "interface %s: Null auth OK, but checksum error, Router-ID %s", + "interface %s: Null auth OK, but checksum error, Router-ID %pI4", IF_NAME(oi), - inet_ntoa(ospfh->router_id)); + &ospfh->router_id); return 0; } return 1; @@ -2505,9 +2511,9 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh) if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) flog_warn( EC_OSPF_PACKET, - "interface %s: Simple auth OK, checksum error, Router-ID %s", + "interface %s: Simple auth OK, checksum error, Router-ID %pI4", IF_NAME(oi), - inet_ntoa(ospfh->router_id)); + &ospfh->router_id); return 0; } return 1; @@ -2906,8 +2912,8 @@ static int ospf_verify_header(struct stream *ibuf, struct ospf_interface *oi, /* Check Area ID. */ if (!ospf_check_area_id(oi, ospfh)) { flog_warn(EC_OSPF_PACKET, - "interface %s: ospf_read invalid Area ID %s.", - IF_NAME(oi), inet_ntoa(ospfh->area_id)); + "interface %s: ospf_read invalid Area ID %pI4", + IF_NAME(oi), &ospfh->area_id); return -1; } @@ -2915,8 +2921,8 @@ static int ospf_verify_header(struct stream *ibuf, struct ospf_interface *oi, if (!ospf_check_network_mask(oi, iph->ip_src)) { flog_warn( EC_OSPF_PACKET, - "interface %s: ospf_read network address is not same [%s]", - IF_NAME(oi), inet_ntoa(iph->ip_src)); + "interface %s: ospf_read network address is not same [%pI4]", + IF_NAME(oi), &iph->ip_src); return -1; } @@ -2974,8 +2980,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) if (ifp == NULL) { if (IS_DEBUG_OSPF_PACKET(0, RECV)) zlog_debug( - "%s: Unable to determine incoming interface from: %s(%s)", - __func__, inet_ntoa(iph->ip_src), + "%s: Unable to determine incoming interface from: %pI4(%s)", + __func__, &iph->ip_src, ospf_get_name(ospf)); return OSPF_READ_CONTINUE; } @@ -2985,8 +2991,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) if (ospf_if_lookup_by_local_addr(ospf, NULL, iph->ip_src)) { if (IS_DEBUG_OSPF_PACKET(0, RECV)) { zlog_debug( - "ospf_read[%s]: Dropping self-originated packet", - inet_ntoa(iph->ip_src)); + "ospf_read[%pI4]: Dropping self-originated packet", + &iph->ip_src); } return OSPF_READ_CONTINUE; } @@ -3064,8 +3070,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) == NULL) { if (!ospf->instance && IS_DEBUG_OSPF_EVENT) zlog_debug( - "Packet from [%s] received on link %s but no ospf_interface", - inet_ntoa(iph->ip_src), ifp->name); + "Packet from [%pI4] received on link %s but no ospf_interface", + &iph->ip_src, ifp->name); return OSPF_READ_CONTINUE; } } @@ -3077,8 +3083,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) else if (oi->ifp != ifp) { if (IS_DEBUG_OSPF_EVENT) flog_warn(EC_OSPF_PACKET, - "Packet from [%s] received on wrong link %s", - inet_ntoa(iph->ip_src), ifp->name); + "Packet from [%pI4] received on wrong link %s", + &iph->ip_src, ifp->name); return OSPF_READ_CONTINUE; } else if (oi->state == ISM_Down) { char buf[2][INET_ADDRSTRLEN]; @@ -3112,8 +3118,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) && (oi->state != ISM_DR && oi->state != ISM_Backup)) { flog_warn( EC_OSPF_PACKET, - "Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)", - inet_ntoa(iph->ip_src), IF_NAME(oi), + "Dropping packet for AllDRouters from [%pI4] via [%s] (ISM: %s)", + &iph->ip_src, IF_NAME(oi), lookup_msg(ospf_ism_state_msg, oi->state, NULL)); /* Try to fix multicast membership. */ SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS); @@ -3126,8 +3132,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) if (ret < 0) { if (IS_DEBUG_OSPF_PACKET(0, RECV)) zlog_debug( - "ospf_read[%s]: Header check failed, dropping.", - inet_ntoa(iph->ip_src)); + "ospf_read[%pI4]: Header check failed, dropping.", + &iph->ip_src); return OSPF_READ_CONTINUE; } @@ -3139,11 +3145,11 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf) ospf_packet_dump(ibuf); } - zlog_debug("%s received from [%s] via [%s]", + zlog_debug("%s received from [%pI4] via [%s]", lookup_msg(ospf_packet_type_str, ospfh->type, NULL), - inet_ntoa(ospfh->router_id), IF_NAME(oi)); - zlog_debug(" src [%s],", inet_ntoa(iph->ip_src)); - zlog_debug(" dst [%s]", inet_ntoa(iph->ip_dst)); + &ospfh->router_id, IF_NAME(oi)); + zlog_debug(" src [%pI4],", &iph->ip_src); + zlog_debug(" dst [%pI4]", &iph->ip_dst); if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, DETAIL)) zlog_debug( @@ -3726,8 +3732,8 @@ int ospf_poll_timer(struct thread *thread) nbr_nbma->t_poll = NULL; if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)", - IF_NAME(nbr_nbma->oi), inet_ntoa(nbr_nbma->addr)); + zlog_debug("NSM[%s:%pI4]: Timer (Poll timer expire)", + IF_NAME(nbr_nbma->oi), &nbr_nbma->addr); ospf_poll_send(nbr_nbma); @@ -3747,8 +3753,8 @@ int ospf_hello_reply_timer(struct thread *thread) nbr->t_hello_reply = NULL; if (IS_DEBUG_OSPF(nsm, NSM_TIMERS)) - zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)", - IF_NAME(nbr->oi), inet_ntoa(nbr->router_id)); + zlog_debug("NSM[%s:%pI4]: Timer (hello-reply timer expire)", + IF_NAME(nbr->oi), &nbr->router_id); ospf_hello_send_sub(nbr->oi, nbr->address.u.prefix4.s_addr); @@ -3865,9 +3871,9 @@ void ospf_db_desc_send(struct ospf_neighbor *nbr) monotime(&nbr->last_send_ts); if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "%s:Packet[DD]: %s DB Desc send with seqnum:%x , flags:%x", + "%s:Packet[DD]: %pI4 DB Desc send with seqnum:%x , flags:%x", (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME, - inet_ntoa(nbr->router_id), nbr->dd_seqnum, + &nbr->router_id, nbr->dd_seqnum, nbr->dd_flags); } @@ -3885,9 +3891,9 @@ void ospf_db_desc_resend(struct ospf_neighbor *nbr) OSPF_ISM_WRITE_ON(oi->ospf); if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) zlog_info( - "%s:Packet[DD]: %s DB Desc resend with seqnum:%x , flags:%x", + "%s:Packet[DD]: %pI4 DB Desc resend with seqnum:%x , flags:%x", (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME, - inet_ntoa(nbr->router_id), nbr->dd_seqnum, + &nbr->router_id, nbr->dd_seqnum, nbr->dd_flags); } @@ -3982,10 +3988,10 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update, if (IS_DEBUG_OSPF_PACKET(0, SEND)) zlog_debug( - "ospf_ls_upd_packet_new: oversized LSA id:%s, %d bytes originated by %s, will be fragmented!", - inet_ntoa(lsa->data->id), + "ospf_ls_upd_packet_new: oversized LSA id:%pI4, %d bytes originated by %pI4, will be fragmented!", + &lsa->data->id, ntohs(lsa->data->length), - inet_ntoa(lsa->data->adv_router)); + &lsa->data->adv_router); /* * Allocate just enough to fit this LSA only, to avoid including @@ -4000,8 +4006,8 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update, if (size > OSPF_MAX_PACKET_SIZE) { flog_warn(EC_OSPF_LARGE_LSA, - "ospf_ls_upd_packet_new: oversized LSA id:%s too big, %d bytes, packet size %ld, dropping it completely. OSPF routing is broken!", - inet_ntoa(lsa->data->id), ntohs(lsa->data->length), + "ospf_ls_upd_packet_new: oversized LSA id:%pI4 too big, %d bytes, packet size %ld, dropping it completely. OSPF routing is broken!", + &lsa->data->id, ntohs(lsa->data->length), (long int)size); list_delete_node(update, ln); return NULL; @@ -4033,8 +4039,8 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi, uint16_t length = OSPF_HEADER_SIZE; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("listcount = %d, [%s]dst %s", listcount(update), - IF_NAME(oi), inet_ntoa(addr)); + zlog_debug("listcount = %d, [%s]dst %pI4", listcount(update), + IF_NAME(oi), &addr); /* Check that we have really something to process */ if (listcount(update) == 0) @@ -4262,6 +4268,12 @@ void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { struct ospf_interface *oi = nbr->oi; + if (IS_GRACE_LSA(lsa)) { + if (IS_DEBUG_OSPF_GR_HELPER) + zlog_debug("%s, Sending GRACE ACK to Restarter.", + __PRETTY_FUNCTION__); + } + if (listcount(oi->ls_ack_direct.ls_ack) == 0) oi->ls_ack_direct.dst = nbr->address.u.prefix4; diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 5a3e029f2e..72b87edafb 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -33,11 +33,11 @@ #define OSPF_LS_UPD_MIN_SIZE 4U #define OSPF_LS_ACK_MIN_SIZE 0U -#define OSPF_MSG_HELLO 1 /* OSPF Hello Message. */ -#define OSPF_MSG_DB_DESC 2 /* OSPF Database Descriptoin Message. */ -#define OSPF_MSG_LS_REQ 3 /* OSPF Link State Request Message. */ -#define OSPF_MSG_LS_UPD 4 /* OSPF Link State Update Message. */ -#define OSPF_MSG_LS_ACK 5 /* OSPF Link State Acknoledgement Message. */ +#define OSPF_MSG_HELLO 1 /* OSPF Hello Message. */ +#define OSPF_MSG_DB_DESC 2 /* OSPF Database Description Message. */ +#define OSPF_MSG_LS_REQ 3 /* OSPF Link State Request Message. */ +#define OSPF_MSG_LS_UPD 4 /* OSPF Link State Update Message. */ +#define OSPF_MSG_LS_ACK 5 /* OSPF Link State Acknowledgement Message. */ #define OSPF_SEND_PACKET_DIRECT 1 #define OSPF_SEND_PACKET_INDIRECT 2 diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index fc9c8f6be6..3145d16161 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -544,8 +544,8 @@ static void initialize_params(struct ospf_router_info *ori) if (!list_isempty(OspfRI.area_info)) list_delete_all_node(OspfRI.area_info); for (ALL_LIST_ELEMENTS(top->areas, node, nnode, area)) { - zlog_debug("RI (%s): Add area %s to Router Information", - __func__, inet_ntoa(area->area_id)); + zlog_debug("RI (%s): Add area %pI4 to Router Information", + __func__, &area->area_id); new = XCALLOC(MTYPE_OSPF_ROUTER_INFO, sizeof(struct ospf_ri_area_info)); new->area = area; @@ -795,8 +795,8 @@ static struct ospf_lsa *ospf_router_info_lsa_new(struct ospf_area *area) if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance", - lsa_type, inet_ntoa(lsa_id)); + "LSA[Type%d:%pI4]: Create an Opaque-LSA/ROUTER INFORMATION instance", + lsa_type, &lsa_id); top = ospf_lookup_by_vrf_id(VRF_DEFAULT); @@ -874,8 +874,8 @@ static int ospf_router_info_lsa_originate_as(void *arg) if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { zlog_debug( - "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION", - new->data->type, inet_ntoa(new->data->id)); + "LSA[Type%d:%pI4]: Originate Opaque-LSA/ROUTER INFORMATION", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -943,8 +943,8 @@ static int ospf_router_info_lsa_originate_area(void *arg) if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { zlog_debug( - "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION", - new->data->type, inet_ntoa(new->data->id)); + "LSA[Type%d:%pI4]: Originate Opaque-LSA/ROUTER INFORMATION", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1094,8 +1094,8 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa) /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { zlog_debug( - "LSA[Type%d:%s]: Refresh Opaque-LSA/ROUTER INFORMATION", - new->data->type, inet_ntoa(new->data->id)); + "LSA[Type%d:%pI4]: Refresh Opaque-LSA/ROUTER INFORMATION", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1247,11 +1247,11 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty, if (ntohs(top->address.type) == PCE_ADDRESS_TYPE_IPV4) { if (vty != NULL) - vty_out(vty, " PCE Address: %s\n", - inet_ntoa(top->address.value)); + vty_out(vty, " PCE Address: %pI4\n", + &top->address.value); else - zlog_debug(" PCE Address: %s", - inet_ntoa(top->address.value)); + zlog_debug(" PCE Address: %pI4", + &top->address.value); } else { /* TODO: Add support to IPv6 with inet_ntop() */ if (vty != NULL) @@ -1288,9 +1288,9 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty, if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) { tmp.s_addr = top->value; if (vty != NULL) - vty_out(vty, " PCE domain Area: %s\n", inet_ntoa(tmp)); + vty_out(vty, " PCE domain Area: %pI4\n", &tmp); else - zlog_debug(" PCE domain Area: %s", inet_ntoa(tmp)); + zlog_debug(" PCE domain Area: %pI4", &tmp); } else { if (vty != NULL) vty_out(vty, " PCE domain AS: %d\n", @@ -1312,10 +1312,10 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty, if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) { tmp.s_addr = top->value; if (vty != NULL) - vty_out(vty, " PCE neighbor Area: %s\n", - inet_ntoa(tmp)); + vty_out(vty, " PCE neighbor Area: %pI4\n", + &tmp); else - zlog_debug(" PCE neighbor Area: %s", inet_ntoa(tmp)); + zlog_debug(" PCE neighbor Area: %pI4", &tmp); } else { if (vty != NULL) vty_out(vty, " PCE neighbor AS: %d\n", @@ -1543,8 +1543,8 @@ static void ospf_router_info_config_write_router(struct vty *vty) if (OspfRI.pce_info.enabled) { if (pce->pce_address.header.type != 0) - vty_out(vty, " pce address %s\n", - inet_ntoa(pce->pce_address.address.value)); + vty_out(vty, " pce address %pI4\n", + &pce->pce_address.address.value); if (pce->pce_cap_flag.header.type != 0) vty_out(vty, " pce flag 0x%x\n", @@ -1554,8 +1554,8 @@ static void ospf_router_info_config_write_router(struct vty *vty) if (domain->header.type != 0) { if (domain->type == PCE_DOMAIN_TYPE_AREA) { tmp.s_addr = domain->value; - vty_out(vty, " pce domain area %s\n", - inet_ntoa(tmp)); + vty_out(vty, " pce domain area %pI4\n", + &tmp); } else { vty_out(vty, " pce domain as %d\n", ntohl(domain->value)); @@ -1567,8 +1567,9 @@ static void ospf_router_info_config_write_router(struct vty *vty) if (neighbor->header.type != 0) { if (neighbor->type == PCE_DOMAIN_TYPE_AREA) { tmp.s_addr = neighbor->value; - vty_out(vty, " pce neighbor area %s\n", - inet_ntoa(tmp)); + vty_out(vty, + " pce neighbor area %pI4\n", + &tmp); } else { vty_out(vty, " pce neighbor as %d\n", ntohl(neighbor->value)); diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 3b049555ba..bcf563a5ba 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -307,8 +307,8 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v, lsa = (struct router_lsa *)v->lsa; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_intra_add_router: LS ID: %s", - inet_ntoa(lsa->header.id)); + zlog_debug("ospf_intra_add_router: LS ID: %pI4", + &lsa->header.id); if (!OSPF_IS_AREA_BACKBONE(area)) ospf_vl_up_check(area, lsa->header.id, v); @@ -364,8 +364,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v, apply_mask_ipv4(&p); if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_intra_add_router: talking about %s/%d", - inet_ntoa(p.prefix), p.prefixlen); + zlog_debug("ospf_intra_add_router: talking about %pFX", &p); rn = route_node_get(rt, (struct prefix *)&p); @@ -467,8 +466,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link, apply_mask_ipv4(&p); if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_intra_add_stub(): processing route to %s/%d", - inet_ntoa(p.prefix), p.prefixlen); + zlog_debug("ospf_intra_add_stub(): processing route to %pFX", + &p); /* (1) Calculate the distance D of stub network from the root. D is equal to the distance from the root to the router vertex @@ -488,8 +487,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link, if (parent_is_root && link->link_data.s_addr == 0xffffffff && ospf_if_lookup_by_local_addr(area->ospf, NULL, link->link_id)) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: ignoring host route %s/32 to self.", - __func__, inet_ntoa(link->link_id)); + zlog_debug("%s: ignoring host route %pI4/32 to self.", + __func__, &link->link_id); return; } @@ -653,8 +652,8 @@ void ospf_route_table_dump(struct route_table *rt) or->cost); for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) - zlog_debug(" -> %s", - inet_ntoa(path->nexthop)); + zlog_debug(" -> %pI4", + &path->nexthop); } else zlog_debug("R %-18pI4 %-15pI4 %s %d", &rn->p.u.prefix4, @@ -682,11 +681,12 @@ void ospf_route_table_print(struct vty *vty, struct route_table *rt) or->cost); for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) - vty_out(vty, " -> %s\n", - path->nexthop.s_addr != 0 - ? inet_ntoa( - path->nexthop) - : "directly connected"); + if (path->nexthop.s_addr != 0) + vty_out(vty, " -> %pI4\n", + &path->nexthop); + else + vty_out(vty, " -> %s\n", + "directly connected"); } else vty_out(vty, "R %-18pI4 %-15pI4 %s %d\n", &rn->p.u.prefix4, & or->u.std.area_id, @@ -896,9 +896,8 @@ void ospf_prune_unreachable_networks(struct route_table *rt) or = rn->info; if (listcount(or->paths) == 0) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Pruning route to %s/%d", - inet_ntoa(rn->p.u.prefix4), - rn->p.prefixlen); + zlog_debug("Pruning route to %pFX", + &rn->p); ospf_route_free(or); rn->info = NULL; @@ -926,11 +925,11 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs) for (ALL_LIST_ELEMENTS(paths, node, nnode, or)) { if (listcount(or->paths) == 0) { if (IS_DEBUG_OSPF_EVENT) { - zlog_debug("Pruning route to rtr %s", - inet_ntoa(rn->p.u.prefix4)); + zlog_debug("Pruning route to rtr %pI4", + &rn->p.u.prefix4); zlog_debug( - " via area %s", - inet_ntoa(or->u.std.area_id)); + " via area %pI4", + &or->u.std.area_id); } listnode_delete(paths, or); @@ -940,8 +939,8 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs) if (listcount(paths) == 0) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Pruning router node %s", - inet_ntoa(rn->p.u.prefix4)); + zlog_debug("Pruning router node %pI4", + &rn->p.u.prefix4); list_delete(&paths); rn->info = NULL; @@ -989,9 +988,7 @@ int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "ospf_add_discard_route(): adding %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + zlog_debug("ospf_add_discard_route(): adding %pFX", p); new_or = ospf_route_new(); new_or->type = OSPF_DESTINATION_DISCARD; @@ -1014,9 +1011,7 @@ void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt, struct ospf_route * or ; if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "ospf_delete_discard_route(): deleting %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + zlog_debug("ospf_delete_discard_route(): deleting %pFX", p); rn = route_node_lookup(rt, (struct prefix *)p); diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 63191d5cb5..033046da0a 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -2455,8 +2455,8 @@ static void ospfTrapNbrStateChange(struct ospf_neighbor *on) ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf)); if (IS_DEBUG_OSPF_EVENT) - zlog_info("%s: trap sent: %s now %s", __func__, - inet_ntoa(on->address.u.prefix4), msgbuf); + zlog_info("%s: trap sent: %pI4 now %s", __func__, + &on->address.u.prefix4, msgbuf); oid_copy_addr(index, &(on->address.u.prefix4), IN_ADDR_SIZE); index[IN_ADDR_SIZE] = 0; @@ -2486,20 +2486,25 @@ static void ospfTrapVirtNbrStateChange(struct ospf_neighbor *on) static int ospf_snmp_nsm_change(struct ospf_neighbor *nbr, int next_state, int old_state) { - /* Terminal state or regression */ - if ((next_state == NSM_Full) || (next_state == NSM_TwoWay) - || (next_state < old_state)) { - /* ospfVirtNbrStateChange */ - if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK) - ospfTrapVirtNbrStateChange(nbr); - /* ospfNbrStateChange trap */ - else - /* To/From FULL, only managed by DR */ - if (((next_state != NSM_Full) - && (nbr->state != NSM_Full)) - || (nbr->oi->state == ISM_DR)) - ospfTrapNbrStateChange(nbr); - } + /* Transition to/from state Full should be handled only by + * DR when in Broadcast or Non-Brodcast Multi-Access networks + */ + if ((next_state == NSM_Full || old_state == NSM_Full) + && (nbr->oi->state != ISM_DR) + && (nbr->oi->type == OSPF_IFTYPE_BROADCAST + || nbr->oi->type == OSPF_IFTYPE_NBMA)) + return 0; + + /* State progression to non-terminal state */ + if (next_state > old_state && next_state != NSM_Full + && next_state != NSM_TwoWay) + return 0; + + if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK) + ospfTrapVirtNbrStateChange(nbr); + else + ospfTrapNbrStateChange(nbr); + return 0; } @@ -2508,8 +2513,8 @@ static void ospfTrapIfStateChange(struct ospf_interface *oi) oid index[sizeof(oid) * (IN_ADDR_SIZE + 1)]; if (IS_DEBUG_OSPF_EVENT) - zlog_info("%s: trap sent: %s now %s", __func__, - inet_ntoa(oi->address->u.prefix4), + zlog_info("%s: trap sent: %pI4 now %s", __func__, + &oi->address->u.prefix4, lookup_msg(ospf_ism_state_msg, oi->state, NULL)); oid_copy_addr(index, &(oi->address->u.prefix4), IN_ADDR_SIZE); diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index f5e393a13c..b53719a402 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -200,10 +200,10 @@ static struct vertex *ospf_vertex_new(struct ospf_area *area, listnode_add(area->spf_vertex_list, new); if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: Created %s vertex %s", __func__, + zlog_debug("%s: Created %s vertex %pI4", __func__, new->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa(new->lsa->id)); + &new->lsa->id); return new; } @@ -213,9 +213,9 @@ static void ospf_vertex_free(void *data) struct vertex *v = data; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: Free %s vertex %s", __func__, + zlog_debug("%s: Free %s vertex %pI4", __func__, v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa(v->lsa->id)); + &v->lsa->id); if (v->children) list_delete(&v->children); @@ -234,9 +234,9 @@ static void ospf_vertex_dump(const char *msg, struct vertex *v, if (!IS_DEBUG_OSPF_EVENT) return; - zlog_debug("%s %s vertex %s distance %u flags %u", msg, + zlog_debug("%s %s vertex %pI4 distance %u flags %u", msg, v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa(v->lsa->id), v->distance, (unsigned int)v->flags); + &v->lsa->id, v->distance, (unsigned int)v->flags); if (print_parents) { struct listnode *node; @@ -247,8 +247,8 @@ static void ospf_vertex_dump(const char *msg, struct vertex *v, if (vp) { zlog_debug( - "parent %s backlink %d nexthop %s lsa pos %d", - inet_ntoa(vp->parent->lsa->id), + "parent %pI4 backlink %d nexthop %s lsa pos %d", + &vp->parent->lsa->id, vp->backlink, inet_ntop(AF_INET, &vp->nexthop->router, buf1, BUFSIZ), @@ -826,9 +826,9 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area, } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("%s: Next vertex of %s vertex %s", __func__, + zlog_debug("%s: Next vertex of %s vertex %pI4", __func__, v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network", - inet_ntoa(v->lsa->id)); + &v->lsa->id); p = ((uint8_t *)v->lsa) + OSPF_LSA_HEADER_SIZE + 4; lim = ((uint8_t *)v->lsa) + ntohs(v->lsa->length); @@ -868,20 +868,20 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area, if (type == LSA_LINK_TYPE_VIRTUALLINK && IS_DEBUG_OSPF_EVENT) zlog_debug( - "looking up LSA through VL: %s", - inet_ntoa(l->link_id)); + "looking up LSA through VL: %pI4", + &l->link_id); w_lsa = ospf_lsa_lookup(area->ospf, area, OSPF_ROUTER_LSA, l->link_id, l->link_id); if (w_lsa && IS_DEBUG_OSPF_EVENT) - zlog_debug("found Router LSA %s", - inet_ntoa(l->link_id)); + zlog_debug("found Router LSA %pI4", + &l->link_id); break; case LSA_LINK_TYPE_TRANSIT: if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "Looking up Network LSA, ID: %s", - inet_ntoa(l->link_id)); + "Looking up Network LSA, ID: %pI4", + &l->link_id); w_lsa = ospf_lsa_lookup_by_id( area, OSPF_NETWORK_LSA, l->link_id); if (w_lsa && IS_DEBUG_OSPF_EVENT) @@ -904,8 +904,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area, w_lsa = ospf_lsa_lookup_by_id(area, OSPF_ROUTER_LSA, *r); if (w_lsa && IS_DEBUG_OSPF_EVENT) - zlog_debug("found Router LSA %s", - inet_ntoa(w_lsa->data->id)); + zlog_debug("found Router LSA %pI4", + &w_lsa->data->id); /* step (d) below */ distance = v->distance; @@ -1003,20 +1003,21 @@ static void ospf_spf_dump(struct vertex *v, int i) if (v->type == OSPF_VERTEX_ROUTER) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug("SPF Result: %d [R] %s", i, - inet_ntoa(v->lsa->id)); + zlog_debug("SPF Result: %d [R] %pI4", i, + &v->lsa->id); } else { struct network_lsa *lsa = (struct network_lsa *)v->lsa; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("SPF Result: %d [N] %s/%d", i, - inet_ntoa(v->lsa->id), + zlog_debug("SPF Result: %d [N] %pI4/%d", i, + &v->lsa->id, ip_masklen(lsa->mask)); } if (IS_DEBUG_OSPF_EVENT) for (ALL_LIST_ELEMENTS_RO(v->parents, nnode, parent)) { - zlog_debug(" nexthop %p %s %d", (void *)parent->nexthop, - inet_ntoa(parent->nexthop->router), + zlog_debug(" nexthop %p %pI4 %d", + (void *)parent->nexthop, + &parent->nexthop->router, parent->nexthop->lsa_pos); } @@ -1033,17 +1034,17 @@ void ospf_spf_print(struct vty *vty, struct vertex *v, int i) struct vertex_parent *parent; if (v->type == OSPF_VERTEX_ROUTER) { - vty_out(vty, "SPF Result: depth %d [R] %s\n", i, - inet_ntoa(v->lsa->id)); + vty_out(vty, "SPF Result: depth %d [R] %pI4\n", i, + &v->lsa->id); } else { struct network_lsa *lsa = (struct network_lsa *)v->lsa; - vty_out(vty, "SPF Result: depth %d [N] %s/%d\n", i, - inet_ntoa(v->lsa->id), ip_masklen(lsa->mask)); + vty_out(vty, "SPF Result: depth %d [N] %pI4/%d\n", i, + &v->lsa->id, ip_masklen(lsa->mask)); } for (ALL_LIST_ELEMENTS_RO(v->parents, nnode, parent)) { - vty_out(vty, " nexthop %s lsa pos %d\n", - inet_ntoa(parent->nexthop->router), + vty_out(vty, " nexthop %pI4 lsa pos %d\n", + &parent->nexthop->router, parent->nexthop->lsa_pos); } @@ -1061,8 +1062,8 @@ static void ospf_spf_process_stubs(struct ospf_area *area, struct vertex *v, struct vertex *child; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("ospf_process_stub():processing stubs for area %s", - inet_ntoa(area->area_id)); + zlog_debug("ospf_process_stub():processing stubs for area %pI4", + &area->area_id); if (v->type == OSPF_VERTEX_ROUTER) { uint8_t *p; @@ -1073,8 +1074,8 @@ static void ospf_spf_process_stubs(struct ospf_area *area, struct vertex *v, if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_process_stubs():processing router LSA, id: %s", - inet_ntoa(v->lsa->id)); + "ospf_process_stubs():processing router LSA, id: %pI4", + &v->lsa->id); router_lsa = (struct router_lsa *)v->lsa; @@ -1211,8 +1212,8 @@ ospf_rtrs_print (struct route_table *rtrs) else { if (IS_DEBUG_OSPF_EVENT) - zlog_debug (" via %s, %s\r", - inet_ntoa (path->nexthop), + zlog_debug (" via %pI4, %s\r", + &path->nexthop, ifindex2ifname (path->ifindex), VRF_DEFAULT); } } @@ -1233,8 +1234,8 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, if (IS_DEBUG_OSPF_EVENT) { zlog_debug("ospf_spf_calculate: Start"); - zlog_debug("ospf_spf_calculate: running Dijkstra for area %s", - inet_ntoa(area->area_id)); + zlog_debug("ospf_spf_calculate: running Dijkstra for area %pI4", + &area->area_id); } /* @@ -1245,8 +1246,8 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa, if (!root_lsa) { if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_spf_calculate: Skip area %s's calculation due to empty root LSA", - inet_ntoa(area->area_id)); + "ospf_spf_calculate: Skip area %pI4's calculation due to empty root LSA", + &area->area_id); return; } @@ -1444,20 +1445,19 @@ static int ospf_spf_calculate_schedule_worker(struct thread *thread) rbuf[0] = '\0'; if (spf_reason_flags) { if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL) - strncat(rbuf, "R, ", sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "R, ", sizeof(rbuf)); if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL) - strncat(rbuf, "N, ", sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "N, ", sizeof(rbuf)); if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL) - strncat(rbuf, "S, ", sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "S, ", sizeof(rbuf)); if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL) - strncat(rbuf, "AS, ", sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "AS, ", sizeof(rbuf)); if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE) - strncat(rbuf, "ABR, ", sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "ABR, ", sizeof(rbuf)); if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE) - strncat(rbuf, "ASBR, ", - sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "ASBR, ", sizeof(rbuf)); if (spf_reason_flags & SPF_FLAG_MAXAGE) - strncat(rbuf, "M, ", sizeof(rbuf) - strlen(rbuf) - 1); + strlcat(rbuf, "M, ", sizeof(rbuf)); size_t rbuflen = strlen(rbuf); if (rbuflen >= 2) diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index eb882c5d0e..e2218957d2 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -516,10 +516,13 @@ static int ospf_sr_start(struct ospf *ospf) static void ospf_sr_stop(void) { + if (OspfSR.status == SR_OFF) + return; + osr_debug("SR (%s): Stop Segment Routing", __func__); /* Disable any re-attempt to connect to Label Manager */ - THREAD_TIMER_OFF(OspfSR.t_start_lm); + THREAD_OFF(OspfSR.t_start_lm); /* Release SRGB & SRLB if active. */ if (OspfSR.srgb.reserved) @@ -1046,6 +1049,7 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl, struct listnode *node; struct sr_link *lk; bool found = false; + bool config = true; /* Sanity check */ if ((srn == NULL) || (srl == NULL)) @@ -1053,11 +1057,11 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl, osr_debug(" |- Process Extended Link Adj/Lan-SID"); - /* Skip Local Adj/Lan_Adj SID coming from neighbors */ + /* Detect if Adj/Lan_Adj SID must be configured */ if (!CHECK_FLAG(lsa_flags, OSPF_LSA_SELF) && (CHECK_FLAG(srl->flags[0], EXT_SUBTLV_LINK_ADJ_SID_LFLG) || CHECK_FLAG(srl->flags[1], EXT_SUBTLV_LINK_ADJ_SID_LFLG))) - return; + config = false; /* Search for existing Segment Link */ for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, lk)) @@ -1077,28 +1081,31 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl, IPV4_ADDR_COPY(&srl->adv_router, &srn->adv_router); listnode_add(srn->ext_link, srl); /* Try to set MPLS table */ - if (compute_link_nhlfe(srl)) { + if (config && compute_link_nhlfe(srl)) { add_adj_sid(srl->nhlfe[0]); add_adj_sid(srl->nhlfe[1]); } } else { + /* Update SR-Link if they are different */ if (sr_link_cmp(lk, srl)) { - if (compute_link_nhlfe(srl)) { - update_adj_sid(lk->nhlfe[0], srl->nhlfe[0]); - update_adj_sid(lk->nhlfe[1], srl->nhlfe[1]); - /* Replace Segment List */ - listnode_delete(srn->ext_link, lk); - XFREE(MTYPE_OSPF_SR_PARAMS, lk); - srl->srn = srn; - IPV4_ADDR_COPY(&srl->adv_router, - &srn->adv_router); - listnode_add(srn->ext_link, srl); - } else { - /* New NHLFE was not found. - * Just free the SR Link - */ - XFREE(MTYPE_OSPF_SR_PARAMS, srl); + /* Try to set MPLS table */ + if (config) { + if (compute_link_nhlfe(srl)) { + update_adj_sid(lk->nhlfe[0], + srl->nhlfe[0]); + update_adj_sid(lk->nhlfe[1], + srl->nhlfe[1]); + } else { + del_adj_sid(lk->nhlfe[0]); + del_adj_sid(lk->nhlfe[1]); + } } + /* Replace SR-Link in SR-Node Adjacency List */ + listnode_delete(srn->ext_link, lk); + XFREE(MTYPE_OSPF_SR_PARAMS, lk); + srl->srn = srn; + IPV4_ADDR_COPY(&srl->adv_router, &srn->adv_router); + listnode_add(srn->ext_link, srl); } else { /* * This is just an LSA refresh. @@ -1879,7 +1886,8 @@ void ospf_sr_update_task(struct ospf *ospf) struct timeval start_time, stop_time; - if (ospf == NULL) + /* Check ospf and SR status */ + if ((ospf == NULL) || (OspfSR.status != SR_UP)) return; monotime(&start_time); @@ -1943,10 +1951,8 @@ void ospf_sr_config_write_router(struct vty *vty) for (ALL_LIST_ELEMENTS_RO(OspfSR.self->ext_prefix, node, srp)) { vty_out(vty, - " segment-routing prefix %s/%u " - "index %u", - inet_ntoa(srp->prefv4.prefix), - srp->prefv4.prefixlen, srp->sid); + " segment-routing prefix %pFX index %u", + &srp->prefv4, srp->sid); if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_EFLG)) vty_out(vty, " explicit-null\n"); @@ -2445,8 +2451,8 @@ DEFUN (sr_prefix_sid, new->instance = ospf_ext_schedule_prefix_index( ifp, new->sid, &new->prefv4, new->flags); if (new->instance == 0) { - vty_out(vty, "Unable to set index %u for prefix %s/%u\n", index, - inet_ntoa(p.u.prefix4), p.prefixlen); + vty_out(vty, "Unable to set index %u for prefix %pFX\n", + index, &p); return CMD_WARNING; } @@ -2568,6 +2574,7 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json, char pref[19]; char sid[22]; char op[32]; + char buf[PREFIX_STRLEN]; int indent = 0; snprintfrr(pref, 19, "%pFX", (struct prefix *)&srp->prefv4); @@ -2594,15 +2601,18 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json, srp->nhlfe.label_out); json_object_string_add(json_obj, "interface", itf ? itf->name : "-"); - json_object_string_add(json_obj, "nexthop", - inet_ntoa(srp->nhlfe.nexthop)); + json_object_string_add( + json_obj, "nexthop", + inet_ntop(AF_INET, &srp->nhlfe.nexthop, + buf, sizeof(buf))); json_object_array_add(json_route, json_obj); } else { sbuf_push(sbuf, 0, "%20s %9s %15s\n", sr_op2str(op, 32, srp->label_in, srp->nhlfe.label_out), itf ? itf->name : "-", - inet_ntoa(srp->nhlfe.nexthop)); + inet_ntop(AF_INET, &srp->nhlfe.nexthop, + buf, sizeof(buf))); } return; } @@ -2629,15 +2639,18 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json, path->srni.label_out); json_object_string_add(json_obj, "interface", itf ? itf->name : "-"); - json_object_string_add(json_obj, "nexthop", - inet_ntoa(path->nexthop)); + json_object_string_add( + json_obj, "nexthop", + inet_ntop(AF_INET, &path->nexthop, + buf, sizeof(buf))); json_object_array_add(json_route, json_obj); } else { sbuf_push(sbuf, indent, "%20s %9s %15s\n", sr_op2str(op, 32, srp->label_in, path->srni.label_out), itf ? itf->name : "-", - inet_ntoa(path->nexthop)); + inet_ntop(AF_INET, &path->nexthop, buf, + sizeof(buf))); /* Offset to align information for ECMP */ indent = 43; } @@ -2656,6 +2669,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json, char pref[19]; char sid[22]; char op[32]; + char buf[PREFIX_STRLEN]; uint32_t upper; json_object *json_node = NULL, *json_algo, *json_obj; json_object *json_prefix = NULL, *json_link = NULL; @@ -2669,7 +2683,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json, if (json) { json_node = json_object_new_object(); json_object_string_add(json_node, "routerID", - inet_ntoa(srn->adv_router)); + inet_ntop(AF_INET, &srn->adv_router, + buf, sizeof(buf))); json_object_int_add(json_node, "srgbSize", srn->srgb.range_size); json_object_int_add(json_node, "srgbLabel", @@ -2696,7 +2711,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json, if (srn->msd != 0) json_object_int_add(json_node, "nodeMsd", srn->msd); } else { - sbuf_push(&sbuf, 0, "SR-Node: %s", inet_ntoa(srn->adv_router)); + sbuf_push(&sbuf, 0, "SR-Node: %pI4", &srn->adv_router); upper = srn->srgb.lower_bound + srn->srgb.range_size - 1; sbuf_push(&sbuf, 0, "\tSRGB: [%u/%u]", srn->srgb.lower_bound, upper); @@ -2760,7 +2775,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json, itf ? itf->name : "-"); json_object_string_add( json_obj, "nexthop", - inet_ntoa(srl->nhlfe[0].nexthop)); + inet_ntop(AF_INET, &srl->nhlfe[0].nexthop, + buf, sizeof(buf))); json_object_array_add(json_link, json_obj); /* Backup Link */ json_obj = json_object_new_object(); @@ -2775,7 +2791,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json, itf ? itf->name : "-"); json_object_string_add( json_obj, "nexthop", - inet_ntoa(srl->nhlfe[1].nexthop)); + inet_ntop(AF_INET, &srl->nhlfe[1].nexthop, + buf, sizeof(buf))); json_object_array_add(json_link, json_obj); } else { sbuf_push(&sbuf, 0, "%18s %21s %20s %9s %15s\n", @@ -2783,14 +2800,16 @@ static void show_sr_node(struct vty *vty, struct json_object *json, sr_op2str(op, 32, srl->nhlfe[0].label_in, srl->nhlfe[0].label_out), itf ? itf->name : "-", - inet_ntoa(srl->nhlfe[0].nexthop)); + inet_ntop(AF_INET, &srl->nhlfe[0].nexthop, + buf, sizeof(buf))); snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); sbuf_push(&sbuf, 0, "%18s %21s %20s %9s %15s\n", pref, sid, sr_op2str(op, 32, srl->nhlfe[1].label_in, srl->nhlfe[1].label_out), itf ? itf->name : "-", - inet_ntoa(srl->nhlfe[1].nexthop)); + inet_ntop(AF_INET, &srl->nhlfe[1].nexthop, + buf, sizeof(buf))); } } if (json) @@ -2833,6 +2852,7 @@ DEFUN (show_ip_opsf_srdb, int idx = 0; struct in_addr rid; struct sr_node *srn; + char buf[PREFIX_STRLEN]; bool uj = use_json(argc, argv); json_object *json = NULL, *json_node_array = NULL; @@ -2844,13 +2864,15 @@ DEFUN (show_ip_opsf_srdb, if (uj) { json = json_object_new_object(); json_node_array = json_object_new_array(); - json_object_string_add(json, "srdbID", - inet_ntoa(OspfSR.self->adv_router)); + json_object_string_add( + json, "srdbID", + inet_ntop(AF_INET, &OspfSR.self->adv_router, + buf, sizeof(buf))); json_object_object_add(json, "srNodes", json_node_array); } else { vty_out(vty, - "\n\t\tOSPF Segment Routing database for ID %s\n\n", - inet_ntoa(OspfSR.self->adv_router)); + "\n\t\tOSPF Segment Routing database for ID %pI4\n\n", + &OspfSR.self->adv_router); } if (argv_find(argv, argc, "self-originate", &idx)) { diff --git a/ospfd/ospf_sr.h b/ospfd/ospf_sr.h index c54d2dcc3c..222675944d 100644 --- a/ospfd/ospf_sr.h +++ b/ospfd/ospf_sr.h @@ -269,7 +269,7 @@ struct sr_node { /* List of Prefix & Link advertise by this node */ struct list *ext_prefix; /* For Node SID */ - struct list *ext_link; /* For Adj and LAN SID */ + struct list *ext_link; /* For Adjacency SID */ /* Pointer to FRR SR-Node or NULL if it is not a neighbor */ struct sr_node *neighbor; diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 1009c7577e..e3c554c530 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -1043,8 +1043,8 @@ static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state) if (IS_DEBUG_OSPF_TE) zlog_debug( - "MPLS-TE (%s): Add Link-ID %s for interface %s ", - __func__, inet_ntoa(lp->link_id.value), oi->ifp->name); + "MPLS-TE (%s): Add Link-ID %pI4 for interface %s ", + __func__, &lp->link_id.value, oi->ifp->name); /* Try to Schedule LSA */ if (OspfMplsTE.enabled) { @@ -1187,8 +1187,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf, if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) zlog_debug( - "LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", - lsa_type, inet_ntoa(lsa_id)); + "LSA[Type%d:%pI4]: Create an Opaque-LSA/MPLS-TE instance", + lsa_type, &lsa_id); /* Set opaque-LSA body fields. */ ospf_mpls_te_lsa_body_set(s, lp); @@ -1243,11 +1243,9 @@ static int ospf_mpls_te_lsa_originate1(struct ospf_area *area, ospf_flood_through_area(area, NULL /*nbr*/, new); if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - char area_id[INET_ADDRSTRLEN]; - strlcpy(area_id, inet_ntoa(area->area_id), sizeof(area_id)); zlog_debug( - "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)", - new->data->type, inet_ntoa(new->data->id), area_id, + "LSA[Type%d:%pI4]: Originate Opaque-LSA/MPLS-TE: Area(%pI4), Link(%s)", + new->data->type, &new->data->id, &area->area_id, lp->ifp->name); ospf_lsa_header_dump(new->data); } @@ -1302,8 +1300,8 @@ static int ospf_mpls_te_lsa_originate_area(void *arg) /* Ok, let's try to originate an LSA for this area and Link. */ if (IS_DEBUG_OSPF_TE) zlog_debug( - "MPLS-TE(ospf_mpls_te_lsa_originate_area) Let's finally reoriginate the LSA %d through the Area %s for Link %s", - lp->instance, inet_ntoa(area->area_id), + "MPLS-TE(ospf_mpls_te_lsa_originate_area) Let's finally reoriginate the LSA %d through the Area %pI4 for Link %s", + lp->instance, &area->area_id, lp->ifp ? lp->ifp->name : "?"); if (ospf_mpls_te_lsa_originate1(area, lp) != 0) return rc; @@ -1347,8 +1345,8 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top, if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { zlog_debug( - "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE Inter-AS", - new->data->type, inet_ntoa(new->data->id)); + "LSA[Type%d:%pI4]: Originate Opaque-LSA/MPLS-TE Inter-AS", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1490,8 +1488,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa) /* Debug logging. */ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { - zlog_debug("LSA[Type%d:%s]: Refresh Opaque-LSA/MPLS-TE", - new->data->type, inet_ntoa(new->data->id)); + zlog_debug("LSA[Type%d:%pI4]: Refresh Opaque-LSA/MPLS-TE", + new->data->type, &new->data->id); ospf_lsa_header_dump(new->data); } @@ -1593,9 +1591,9 @@ static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh) struct te_tlv_router_addr *top = (struct te_tlv_router_addr *)tlvh; if (vty != NULL) - vty_out(vty, " Router-Address: %s\n", inet_ntoa(top->value)); + vty_out(vty, " Router-Address: %pI4\n", &top->value); else - zlog_debug(" Router-Address: %s", inet_ntoa(top->value)); + zlog_debug(" Router-Address: %pI4", &top->value); return TLV_SIZE(tlvh); } @@ -1648,9 +1646,9 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty, top = (struct te_link_subtlv_link_id *)tlvh; if (vty != NULL) - vty_out(vty, " Link-ID: %s\n", inet_ntoa(top->value)); + vty_out(vty, " Link-ID: %pI4\n", &top->value); else - zlog_debug(" Link-ID: %s", inet_ntoa(top->value)); + zlog_debug(" Link-ID: %pI4", &top->value); return TLV_SIZE(tlvh); } @@ -1671,11 +1669,9 @@ static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty, for (i = 0; i < n; i++) { if (vty != NULL) - vty_out(vty, " #%d: %s\n", i, - inet_ntoa(top->value[i])); + vty_out(vty, " #%d: %pI4\n", i, &top->value[i]); else - zlog_debug(" #%d: %s", i, - inet_ntoa(top->value[i])); + zlog_debug(" #%d: %pI4", i, &top->value[i]); } return TLV_SIZE(tlvh); } @@ -1695,11 +1691,9 @@ static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty, for (i = 0; i < n; i++) { if (vty != NULL) - vty_out(vty, " #%d: %s\n", i, - inet_ntoa(top->value[i])); + vty_out(vty, " #%d: %pI4\n", i, &top->value[i]); else - zlog_debug(" #%d: %s", i, - inet_ntoa(top->value[i])); + zlog_debug(" #%d: %pI4", i, &top->value[i]); } return TLV_SIZE(tlvh); } @@ -1811,15 +1805,15 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty, top = (struct te_link_subtlv_lrrid *)tlvh; if (vty != NULL) { - vty_out(vty, " Local TE Router ID: %s\n", - inet_ntoa(top->local)); - vty_out(vty, " Remote TE Router ID: %s\n", - inet_ntoa(top->remote)); + vty_out(vty, " Local TE Router ID: %pI4\n", + &top->local); + vty_out(vty, " Remote TE Router ID: %pI4\n", + &top->remote); } else { - zlog_debug(" Local TE Router ID: %s", - inet_ntoa(top->local)); - zlog_debug(" Remote TE Router ID: %s", - inet_ntoa(top->remote)); + zlog_debug(" Local TE Router ID: %pI4", + &top->local); + zlog_debug(" Remote TE Router ID: %pI4", + &top->remote); } return TLV_SIZE(tlvh); @@ -1855,11 +1849,11 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty, top = (struct te_link_subtlv_rip *)tlvh; if (vty != NULL) - vty_out(vty, " Inter-AS TE Remote ASBR IP address: %s\n", - inet_ntoa(top->value)); + vty_out(vty, " Inter-AS TE Remote ASBR IP address: %pI4\n", + &top->value); else - zlog_debug(" Inter-AS TE Remote ASBR IP address: %s", - inet_ntoa(top->value)); + zlog_debug(" Inter-AS TE Remote ASBR IP address: %pI4", + &top->value); return TLV_SIZE(tlvh); } @@ -2160,15 +2154,15 @@ static void ospf_mpls_te_config_write_router(struct vty *vty) if (OspfMplsTE.enabled) { vty_out(vty, " mpls-te on\n"); - vty_out(vty, " mpls-te router-address %s\n", - inet_ntoa(OspfMplsTE.router_addr.value)); + vty_out(vty, " mpls-te router-address %pI4\n", + &OspfMplsTE.router_addr.value); } if (OspfMplsTE.inter_as == AS) vty_out(vty, " mpls-te inter-as as\n"); if (OspfMplsTE.inter_as == Area) - vty_out(vty, " mpls-te inter-as area %s \n", - inet_ntoa(OspfMplsTE.interas_areaid)); + vty_out(vty, " mpls-te inter-as area %pI4 \n", + &OspfMplsTE.interas_areaid); return; } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 8099b0160c..28ee4db3a1 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -22,6 +22,7 @@ #include <zebra.h> #include <string.h> +#include "printfrr.h" #include "monotime.h" #include "memory.h" #include "thread.h" @@ -34,6 +35,7 @@ #include "zclient.h" #include <lib/json.h> #include "defaults.h" +#include "lib/printfrr.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_asbr.h" @@ -54,6 +56,7 @@ #include "ospfd/ospf_bfd.h" #include "ospfd/ospf_ldp_sync.h" + FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, @@ -213,9 +216,6 @@ DEFUN_NOSH (router_ospf, struct ospf *ospf = NULL; int ret = CMD_SUCCESS; unsigned short instance = 0; - struct vrf *vrf = NULL; - struct route_node *rn; - struct interface *ifp; ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance); if (!ospf) @@ -227,46 +227,12 @@ DEFUN_NOSH (router_ospf, VTY_PUSH_CONTEXT_NULL(OSPF_NODE); ret = CMD_NOT_MY_INSTANCE; } else { - if (ospf->vrf_id != VRF_UNKNOWN) - ospf->oi_running = 1; if (IS_DEBUG_OSPF_EVENT) zlog_debug( "Config command 'router ospf %d' received, vrf %s id %u oi_running %u", instance, ospf->name ? ospf->name : "NIL", ospf->vrf_id, ospf->oi_running); VTY_PUSH_CONTEXT(OSPF_NODE, ospf); - - /* Activate 'ip ospf area x' configured interfaces for given - * vrf. Activate area on vrf x aware interfaces. - * vrf_enable callback calls router_id_update which - * internally will call ospf_if_update to trigger - * network_run_state - */ - vrf = vrf_lookup_by_id(ospf->vrf_id); - - FOR_ALL_INTERFACES (vrf, ifp) { - struct ospf_if_params *params; - - params = IF_DEF_PARAMS(ifp); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { - for (rn = route_top(ospf->networks); rn; - rn = route_next(rn)) { - if (rn->info != NULL) { - vty_out(vty, - "Interface %s has area config but please remove all network commands first.\n", - ifp->name); - return ret; - } - } - if (!ospf_interface_area_is_already_set(ospf, - ifp)) { - ospf_interface_area_set(ospf, ifp); - ospf->if_ospf_cli_count++; - } - } - } - - ospf_router_id_update(ospf); } return ret; @@ -921,7 +887,7 @@ ospf_find_vl_data(struct ospf *ospf, struct ospf_vl_config_data *vl_config) if (area->external_routing != OSPF_AREA_DEFAULT) { if (vl_config->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) - vty_out(vty, "Area %s is %s\n", inet_ntoa(area_id), + vty_out(vty, "Area %pI4 is %s\n", &area_id, area->external_routing == OSPF_AREA_NSSA ? "nssa" : "stub"); @@ -1445,6 +1411,8 @@ DEFUN (ospf_area_stub, return CMD_WARNING_CONFIG_FAILED; } + /* Flush the external LSAs from the specified area */ + ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA); ospf_area_no_summary_unset(ospf, area_id); return CMD_SUCCESS; @@ -1567,6 +1535,8 @@ static int ospf_area_nssa_cmd_handler(struct vty *vty, int argc, ospf_area_no_summary_unset(ospf, area_id); } + /* Flush the external LSA for the specified area */ + ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA); ospf_schedule_abr_task(ospf); return CMD_SUCCESS; @@ -1672,6 +1642,8 @@ DEFUN (no_ospf_area_nssa, VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, argv[idx_ipv4_number]->arg); + /* Flush the NSSA LSA for the specified area */ + ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA); ospf_area_nssa_unset(ospf, area_id, argc); ospf_schedule_abr_task(ospf); @@ -1717,8 +1689,8 @@ DEFUN (ospf_area_default_cost, p.prefixlen = 0; if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4", + &area->area_id); ospf_abr_announce_network_to_area(&p, area->default_cost, area); return CMD_SUCCESS; @@ -1760,8 +1732,8 @@ DEFUN (no_ospf_area_default_cost, p.prefixlen = 0; if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s", - inet_ntoa(area->area_id)); + "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4", + &area->area_id); ospf_abr_announce_network_to_area(&p, area->default_cost, area); @@ -2643,13 +2615,14 @@ static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area, json_object *json_areas, bool use_json) { json_object *json_area = NULL; + char buf[PREFIX_STRLEN]; if (use_json) json_area = json_object_new_object(); /* Show Area ID. */ if (!use_json) - vty_out(vty, " Area ID: %s", inet_ntoa(area->area_id)); + vty_out(vty, " Area ID: %pI4", &area->area_id); /* Show Area type/mode. */ if (OSPF_IS_AREA_BACKBONE(area)) { @@ -2936,7 +2909,9 @@ static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area, } if (use_json) - json_object_object_add(json_areas, inet_ntoa(area->area_id), + json_object_object_add(json_areas, + inet_ntop(AF_INET, &area->area_id, + buf, sizeof(buf)), json_area); else vty_out(vty, "\n"); @@ -2949,6 +2924,7 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf, struct ospf_area *area; struct timeval result; char timebuf[OSPF_TIME_DUMP_SIZE]; + char buf[PREFIX_STRLEN]; json_object *json_vrf = NULL; json_object *json_areas = NULL; @@ -2974,10 +2950,11 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf, /* Show Router ID. */ if (json) { json_object_string_add(json_vrf, "routerId", - inet_ntoa(ospf->router_id)); + inet_ntop(AF_INET, &ospf->router_id, + buf, sizeof(buf))); } else { - vty_out(vty, " OSPF Routing Process, Router ID: %s\n", - inet_ntoa(ospf->router_id)); + vty_out(vty, " OSPF Routing Process, Router ID: %pI4\n", + &ospf->router_id); } /* Graceful shutdown */ @@ -3389,6 +3366,7 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, int is_up; struct ospf_neighbor *nbr; struct route_node *rn; + char buf[PREFIX_STRLEN]; uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed; /* Is interface up? */ @@ -3460,14 +3438,15 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, if (use_json) { json_object_string_add( json_interface_sub, "ipAddress", - inet_ntoa(oi->address->u.prefix4)); + inet_ntop(AF_INET, + &oi->address->u.prefix4, + buf, sizeof(buf))); json_object_int_add(json_interface_sub, "ipAddressPrefixlen", oi->address->prefixlen); } else - vty_out(vty, " Internet Address %s/%d,", - inet_ntoa(oi->address->u.prefix4), - oi->address->prefixlen); + vty_out(vty, " Internet Address %pFX,", + oi->address); /* For Vlinks, showing the peer address is * probably more informative than the local @@ -3494,15 +3473,17 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_string_add( json_interface_sub, "vlinkPeer", - inet_ntoa(dest)); + inet_ntop(AF_INET, &dest, + buf, sizeof(buf))); else json_object_string_add( json_interface_sub, "localIfUsed", - inet_ntoa(dest)); + inet_ntop(AF_INET, &dest, + buf, sizeof(buf))); } else - vty_out(vty, " %s %s,", dstr, - inet_ntoa(dest)); + vty_out(vty, " %s %pI4,", dstr, + &dest); } if (use_json) { json_object_string_add(json_interface_sub, "area", @@ -3511,8 +3492,10 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_boolean_true_add( json_interface_sub, "mtuMismatchDetect"); - json_object_string_add(json_interface_sub, "routerId", - inet_ntoa(ospf->router_id)); + json_object_string_add( + json_interface_sub, "routerId", + inet_ntop(AF_INET, &ospf->router_id, + buf, sizeof(buf))); json_object_string_add(json_interface_sub, "networkType", ospf_network_type_str[oi->type]); @@ -3535,8 +3518,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, : "enabled"); vty_out(vty, - " Router ID %s, Network Type %s, Cost: %d\n", - inet_ntoa(ospf->router_id), + " Router ID %pI4, Network Type %s, Cost: %d\n", + &ospf->router_id, ospf_network_type_str[oi->type], oi->output_cost); @@ -3562,19 +3545,22 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, if (use_json) { json_object_string_add( json_interface_sub, "bdrId", - inet_ntoa(nbr->router_id)); + inet_ntop(AF_INET, + &nbr->router_id, + buf, sizeof(buf))); json_object_string_add( json_interface_sub, "bdrAddress", - inet_ntoa(nbr->address.u - .prefix4)); + inet_ntop(AF_INET, + &nbr->address.u + .prefix4, + buf, sizeof(buf))); } else { vty_out(vty, - " Backup Designated Router (ID) %s,", - inet_ntoa(nbr->router_id)); - vty_out(vty, " Interface Address %s\n", - inet_ntoa(nbr->address.u - .prefix4)); + " Backup Designated Router (ID) %pI4,", + &nbr->router_id); + vty_out(vty, " Interface Address %pI4\n", + &nbr->address.u.prefix4); } } } @@ -4174,6 +4160,7 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, struct route_node *rn; struct ospf_neighbor *nbr, *prev_nbr = NULL; char msgbuf[16]; + char buf[PREFIX_STRLEN]; char timebuf[OSPF_TIME_DUMP_SIZE]; json_object *json_neighbor = NULL, *json_neigh_array = NULL; @@ -4200,9 +4187,8 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, strlcpy(neigh_str, "neighbor", sizeof(neigh_str)); else - strlcpy(neigh_str, - inet_ntoa(nbr->router_id), - sizeof(neigh_str)); + inet_ntop(AF_INET, &nbr->router_id, + neigh_str, sizeof(neigh_str)); json_object_object_get_ex(json, neigh_str, &json_neigh_array); @@ -4234,8 +4220,10 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, json_object_int_add(json_neighbor, "deadTimeMsecs", time_store); - json_object_string_add(json_neighbor, "address", - inet_ntoa(nbr->src)); + json_object_string_add( + json_neighbor, "address", + inet_ntop(AF_INET, &nbr->src, + buf, sizeof(buf))); json_object_string_add(json_neighbor, "ifaceName", IF_NAME(oi)); @@ -4259,15 +4247,15 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, vty_out(vty, "%-15s %3d %-15s ", "-", nbr->priority, msgbuf); else - vty_out(vty, "%-15s %3d %-15s ", - inet_ntoa(nbr->router_id), + vty_out(vty, "%-15pI4 %3d %-15s ", + &nbr->router_id, nbr->priority, msgbuf); vty_out(vty, "%9s ", ospf_timer_dump(nbr->t_inactivity, timebuf, sizeof(timebuf))); - vty_out(vty, "%-15s ", inet_ntoa(nbr->src)); + vty_out(vty, "%-15pI4 ", &nbr->src); vty_out(vty, "%-32s %5ld %5ld %5d\n", IF_NAME(oi), ospf_ls_retransmit_count(nbr), @@ -4470,6 +4458,7 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, { struct listnode *node; struct ospf_interface *oi; + char buf[PREFIX_STRLEN]; json_object *json_vrf = NULL; json_object *json_neighbor_sub = NULL; @@ -4525,15 +4514,17 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf, "nbrNbmaDbSummaryCounter", 0); json_object_object_add( json_vrf, - inet_ntoa(nbr_nbma->addr), + inet_ntop(AF_INET, + &nbr_nbma->addr, buf, + sizeof(buf)), json_neighbor_sub); } else { vty_out(vty, "%-15s %3d %-15s %9s ", "-", nbr_nbma->priority, "Down", "-"); vty_out(vty, - "%-32s %-20s %5d %5d %5d\n", - inet_ntoa(nbr_nbma->addr), + "%-32pI4 %-20s %5d %5d %5d\n", + &nbr_nbma->addr, IF_NAME(oi), 0, 0, 0); } } @@ -4815,6 +4806,7 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty, bool use_json, json_object *json) { char timebuf[OSPF_TIME_DUMP_SIZE]; + char buf[PREFIX_STRLEN]; json_object *json_sub = NULL; if (use_json) @@ -4825,10 +4817,11 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty, /* Show interface address. */ if (use_json) json_object_string_add(json_sub, "ifaceAddress", - inet_ntoa(nbr_nbma->addr)); + inet_ntop(AF_INET, &nbr_nbma->addr, + buf, sizeof(buf))); else - vty_out(vty, " interface address %s\n", - inet_ntoa(nbr_nbma->addr)); + vty_out(vty, " interface address %pI4\n", + &nbr_nbma->addr); /* Show Area ID. */ if (use_json) { @@ -4898,6 +4891,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, char timebuf[OSPF_TIME_DUMP_SIZE]; json_object *json_neigh = NULL, *json_neigh_array = NULL; char neigh_str[INET_ADDRSTRLEN] = {0}; + char buf[PREFIX_STRLEN]; if (use_json) { if (prev_nbr && @@ -4909,8 +4903,8 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, && nbr->router_id.s_addr == INADDR_ANY) strlcpy(neigh_str, "noNbrId", sizeof(neigh_str)); else - strlcpy(neigh_str, inet_ntoa(nbr->router_id), - sizeof(neigh_str)); + inet_ntop(AF_INET, &nbr->router_id, + neigh_str, sizeof(neigh_str)); json_object_object_get_ex(json, neigh_str, &json_neigh_array); @@ -4928,17 +4922,19 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, && nbr->router_id.s_addr == INADDR_ANY) vty_out(vty, " Neighbor %s,", "-"); else - vty_out(vty, " Neighbor %s,", - inet_ntoa(nbr->router_id)); + vty_out(vty, " Neighbor %pI4,", + &nbr->router_id); } /* Show interface address. */ if (use_json) json_object_string_add(json_neigh, "ifaceAddress", - inet_ntoa(nbr->address.u.prefix4)); + inet_ntop(AF_INET, + &nbr->address.u.prefix4, + buf, sizeof(buf))); else - vty_out(vty, " interface address %s\n", - inet_ntoa(nbr->address.u.prefix4)); + vty_out(vty, " interface address %pI4\n", + &nbr->address.u.prefix4); /* Show Area ID. */ if (use_json) { @@ -5013,16 +5009,18 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, /* Show Designated Rotuer ID. */ if (use_json) json_object_string_add(json_neigh, "routerDesignatedId", - inet_ntoa(nbr->d_router)); + inet_ntop(AF_INET, &nbr->d_router, + buf, sizeof(buf))); else - vty_out(vty, " DR is %s,", inet_ntoa(nbr->d_router)); + vty_out(vty, " DR is %pI4,", &nbr->d_router); /* Show Backup Designated Rotuer ID. */ if (use_json) json_object_string_add(json_neigh, "routerDesignatedBackupId", - inet_ntoa(nbr->bd_router)); + inet_ntop(AF_INET, &nbr->bd_router, + buf, sizeof(buf))); else - vty_out(vty, " BDR is %s\n", inet_ntoa(nbr->bd_router)); + vty_out(vty, " BDR is %pI4\n", &nbr->bd_router); /* Show options. */ if (use_json) { @@ -5121,6 +5119,68 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, " Thread Link State Update Retransmission %s\n\n", nbr->t_ls_upd != NULL ? "on" : "off"); + if (!use_json) { + vty_out(vty, " Graceful restart Helper info:\n"); + + if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) { + vty_out(vty, + " Graceful Restart HELPER Status : Inprogress.\n"); + + vty_out(vty, + " Graceful Restart grace period time: %d (seconds).\n", + nbr->gr_helper_info.recvd_grace_period); + vty_out(vty, " Graceful Restart reason: %s.\n", + ospf_restart_reason2str( + nbr->gr_helper_info.gr_restart_reason)); + } else { + vty_out(vty, + " Graceful Restart HELPER Status : None\n"); + } + + if (nbr->gr_helper_info.rejected_reason + != OSPF_HELPER_REJECTED_NONE) + vty_out(vty, " Helper rejected reason: %s.\n", + ospf_rejected_reason2str( + nbr->gr_helper_info.rejected_reason)); + + if (nbr->gr_helper_info.helper_exit_reason + != OSPF_GR_HELPER_EXIT_NONE) + vty_out(vty, " Last helper exit reason: %s.\n\n", + ospf_exit_reason2str( + nbr->gr_helper_info.helper_exit_reason)); + else + vty_out(vty, "\n"); + } else { + json_object_string_add(json_neigh, "grHelperStatus", + OSPF_GR_IS_ACTIVE_HELPER(nbr) ? + "Inprogress" + : "None"); + if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) { + json_object_int_add( + json_neigh, "graceInterval", + nbr->gr_helper_info.recvd_grace_period); + json_object_string_add( + json_neigh, "grRestartReason", + ospf_restart_reason2str( + nbr->gr_helper_info.gr_restart_reason)); + } + + if (nbr->gr_helper_info.rejected_reason + != OSPF_HELPER_REJECTED_NONE) + json_object_string_add( + json_neigh, "helperRejectReason", + ospf_rejected_reason2str( + nbr->gr_helper_info.rejected_reason)); + + if (nbr->gr_helper_info.helper_exit_reason + != OSPF_GR_HELPER_EXIT_NONE) + json_object_string_add( + json_neigh, "helperExitReason", + ospf_exit_reason2str( + nbr->gr_helper_info + .helper_exit_reason)); + } + ospf_bfd_show_info(vty, nbr->bfd_info, json_neigh, use_json, 0); if (use_json) @@ -5716,27 +5776,62 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail, } /* Show functions */ -static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) +static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self, + json_object *json_lsa) { struct router_lsa *rl; struct summary_lsa *sl; struct as_external_lsa *asel; struct prefix_ipv4 p; + char buf[PREFIX2STR_BUFFER]; if (lsa != NULL) /* If self option is set, check LSA self flag. */ if (self == 0 || IS_LSA_SELF(lsa)) { - /* LSA common part show. */ - vty_out(vty, "%-15s ", inet_ntoa(lsa->data->id)); - vty_out(vty, "%-15s %4d 0x%08lx 0x%04x", - inet_ntoa(lsa->data->adv_router), LS_AGE(lsa), - (unsigned long)ntohl(lsa->data->ls_seqnum), - ntohs(lsa->data->checksum)); + + if (!json_lsa) { + /* LSA common part show. */ + vty_out(vty, "%-15pI4", + &lsa->data->id); + vty_out(vty, "%-15s %4d 0x%08lx 0x%04x", + inet_ntoa(lsa->data->adv_router), + LS_AGE(lsa), + (unsigned long)ntohl( + lsa->data->ls_seqnum), + ntohs(lsa->data->checksum)); + } else { + char seqnum[10]; + char checksum[10]; + + snprintf(seqnum, sizeof(seqnum), "%x", + ntohl(lsa->data->ls_seqnum)); + snprintf(checksum, sizeof(checksum), "%x", + ntohs(lsa->data->checksum)); + json_object_string_add( + json_lsa, "lsId", + inet_ntoa(lsa->data->id)); + json_object_string_add( + json_lsa, "advertisedRouter", + inet_ntoa(lsa->data->adv_router)); + json_object_int_add(json_lsa, "lsaAge", + LS_AGE(lsa)); + json_object_string_add( + json_lsa, "sequenceNumber", seqnum); + json_object_string_add(json_lsa, "checksum", + checksum); + } + /* LSA specific part show. */ switch (lsa->data->type) { case OSPF_ROUTER_LSA: rl = (struct router_lsa *)lsa->data; - vty_out(vty, " %-d", ntohs(rl->links)); + + if (!json_lsa) + vty_out(vty, " %-d", ntohs(rl->links)); + else + json_object_int_add(json_lsa, + "numOfRouterLinks", + ntohs(rl->links)); break; case OSPF_SUMMARY_LSA: sl = (struct summary_lsa *)lsa->data; @@ -5746,8 +5841,14 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) p.prefixlen = ip_masklen(sl->mask); apply_mask_ipv4(&p); - vty_out(vty, " %s/%d", inet_ntoa(p.prefix), - p.prefixlen); + if (!json_lsa) + vty_out(vty, " %pFX", &p); + else { + prefix2str(&p, buf, sizeof(buf)); + json_object_string_add(json_lsa, + "summaryAddress", + buf); + } break; case OSPF_AS_EXTERNAL_LSA: case OSPF_AS_NSSA_LSA: @@ -5758,13 +5859,30 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) p.prefixlen = ip_masklen(asel->mask); apply_mask_ipv4(&p); - vty_out(vty, " %s %s/%d [0x%lx]", - IS_EXTERNAL_METRIC(asel->e[0].tos) - ? "E2" - : "E1", - inet_ntoa(p.prefix), p.prefixlen, - (unsigned long)ntohl( - asel->e[0].route_tag)); + if (!json_lsa) + vty_out(vty, " %s %pFX [0x%lx]", + IS_EXTERNAL_METRIC( + asel->e[0].tos) + ? "E2" + : "E1", + &p, + (unsigned long)ntohl( + asel->e[0].route_tag)); + else { + prefix2str(&p, buf, sizeof(buf)); + json_object_string_add( + json_lsa, "metricType", + IS_EXTERNAL_METRIC( + asel->e[0].tos) + ? "E2" + : "E1"); + json_object_string_add(json_lsa, + "route", buf); + json_object_int_add( + json_lsa, "tag", + (unsigned long)ntohl( + asel->e[0].route_tag)); + } break; case OSPF_NETWORK_LSA: case OSPF_ASBR_SUMMARY_LSA: @@ -5774,7 +5892,9 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) default: break; } - vty_out(vty, "\n"); + + if (!json_lsa) + vty_out(vty, "\n"); } return 0; @@ -5795,6 +5915,21 @@ static const char *const show_database_desc[] = { "AS-external Opaque-LSA", }; +static const char * const show_database_desc_json[] = { + "unknown", + "routerLinkStates", + "networkLinkStates", + "summaryLinkStates", + "asbrSummaryLinkStates", + "asExternalLinkStates", + "groupMembershipLsa", + "nssaExternalLinkStates", + "type8Lsa", + "linkLocalOpaqueLsa", + "areaLocalOpaqueLsa", + "asExternalOpaqueLsa", +}; + static const char *const show_database_header[] = { "", "Link ID ADV Router Age Seq# CkSum Link count", @@ -5810,41 +5945,97 @@ static const char *const show_database_header[] = { "Opaque-Type/Id ADV Router Age Seq# CkSum", }; -static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa) +static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { struct router_lsa *rlsa = (struct router_lsa *)lsa->data; - vty_out(vty, " LS age: %d\n", LS_AGE(lsa)); - vty_out(vty, " Options: 0x%-2x : %s\n", lsa->data->options, - ospf_options_dump(lsa->data->options)); - vty_out(vty, " LS Flags: 0x%-2x %s\n", lsa->flags, - ((lsa->flags & OSPF_LSA_LOCAL_XLT) ? "(Translated from Type-7)" - : "")); - - if (lsa->data->type == OSPF_ROUTER_LSA) { - vty_out(vty, " Flags: 0x%x", rlsa->flags); - - if (rlsa->flags) - vty_out(vty, " :%s%s%s%s", - IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" : "", - IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" : "", - IS_ROUTER_LSA_VIRTUAL(rlsa) ? " VL-endpoint" - : "", - IS_ROUTER_LSA_SHORTCUT(rlsa) ? " Shortcut" - : ""); + if (!json) { + vty_out(vty, " LS age: %d\n", LS_AGE(lsa)); + vty_out(vty, " Options: 0x%-2x : %s\n", lsa->data->options, + ospf_options_dump(lsa->data->options)); + vty_out(vty, " LS Flags: 0x%-2x %s\n", lsa->flags, + ((lsa->flags & OSPF_LSA_LOCAL_XLT) + ? "(Translated from Type-7)" + : "")); + + if (lsa->data->type == OSPF_ROUTER_LSA) { + vty_out(vty, " Flags: 0x%x", rlsa->flags); + + if (rlsa->flags) + vty_out(vty, " :%s%s%s%s", + IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" + : "", + IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" + : "", + IS_ROUTER_LSA_VIRTUAL(rlsa) + ? " VL-endpoint" + : "", + IS_ROUTER_LSA_SHORTCUT(rlsa) + ? " Shortcut" + : ""); - vty_out(vty, "\n"); + vty_out(vty, "\n"); + } + vty_out(vty, " LS Type: %s\n", + lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); + vty_out(vty, " Link State ID: %pI4 %s\n", + &lsa->data->id, + lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, + NULL)); + vty_out(vty, " Advertising Router: %pI4\n", + &lsa->data->adv_router); + vty_out(vty, " LS Seq Number: %08lx\n", + (unsigned long)ntohl(lsa->data->ls_seqnum)); + vty_out(vty, " Checksum: 0x%04x\n", + ntohs(lsa->data->checksum)); + vty_out(vty, " Length: %d\n\n", ntohs(lsa->data->length)); + } else { + char seqnum[10]; + char checksum[10]; + + snprintf(seqnum, 10, "%x", ntohl(lsa->data->ls_seqnum)); + snprintf(checksum, 10, "%x", ntohs(lsa->data->checksum)); + + json_object_int_add(json, "lsaAge", LS_AGE(lsa)); + json_object_string_add(json, "options", + ospf_options_dump(lsa->data->options)); + json_object_int_add(json, "lsaFlags", lsa->flags); + + if (lsa->flags & OSPF_LSA_LOCAL_XLT) + json_object_boolean_true_add(json, + "translatedFromType7"); + + if (lsa->data->type == OSPF_ROUTER_LSA) { + json_object_int_add(json, "flags", rlsa->flags); + + if (rlsa->flags) { + if (IS_ROUTER_LSA_BORDER(rlsa)) + json_object_boolean_true_add(json, + "abr"); + if (IS_ROUTER_LSA_EXTERNAL(rlsa)) + json_object_boolean_true_add(json, + "asbr"); + if (IS_ROUTER_LSA_VIRTUAL(rlsa)) + json_object_boolean_true_add( + json, "vlEndpoint"); + if (IS_ROUTER_LSA_SHORTCUT(rlsa)) + json_object_boolean_true_add( + json, "shortcut"); + } + } + + json_object_string_add( + json, "lsaType", + lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); + json_object_string_add(json, "linkStateId", + inet_ntoa(lsa->data->id)); + json_object_string_add(json, "advertisingRouter", + inet_ntoa(lsa->data->adv_router)); + json_object_string_add(json, "lsaSeqNumber", seqnum); + json_object_string_add(json, "checksum", checksum); + json_object_int_add(json, "length", ntohs(lsa->data->length)); } - vty_out(vty, " LS Type: %s\n", - lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); - vty_out(vty, " Link State ID: %s %s\n", inet_ntoa(lsa->data->id), - lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, NULL)); - vty_out(vty, " Advertising Router: %s\n", - inet_ntoa(lsa->data->adv_router)); - vty_out(vty, " LS Seq Number: %08lx\n", - (unsigned long)ntohl(lsa->data->ls_seqnum)); - vty_out(vty, " Checksum: 0x%04x\n", ntohs(lsa->data->checksum)); - vty_out(vty, " Length: %d\n\n", ntohs(lsa->data->length)); } static const char *const link_type_desc[] = { @@ -5865,128 +6056,240 @@ static const char *const link_data_desc[] = { "Network Mask", "Router Interface address", }; +static const char *const link_id_desc_json[] = { + "null", "neighborRouterId", "designatedRouterAddress", + "networkAddress", "neighborRouterId", +}; + +static const char *const link_data_desc_json[] = { + "null", "routerInterfaceAddress", "routerInterfaceAddress", + "networkMask", "routerInterfaceAddress", +}; + /* Show router-LSA each Link information. */ static void show_ip_ospf_database_router_links(struct vty *vty, - struct router_lsa *rl) + struct router_lsa *rl, + json_object *json) { int len, type; - unsigned int i; + unsigned short i; + json_object *json_links = NULL; + json_object *json_link = NULL; + int metric = 0; + + if (json) + json_links = json_object_new_object(); len = ntohs(rl->header.length) - 4; for (i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) { type = rl->link[i].type; - vty_out(vty, " Link connected to: %s\n", - link_type_desc[type]); - vty_out(vty, " (Link ID) %s: %s\n", link_id_desc[type], - inet_ntoa(rl->link[i].link_id)); - vty_out(vty, " (Link Data) %s: %s\n", link_data_desc[type], - inet_ntoa(rl->link[i].link_data)); - vty_out(vty, " Number of TOS metrics: 0\n"); - vty_out(vty, " TOS 0 Metric: %d\n", - ntohs(rl->link[i].metric)); - vty_out(vty, "\n"); + if (json) { + char link[16]; + + snprintf(link, sizeof(link), "link%u", i); + json_link = json_object_new_object(); + json_object_string_add(json_link, "linkType", + link_type_desc[type]); + json_object_string_add(json_link, + link_id_desc_json[type], + inet_ntoa(rl->link[i].link_id)); + json_object_string_add( + json_link, link_data_desc_json[type], + inet_ntoa(rl->link[i].link_data)); + json_object_int_add(json_link, "numOfTosMetrics", + metric); + json_object_int_add(json_link, "tos0Metric", + ntohs(rl->link[i].metric)); + json_object_object_add(json_links, link, json_link); + } else { + vty_out(vty, " Link connected to: %s\n", + link_type_desc[type]); + vty_out(vty, " (Link ID) %s: %pI4\n", + link_id_desc[type], + &rl->link[i].link_id); + vty_out(vty, " (Link Data) %s: %pI4\n", + link_data_desc[type], + &rl->link[i].link_data); + vty_out(vty, " Number of TOS metrics: 0\n"); + vty_out(vty, " TOS 0 Metric: %d\n", + ntohs(rl->link[i].metric)); + vty_out(vty, "\n"); + } } + if (json) + json_object_object_add(json, "routerLinks", json_links); } /* Show router-LSA detail information. */ -static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { struct router_lsa *rl = (struct router_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Number of Links: %d\n\n", ntohs(rl->links)); + if (!json) + vty_out(vty, " Number of Links: %d\n\n", + ntohs(rl->links)); + else + json_object_int_add(json, "numOfLinks", + ntohs(rl->links)); - show_ip_ospf_database_router_links(vty, rl); - vty_out(vty, "\n"); + show_ip_ospf_database_router_links(vty, rl, json); + + if (!json) + vty_out(vty, "\n"); } return 0; } /* Show network-LSA detail information. */ -static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { int length, i; + json_object *json_attached_rt = NULL; + json_object *json_router = NULL; + + if (json) + json_attached_rt = json_object_new_object(); if (lsa != NULL) { struct network_lsa *nl = (struct network_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Network Mask: /%d\n", ip_masklen(nl->mask)); + if (!json) + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(nl->mask)); + else + json_object_int_add(json, "networkMask", + ip_masklen(nl->mask)); length = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4; for (i = 0; length > 0; i++, length -= 4) - vty_out(vty, " Attached Router: %s\n", - inet_ntoa(nl->routers[i])); - - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, " Attached Router: %pI4\n", + &nl->routers[i]); + vty_out(vty, "\n"); + } else { + json_router = json_object_new_object(); + json_object_string_add( + json_router, "attachedRouterId", + inet_ntoa(nl->routers[i])); + json_object_object_add( + json_attached_rt, + inet_ntoa(nl->routers[i]), json_router); + } } + if (json) + json_object_object_add(json, "attchedRouters", + json_attached_rt); + return 0; } /* Show summary-LSA detail information. */ -static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { struct summary_lsa *sl = (struct summary_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Network Mask: /%d\n", ip_masklen(sl->mask)); - vty_out(vty, " TOS: 0 Metric: %d\n", - GET_METRIC(sl->metric)); - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(sl->mask)); + vty_out(vty, " TOS: 0 Metric: %d\n", + GET_METRIC(sl->metric)); + vty_out(vty, "\n"); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(sl->mask)); + json_object_int_add(json, "tos0Metric", + GET_METRIC(sl->metric)); + } } return 0; } /* Show summary-ASBR-LSA detail information. */ -static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { struct summary_lsa *sl = (struct summary_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Network Mask: /%d\n", ip_masklen(sl->mask)); - vty_out(vty, " TOS: 0 Metric: %d\n", - GET_METRIC(sl->metric)); - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(sl->mask)); + vty_out(vty, " TOS: 0 Metric: %d\n", + GET_METRIC(sl->metric)); + vty_out(vty, "\n"); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(sl->mask)); + json_object_int_add(json, "tos0Metric", + GET_METRIC(sl->metric)); + } } return 0; } /* Show AS-external-LSA detail information. */ -static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { + int tos = 0; + if (lsa != NULL) { struct as_external_lsa *al = (struct as_external_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); - - vty_out(vty, " Network Mask: /%d\n", ip_masklen(al->mask)); - vty_out(vty, " Metric Type: %s\n", - IS_EXTERNAL_METRIC(al->e[0].tos) - ? "2 (Larger than any link state path)" - : "1"); - vty_out(vty, " TOS: 0\n"); - vty_out(vty, " Metric: %d\n", - GET_METRIC(al->e[0].metric)); - vty_out(vty, " Forward Address: %s\n", - inet_ntoa(al->e[0].fwd_addr)); - - vty_out(vty, - " External Route Tag: %" ROUTE_TAG_PRI "\n\n", - (route_tag_t)ntohl(al->e[0].route_tag)); + show_ip_ospf_database_header(vty, lsa, json); + + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(al->mask)); + vty_out(vty, " Metric Type: %s\n", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "2 (Larger than any link state path)" + : "1"); + vty_out(vty, " TOS: 0\n"); + vty_out(vty, " Metric: %d\n", + GET_METRIC(al->e[0].metric)); + vty_out(vty, " Forward Address: %pI4\n", + &al->e[0].fwd_addr); + vty_out(vty, + " External Route Tag: %" ROUTE_TAG_PRI "\n\n", + (route_tag_t)ntohl(al->e[0].route_tag)); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(al->mask)); + json_object_string_add( + json, "metricType", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "E2 (Larger than any link state path)" + : "E1"); + json_object_int_add(json, "tos", tos); + json_object_int_add(json, "metric", + GET_METRIC(al->e[0].metric)); + json_object_string_add(json, "forwardAddress", + inet_ntoa(al->e[0].fwd_addr)); + json_object_int_add( + json, "externalRouteTag", + (route_tag_t)ntohl(al->e[0].route_tag)); + } } return 0; @@ -6007,8 +6310,8 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa) zlog_debug( " TOS: 0%s", "\n"); zlog_debug( " Metric: %d%s", GET_METRIC (al->e[0].metric), "\n"); - zlog_debug( " Forward Address: %s%s", - inet_ntoa (al->e[0].fwd_addr), "\n"); + zlog_debug( " Forward Address: %pI4%s", + &al->e[0].fwd_addr, "\n"); zlog_debug( " External Route Tag: %"ROUTE_TAG_PRI"%s%s", (route_tag_t)ntohl (al->e[0].route_tag), "\n", "\n"); @@ -6017,50 +6320,74 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa) } #endif /* Show AS-NSSA-LSA detail information. */ -static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { + int tos = 0; + if (lsa != NULL) { struct as_external_lsa *al = (struct as_external_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); - - vty_out(vty, " Network Mask: /%d\n", ip_masklen(al->mask)); - vty_out(vty, " Metric Type: %s\n", - IS_EXTERNAL_METRIC(al->e[0].tos) - ? "2 (Larger than any link state path)" - : "1"); - vty_out(vty, " TOS: 0\n"); - vty_out(vty, " Metric: %d\n", - GET_METRIC(al->e[0].metric)); - vty_out(vty, " NSSA: Forward Address: %s\n", - inet_ntoa(al->e[0].fwd_addr)); - - vty_out(vty, - " External Route Tag: %" ROUTE_TAG_PRI "\n\n", - (route_tag_t)ntohl(al->e[0].route_tag)); + show_ip_ospf_database_header(vty, lsa, json); + + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(al->mask)); + vty_out(vty, " Metric Type: %s\n", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "2 (Larger than any link state path)" + : "1"); + vty_out(vty, " TOS: 0\n"); + vty_out(vty, " Metric: %d\n", + GET_METRIC(al->e[0].metric)); + vty_out(vty, " NSSA: Forward Address: %pI4\n", + &al->e[0].fwd_addr); + vty_out(vty, + " External Route Tag: %" ROUTE_TAG_PRI + "\n\n", + (route_tag_t)ntohl(al->e[0].route_tag)); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(al->mask)); + json_object_string_add( + json, "metricType", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "E2 (Larger than any link state path)" + : "E1"); + json_object_int_add(json, "tos", tos); + json_object_int_add(json, "metric", + GET_METRIC(al->e[0].metric)); + json_object_string_add(json, "nssaForwardAddress", + inet_ntoa(al->e[0].fwd_addr)); + json_object_int_add( + json, "externalRouteTag", + (route_tag_t)ntohl(al->e[0].route_tag)); + } } return 0; } -static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa) +static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { return 0; } -static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { - show_ip_ospf_database_header(vty, lsa); - show_opaque_info_detail(vty, lsa); - - vty_out(vty, "\n"); + show_ip_ospf_database_header(vty, lsa, json); + show_opaque_info_detail(vty, lsa, json); + if (!json) + vty_out(vty, "\n"); } return 0; } -int (*const show_function[])(struct vty *, struct ospf_lsa *) = { +int (*show_function[])(struct vty *, struct ospf_lsa *, json_object *) = { NULL, show_router_lsa_detail, show_network_lsa_detail, @@ -6093,11 +6420,13 @@ static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp, } static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, - struct in_addr *id, struct in_addr *adv_router) + struct in_addr *id, struct in_addr *adv_router, + json_object *json) { struct prefix_ls lp; struct route_node *rn, *start; struct ospf_lsa *lsa; + json_object *json_lsa = NULL; show_lsa_prefix_set(vty, &lp, id, adv_router); start = route_node_get(rt, (struct prefix *)&lp); @@ -6105,9 +6434,14 @@ static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, route_lock_node(start); for (rn = start; rn; rn = route_next_until(rn, start)) if ((lsa = rn->info)) { + if (json) { + json_lsa = json_object_new_object(); + json_object_array_add(json, json_lsa); + } + if (show_function[lsa->data->type] != NULL) - show_function[lsa->data->type](vty, - lsa); + show_function[lsa->data->type]( + vty, lsa, json_lsa); } route_unlock_node(start); } @@ -6116,25 +6450,62 @@ static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, /* Show detail LSA information -- if id is NULL then show all LSAs. */ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, - struct in_addr *id, struct in_addr *adv_router) + struct in_addr *id, struct in_addr *adv_router, + json_object *json) { struct listnode *node; struct ospf_area *area; + json_object *json_lsa_type = NULL; + json_object *json_areas = NULL; + json_object *json_lsa_array = NULL; + + if (json) + json_lsa_type = json_object_new_object(); switch (type) { case OSPF_AS_EXTERNAL_LSA: case OSPF_OPAQUE_AS_LSA: - vty_out(vty, " %s \n\n", - show_database_desc[type]); - show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router); + if (!json) + vty_out(vty, " %s \n\n", + show_database_desc[type]); + else + json_lsa_array = json_object_new_array(); + + show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router, + json_lsa_array); + if (json) + json_object_object_add(json, + show_database_desc_json[type], + json_lsa_array); + break; default: + if (json) + json_areas = json_object_new_object(); + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { - vty_out(vty, "\n %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string(area)); + if (!json) { + vty_out(vty, + "\n %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + } else { + json_lsa_array = json_object_new_array(); + json_object_object_add(json_areas, + inet_ntoa(area->area_id), + json_lsa_array); + } + show_lsa_detail_proc(vty, AREA_LSDB(area, type), id, - adv_router); + adv_router, json_lsa_array); + } + + if (json) { + json_object_object_add(json_lsa_type, "areas", + json_areas); + json_object_object_add(json, + show_database_desc_json[type], + json_lsa_type); } break; } @@ -6142,60 +6513,104 @@ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, static void show_lsa_detail_adv_router_proc(struct vty *vty, struct route_table *rt, - struct in_addr *adv_router) + struct in_addr *adv_router, + json_object *json) { struct route_node *rn; struct ospf_lsa *lsa; for (rn = route_top(rt); rn; rn = route_next(rn)) - if ((lsa = rn->info)) + if ((lsa = rn->info)) { + json_object *json_lsa = NULL; + if (IPV4_ADDR_SAME(adv_router, &lsa->data->adv_router)) { if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) continue; + if (json) + json_lsa = json_object_new_object(); + if (show_function[lsa->data->type] != NULL) - show_function[lsa->data->type](vty, - lsa); + show_function[lsa->data->type]( + vty, lsa, json_lsa); + if (json) + json_object_object_add( + json, inet_ntoa(lsa->data->id), + json_lsa); } + } } /* Show detail LSA information. */ static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf, - int type, struct in_addr *adv_router) + int type, struct in_addr *adv_router, + json_object *json) { struct listnode *node; struct ospf_area *area; + json_object *json_lstype = NULL; + json_object *json_area = NULL; + + if (json) + json_lstype = json_object_new_object(); switch (type) { case OSPF_AS_EXTERNAL_LSA: case OSPF_OPAQUE_AS_LSA: - vty_out(vty, " %s \n\n", - show_database_desc[type]); + if (!json) + vty_out(vty, " %s \n\n", + show_database_desc[type]); + show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type), - adv_router); + adv_router, json_lstype); break; default: + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { - vty_out(vty, "\n %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string(area)); - show_lsa_detail_adv_router_proc( - vty, AREA_LSDB(area, type), adv_router); + if (json) + json_area = json_object_new_object(); + else + vty_out(vty, + "\n %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + show_lsa_detail_adv_router_proc(vty, + AREA_LSDB(area, type), + adv_router, json_area); + + if (json) + json_object_object_add(json_lstype, + inet_ntoa(area->area_id), + json_area); } break; } + + if (json) + json_object_object_add(json, show_database_desc[type], + json_lstype); } static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, - int self) + int self, json_object *json) { struct ospf_lsa *lsa; struct route_node *rn; struct ospf_area *area; struct listnode *node; + json_object *json_areas = NULL; + json_object *json_area = NULL; + json_object *json_lsa = NULL; int type; + json_object *json_lsa_array = NULL; + + if (json) + json_areas = json_object_new_object(); for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (json) + json_area = json_object_new_object(); + for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) { switch (type) { case OSPF_AS_EXTERNAL_LSA: @@ -6207,20 +6622,49 @@ static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, if (ospf_lsdb_count_self(area->lsdb, type) > 0 || (!self && ospf_lsdb_count(area->lsdb, type) > 0)) { - vty_out(vty, " %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string(area)); - vty_out(vty, "%s\n", - show_database_header[type]); - LSDB_LOOP (AREA_LSDB(area, type), rn, lsa) - show_lsa_summary(vty, lsa, self); + if (!json) { + vty_out(vty, + " %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + vty_out(vty, "%s\n", + show_database_header[type]); + } else { + json_lsa_array = + json_object_new_array(); + json_object_object_add( + json_area, + show_database_desc_json[type], + json_lsa_array); + } + + LSDB_LOOP (AREA_LSDB(area, type), rn, lsa) { + if (json) { + json_lsa = + json_object_new_object(); + json_object_array_add( + json_lsa_array, + json_lsa); + } + + show_lsa_summary(vty, lsa, self, + json_lsa); + } - vty_out(vty, "\n"); + if (!json) + vty_out(vty, "\n"); } } + if (json) + json_object_object_add(json_areas, + inet_ntoa(area->area_id), + json_area); } + if (json) + json_object_object_add(json, "areas", json_areas); + for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) { switch (type) { case OSPF_AS_EXTERNAL_LSA: @@ -6231,39 +6675,82 @@ static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, } if (ospf_lsdb_count_self(ospf->lsdb, type) || (!self && ospf_lsdb_count(ospf->lsdb, type))) { - vty_out(vty, " %s\n\n", - show_database_desc[type]); - vty_out(vty, "%s\n", show_database_header[type]); + if (!json) { + vty_out(vty, " %s\n\n", + show_database_desc[type]); + vty_out(vty, "%s\n", + show_database_header[type]); + } else { + json_lsa_array = json_object_new_array(); + json_object_object_add( + json, show_database_desc_json[type], + json_lsa_array); + } + + LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa) { + if (json) { + json_lsa = json_object_new_object(); + json_object_array_add(json_lsa_array, + json_lsa); + } - LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa) - show_lsa_summary(vty, lsa, self); + show_lsa_summary(vty, lsa, self, json_lsa); + } - vty_out(vty, "\n"); + if (!json) + vty_out(vty, "\n"); } } - vty_out(vty, "\n"); + if (!json) + vty_out(vty, "\n"); } -static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf) +static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf, + json_object *json) { struct route_node *rn; + json_object *json_maxage = NULL; - vty_out(vty, "\n MaxAge Link States:\n\n"); + if (!json) + vty_out(vty, "\n MaxAge Link States:\n\n"); + else + json_maxage = json_object_new_object(); for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) { struct ospf_lsa *lsa; + json_object *json_lsa = NULL; if ((lsa = rn->info) != NULL) { - vty_out(vty, "Link type: %d\n", lsa->data->type); - vty_out(vty, "Link State ID: %s\n", - inet_ntoa(lsa->data->id)); - vty_out(vty, "Advertising Router: %s\n", - inet_ntoa(lsa->data->adv_router)); - vty_out(vty, "LSA lock count: %d\n", lsa->lock); - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, "Link type: %d\n", + lsa->data->type); + vty_out(vty, "Link State ID: %s\n", + inet_ntoa(lsa->data->id)); + vty_out(vty, "Advertising Router: %pI4\n", + &lsa->data->adv_router); + vty_out(vty, "LSA lock count: %d\n", lsa->lock); + vty_out(vty, "\n"); + } else { + json_lsa = json_object_new_object(); + json_object_int_add(json_lsa, "linkType", + lsa->data->type); + json_object_string_add( + json_lsa, "linkStateId", + inet_ntoa(lsa->data->id)); + json_object_string_add( + json_lsa, "advertisingRouter", + inet_ntoa(lsa->data->adv_router)); + json_object_int_add(json_lsa, "lsaLockCount", + lsa->lock); + json_object_object_add(json_maxage, + inet_ntoa(lsa->data->id), + json_lsa); + } } } + if (json) + json_object_object_add(json, "maxAgeLinkStates", json_maxage); } #define OSPF_LSA_TYPE_NSSA_DESC "NSSA external link state\n" @@ -6286,23 +6773,53 @@ static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf) static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, int arg_base, int argc, struct cmd_token **argv, - uint8_t use_vrf) + uint8_t use_vrf, json_object *json, + bool uj) { int idx_type = 4; int type, ret; struct in_addr id, adv_router; + json_object *json_vrf = NULL; - if (ospf->instance) - vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + if (uj) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + } - ospf_show_vrf_name(ospf, vty, NULL, use_vrf); + if (ospf->instance) { + if (uj) + json_object_int_add(json_vrf, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } - vty_out(vty, "\n OSPF Router with ID (%s)\n\n", - inet_ntoa(ospf->router_id)); + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); + + /* Show Router ID. */ + if (uj) { + json_object_string_add(json_vrf, "routerId", + inet_ntoa(ospf->router_id)); + } else { + vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", + &ospf->router_id); + } /* Show all LSA. */ - if (argc == arg_base + 4) { - show_ip_ospf_database_summary(vty, ospf, 0); + if ((argc == arg_base + 4) || (uj && (argc == arg_base + 5))) { + show_ip_ospf_database_summary(vty, ospf, 0, json_vrf); + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } @@ -6320,10 +6837,30 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0) type = OSPF_AS_EXTERNAL_LSA; else if (strncmp(argv[arg_base + idx_type]->text, "se", 2) == 0) { - show_ip_ospf_database_summary(vty, ospf, 1); + show_ip_ospf_database_summary(vty, ospf, 1, json_vrf); + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } else if (strncmp(argv[arg_base + idx_type]->text, "m", 1) == 0) { - show_ip_ospf_database_maxage(vty, ospf); + show_ip_ospf_database_maxage(vty, ospf, json_vrf); + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0) type = OSPF_OPAQUE_LINK_LSA; @@ -6335,18 +6872,19 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, return CMD_WARNING; /* `show ip ospf database LSA'. */ - if (argc == arg_base + 5) - show_lsa_detail(vty, ospf, type, NULL, NULL); + if ((argc == arg_base + 5) || (uj && (argc == arg_base + 6))) + show_lsa_detail(vty, ospf, type, NULL, NULL, json_vrf); else if (argc >= arg_base + 6) { ret = inet_aton(argv[arg_base + 5]->arg, &id); if (!ret) return CMD_WARNING; /* `show ip ospf database LSA ID'. */ - if (argc == arg_base + 6) - show_lsa_detail(vty, ospf, type, &id, NULL); + if ((argc == arg_base + 6) || (uj && (argc == arg_base + 7))) + show_lsa_detail(vty, ospf, type, &id, NULL, json_vrf); /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */ - else if (argc == arg_base + 7) { + else if ((argc == arg_base + 7) + || (uj && (argc == arg_base + 8))) { if (strncmp(argv[arg_base + 6]->text, "s", 1) == 0) adv_router = ospf->router_id; else { @@ -6355,7 +6893,19 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, if (!ret) return CMD_WARNING; } - show_lsa_detail(vty, ospf, type, &id, &adv_router); + show_lsa_detail(vty, ospf, type, &id, &adv_router, + json_vrf); + } + } + + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); } } @@ -6364,7 +6914,7 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_database_max, show_ip_ospf_database_max_cmd, - "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>", + "show ip ospf [vrf <NAME|all>] database <max-age|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" @@ -6372,7 +6922,8 @@ DEFUN (show_ip_ospf_database_max, "All VRFs\n" "Database summary\n" "LSAs in MaxAge list\n" - "Self-originated link states\n") + "Self-originated link states\n" + JSON_STR) { struct ospf *ospf = NULL; struct listnode *node = NULL; @@ -6382,6 +6933,11 @@ DEFUN (show_ip_ospf_database_max, int inst = 0; int idx_vrf = 0; uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); @@ -6397,7 +6953,7 @@ DEFUN (show_ip_ospf_database_max, ospf_output = true; ret = show_ip_ospf_database_common( vty, ospf, idx_vrf ? 2 : 0, argc, argv, - use_vrf); + use_vrf, json, uj); } if (!ospf_output) @@ -6409,8 +6965,8 @@ DEFUN (show_ip_ospf_database_max, return CMD_SUCCESS; } ret = (show_ip_ospf_database_common( - vty, ospf, idx_vrf ? 2 : 0, argc, argv, - use_vrf)); + vty, ospf, idx_vrf ? 2 : 0, argc, argv, use_vrf, + json, uj)); } } else { /* Display default ospf (instance 0) info */ @@ -6421,7 +6977,12 @@ DEFUN (show_ip_ospf_database_max, } ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv, - use_vrf); + use_vrf, json, uj); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string(json)); + json_object_free(json); } return ret; @@ -6429,7 +6990,7 @@ DEFUN (show_ip_ospf_database_max, DEFUN (show_ip_ospf_instance_database, show_ip_ospf_instance_database_cmd, - "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]", + "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]] [json]", SHOW_STR IP_STR "OSPF information\n" @@ -6440,7 +7001,8 @@ DEFUN (show_ip_ospf_instance_database, "Link State ID (as an IP address)\n" "Self-originated link states\n" "Advertising Router link states\n" - "Advertising Router (as an IP address)\n") + "Advertising Router (as an IP address)\n" + JSON_STR) { struct ospf *ospf; unsigned short instance = 0; @@ -6451,6 +7013,11 @@ DEFUN (show_ip_ospf_instance_database, int inst = 0; int idx = 0; uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); @@ -6460,8 +7027,8 @@ DEFUN (show_ip_ospf_instance_database, if (!ospf->oi_running) return CMD_SUCCESS; - return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, - argc, argv, use_vrf)); + return (show_ip_ospf_database_common( + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); } else if (argv_find(argv, argc, "vrf", &idx)) { vrf_name = argv[++idx]->arg; all_vrf = strmatch(vrf_name, "all"); @@ -6475,7 +7042,7 @@ DEFUN (show_ip_ospf_instance_database, continue; ret = (show_ip_ospf_database_common( vty, ospf, idx ? 2 : 0, argc, argv, - use_vrf)); + use_vrf, json, uj)); } } else { ospf = ospf_lookup_by_inst_name(inst, vrf_name); @@ -6485,7 +7052,8 @@ DEFUN (show_ip_ospf_instance_database, } ret = (show_ip_ospf_database_common( - vty, ospf, idx ? 2 : 0, argc, argv, use_vrf)); + vty, ospf, idx ? 2 : 0, argc, argv, use_vrf, + json, uj)); } } else { /* Display default ospf (instance 0) info */ @@ -6496,7 +7064,12 @@ DEFUN (show_ip_ospf_instance_database, } ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv, - use_vrf)); + use_vrf, json, uj)); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string(json)); + json_object_free(json); } return ret; @@ -6504,18 +7077,24 @@ DEFUN (show_ip_ospf_instance_database, DEFUN (show_ip_ospf_instance_database_max, show_ip_ospf_instance_database_max_cmd, - "show ip ospf (1-65535) database <max-age|self-originate>", + "show ip ospf (1-65535) database <max-age|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" "Instance ID\n" "Database summary\n" "LSAs in MaxAge list\n" - "Self-originated link states\n") + "Self-originated link states\n" + JSON_STR) { int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); instance = strtoul(argv[idx_number]->arg, NULL, 10); @@ -6528,7 +7107,16 @@ DEFUN (show_ip_ospf_instance_database_max, return CMD_SUCCESS; } - return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0); + show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0, json, uj); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return CMD_SUCCESS; } @@ -6536,19 +7124,40 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, struct ospf *ospf, int arg_base, int argc, struct cmd_token **argv, - uint8_t use_vrf) + uint8_t use_vrf, + json_object *json, + bool uj) { int idx_type = 4; int type, ret; struct in_addr adv_router; + json_object *json_vrf = NULL; - if (ospf->instance) - vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + if (uj) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + } - ospf_show_vrf_name(ospf, vty, NULL, use_vrf); + if (ospf->instance) { + if (uj) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } - vty_out(vty, "\n OSPF Router with ID (%s)\n\n", - inet_ntoa(ospf->router_id)); + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); + + /* Show Router ID. */ + if (uj) { + json_object_string_add(json_vrf, "routerId", + inet_ntoa(ospf->router_id)); + } else { + vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", + &ospf->router_id); + } /* Set database type to show. */ if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0) @@ -6581,14 +7190,25 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, return CMD_WARNING; } - show_lsa_detail_adv_router(vty, ospf, type, &adv_router); + show_lsa_detail_adv_router(vty, ospf, type, &adv_router, json_vrf); + + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } DEFUN (show_ip_ospf_instance_database_type_adv_router, show_ip_ospf_instance_database_type_adv_router_cmd, - "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>", + "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" @@ -6598,7 +7218,8 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, OSPF_LSA_TYPES_DESC "Advertising Router link states\n" "Advertising Router (as an IP address)\n" - "Self-originated link states\n") + "Self-originated link states\n" + JSON_STR) { struct ospf *ospf = NULL; unsigned short instance = 0; @@ -6609,6 +7230,11 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, int inst = 0; int idx = 0, idx_vrf = 0; uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); @@ -6621,7 +7247,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } return (show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf)); + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); } OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); @@ -6638,7 +7264,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, ospf_output = true; ret = show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, - use_vrf); + use_vrf, json, uj); } if (!ospf_output) vty_out(vty, "%% OSPF instance not found\n"); @@ -6650,7 +7276,8 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } ret = show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, + json, uj); } } else { /* Display default ospf (instance 0) info */ @@ -6661,8 +7288,14 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } ret = show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string(json)); + json_object_free(json); } + return ret; /*return (show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv));*/ @@ -8057,6 +8690,7 @@ DEFUN (ip_ospf_area, struct ospf *ospf = NULL; unsigned short instance = 0; char *areaid; + uint32_t count = 0; if (argv_find(argv, argc, "(1-65535)", &idx)) instance = strtol(argv[idx]->arg, NULL, 10); @@ -8070,13 +8704,39 @@ DEFUN (ip_ospf_area, ospf = ospf_lookup_instance(instance); if (instance && ospf == NULL) { + /* + * At this point we know we have received + * an instance and there is no ospf instance + * associated with it. This means we are + * in a situation where we have an + * ospf command that is setup for a different + * process(instance). We need to safely + * remove the command from ourselves and + * allow the other instance(process) handle + * the configuration command. + */ + count = 0; + params = IF_DEF_PARAMS(ifp); if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { UNSET_IF_PARAM(params, if_area); - ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); - ospf_interface_area_unset(ospf, ifp); - ospf->if_ospf_cli_count--; + count++; + } + + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) + if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) { + UNSET_IF_PARAM(params, if_area); + count++; + } + + if (count > 0) { + ospf = ospf_lookup_by_vrf_id(ifp->vrf_id); + if (ospf) { + ospf_interface_area_unset(ospf, ifp); + ospf->if_ospf_cli_count -= count; + } } + return CMD_NOT_MY_INSTANCE; } @@ -8090,6 +8750,16 @@ DEFUN (ip_ospf_area, return CMD_WARNING_CONFIG_FAILED; } + if (ospf) { + for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) { + if (rn->info != NULL) { + vty_out(vty, + "Please remove all network commands first.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + } + params = IF_DEF_PARAMS(ifp); if (OSPF_IF_PARAM_CONFIGURED(params, if_area) && !IPV4_ADDR_SAME(¶ms->if_area, &area_id)) { @@ -8109,22 +8779,12 @@ DEFUN (ip_ospf_area, params = ospf_get_if_params((ifp), (addr)); if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { vty_out(vty, - "Must remove previous area/address config before changing ospf area"); + "Must remove previous area/address config before changing ospf area\n"); return CMD_WARNING_CONFIG_FAILED; } ospf_if_update_params((ifp), (addr)); } - if (ospf) { - for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) { - if (rn->info != NULL) { - vty_out(vty, - "Please remove all network commands first.\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - } - /* enable ospf on this interface with area_id */ if (params) { SET_IF_PARAM(params, if_area); @@ -8167,7 +8827,7 @@ DEFUN (no_ip_ospf_area, else ospf = ospf_lookup_instance(instance); - if (ospf == NULL) + if (instance && ospf == NULL) return CMD_NOT_MY_INSTANCE; argv_find(argv, argc, "area", &idx); @@ -8197,8 +8857,11 @@ DEFUN (no_ip_ospf_area, ospf_if_update_params((ifp), (addr)); } - ospf_interface_area_unset(ospf, ifp); - ospf->if_ospf_cli_count--; + if (ospf) { + ospf_interface_area_unset(ospf, ifp); + ospf->if_ospf_cli_count--; + } + return CMD_SUCCESS; } @@ -8988,6 +9651,676 @@ DEFUN (no_ospf_proactive_arp, return CMD_SUCCESS; } +/* Graceful Restart HELPER Commands */ +DEFPY(ospf_gr_helper_enable, ospf_gr_helper_enable_cmd, + "graceful-restart helper-only [A.B.C.D]", + "OSPF Graceful Restart\n" + "Enable Helper support\n" + "Advertising router id\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct in_addr addr; + int ret; + + if (argc == 3) { + ret = inet_aton(argv[2]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify the valid routerid address.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ospf_gr_helper_support_set_per_routerid(ospf, &addr, OSPF_GR_TRUE); + return CMD_SUCCESS; + } + + ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE); + + return CMD_SUCCESS; +} + +DEFPY(no_ospf_gr_helper_enable, + no_ospf_gr_helper_enable_cmd, + "no graceful-restart helper-only [A.B.C.D]", + NO_STR + "OSPF Graceful Restart\n" + "Disable Helper support\n" + "Advertising router id\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct in_addr addr; + int ret; + + if (argc == 4) { + ret = inet_aton(argv[3]->arg, &addr); + if (!ret) { + vty_out(vty, + "Please specify the valid routerid address.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ospf_gr_helper_support_set_per_routerid(ospf, &addr, + OSPF_GR_FALSE); + return CMD_SUCCESS; + } + + ospf_gr_helper_support_set(ospf, OSPF_GR_FALSE); + return CMD_SUCCESS; +} + +DEFPY(ospf_gr_helper_enable_lsacheck, + ospf_gr_helper_enable_lsacheck_cmd, + "graceful-restart helper strict-lsa-checking", + "OSPF Graceful Restart\n" + "OSPF GR Helper\n" + "Enable strict LSA check\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_TRUE); + return CMD_SUCCESS; +} + +DEFPY(no_ospf_gr_helper_enable_lsacheck, + no_ospf_gr_helper_enable_lsacheck_cmd, + "no graceful-restart helper strict-lsa-checking", + NO_STR + "OSPF Graceful Restart\n" + "OSPF GR Helper\n" + "Disable strict LSA check\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_FALSE); + return CMD_SUCCESS; +} + +DEFPY(ospf_gr_helper_supported_grace_time, + ospf_gr_helper_supported_grace_time_cmd, + "graceful-restart helper supported-grace-time (10-1800)$interval", + "OSPF Graceful Restart\n" + "OSPF GR Helper\n" + "Supported grace timer\n" + "Grace interval(in seconds)\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_gr_helper_supported_gracetime_set(ospf, interval); + return CMD_SUCCESS; +} + +DEFPY(no_ospf_gr_helper_supported_grace_time, + no_ospf_gr_helper_supported_grace_time_cmd, + "no graceful-restart helper supported-grace-time (10-1800)$interval", + NO_STR + "OSPF Graceful Restart\n" + "OSPF GR Helper\n" + "Supported grace timer\n" + "Grace interval(in seconds)\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_gr_helper_supported_gracetime_set(ospf, OSPF_MAX_GRACE_INTERVAL); + return CMD_SUCCESS; +} + +DEFPY(ospf_gr_helper_planned_only, + ospf_gr_helper_planned_only_cmd, + "graceful-restart helper planned-only", + "OSPF Graceful Restart\n" + "OSPF GR Helper\n" + "Supported only planned restart\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_TRUE); + + return CMD_SUCCESS; +} + +/* External Route Aggregation */ +DEFUN (ospf_external_route_aggregation, + ospf_external_route_aggregation_cmd, + "summary-address A.B.C.D/M [tag (1-4294967295)]", + "External summary address\n" + "Summary address prefix (a.b.c.d/m) \n" + "Router tag \n" + "Router tag value\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct prefix_ipv4 p; + int idx = 1; + route_tag_t tag = 0; + int ret = OSPF_SUCCESS; + + str2prefix_ipv4(argv[idx]->arg, &p); + + if (is_prefix_default(&p)) { + vty_out(vty, + "Default address shouldn't be configured as summary address.\n"); + return CMD_SUCCESS; + } + + /* Apply mask for given prefix. */ + apply_mask((struct prefix *)&p); + + if (!is_valid_summary_addr(&p)) { + vty_out(vty, "Not a valid summary address.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > 2) + tag = strtoul(argv[idx + 2]->arg, NULL, 10); + + ret = ospf_asbr_external_aggregator_set(ospf, &p, tag); + if (ret == OSPF_INVALID) + vty_out(vty, "Inavlid configuration!!\n"); + + return CMD_SUCCESS; +} + +DEFUN (no_ospf_external_route_aggregation, + no_ospf_external_route_aggregation_cmd, + "no summary-address A.B.C.D/M [tag (1-4294967295)]", + NO_STR + "External summary address\n" + "Summary address prefix (a.b.c.d/m)\n" + "Router tag\n" + "Router tag value\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct prefix_ipv4 p; + int idx = 2; + route_tag_t tag = 0; + int ret = OSPF_SUCCESS; + + str2prefix_ipv4(argv[idx]->arg, &p); + + if (is_prefix_default(&p)) { + vty_out(vty, + "Default address shouldn't be configured as summary address.\n"); + return CMD_SUCCESS; + } + + /* Apply mask for given prefix. */ + apply_mask((struct prefix *)&p); + + if (!is_valid_summary_addr(&p)) { + vty_out(vty, "Not a valid summary address.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argc > 3) + tag = strtoul(argv[idx + 2]->arg, NULL, 10); + + ret = ospf_asbr_external_aggregator_unset(ospf, &p, tag); + if (ret == OSPF_INVALID) + vty_out(vty, "Inavlid configuration!!\n"); + + return CMD_SUCCESS; +} + +DEFPY(no_ospf_gr_helper_planned_only, + no_ospf_gr_helper_planned_only_cmd, + "no graceful-restart helper planned-only", + NO_STR + "OSPF Graceful Restart\n" + "OSPF GR Helper\n" + "Supported only for planned restart\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_FALSE); + + return CMD_SUCCESS; +} + +static int ospf_print_vty_helper_dis_rtr_walkcb(struct hash_bucket *backet, + void *arg) +{ + struct advRtr *rtr = backet->data; + struct vty *vty = (struct vty *)arg; + static unsigned int count; + + vty_out(vty, "%-6pI4,", &rtr->advRtrAddr); + count++; + + if (count % 5 == 0) + vty_out(vty, "\n"); + + return HASHWALK_CONTINUE; +} + +static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf, + uint8_t use_vrf, json_object *json, + bool uj, bool detail) +{ + struct listnode *node; + struct ospf_interface *oi; + char buf[PREFIX_STRLEN]; + json_object *json_vrf = NULL; + + if (uj) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + } + + if (ospf->instance) { + if (uj) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); + + if (uj) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } else + vty_out(vty, "\n"); + + /* Show Router ID. */ + if (uj) { + json_object_string_add(json_vrf, "routerId", + inet_ntop(AF_INET, &ospf->router_id, + buf, sizeof(buf))); + } else { + vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", + &ospf->router_id); + } + + if (!uj) { + + if (ospf->is_helper_supported) + vty_out(vty, + " Graceful restart helper support enabled.\n"); + else + vty_out(vty, + " Graceful restart helper support disabled.\n"); + + if (ospf->strict_lsa_check) + vty_out(vty, " Strict LSA check is enabled.\n"); + else + vty_out(vty, " Strict LSA check is disabled.\n"); + + if (ospf->only_planned_restart) + vty_out(vty, + " Helper supported for planned restarts only.\n"); + else + vty_out(vty, + " Helper supported for Planned and Unplanned Restarts.\n"); + + vty_out(vty, + " Supported Graceful restart interval: %d(in seconds).\n", + ospf->supported_grace_time); + + if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) { + vty_out(vty, " Enable Router list:\n"); + vty_out(vty, " "); + hash_walk(ospf->enable_rtr_list, + ospf_print_vty_helper_dis_rtr_walkcb, vty); + vty_out(vty, "\n\n"); + } + + if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) { + vty_out(vty, " Last Helper exit Reason :%s\n", + ospf_exit_reason2str(ospf->last_exit_reason)); + } + + if (ospf->active_restarter_cnt) + vty_out(vty, + " Number of Active neighbours in graceful restart: %d\n", + ospf->active_restarter_cnt); + else + vty_out(vty, "\n"); + + } else { + json_object_string_add( + json_vrf, "helperSupport", + (ospf->is_helper_supported) ? "Enabled" : "Disabled"); + json_object_string_add(json_vrf, "strictLsaCheck", + (ospf->strict_lsa_check) ? "Enabled" + : "Disabled"); + json_object_string_add( + json_vrf, "restartSupoort", + (ospf->only_planned_restart) + ? "Planned Restart only" + : "Planned and Unplanned Restarts"); + + json_object_int_add(json_vrf, "supportedGracePeriod", + ospf->supported_grace_time); + + if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) + json_object_string_add( + json_vrf, "LastExitReason", + ospf_exit_reason2str(ospf->last_exit_reason)); + + if (ospf->active_restarter_cnt) + json_object_int_add(json_vrf, "activeRestarterCnt", + ospf->active_restarter_cnt); + } + + + if (detail) { + int cnt = 1; + json_object *json_neighbors = NULL; + + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + struct route_node *rn; + struct ospf_neighbor *nbr; + json_object *json_neigh; + + if (ospf_interface_neighbor_count(oi) == 0) + continue; + + if (uj) { + json_object_object_get_ex(json_vrf, "Neighbors", + &json_neighbors); + if (!json_neighbors) { + json_neighbors = + json_object_new_object(); + json_object_object_add(json_vrf, + "Neighbors", + json_neighbors); + } + } + + for (rn = route_top(oi->nbrs); rn; + rn = route_next(rn)) { + + if (!rn->info) + continue; + + nbr = rn->info; + + if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) + continue; + + if (!uj) { + vty_out(vty, " Neighbour %d :\n", cnt); + vty_out(vty, " Address : %pI4\n", + &nbr->address.u.prefix4); + vty_out(vty, " Routerid : %pI4\n", + &nbr->router_id); + vty_out(vty, + " Received Grace period : %d(in seconds).\n", + nbr->gr_helper_info + .recvd_grace_period); + vty_out(vty, + " Actual Grace period : %d(in seconds)\n", + nbr->gr_helper_info + .actual_grace_period); + vty_out(vty, + " Remaining GraceTime:%ld(in seconds).\n", + thread_timer_remain_second( + nbr->gr_helper_info + .t_grace_timer)); + vty_out(vty, + " Graceful Restart reason: %s.\n\n", + ospf_restart_reason2str( + nbr->gr_helper_info + .gr_restart_reason)); + cnt++; + } else { + json_neigh = json_object_new_object(); + json_object_string_add( + json_neigh, "srcAddr", + inet_ntop(AF_INET, &nbr->src, + buf, sizeof(buf))); + + json_object_string_add( + json_neigh, "routerid", + inet_ntop(AF_INET, + &nbr->router_id, + buf, sizeof(buf))); + json_object_int_add( + json_neigh, + "recvdGraceInterval", + nbr->gr_helper_info + .recvd_grace_period); + json_object_int_add( + json_neigh, + "actualGraceInterval", + nbr->gr_helper_info + .actual_grace_period); + json_object_int_add( + json_neigh, "remainGracetime", + thread_timer_remain_second( + nbr->gr_helper_info + .t_grace_timer)); + json_object_string_add( + json_neigh, "restartReason", + ospf_restart_reason2str( + nbr->gr_helper_info + .gr_restart_reason)); + json_object_object_add( + json_neighbors, + inet_ntop(AF_INET, &nbr->src, + buf, sizeof(buf)), + json_neigh); + } + } + } + } + return CMD_SUCCESS; +} + +DEFUN (ospf_external_route_aggregation_no_adrvertise, + ospf_external_route_aggregation_no_adrvertise_cmd, + "summary-address A.B.C.D/M no-advertise", + "External summary address\n" + "Summary address prefix (a.b.c.d/m) \n" + "Don't advertise summary route \n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct prefix_ipv4 p; + int idx = 1; + int ret = OSPF_SUCCESS; + + str2prefix_ipv4(argv[idx]->arg, &p); + + if (is_prefix_default(&p)) { + vty_out(vty, + "Default address shouldn't be configured as summary address.\n"); + return CMD_SUCCESS; + } + + /* Apply mask for given prefix. */ + apply_mask((struct prefix *)&p); + + if (!is_valid_summary_addr(&p)) { + vty_out(vty, "Not a valid summary address.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = ospf_asbr_external_rt_no_advertise(ospf, &p); + if (ret == OSPF_INVALID) + vty_out(vty, "Inavlid configuration!!\n"); + + return CMD_SUCCESS; +} + +DEFUN (no_ospf_external_route_aggregation_no_adrvertise, + no_ospf_external_route_aggregation_no_adrvertise_cmd, + "no summary-address A.B.C.D/M no-advertise", + NO_STR + "External summary address\n" + "Summary address prefix (a.b.c.d/m) \n" + "Adverise summary route to the AS \n.") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + struct prefix_ipv4 p; + int idx = 2; + int ret = OSPF_SUCCESS; + + str2prefix_ipv4(argv[idx]->arg, &p); + + if (is_prefix_default(&p)) { + vty_out(vty, + "Default address shouldn't be configured as summary address.\n"); + return CMD_SUCCESS; + } + + /* Apply mask for given prefix. */ + apply_mask((struct prefix *)&p); + + if (!is_valid_summary_addr(&p)) { + vty_out(vty, "Not a valid summary address.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = ospf_asbr_external_rt_advertise(ospf, &p); + if (ret == OSPF_INVALID) + vty_out(vty, "Inavlid configuration!!\n"); + + return CMD_SUCCESS; +} + +DEFUN (ospf_route_aggregation_timer, + ospf_route_aggregation_timer_cmd, + "aggregation timer (5-1800)", + "External route aggregation\n" + "Delay timer (in seconds)\n" + "Timer interval(in seconds)\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + unsigned int interval = 0; + + interval = strtoul(argv[2]->arg, NULL, 10); + + ospf_external_aggregator_timer_set(ospf, interval); + + return CMD_SUCCESS; +} + +DEFPY (show_ip_ospf_gr_helper, + show_ip_ospf_gr_helper_cmd, + "show ip ospf [vrf <NAME|all>] graceful-restart helper [detail] [json]", + SHOW_STR + IP_STR + "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" + "OSPF Graceful Restart\n" + "Helper details in the router\n" + "Detailed informtion\n" + JSON_STR) +{ + char *vrf_name = NULL; + bool all_vrf = false; + int ret = CMD_SUCCESS; + int idx_vrf = 0; + int idx = 0; + uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + struct ospf *ospf = NULL; + json_object *json = NULL; + struct listnode *node = NULL; + int inst = 0; + bool detail = false; + + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + + if (argv_find(argv, argc, "detail", &idx)) + detail = true; + + if (uj) + json = json_object_new_object(); + + /* vrf input is provided */ + if (vrf_name) { + use_vrf = 1; + + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + + ret = ospf_show_gr_helper_details( + vty, ospf, use_vrf, json, uj, detail); + } + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return ret; + } + + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + + if (ospf == NULL || !ospf->oi_running) { + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + + return CMD_SUCCESS; + } + + } else { + /* Default Vrf */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + + if (ospf == NULL || !ospf->oi_running) { + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + + return CMD_SUCCESS; + } + + ospf_show_gr_helper_details(vty, ospf, use_vrf, json, uj, + detail); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return CMD_SUCCESS; +} +/* Graceful Restart HELPER commands end */ +DEFUN (no_ospf_route_aggregation_timer, + no_ospf_route_aggregation_timer_cmd, + "no aggregation timer", + NO_STR + "External route aggregation\n" + "Delay timer\n") +{ + VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + + ospf_external_aggregator_timer_set(ospf, OSPF_EXTL_AGGR_DEFAULT_DELAY); + + return CMD_SUCCESS; +} + +/* External Route Aggregation End */ + static void config_write_stub_router(struct vty *vty, struct ospf *ospf) { struct listnode *ln; @@ -9017,6 +10350,7 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, struct ospf_route * or ; struct listnode *pnode, *pnnode; struct ospf_path *path; + char buf[PREFIX_STRLEN]; json_object *json_route = NULL, *json_nexthop_array = NULL, *json_nexthop = NULL; @@ -9025,11 +10359,11 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, "============ OSPF network routing table ============\n"); for (rn = route_top(rt); rn; rn = route_next(rn)) { + char buf1[PREFIX2STR_BUFFER]; + if ((or = rn->info) == NULL) continue; - char buf1[PREFIX2STR_BUFFER]; - memset(buf1, 0, sizeof(buf1)); prefix2str(&rn->p, buf1, sizeof(buf1)); json_route = json_object_new_object(); @@ -9050,12 +10384,14 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, or->cost); json_object_string_add( json_route, "area", - inet_ntoa(or->u.std.area_id)); + inet_ntop(AF_INET, + &or->u.std.area_id, + buf1, sizeof(buf1))); } else { vty_out(vty, - "N IA %-18s [%d] area: %s\n", + "N IA %-18s [%d] area: %pI4\n", buf1, or->cost, - inet_ntoa(or->u.std.area_id)); + &or->u.std.area_id); } } else if (or->type == OSPF_DESTINATION_DISCARD) { if (json) { @@ -9077,11 +10413,12 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, or->cost); json_object_string_add( json_route, "area", - inet_ntoa(or->u.std.area_id)); + inet_ntop(AF_INET, &or->u.std.area_id, + buf1, sizeof(buf1))); } else { - vty_out(vty, "N %-18s [%d] area: %s\n", + vty_out(vty, "N %-18s [%d] area: %pI4\n", buf1, or->cost, - inet_ntoa(or->u.std.area_id)); + &or->u.std.area_id); } break; default: @@ -9130,8 +10467,11 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, json_object_string_add( json_nexthop, "ip", - inet_ntoa( - path->nexthop)); + inet_ntop( + AF_INET, + &path->nexthop, + buf, + sizeof(buf))); json_object_string_add( json_nexthop, "via", @@ -9140,10 +10480,9 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf, ospf->vrf_id)); } else { vty_out(vty, - "%24s via %s, %s\n", + "%24s via %pI4, %s\n", "", - inet_ntoa( - path->nexthop), + &path->nexthop, ifindex2ifname( path->ifindex, ospf->vrf_id)); @@ -9168,6 +10507,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, struct listnode *pnode; struct listnode *node; struct ospf_path *path; + char buf[PREFIX_STRLEN]; json_object *json_route = NULL, *json_nexthop_array = NULL, *json_nexthop = NULL; @@ -9182,12 +10522,14 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, json_route = json_object_new_object(); if (json) { - json_object_object_add(json, inet_ntoa(rn->p.u.prefix4), - json_route); + json_object_object_add( + json, inet_ntop(AF_INET, &rn->p.u.prefix4, + buf, sizeof(buf)), + json_route); json_object_string_add(json_route, "routeType", "R "); } else { - vty_out(vty, "R %-15s ", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, "R %-15pI4 ", + &rn->p.u.prefix4); } for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) { @@ -9202,7 +10544,8 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, or->cost); json_object_string_add( json_route, "area", - inet_ntoa(or->u.std.area_id)); + inet_ntop(AF_INET, &or->u.std.area_id, + buf, sizeof(buf))); if (or->path_type == OSPF_PATH_INTER_AREA) json_object_boolean_true_add(json_route, "IA"); @@ -9215,11 +10558,11 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, "routerType", "asbr"); } else { - vty_out(vty, "%s [%d] area: %s", + vty_out(vty, "%s [%d] area: %pI4", (or->path_type == OSPF_PATH_INTER_AREA ? "IA" : " "), - or->cost, inet_ntoa(or->u.std.area_id)); + or->cost, &or->u.std.area_id); /* Show flags. */ vty_out(vty, "%s%s\n", (or->u.std.flags & ROUTER_LSA_BORDER @@ -9269,8 +10612,10 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, json_object_string_add( json_nexthop, "ip", - inet_ntoa( - path->nexthop)); + inet_ntop( + AF_INET, + &path->nexthop, + buf, sizeof(buf))); json_object_string_add( json_nexthop, "via", @@ -9279,10 +10624,9 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf, ospf->vrf_id)); } else { vty_out(vty, - "%24s via %s, %s\n", + "%24s via %pI4, %s\n", "", - inet_ntoa( - path->nexthop), + &path->nexthop, ifindex2ifname( path->ifindex, ospf->vrf_id)); @@ -9306,6 +10650,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, struct ospf_route *er; struct listnode *pnode, *pnnode; struct ospf_path *path; + char buf[PREFIX_STRLEN]; json_object *json_route = NULL, *json_nexthop_array = NULL, *json_nexthop = NULL; @@ -9319,8 +10664,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, char buf1[19]; - snprintf(buf1, sizeof(buf1), "%s/%d", - inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); + snprintfrr(buf1, sizeof(buf1), "%pFX", &rn->p); json_route = json_object_new_object(); if (json) { json_object_object_add(json, buf1, json_route); @@ -9395,8 +10739,11 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, if (json) { json_object_string_add( json_nexthop, "ip", - inet_ntoa( - path->nexthop)); + inet_ntop( + AF_INET, + &path->nexthop, + buf, + sizeof(buf))); json_object_string_add( json_nexthop, "via", ifindex2ifname( @@ -9404,10 +10751,9 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, ospf->vrf_id)); } else { vty_out(vty, - "%24s via %s, %s\n", + "%24s via %pI4, %s\n", "", - inet_ntoa( - path->nexthop), + &path->nexthop, ifindex2ifname( path->ifindex, ospf->vrf_id)); @@ -9717,6 +11063,7 @@ DEFUN (show_ip_ospf_vrfs, struct ospf *ospf = NULL; struct listnode *node = NULL; int count = 0; + char buf[PREFIX_STRLEN]; static const char header[] = "Name Id RouterId "; if (uj) { @@ -9747,14 +11094,16 @@ DEFUN (show_ip_ospf_vrfs, if (uj) { json_object_int_add(json_vrf, "vrfId", vrf_id_ui); - json_object_string_add(json_vrf, "routerId", - inet_ntoa(ospf->router_id)); + json_object_string_add( + json_vrf, "routerId", + inet_ntop(AF_INET, &ospf->router_id, + buf, sizeof(buf))); json_object_object_add(json_vrfs, name, json_vrf); } else { - vty_out(vty, "%-25s %-5d %-16s \n", name, - ospf->vrf_id, inet_ntoa(ospf->router_id)); + vty_out(vty, "%-25s %-5d %-16pI4 \n", name, + ospf->vrf_id, &ospf->router_id); } } @@ -9781,6 +11130,264 @@ static const char *const ospf_abr_type_str[] = { static const char *const ospf_shortcut_mode_str[] = { "default", "enable", "disable" }; +static int ospf_vty_external_rt_walkcb(struct hash_bucket *backet, + void *arg) +{ + struct external_info *ei = backet->data; + struct vty *vty = (struct vty *)arg; + static unsigned int count; + + vty_out(vty, "%-4pI4/%d, ", &ei->p.prefix, ei->p.prefixlen); + count++; + + if (count % 5 == 0) + vty_out(vty, "\n"); + + if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count) + count = 0; + + return HASHWALK_CONTINUE; +} + +static int ospf_json_external_rt_walkcb(struct hash_bucket *backet, + void *arg) +{ + struct external_info *ei = backet->data; + struct json_object *json = (struct json_object *)arg; + char buf[PREFIX2STR_BUFFER]; + char exnalbuf[20]; + static unsigned int count; + + prefix2str(&ei->p, buf, sizeof(buf)); + + snprintf(exnalbuf, 20, "Exnl Addr-%d", count); + + json_object_string_add(json, exnalbuf, buf); + + count++; + + if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count) + count = 0; + + return HASHWALK_CONTINUE; +} + +static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf, + uint8_t use_vrf, json_object *json, + bool uj, bool detail) +{ + struct route_node *rn; + json_object *json_vrf = NULL; + int mtype = 0; + int mval = 0; + static char header[] = + "Summary-address Metric-type Metric Tag External_Rt_count\n"; + + mtype = metric_type(ospf, 0, ospf->instance); + mval = metric_value(ospf, 0, ospf->instance); + + if (!uj) + vty_out(vty, "%s\n", header); + + if (uj) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + } + + if (ospf->instance) { + if (uj) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); + + if (!uj) + vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n", + ospf->aggr_delay_interval); + else + json_object_int_add(json_vrf, "aggregation delay interval", + ospf->aggr_delay_interval); + + for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) + if (rn->info) { + struct ospf_external_aggr_rt *aggr = rn->info; + json_object *json_aggr = NULL; + char buf[PREFIX2STR_BUFFER]; + + prefix2str(&aggr->p, buf, sizeof(buf)); + + if (uj) { + + json_aggr = json_object_new_object(); + + json_object_object_add(json_vrf, buf, + json_aggr); + + json_object_string_add(json_aggr, + "Summary address", buf); + + json_object_string_add( + json_aggr, "Metric-type", + (mtype == EXTERNAL_METRIC_TYPE_1) + ? "E1" + : "E2"); + + json_object_int_add(json_aggr, "Metric", mval); + + json_object_int_add(json_aggr, "Tag", + aggr->tag); + + json_object_int_add( + json_aggr, "External route count", + OSPF_EXTERNAL_RT_COUNT(aggr)); + + if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) { + hash_walk( + aggr->match_extnl_hash, + ospf_json_external_rt_walkcb, + json_aggr); + } + + } else { + vty_out(vty, "%-20s", buf); + + (mtype == EXTERNAL_METRIC_TYPE_1) + ? vty_out(vty, "%-16s", "E1") + : vty_out(vty, "%-16s", "E2"); + vty_out(vty, "%-11d", mval); + + vty_out(vty, "%-12u", aggr->tag); + + vty_out(vty, "%-5ld\n", + OSPF_EXTERNAL_RT_COUNT(aggr)); + + if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) { + vty_out(vty, + "Matched External routes:\n"); + hash_walk( + aggr->match_extnl_hash, + ospf_vty_external_rt_walkcb, + vty); + vty_out(vty, "\n"); + } + + vty_out(vty, "\n"); + } + } + + if (uj) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } else + vty_out(vty, "\n"); + + return CMD_SUCCESS; +} + +DEFUN (show_ip_ospf_external_aggregator, + show_ip_ospf_external_aggregator_cmd, + "show ip ospf [vrf <NAME|all>] summary-address [detail] [json]", + SHOW_STR IP_STR + "OSPF information\n" + VRF_CMD_HELP_STR + "All VRFs\n" + "Show external summary addresses\n" + "Detailed informtion\n" + JSON_STR) +{ + char *vrf_name = NULL; + bool all_vrf = false; + int ret = CMD_SUCCESS; + int idx_vrf = 0; + int idx = 0; + uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + struct ospf *ospf = NULL; + json_object *json = NULL; + struct listnode *node = NULL; + int inst = 0; + bool detail = false; + + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + + if (argv_find(argv, argc, "detail", &idx)) + detail = true; + + if (uj) + json = json_object_new_object(); + + /* vrf input is provided */ + if (vrf_name) { + use_vrf = 1; + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + ret = ospf_show_summary_address( + vty, ospf, use_vrf, json, uj, detail); + } + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return ret; + } + + ospf = ospf_lookup_by_inst_name(inst, vrf_name); + + if (ospf == NULL || !ospf->oi_running) { + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + + return CMD_SUCCESS; + } + ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail); + + } else { + /* Default Vrf */ + ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT); + if (ospf == NULL || !ospf->oi_running) { + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else + vty_out(vty, "%% OSPF instance not found\n"); + + return CMD_SUCCESS; + } + + ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + return CMD_SUCCESS; +} static const char *const ospf_int_type_str[] = { "unknown", /* should never be used. */ @@ -9829,9 +11436,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) ospf_int_type_str [params->type]); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa( - rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } } @@ -9866,8 +11472,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf authentication%s", auth_str); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9877,8 +11483,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf authentication-key %s", params->auth_simple); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9890,9 +11496,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) " ip ospf message-digest-key %d md5 %s", ck->key_id, ck->auth_key); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa( - rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } } @@ -9902,8 +11507,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf cost %u", params->output_cost_cmd); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9913,8 +11518,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf hello-interval %u", params->v_hello); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9935,8 +11540,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, "%u", params->v_wait); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9947,8 +11552,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf priority %u", params->priority); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9960,8 +11565,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf retransmit-interval %u", params->retransmit_interval); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9972,8 +11577,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " ip ospf transmit-delay %u", params->transmit_delay); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -9991,8 +11596,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) params->if_area_id_fmt); vty_out(vty, " area %s", buf); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -10008,8 +11613,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) else vty_out(vty, " ip ospf mtu-ignore"); if (params != IF_DEF_PARAMS(ifp) && rn) - vty_out(vty, " %s", - inet_ntoa(rn->p.u.prefix4)); + vty_out(vty, " %pI4", + &rn->p.u.prefix4); vty_out(vty, "\n"); } @@ -10073,9 +11678,7 @@ static int config_write_network_area(struct vty *vty, struct ospf *ospf) n->area_id.s_addr)); /* Network print. */ - vty_out(vty, " network %s/%d area %s\n", - inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen, - buf); + vty_out(vty, " network %pFX area %s\n", &rn->p, buf); } return 0; @@ -10146,9 +11749,8 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf) if (rn1->info) { struct ospf_area_range *range = rn1->info; - vty_out(vty, " area %s range %s/%d", buf, - inet_ntoa(rn1->p.u.prefix4), - rn1->p.prefixlen); + vty_out(vty, " area %s range %pFX", buf, + &rn1->p); if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) @@ -10161,8 +11763,8 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf) if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE)) - vty_out(vty, " substitute %s/%d", - inet_ntoa(range->subst_addr), + vty_out(vty, " substitute %pI4/%d", + &range->subst_addr, range->subst_masklen); vty_out(vty, "\n"); @@ -10196,7 +11798,7 @@ static int config_write_ospf_nbr_nbma(struct vty *vty, struct ospf *ospf) /* Static Neighbor configuration print. */ for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn)) if ((nbr_nbma = rn->info)) { - vty_out(vty, " neighbor %s", inet_ntoa(nbr_nbma->addr)); + vty_out(vty, " neighbor %pI4", &nbr_nbma->addr); if (nbr_nbma->priority != OSPF_NEIGHBOR_PRIORITY_DEFAULT) @@ -10240,21 +11842,21 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf) || OSPF_IF_PARAM(oi, transmit_delay) != OSPF_TRANSMIT_DELAY_DEFAULT) vty_out(vty, - " area %s virtual-link %s hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n", - buf, inet_ntoa(vl_data->vl_peer), + " area %s virtual-link %pI4 hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n", + buf, &vl_data->vl_peer, OSPF_IF_PARAM(oi, v_hello), OSPF_IF_PARAM(oi, retransmit_interval), OSPF_IF_PARAM(oi, transmit_delay), OSPF_IF_PARAM(oi, v_wait)); else - vty_out(vty, " area %s virtual-link %s\n", buf, - inet_ntoa(vl_data->vl_peer)); + vty_out(vty, " area %s virtual-link %pI4\n", buf, + &vl_data->vl_peer); /* Auth key */ if (IF_DEF_PARAMS(vl_data->vl_oi->ifp)->auth_simple[0] != '\0') vty_out(vty, - " area %s virtual-link %s authentication-key %s\n", - buf, inet_ntoa(vl_data->vl_peer), + " area %s virtual-link %pI4 authentication-key %s\n", + buf, &vl_data->vl_peer, IF_DEF_PARAMS(vl_data->vl_oi->ifp) ->auth_simple); /* md5 keys */ @@ -10263,8 +11865,8 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf) ->auth_crypt, n2, ck)) vty_out(vty, - " area %s virtual-link %s message-digest-key %d md5 %s\n", - buf, inet_ntoa(vl_data->vl_peer), + " area %s virtual-link %pI4 message-digest-key %d md5 %s\n", + buf, &vl_data->vl_peer, ck->key_id, ck->auth_key); } } @@ -10310,6 +11912,66 @@ static int config_write_ospf_redistribute(struct vty *vty, struct ospf *ospf) return 0; } +static int ospf_cfg_write_helper_dis_rtr_walkcb(struct hash_bucket *backet, + void *arg) +{ + struct advRtr *rtr = backet->data; + struct vty *vty = (struct vty *)arg; + + vty_out(vty, " graceful-restart helper-only %pI4\n", + &rtr->advRtrAddr); + return HASHWALK_CONTINUE; +} + +static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf) +{ + if (ospf->is_helper_supported) + vty_out(vty, " graceful-restart helper-only\n"); + + if (!ospf->strict_lsa_check) + vty_out(vty, + " no graceful-restart helper strict-lsa-checking\n"); + + if (ospf->only_planned_restart) + vty_out(vty, " graceful-restart helper planned-only\n"); + + if (ospf->supported_grace_time != OSPF_MAX_GRACE_INTERVAL) + vty_out(vty, + " graceful-restart helper supported-grace-time %d\n", + ospf->supported_grace_time); + + if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) { + hash_walk(ospf->enable_rtr_list, + ospf_cfg_write_helper_dis_rtr_walkcb, vty); + } + return 0; +} + +static int config_write_ospf_external_aggregator(struct vty *vty, + struct ospf *ospf) +{ + struct route_node *rn; + + /* print 'summary-address A.B.C.D/M' */ + for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) + if (rn->info) { + struct ospf_external_aggr_rt *aggr = rn->info; + + vty_out(vty, " summary-address %pI4/%d ", + &aggr->p.prefix, aggr->p.prefixlen); + if (aggr->tag) + vty_out(vty, " tag %u ", aggr->tag); + + if (CHECK_FLAG(aggr->flags, + OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) + vty_out(vty, " no-advertise"); + + vty_out(vty, "\n"); + } + + return 0; +} + static int config_write_ospf_default_metric(struct vty *vty, struct ospf *ospf) { if (ospf->default_metric != -1) @@ -10381,9 +12043,8 @@ static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf) for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn)) if ((odistance = rn->info) != NULL) { - vty_out(vty, " distance %d %s/%d %s\n", - odistance->distance, inet_ntoa(rn->p.u.prefix4), - rn->p.prefixlen, + vty_out(vty, " distance %d %pFX %s\n", + odistance->distance, &rn->p, odistance->access_list ? odistance->access_list : ""); } @@ -10416,8 +12077,8 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf) /* Router ID print. */ if (ospf->router_id_static.s_addr != 0) - vty_out(vty, " ospf router-id %s\n", - inet_ntoa(ospf->router_id_static)); + vty_out(vty, " ospf router-id %pI4\n", + &ospf->router_id_static); /* ABR type print. */ if (ospf->abr_type != OSPF_ABR_DEFAULT) @@ -10477,6 +12138,12 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf) /* Redistribute information print. */ config_write_ospf_redistribute(vty, ospf); + /* Print gr helper configs */ + config_write_ospf_gr_helper(vty, ospf); + + /* Print external route aggregation. */ + config_write_ospf_external_aggregator(vty, ospf); + /* passive-interface print. */ if (ospf->passive_interface_default == OSPF_IF_PASSIVE) vty_out(vty, " passive-interface default\n"); @@ -10511,9 +12178,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf) == ospf->passive_interface_default) continue; - vty_out(vty, " %spassive-interface %s %s\n", + vty_out(vty, " %spassive-interface %s %pI4\n", oi->params->passive_interface ? "" : "no ", - oi->ifp->name, inet_ntoa(oi->address->u.prefix4)); + oi->ifp->name, &oi->address->u.prefix4); } /* Network area print. */ @@ -10620,8 +12287,13 @@ void ospf_vty_show_init(void) /* "show ip ospf vrfs" commands. */ install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd); -} + /* "show ip ospf gr-helper details" command */ + install_element(VIEW_NODE, &show_ip_ospf_gr_helper_cmd); + + /* "show ip ospf summary-address" command */ + install_element(VIEW_NODE, &show_ip_ospf_external_aggregator_cmd); +} static int config_write_interface(struct vty *vty); /* ospfd's interface node. */ @@ -10735,6 +12407,27 @@ static void ospf_vty_zebra_init(void) install_element(OSPF_NODE, &no_ospf_distance_cmd); install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd); install_element(OSPF_NODE, &ospf_distance_ospf_cmd); + + /*Ospf garcefull restart helper configurations */ + install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd); + install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd); + install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd); + install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd); + install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd); + install_element(OSPF_NODE, &no_ospf_gr_helper_supported_grace_time_cmd); + install_element(OSPF_NODE, &ospf_gr_helper_planned_only_cmd); + install_element(OSPF_NODE, &no_ospf_gr_helper_planned_only_cmd); + + /* External LSA summarisation config commands.*/ + install_element(OSPF_NODE, &ospf_external_route_aggregation_cmd); + install_element(OSPF_NODE, &no_ospf_external_route_aggregation_cmd); + install_element(OSPF_NODE, + &ospf_external_route_aggregation_no_adrvertise_cmd); + install_element(OSPF_NODE, + &no_ospf_external_route_aggregation_no_adrvertise_cmd); + install_element(OSPF_NODE, &ospf_route_aggregation_timer_cmd); + install_element(OSPF_NODE, &no_ospf_route_aggregation_timer_cmd); + #if 0 install_element (OSPF_NODE, &ospf_distance_source_cmd); install_element (OSPF_NODE, &no_ospf_distance_source_cmd); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index dc8a8dccd2..fd965e8f21 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -73,12 +73,9 @@ static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS) struct prefix router_id; zebra_router_id_update_read(zclient->ibuf, &router_id); - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&router_id, buf, sizeof(buf)); - zlog_debug("Zebra rcvd: router id update %s vrf %s id %u", buf, - ospf_vrf_id_to_name(vrf_id), vrf_id); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra rcvd: router id update %pFX vrf %s id %u", + &router_id, ospf_vrf_id_to_name(vrf_id), vrf_id); ospf = ospf_lookup_by_vrf_id(vrf_id); @@ -86,15 +83,11 @@ static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS) ospf->router_id_zebra = router_id.u.prefix4; ospf_router_id_update(ospf); } else { - if (IS_DEBUG_OSPF_EVENT) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&router_id, buf, sizeof(buf)); + if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "%s: ospf instance not found for vrf %s id %u router_id %s", + "%s: ospf instance not found for vrf %s id %u router_id %pFX", __func__, ospf_vrf_id_to_name(vrf_id), vrf_id, - buf); - } + &router_id); } return 0; } @@ -110,13 +103,10 @@ static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS) if (c == NULL) return 0; - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address add %s vrf %s id %u", - c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id), - vrf_id); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: interface %s address add %pFX vrf %s id %u", + c->ifp->name, c->address, + ospf_vrf_id_to_name(vrf_id), vrf_id); ospf = ospf_lookup_by_vrf_id(vrf_id); if (!ospf) @@ -142,12 +132,9 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS) if (c == NULL) return 0; - if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(c->address, buf, sizeof(buf)); - zlog_debug("Zebra: interface %s address delete %s", - c->ifp->name, buf); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) + zlog_debug("Zebra: interface %s address delete %pFX", + c->ifp->name, c->address); ifp = c->ifp; p = *c->address; @@ -279,17 +266,14 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, count++; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[2][PREFIX2STR_BUFFER]; struct interface *ifp; ifp = if_lookup_by_index(path->ifindex, ospf->vrf_id); zlog_debug( - "Zebra: Route add %s nexthop %s, ifindex=%d %s", - prefix2str(p, buf[0], sizeof(buf[0])), - inet_ntop(AF_INET, &path->nexthop, - buf[1], sizeof(buf[1])), - path->ifindex, ifp ? ifp->name : " "); + "Zebra: Route add %pFX nexthop %pI4, ifindex=%d %s", + p, &path->nexthop, path->ifindex, + ifp ? ifp->name : " "); } } api.nexthop_num = count; @@ -309,11 +293,8 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[PREFIX2STR_BUFFER]; - zlog_debug("Zebra: Route delete %s", - prefix2str(p, buf, sizeof(buf))); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route delete %pFX", p); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } @@ -332,11 +313,8 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[PREFIX2STR_BUFFER]; - zlog_debug("Zebra: Route add discard %s", - prefix2str(p, buf, sizeof(buf))); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route add discard %pFX", p); } void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) @@ -353,11 +331,8 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[PREFIX2STR_BUFFER]; - zlog_debug("Zebra: Route delete discard %s", - prefix2str(p, buf, sizeof(buf))); - } + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("Zebra: Route delete discard %pFX", p); } struct ospf_external *ospf_external_lookup(struct ospf *ospf, uint8_t type, @@ -433,8 +408,8 @@ bool ospf_external_default_routemap_apply_walk(struct ospf *ospf, if (ret && ei) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Default originate routemap permit ei: %s", - inet_ntoa(ei->p.prefix)); + zlog_debug("Default originate routemap permit ei: %pI4", + &ei->p.prefix); return true; } @@ -488,7 +463,7 @@ static int ospf_external_lsa_default_routemap_timer(struct thread *thread) if (ret && !lsa) ospf_external_lsa_originate(ospf, default_ei); else if (ret && lsa && IS_LSA_MAXAGE(lsa)) - ospf_external_lsa_refresh(ospf, lsa, default_ei, true); + ospf_external_lsa_refresh(ospf, lsa, default_ei, true, false); else if (!ret && lsa) ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &default_ei->p, 0); @@ -875,8 +850,8 @@ static int ospf_external_lsa_originate_check(struct ospf *ospf, /* If prefix is multicast, then do not originate LSA. */ if (IN_MULTICAST(htonl(ei->p.prefix.s_addr))) { zlog_info( - "LSA[Type5:%s]: Not originate AS-external-LSA, Prefix belongs multicast", - inet_ntoa(ei->p.prefix)); + "LSA[Type5:%pI4]: Not originate AS-external-LSA, Prefix belongs multicast", + &ei->p.prefix); return 0; } @@ -968,16 +943,16 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, } if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Apply default originate routemap on ei: %s cmd: %d", - inet_ntoa(ei->p.prefix), cmd); + zlog_debug("Apply default originate routemap on ei: %pI4 cmd: %d", + &ei->p.prefix, cmd); ret = ospf_external_info_apply_default_routemap(ospf, ei, default_ei); /* If deny then nothing to be done both in add and del case. */ if (!ret) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Default originte routemap deny for ei: %s", - inet_ntoa(ei->p.prefix)); + zlog_debug("Default originte routemap deny for ei: %pI4", + &ei->p.prefix); return false; } @@ -989,7 +964,7 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, /* If permit and default already advertise then return. */ if (lsa && !IS_LSA_MAXAGE(lsa)) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Defult lsa already originated"); + zlog_debug("Default lsa already originated"); return true; } @@ -998,7 +973,8 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, if (lsa && IS_LSA_MAXAGE(lsa)) /* Refresh lsa.*/ - ospf_external_lsa_refresh(ospf, lsa, default_ei, true); + ospf_external_lsa_refresh(ospf, lsa, default_ei, true, + false); else /* If permit and default not advertised then advertise. */ @@ -1015,8 +991,8 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, if (IS_DEBUG_OSPF_DEFAULT_INFO) zlog_debug( - "Running default route-map again as ei: %s deleted", - inet_ntoa(ei->p.prefix)); + "Running default route-map again as ei: %pI4 deleted", + &ei->p.prefix); /* * if this route delete was permitted then we need to check * there are any other external info which can still trigger @@ -1061,13 +1037,10 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei, if (DISTRIBUTE_LIST(ospf, type)) if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p) == FILTER_DENY) { - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[PREFIX2STR_BUFFER]; + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug( - "Redistribute[%s]: %s filtered by distribute-list.", - ospf_redist_string(type), - prefix2str(p, buf, sizeof(buf))); - } + "Redistribute[%s]: %pFX filtered by distribute-list.", + ospf_redist_string(type), p); return 0; } @@ -1088,13 +1061,10 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei, if (ret == RMAP_DENYMATCH) { ei->route_map_set = save_values; - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf[PREFIX2STR_BUFFER]; + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug( - "Redistribute[%s]: %s filtered by route-map.", - ospf_redist_string(type), - prefix2str(p, buf, sizeof(buf))); - } + "Redistribute[%s]: %pFX filtered by route-map.", + ospf_redist_string(type), p); return 0; } @@ -1171,14 +1141,10 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) if (is_prefix_default(&p)) rt_type = DEFAULT_ROUTE; - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { - char buf_prefix[PREFIX_STRLEN]; - prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix)); - - zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %s", + if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %pFX", __func__, zserv_command_string(cmd), - zebra_route_string(api.type), vrf_id, buf_prefix); - } + zebra_route_string(api.type), vrf_id, &api.prefix); if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { /* XXX|HACK|TODO|FIXME: @@ -1215,24 +1181,100 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) if (is_prefix_default(&p)) ospf_external_lsa_refresh_default(ospf); else { - struct ospf_lsa *current; + struct ospf_external_aggr_rt *aggr; + struct as_external_lsa *al; + struct ospf_lsa *lsa = NULL; + struct in_addr mask; + + aggr = ospf_external_aggr_match(ospf, + &ei->p); + + if (aggr) { + /* Check the AS-external-LSA + * should be originated. + */ + if (!ospf_redistribute_check( + ospf, ei, NULL)) + return 0; - current = ospf_external_info_find_lsa( - ospf, &ei->p); - if (!current) - ospf_external_lsa_originate( - ospf, ei); - else { if (IS_DEBUG_OSPF( - zebra, - ZEBRA_REDISTRIBUTE)) + lsa, + EXTNL_LSA_AGGR)) zlog_debug( - "ospf_zebra_read_route() : %s refreshing LSA", - inet_ntoa( - p.prefix)); - ospf_external_lsa_refresh( - ospf, current, ei, - LSA_REFRESH_FORCE); + "%s: Send Aggreate LSA (%pI4/%d)", + __func__, + &aggr->p.prefix, + aggr->p.prefixlen); + + ospf_originate_summary_lsa( + ospf, aggr, ei); + + /* Handling the case where the + * external route prefix + * and aggegate prefix is same + * If same dont flush the + * originated + * external LSA. + */ + if (prefix_same( + (struct prefix + *)&aggr->p, + (struct prefix *)&ei + ->p)) + return 0; + + lsa = ospf_external_info_find_lsa( + ospf, &ei->p); + + if (lsa) { + al = (struct + as_external_lsa *) + lsa->data; + masklen2ip( + ei->p.prefixlen, + &mask); + + if (mask.s_addr + != al->mask.s_addr) + return 0; + + ospf_external_lsa_flush( + ospf, ei->type, + &ei->p, 0); + } + } else { + struct ospf_lsa *current; + + current = + ospf_external_info_find_lsa( + ospf, &ei->p); + if (!current) { + /* Check the + * AS-external-LSA + * should be + * originated. + */ + if (!ospf_redistribute_check( + ospf, ei, + NULL)) + return 0; + + ospf_external_lsa_originate( + ospf, ei); + } else { + if (IS_DEBUG_OSPF( + zebra, + ZEBRA_REDISTRIBUTE)) + zlog_debug( + "%s: %pI4 refreshing LSA", + __func__, + &p.prefix); + ospf_external_lsa_refresh( + ospf, current, + ei, + LSA_REFRESH_FORCE, + false); + } } } } @@ -1246,21 +1288,36 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) } else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { - /* - * Check if default-information originate is - * with some routemap prefix/access list match. - * Apply before ei is deleted. - */ + struct ospf_external_aggr_rt *aggr; + ei = ospf_external_info_lookup(ospf, rt_type, api.instance, &p); - if (ei) + if (ei == NULL) + return 0; + else + /* + * Check if default-information originate i + * with some routemap prefix/access list match. + * Apply before ei is deleted. + */ ospf_external_lsa_default_routemap_apply(ospf, ei, cmd); - ospf_external_info_delete(ospf, rt_type, api.instance, p); - if (is_prefix_default(&p)) - ospf_external_lsa_refresh_default(ospf); - else - ospf_external_lsa_flush(ospf, rt_type, &p, - ifindex /*, nexthop */); + aggr = ospf_external_aggr_match(ospf, &ei->p); + + if (aggr && (ei->aggr_route == aggr)) { + ospf_unlink_ei_from_aggr(ospf, aggr, ei); + + ospf_external_info_delete(ospf, rt_type, api.instance, + p); + } else { + ospf_external_info_delete(ospf, rt_type, api.instance, + p); + + if (is_prefix_default(&p)) + ospf_external_lsa_refresh_default(ospf); + else + ospf_external_lsa_flush(ospf, rt_type, &p, + ifindex /*, nexthop */); + } } @@ -1352,32 +1409,80 @@ static int ospf_distribute_list_update_timer(struct thread *thread) if ((ei = rn->info) != NULL) { if (is_prefix_default(&ei->p)) default_refresh = 1; - else if ( - (lsa = ospf_external_info_find_lsa( - ospf, &ei->p))) { - int force = - LSA_REFRESH_IF_CHANGED; - /* If this is a MaxAge LSA, we - * need to force refresh it - * because distribute settings - * might have changed and now, - * this LSA needs to be - * originated, not be removed. - * If we don't force refresh it, - * it will remain a MaxAge LSA - * because it will look like it - * hasn't changed. Neighbors - * will not receive updates for - * this LSA. - */ - if (IS_LSA_MAXAGE(lsa)) - force = LSA_REFRESH_FORCE; - - ospf_external_lsa_refresh( - ospf, lsa, ei, force); - } else - ospf_external_lsa_originate( - ospf, ei); + else { + struct ospf_external_aggr_rt + *aggr; + aggr = ospf_external_aggr_match( + ospf, &ei->p); + if (aggr) { + /* Check the + * AS-external-LSA + * should be originated. + */ + if (!ospf_redistribute_check( + ospf, ei, + NULL)) { + + ospf_unlink_ei_from_aggr( + ospf, + aggr, + ei); + continue; + } + + if (IS_DEBUG_OSPF( + lsa, + EXTNL_LSA_AGGR)) + zlog_debug( + "%s: Send Aggregate LSA (%pI4/%d)", + __func__, + &aggr->p.prefix, + aggr->p.prefixlen); + + /* Originate Aggregate + * LSA + */ + ospf_originate_summary_lsa( + ospf, aggr, ei); + } else if ( + (lsa = ospf_external_info_find_lsa( + ospf, + &ei->p))) { + int force = + LSA_REFRESH_IF_CHANGED; + /* If this is a MaxAge + * LSA, we need to + * force refresh it + * because distribute + * settings might have + * changed and now, + * this LSA needs to be + * originated, not be + * removed. + * If we don't force + * refresh it, it will + * remain a MaxAge LSA + * because it will look + * like it hasn't + * changed. Neighbors + * will not receive + * updates for this LSA. + */ + if (IS_LSA_MAXAGE(lsa)) + force = LSA_REFRESH_FORCE; + + ospf_external_lsa_refresh( + ospf, lsa, ei, + force, false); + } else { + if (!ospf_redistribute_check( + ospf, ei, + NULL)) + continue; + ospf_external_lsa_originate( + ospf, ei); + } + } } } } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index cc5839a810..a839806720 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -59,6 +59,7 @@ #include "ospfd/ospf_flood.h" #include "ospfd/ospf_ase.h" #include "ospfd/ospf_ldp_sync.h" +#include "ospfd/ospf_gr_helper.h" DEFINE_QOBJ_TYPE(ospf) @@ -102,8 +103,8 @@ void ospf_router_id_update(struct ospf *ospf) } if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Router-ID[OLD:%s]: Update", - inet_ntoa(ospf->router_id)); + zlog_debug("Router-ID[OLD:%pI4]: Update", + &ospf->router_id); router_id_old = ospf->router_id; @@ -122,8 +123,8 @@ void ospf_router_id_update(struct ospf *ospf) router_id = ospf->router_id_zebra; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Router-ID[OLD:%s]: Update to %s", - inet_ntoa(ospf->router_id), inet_ntoa(router_id)); + zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4", + &ospf->router_id, &router_id); if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) { @@ -161,8 +162,8 @@ void ospf_router_id_update(struct ospf *ospf) ospf->router_id = router_id; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Router-ID[NEW:%s]: Update", - inet_ntoa(ospf->router_id)); + zlog_debug("Router-ID[NEW:%pI4]: Update", + &ospf->router_id); /* Flush (inline) all external LSAs which now match the new router-id, @@ -309,6 +310,10 @@ static struct ospf *ospf_new(unsigned short instance, const char *name) new->proactive_arp = OSPF_PROACTIVE_ARP_DEFAULT; + ospf_gr_helper_init(new); + + ospf_asbr_external_aggregator_init(new); + QOBJ_REG(new, ospf); new->fd = -1; @@ -382,6 +387,8 @@ struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name) struct ospf *ospf_get(unsigned short instance, const char *name, bool *created) { struct ospf *ospf; + struct vrf *vrf; + struct interface *ifp; /* vrf name provided call inst and name based api * in case of no name pass default ospf instance */ @@ -395,10 +402,39 @@ struct ospf *ospf_get(unsigned short instance, const char *name, bool *created) ospf = ospf_new(instance, name); ospf_add(ospf); - if (ospf->router_id_static.s_addr == INADDR_ANY) - ospf_router_id_update(ospf); - ospf_opaque_type11_lsa_init(ospf); + + if (ospf->vrf_id != VRF_UNKNOWN) + ospf->oi_running = 1; + + /* Activate 'ip ospf area x' configured interfaces for given + * vrf. Activate area on vrf x aware interfaces. + * vrf_enable callback calls router_id_update which + * internally will call ospf_if_update to trigger + * network_run_state + */ + vrf = vrf_lookup_by_id(ospf->vrf_id); + + FOR_ALL_INTERFACES (vrf, ifp) { + struct ospf_if_params *params; + struct route_node *rn; + uint32_t count = 0; + + params = IF_DEF_PARAMS(ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + count++; + + for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) + if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) + count++; + + if (count > 0) { + ospf_interface_area_set(ospf, ifp); + ospf->if_ospf_cli_count += count; + } + } + + ospf_router_id_update(ospf); } return ospf; @@ -414,9 +450,6 @@ struct ospf *ospf_get_instance(unsigned short instance, bool *created) ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/); ospf_add(ospf); - if (ospf->router_id_static.s_addr == INADDR_ANY) - ospf_router_id_update(ospf); - ospf_opaque_type11_lsa_init(ospf); } @@ -578,11 +611,10 @@ void ospf_finish(struct ospf *ospf) /* Final cleanup of ospf instance */ static void ospf_finish_final(struct ospf *ospf) { - struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); + struct vrf *vrf; struct route_node *rn; struct ospf_nbr_nbma *nbr_nbma; struct ospf_lsa *lsa; - struct interface *ifp; struct ospf_interface *oi; struct ospf_area *area; struct ospf_vl_data *vl_data; @@ -625,15 +657,6 @@ static void ospf_finish_final(struct ospf *ospf) if (ospf->vrf_id == VRF_DEFAULT) ospf_ldp_sync_gbl_exit(ospf, true); - /* Remove any ospf interface config params */ - FOR_ALL_INTERFACES (vrf, ifp) { - struct ospf_if_params *params; - - params = IF_DEF_PARAMS(ifp); - if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) - UNSET_IF_PARAM(params, if_area); - } - /* Reset interface. */ for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) ospf_if_free(oi); @@ -695,6 +718,7 @@ static void ospf_finish_final(struct ospf *ospf) OSPF_TIMER_OFF(ospf->t_opaque_lsa_self); OSPF_TIMER_OFF(ospf->t_sr_update); OSPF_TIMER_OFF(ospf->t_default_routemap_timer); + OSPF_TIMER_OFF(ospf->t_external_aggr); LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa) ospf_discard_from_db(ospf, ospf->lsdb, lsa); @@ -763,9 +787,28 @@ static void ospf_finish_final(struct ospf *ospf) ospf_distance_reset(ospf); route_table_finish(ospf->distance_table); + /* Release extrenal Aggregator table */ + for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) { + struct ospf_external_aggr_rt *aggr; + + aggr = rn->info; + + if (aggr) { + ospf_external_aggregator_free(aggr); + rn->info = NULL; + route_unlock_node(rn); + } + } + + route_table_finish(ospf->rt_aggr_tbl); + + list_delete(&ospf->areas); list_delete(&ospf->oi_write_q); + /* Reset GR helper data structers */ + ospf_gr_helper_stop(ospf); + close(ospf->fd); stream_free(ospf->ibuf); ospf->fd = -1; @@ -1138,32 +1181,6 @@ void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp) update_redistributed(ospf, 0); /* interfaces possibly removed */ } -bool ospf_interface_area_is_already_set(struct ospf *ospf, - struct interface *ifp) -{ - struct route_node *rn_oi; - - if (!ospf) - return false; /* Ospf not ready yet */ - - /* Find interfaces that may need to be removed. */ - for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi; - rn_oi = route_next(rn_oi)) { - struct ospf_interface *oi = rn_oi->info; - - if (oi == NULL) - continue; - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - /* at least one route covered by interface - * that implies already done - */ - return true; - } - return false; -} - /* Check whether interface matches given network * returns: 1, true. 0, false */ @@ -1318,10 +1335,7 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi) } /* remove update event */ - if (oi->t_ls_upd_event) { - thread_cancel(oi->t_ls_upd_event); - oi->t_ls_upd_event = NULL; - } + thread_cancel(&oi->t_ls_upd_event); } void ospf_if_update(struct ospf *ospf, struct interface *ifp) @@ -1332,10 +1346,10 @@ void ospf_if_update(struct ospf *ospf, struct interface *ifp) if (IS_DEBUG_OSPF_EVENT) zlog_debug( - "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s", + "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %pI4", __func__, ifp->name, ifp->vrf_id, ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id, - inet_ntoa(ospf->router_id)); + &ospf->router_id); /* OSPF must be ready. */ if (!ospf_is_ready(ospf)) @@ -1372,16 +1386,16 @@ static void ospf_area_type_set(struct ospf_area *area, int type) if (area->external_routing == type) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Area[%s]: Types are the same, ignored.", - inet_ntoa(area->area_id)); + zlog_debug("Area[%pI4]: Types are the same, ignored.", + &area->area_id); return; } area->external_routing = type; if (IS_DEBUG_OSPF_EVENT) - zlog_debug("Area[%s]: Configured as %s", - inet_ntoa(area->area_id), + zlog_debug("Area[%pI4]: Configured as %s", + &area->area_id, lookup_msg(ospf_area_type_msg, type, NULL)); switch (area->external_routing) { @@ -2152,7 +2166,7 @@ static int ospf_vrf_disable(struct vrf *vrf) if (IS_DEBUG_OSPF_EVENT) zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__, old_vrf_id); - thread_cancel(ospf->t_read); + thread_cancel(&ospf->t_read); close(ospf->fd); ospf->fd = -1; } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 55bc64317e..bdd09e1e76 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -319,7 +319,57 @@ struct ospf { /* Redistributed external information. */ struct list *external[ZEBRA_ROUTE_MAX + 1]; -#define EXTERNAL_INFO(E) (E->external_info) +#define EXTERNAL_INFO(E) (E->external_info) + + /* Gracefull restart Helper supported configs*/ + /* Supported grace interval*/ + uint32_t supported_grace_time; + + /* Helper support + * Supported : True + * Not Supported : False. + */ + bool is_helper_supported; + + /* Support for strict LSA check. + * if it is set,Helper aborted + * upon a TOPO change. + */ + bool strict_lsa_check; + + /* Support as HELPER only for + * planned restarts. + */ + bool only_planned_restart; + + /* This list contains the advertisement + * routerids which are not support for HELPERs. + */ + struct hash *enable_rtr_list; + + /* HELPER for number of active + * RESTARTERs. + */ + uint16_t active_restarter_cnt; + + /* last HELPER exit reason */ + uint32_t last_exit_reason; + + /* delay timer to process external routes + * with summary address. + */ + struct thread *t_external_aggr; + + /* delay interval in seconds */ + unsigned int aggr_delay_interval; + + /* Table of configured Aggregate addresses */ + struct route_table *rt_aggr_tbl; + + /* used as argument for aggr delay + * timer thread. + */ + int aggr_action; /* MPLS LDP-IGP Sync */ struct ldp_sync_info_cmd ldp_sync_cmd; @@ -501,13 +551,7 @@ struct ospf_nbr_nbma { #define OSPF_AREA_TIMER_ON(T,F,V) thread_add_timer (master, (F), area, (V), &(T)) #define OSPF_POLL_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr_nbma, (V), &(T)) #define OSPF_POLL_TIMER_OFF(X) OSPF_TIMER_OFF((X)) -#define OSPF_TIMER_OFF(X) \ - do { \ - if (X) { \ - thread_cancel(X); \ - (X) = NULL; \ - } \ - } while (0) +#define OSPF_TIMER_OFF(X) thread_cancel(&(X)) /* Extern variables. */ extern struct ospf_master *om; @@ -580,8 +624,6 @@ extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *); extern void ospf_interface_area_set(struct ospf *, struct interface *); extern void ospf_interface_area_unset(struct ospf *, struct interface *); -extern bool ospf_interface_area_is_already_set(struct ospf *ospf, - struct interface *ifp); extern void ospf_route_map_init(void); diff --git a/ospfd/subdir.am b/ospfd/subdir.am index e586937478..1a807ea12b 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -57,6 +57,7 @@ ospfd_libfrrospf_a_SOURCES = \ ospfd/ospf_vty.c \ ospfd/ospf_zebra.c \ ospfd/ospfd.c \ + ospfd/ospf_gr_helper.c \ # end if OSPFD @@ -78,6 +79,7 @@ endif clippy_scan += \ ospfd/ospf_vty.c \ ospfd/ospf_ldp_sync.c \ + ospfd/ospf_dump.c \ # end noinst_HEADERS += \ @@ -102,6 +104,7 @@ noinst_HEADERS += \ ospfd/ospf_te.h \ ospfd/ospf_vty.h \ ospfd/ospf_zebra.h \ + ospfd/ospf_gr_helper.h \ # end ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la $(LIBCAP) $(LIBM) diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c index 9a9edd79c6..01c52f24e5 100644 --- a/pbrd/pbr_main.c +++ b/pbrd/pbr_main.c @@ -82,6 +82,8 @@ static void sigint(void) { zlog_notice("Terminating on signal"); + pbr_vrf_terminate(); + frr_fini(); exit(0); diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index 3fb3759049..ce7780ed49 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -827,16 +827,14 @@ static void pbr_nht_individual_nexthop_update_lookup(struct hash_bucket *b, { struct pbr_nexthop_cache *pnhc = b->data; struct pbr_nht_individual *pnhi = data; - char buf[PREFIX_STRLEN]; bool old_valid; old_valid = pnhc->valid; pbr_nht_individual_nexthop_update(pnhc, pnhi); - DEBUGD(&pbr_dbg_nht, "\tFound %s: old: %d new: %d", - prefix2str(&pnhi->nhr->prefix, buf, sizeof(buf)), old_valid, - pnhc->valid); + DEBUGD(&pbr_dbg_nht, "\tFound %pFX: old: %d new: %d", + &pnhi->nhr->prefix, old_valid, pnhc->valid); if (pnhc->valid) pnhi->valid = true; diff --git a/pbrd/pbr_vrf.c b/pbrd/pbr_vrf.c index 389e5e8be0..3284607406 100644 --- a/pbrd/pbr_vrf.c +++ b/pbrd/pbr_vrf.c @@ -26,6 +26,7 @@ #include "pbr_map.h" #include "pbr_debug.h" #include "pbr_nht.h" +#include "pbr_zebra.h" DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_VRF, "PBR Map VRF") @@ -137,3 +138,14 @@ void pbr_vrf_init(void) vrf_init(pbr_vrf_new, pbr_vrf_enable, pbr_vrf_disable, pbr_vrf_delete, NULL); } + +void pbr_vrf_terminate(void) +{ + struct vrf *vrf; + struct interface *ifp; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + FOR_ALL_INTERFACES (vrf, ifp) + pbr_if_del(ifp); + } +} diff --git a/pbrd/pbr_vrf.h b/pbrd/pbr_vrf.h index c9448762eb..5953387de2 100644 --- a/pbrd/pbr_vrf.h +++ b/pbrd/pbr_vrf.h @@ -40,4 +40,5 @@ extern bool pbr_vrf_is_valid(const struct pbr_vrf *pbr_vrf); extern bool pbr_vrf_is_enabled(const struct pbr_vrf *pbr_vrf); extern void pbr_vrf_init(void); +extern void pbr_vrf_terminate(void); #endif diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index 9f966f617f..26163dcc56 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -648,7 +648,6 @@ pbrms_nexthop_group_write_individual_nexthop( static void vty_show_pbrms(struct vty *vty, const struct pbr_map_sequence *pbrms, bool detail) { - char buf[PREFIX_STRLEN]; char rbuf[64]; if (pbrms->reason) @@ -666,11 +665,9 @@ static void vty_show_pbrms(struct vty *vty, pbrms->reason ? rbuf : "Valid"); if (pbrms->src) - vty_out(vty, " SRC Match: %s\n", - prefix2str(pbrms->src, buf, sizeof(buf))); + vty_out(vty, " SRC Match: %pFX\n", pbrms->src); if (pbrms->dst) - vty_out(vty, " DST Match: %s\n", - prefix2str(pbrms->dst, buf, sizeof(buf))); + vty_out(vty, " DST Match: %pFX\n", pbrms->dst); if (pbrms->dsfield & PBR_DSFIELD_DSCP) vty_out(vty, " DSCP Match: %u\n", (pbrms->dsfield & PBR_DSFIELD_DSCP) >> 2); @@ -910,16 +907,22 @@ DEFPY (show_pbr_interface, if (j) this_iface = json_object_new_object(); - if (!ifp->info) + if (!ifp->info) { + json_object_free(this_iface); continue; + } - if (name && strcmp(ifp->name, name) != 0) + if (name && strcmp(ifp->name, name) != 0) { + json_object_free(this_iface); continue; + } pbr_ifp = ifp->info; - if (strcmp(pbr_ifp->mapname, "") == 0) + if (strcmp(pbr_ifp->mapname, "") == 0) { + json_object_free(this_iface); continue; + } pbrm = pbrm_find(pbr_ifp->mapname); @@ -1058,17 +1061,13 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty, struct pbr_map *pbrm, struct pbr_map_sequence *pbrms) { - char buff[PREFIX_STRLEN]; - vty_out(vty, "pbr-map %s seq %u\n", pbrm->name, pbrms->seqno); if (pbrms->src) - vty_out(vty, " match src-ip %s\n", - prefix2str(pbrms->src, buff, sizeof(buff))); + vty_out(vty, " match src-ip %pFX\n", pbrms->src); if (pbrms->dst) - vty_out(vty, " match dst-ip %s\n", - prefix2str(pbrms->dst, buff, sizeof(buff))); + vty_out(vty, " match dst-ip %pFX\n", pbrms->dst); if (pbrms->dsfield & PBR_DSFIELD_DSCP) vty_out(vty, " match dscp %u\n", @@ -1145,9 +1144,9 @@ void pbr_vty_init(void) /* debug */ install_node(&debug_node); - install_element(VIEW_NODE, &debug_pbr_cmd); + install_element(ENABLE_NODE, &debug_pbr_cmd); install_element(CONFIG_NODE, &debug_pbr_cmd); - install_element(VIEW_NODE, &show_debugging_pbr_cmd); + install_element(ENABLE_NODE, &show_debugging_pbr_cmd); install_default(PBRMAP_NODE); diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index 866f27136e..32660b4dee 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -59,6 +59,11 @@ struct pbr_interface *pbr_if_new(struct interface *ifp) return pbr_ifp; } +void pbr_if_del(struct interface *ifp) +{ + XFREE(MTYPE_PBR_INTERFACE, ifp->info); +} + /* Inteface addition message from zebra. */ int pbr_ifp_create(struct interface *ifp) { @@ -102,15 +107,14 @@ static int interface_address_add(ZAPI_CALLBACK_ARGS) static int interface_address_delete(ZAPI_CALLBACK_ARGS) { struct connected *c; - char buf[PREFIX_STRLEN]; c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id); if (!c) return 0; - DEBUGD(&pbr_dbg_zebra, "%s: %s deleted %s", __func__, c->ifp->name, - prefix2str(c->address, buf, sizeof(buf))); + DEBUGD(&pbr_dbg_zebra, "%s: %s deleted %pFX", __func__, c->ifp->name, + c->address); connected_free(&c); return 0; @@ -162,40 +166,37 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS) struct prefix p; enum zapi_route_notify_owner note; uint32_t table_id; - char buf[PREFIX_STRLEN]; if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, ¬e)) return -1; - prefix2str(&p, buf, sizeof(buf)); - switch (note) { case ZAPI_ROUTE_FAIL_INSTALL: DEBUGD(&pbr_dbg_zebra, - "%s: [%s] Route install failure for table: %u", __func__, - buf, table_id); + "%s: [%pFX] Route install failure for table: %u", + __func__, &p, table_id); break; case ZAPI_ROUTE_BETTER_ADMIN_WON: DEBUGD(&pbr_dbg_zebra, - "%s: [%s] Route better admin distance won for table: %u", - __func__, buf, table_id); + "%s: [%pFX] Route better admin distance won for table: %u", + __func__, &p, table_id); break; case ZAPI_ROUTE_INSTALLED: DEBUGD(&pbr_dbg_zebra, - "%s: [%s] Route installed succeeded for table: %u", - __func__, buf, table_id); + "%s: [%pFX] Route installed succeeded for table: %u", + __func__, &p, table_id); pbr_nht_route_installed_for_table(table_id); break; case ZAPI_ROUTE_REMOVED: DEBUGD(&pbr_dbg_zebra, - "%s: [%s] Route Removed succeeded for table: %u", - __func__, buf, table_id); + "%s: [%pFX] Route Removed succeeded for table: %u", + __func__, &p, table_id); pbr_nht_route_removed_for_table(table_id); break; case ZAPI_ROUTE_REMOVE_FAIL: DEBUGD(&pbr_dbg_zebra, - "%s: [%s] Route remove fail for table: %u", __func__, - buf, table_id); + "%s: [%pFX] Route remove fail for table: %u", __func__, + &p, table_id); break; } @@ -259,14 +260,12 @@ static void route_add_helper(struct zapi_route *api, struct nexthop_group nhg, uint8_t install_afi) { struct zapi_nexthop *api_nh; - char buf[PREFIX_STRLEN]; struct nexthop *nhop; int i; api->prefix.family = install_afi; - DEBUGD(&pbr_dbg_zebra, "\tEncoding %s", - prefix2str(&api->prefix, buf, sizeof(buf))); + DEBUGD(&pbr_dbg_zebra, "\tEncoding %pFX", &api->prefix); i = 0; for (ALL_NEXTHOPS(nhg, nhop)) { @@ -397,7 +396,6 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi) static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS) { struct zapi_route nhr; - char buf[PREFIX2STR_BUFFER]; uint32_t i; if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) { @@ -407,18 +405,18 @@ static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS) if (DEBUG_MODE_CHECK(&pbr_dbg_zebra, DEBUG_MODE_ALL)) { - DEBUGD(&pbr_dbg_zebra, "%s: Received Nexthop update: %s", - __func__, prefix2str(&nhr.prefix, buf, sizeof(buf))); + DEBUGD(&pbr_dbg_zebra, "%s: Received Nexthop update: %pFX", + __func__, &nhr.prefix); DEBUGD(&pbr_dbg_zebra, "%s: (\tNexthops(%u)", __func__, nhr.nexthop_num); for (i = 0; i < nhr.nexthop_num; i++) { DEBUGD(&pbr_dbg_zebra, - "%s: \tType: %d: vrf: %d, ifindex: %d gate: %s", + "%s: \tType: %d: vrf: %d, ifindex: %d gate: %pI4", __func__, nhr.nexthops[i].type, nhr.nexthops[i].vrf_id, nhr.nexthops[i].ifindex, - inet_ntoa(nhr.nexthops[i].gate.ipv4)); + &nhr.nexthops[i].gate.ipv4); } } diff --git a/pbrd/pbr_zebra.h b/pbrd/pbr_zebra.h index e8f9bff5d9..d0f9ff910c 100644 --- a/pbrd/pbr_zebra.h +++ b/pbrd/pbr_zebra.h @@ -46,4 +46,7 @@ extern int pbr_ifp_up(struct interface *ifp); extern int pbr_ifp_down(struct interface *ifp); extern int pbr_ifp_destroy(struct interface *ifp); +/* Free the ifp->info pointer */ +extern void pbr_if_del(struct interface *ifp); + #endif diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c index 1b812de92c..3b69964960 100644 --- a/pimd/mtracebis.c +++ b/pimd/mtracebis.c @@ -26,7 +26,6 @@ #include "checksum.h" #include "prefix.h" #include "mtracebis_routeget.h" - #include <sys/select.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -64,13 +63,14 @@ static void version(void) static void print_host(struct in_addr addr) { struct hostent *h; + char buf[PREFIX_STRLEN]; h = gethostbyaddr(&addr, sizeof(addr), AF_INET); if (h == NULL) printf("?"); else printf("%s", h->h_name); - printf(" (%s) ", inet_ntoa(addr)); + printf(" (%s) ", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); } static void print_line_no(int i) diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index 146b53fa8f..1d653cdc3f 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -244,12 +244,9 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) return 0; } - if (PIM_DEBUG_PIM_TRACE) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&p, buf, sizeof(buf)); - zlog_debug("%s: interface %s bfd destination %s %s", __func__, - ifp->name, buf, bfd_get_status_str(status)); - } + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("%s: interface %s bfd destination %pFX %s", __func__, + ifp->name, &p, bfd_get_status_str(status)); for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node, neigh_nextnode, neigh)) { diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 1c9005588f..1acfece895 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -117,8 +117,7 @@ static int pim_g2rp_list_compare(struct bsm_rpinfo *node1, static void pim_free_bsrp_node(struct bsm_rpinfo *bsrp_info) { - if (bsrp_info->g2rp_timer) - THREAD_OFF(bsrp_info->g2rp_timer); + THREAD_OFF(bsrp_info->g2rp_timer); XFREE(MTYPE_PIM_BSRP_NODE, bsrp_info); } @@ -171,7 +170,6 @@ static int pim_on_bs_timer(struct thread *t) struct bsgrp_node *bsgrp_node; struct bsm_rpinfo *bsrp; struct prefix nht_p; - char buf[PREFIX2STR_BUFFER]; bool is_bsr_tracking = true; scope = THREAD_ARG(t); @@ -185,11 +183,9 @@ static int pim_on_bs_timer(struct thread *t) nht_p.family = AF_INET; nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = scope->current_bsr; - if (PIM_DEBUG_BSM) { - prefix2str(&nht_p, buf, sizeof(buf)); - zlog_debug("%s: Deregister BSR addr %s with Zebra NHT", - __func__, buf); - } + if (PIM_DEBUG_BSM) + zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT", + __func__, &nht_p); pim_delete_tracked_nexthop(scope->pim, &nht_p, NULL, NULL, is_bsr_tracking); @@ -378,15 +374,12 @@ static void pim_g2rp_timer_start(struct bsm_rpinfo *bsrp, int hold_time) return; } THREAD_OFF(bsrp->g2rp_timer); - if (PIM_DEBUG_BSM) { - char buf[48]; - + if (PIM_DEBUG_BSM) zlog_debug( - "%s : starting g2rp timer for grp: %s - rp: %s with timeout %d secs(Actual Hold time : %d secs)", - __func__, prefix2str(&bsrp->bsgrp_node->group, buf, 48), - inet_ntoa(bsrp->rp_address), hold_time, + "%s : starting g2rp timer for grp: %pFX - rp: %pI4 with timeout %d secs(Actual Hold time : %d secs)", + __func__, &bsrp->bsgrp_node->group, + &bsrp->rp_address, hold_time, bsrp->rp_holdtime); - } thread_add_timer(router->master, pim_on_g2rp_timer, bsrp, hold_time, &bsrp->g2rp_timer); @@ -403,14 +396,10 @@ static void pim_g2rp_timer_stop(struct bsm_rpinfo *bsrp) if (!bsrp) return; - if (PIM_DEBUG_BSM) { - char buf[48]; - - zlog_debug("%s : stopping g2rp timer for grp: %s - rp: %s", - __func__, - prefix2str(&bsrp->bsgrp_node->group, buf, 48), - inet_ntoa(bsrp->rp_address)); - } + if (PIM_DEBUG_BSM) + zlog_debug("%s : stopping g2rp timer for grp: %pFX - rp: %pI4", + __func__, &bsrp->bsgrp_node->group, + &bsrp->rp_address); THREAD_OFF(bsrp->g2rp_timer); } @@ -617,7 +606,6 @@ static void pim_bsm_update(struct pim_instance *pim, struct in_addr bsr, if (bsr.s_addr != pim->global_scope.current_bsr.s_addr) { struct prefix nht_p; - char buf[PREFIX2STR_BUFFER]; bool is_bsr_tracking = true; /* De-register old BSR and register new BSR with Zebra NHT */ @@ -626,23 +614,19 @@ static void pim_bsm_update(struct pim_instance *pim, struct in_addr bsr, if (pim->global_scope.current_bsr.s_addr != INADDR_ANY) { nht_p.u.prefix4 = pim->global_scope.current_bsr; - if (PIM_DEBUG_BSM) { - prefix2str(&nht_p, buf, sizeof(buf)); + if (PIM_DEBUG_BSM) zlog_debug( - "%s: Deregister BSR addr %s with Zebra NHT", - __func__, buf); - } + "%s: Deregister BSR addr %pFX with Zebra NHT", + __func__, &nht_p); pim_delete_tracked_nexthop(pim, &nht_p, NULL, NULL, is_bsr_tracking); } nht_p.u.prefix4 = bsr; - if (PIM_DEBUG_BSM) { - prefix2str(&nht_p, buf, sizeof(buf)); + if (PIM_DEBUG_BSM) zlog_debug( - "%s: NHT Register BSR addr %s with Zebra NHT", - __func__, buf); - } + "%s: NHT Register BSR addr %pFX with Zebra NHT", + __func__, &nht_p); memset(&pnc, 0, sizeof(struct pim_nexthop_cache)); pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL, diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index db3f0b8b23..2a7ff4e7f8 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -199,6 +199,7 @@ static void pim_show_assert_helper(struct vty *vty, struct in_addr ifaddr; char uptime[10]; char timer[10]; + char buf[PREFIX_STRLEN]; ifaddr = pim_ifp->primary_address; @@ -211,9 +212,10 @@ static void pim_show_assert_helper(struct vty *vty, pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer); vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n", - ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str, - pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str, - uptime, timer); + ch->interface->name, + inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), ch_src_str, + ch_grp_str, pim_ifchannel_ifassert_name(ch->ifassert_state), + winner_str, uptime, timer); } static void pim_show_assert(struct pim_instance *pim, struct vty *vty) @@ -246,13 +248,16 @@ static void pim_show_assert_internal_helper(struct vty *vty, char ch_src_str[INET_ADDRSTRLEN]; char ch_grp_str[INET_ADDRSTRLEN]; struct in_addr ifaddr; + char buf[PREFIX_STRLEN]; ifaddr = pim_ifp->primary_address; pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str)); pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str)); vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n", - ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str, + ch->interface->name, + inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), + ch_src_str, ch_grp_str, PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no", pim_macro_ch_could_assert_eval(ch) ? "yes" : "no", PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" @@ -294,6 +299,7 @@ static void pim_show_assert_metric_helper(struct vty *vty, char addr_str[INET_ADDRSTRLEN]; struct pim_assert_metric am; struct in_addr ifaddr; + char buf[PREFIX_STRLEN]; ifaddr = pim_ifp->primary_address; @@ -305,9 +311,10 @@ static void pim_show_assert_metric_helper(struct vty *vty, pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str)); vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n", - ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str, - am.rpt_bit_flag ? "yes" : "no", am.metric_preference, - am.route_metric, addr_str); + ch->interface->name, + inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), + ch_src_str, ch_grp_str, am.rpt_bit_flag ? "yes" : "no", + am.metric_preference, am.route_metric, addr_str); } static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty) @@ -341,6 +348,7 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty, struct in_addr ifaddr; char pref_str[16]; char metr_str[16]; + char buf[PREFIX_STRLEN]; ifaddr = pim_ifp->primary_address; @@ -362,8 +370,10 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty, snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric); vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n", - ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str, - am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str); + ch->interface->name, + inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), ch_src_str, + ch_grp_str, am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, + addr_str); } static void pim_show_assert_winner_metric(struct pim_instance *pim, @@ -391,12 +401,14 @@ static void json_object_pim_ifp_add(struct json_object *json, struct interface *ifp) { struct pim_interface *pim_ifp; + char buf[PREFIX_STRLEN]; pim_ifp = ifp->info; json_object_string_add(json, "name", ifp->name); json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down"); json_object_string_add(json, "address", - inet_ntoa(pim_ifp->primary_address)); + inet_ntop(AF_INET, &pim_ifp->primary_address, + buf, sizeof(buf))); json_object_int_add(json, "index", ifp->ifindex); if (if_is_multicast(ifp)) @@ -569,6 +581,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, { struct interface *ifp; time_t now; + char buf[PREFIX_STRLEN]; json_object *json = NULL; json_object *json_row = NULL; @@ -632,7 +645,8 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty, ? (igmp->mtrace_only ? "mtrc" : "up") : "down", - inet_ntoa(igmp->ifaddr), + inet_ntop(AF_INET, &igmp->ifaddr, + buf, sizeof(buf)), pim_ifp->igmp_version, igmp->t_igmp_query_timer ? "local" : "other", @@ -797,8 +811,8 @@ static void igmp_show_interfaces_single(struct pim_instance *pim, ? (igmp->mtrace_only ? "mtrace" : "up") : "down"); - vty_out(vty, "Address : %s\n", - inet_ntoa(pim_ifp->primary_address)); + vty_out(vty, "Address : %pI4\n", + &pim_ifp->primary_address); vty_out(vty, "Uptime : %s\n", uptime); vty_out(vty, "Version : %d\n", pim_ifp->igmp_version); @@ -940,6 +954,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim, int mloop = 0; int found_ifname = 0; int print_header; + char buf[PREFIX_STRLEN]; json_object *json = NULL; json_object *json_row = NULL; json_object *json_pim_neighbor = NULL; @@ -992,7 +1007,9 @@ static void pim_show_interfaces_single(struct pim_instance *pim, if (pim_ifp->update_source.s_addr != INADDR_ANY) { json_object_string_add( json_row, "useSource", - inet_ntoa(pim_ifp->update_source)); + inet_ntop(AF_INET, + &pim_ifp->update_source, + buf, sizeof(buf))); } if (pim_ifp->sec_addr_list) { json_object *sec_list = NULL; @@ -1160,23 +1177,20 @@ static void pim_show_interfaces_single(struct pim_instance *pim, vty_out(vty, "State : %s\n", if_is_up(ifp) ? "up" : "down"); if (pim_ifp->update_source.s_addr != INADDR_ANY) { - vty_out(vty, "Use Source : %s\n", - inet_ntoa(pim_ifp->update_source)); + vty_out(vty, "Use Source : %pI4\n", + &pim_ifp->update_source); } if (pim_ifp->sec_addr_list) { - char pbuf[PREFIX2STR_BUFFER]; - vty_out(vty, "Address : %s (primary)\n", - inet_ntoa(ifaddr)); + vty_out(vty, "Address : %pI4 (primary)\n", + &ifaddr); for (ALL_LIST_ELEMENTS_RO( pim_ifp->sec_addr_list, sec_node, - sec_addr)) { - vty_out(vty, " %s\n", - prefix2str(&sec_addr->addr, - pbuf, sizeof(pbuf))); - } + sec_addr)) + vty_out(vty, " %pFX\n", + &sec_addr->addr); } else { - vty_out(vty, "Address : %s\n", - inet_ntoa(ifaddr)); + vty_out(vty, "Address : %pI4\n", + &ifaddr); } vty_out(vty, "\n"); @@ -1400,6 +1414,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, int fhr = 0; int pim_nbrs = 0; int pim_ifchannels = 0; + char buf[PREFIX_STRLEN]; json_object *json = NULL; json_object *json_row = NULL; json_object *json_tmp; @@ -1430,7 +1445,9 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, json_object_int_add(json_row, "pimIfChannels", pim_ifchannels); json_object_int_add(json_row, "firstHopRouterCount", fhr); json_object_string_add(json_row, "pimDesignatedRouter", - inet_ntoa(pim_ifp->pim_dr_addr)); + inet_ntop(AF_INET, + &pim_ifp->pim_dr_addr, buf, + sizeof(buf))); if (pim_ifp->pim_dr_addr.s_addr == pim_ifp->primary_address.s_addr) @@ -1685,6 +1702,7 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, char uptime[10]; char expire[10]; char prune[10]; + char buf[PREFIX_STRLEN]; ifaddr = pim_ifp->primary_address; @@ -1733,8 +1751,9 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp, json_object_object_add(json_grp, ch_src_str, json_row); } else { vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n", - ch->interface->name, inet_ntoa(ifaddr), ch_src_str, - ch_grp_str, + ch->interface->name, + inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), + ch_src_str, ch_grp_str, pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags), uptime, expire, prune); } @@ -2307,6 +2326,7 @@ static void pim_show_neighbors_secondary(struct pim_instance *pim, struct in_addr ifaddr; struct listnode *neighnode; struct pim_neighbor *neigh; + char buf[PREFIX_STRLEN]; pim_ifp = ifp->info; @@ -2331,16 +2351,12 @@ static void pim_show_neighbors_secondary(struct pim_instance *pim, neigh_src_str, sizeof(neigh_src_str)); for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, - prefix_node, p)) { - char neigh_sec_str[PREFIX2STR_BUFFER]; - - prefix2str(p, neigh_sec_str, - sizeof(neigh_sec_str)); - - vty_out(vty, "%-16s %-15s %-15s %-15s\n", - ifp->name, inet_ntoa(ifaddr), - neigh_src_str, neigh_sec_str); - } + prefix_node, p)) + vty_out(vty, "%-16s %-15s %-15s %-15pFX\n", + ifp->name, + inet_ntop(AF_INET, &ifaddr, + buf, sizeof(buf)), + neigh_src_str, p); } } } @@ -2984,14 +3000,17 @@ static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg) struct nexthop *nh_node = NULL; ifindex_t first_ifindex; struct interface *ifp = NULL; + char buf[PREFIX_STRLEN]; for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) { first_ifindex = nh_node->ifindex; ifp = if_lookup_by_index(first_ifindex, pim->vrf_id); - vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4)); + vty_out(vty, "%-15s ", inet_ntop(AF_INET, + &pnc->rpf.rpf_addr.u.prefix4, + buf, sizeof(buf))); vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL"); - vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4)); + vty_out(vty, "%pI4 ", &nh_node->gate.ipv4); vty_out(vty, "\n"); } return CMD_SUCCESS; @@ -3215,7 +3234,7 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim, json_group); } } else { - vty_out(vty, "Group Address %s\n", grp_str); + vty_out(vty, "Group Address %pFX\n", &bsgrp->group); vty_out(vty, "--------------------------\n"); vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address", "priority", "Holdtime", "Hash"); @@ -5665,6 +5684,7 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty, bool uj) { struct interface *ifp; + char buf[PREFIX_STRLEN]; json_object *json = NULL; json_object *json_row = NULL; @@ -5705,7 +5725,8 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty, if_is_up(ifp) ? "up" : "down"); json_object_string_add( json_row, "address", - inet_ntoa(pim_ifp->primary_address)); + inet_ntop(AF_INET, &pim_ifp->primary_address, + buf, sizeof(buf))); json_object_int_add(json_row, "ifIndex", ifp->ifindex); json_object_int_add(json_row, "vif", pim_ifp->mroute_vif_index); @@ -5721,8 +5742,9 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty, } else { vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n", - ifp->name, inet_ntoa(ifaddr), ifp->ifindex, - pim_ifp->mroute_vif_index, + ifp->name, + inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), + ifp->ifindex, pim_ifp->mroute_vif_index, (unsigned long)vreq.icount, (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes, @@ -9694,7 +9716,7 @@ static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty, return ret; } -DEFUN_HIDDEN (ip_msdp_peer, +DEFUN (ip_msdp_peer, ip_msdp_peer_cmd, "ip msdp peer A.B.C.D source A.B.C.D", IP_STR @@ -9735,7 +9757,7 @@ static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty, return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; } -DEFUN_HIDDEN (no_ip_msdp_peer, +DEFUN (no_ip_msdp_peer, no_ip_msdp_peer_cmd, "no ip msdp peer A.B.C.D", NO_STR @@ -11236,7 +11258,6 @@ void pim_cmd_init(void) install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd); install_element(VIEW_NODE, &show_ip_rib_cmd); install_element(VIEW_NODE, &show_ip_ssmpingd_cmd); - install_element(VIEW_NODE, &show_debugging_pim_cmd); install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd); install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd); install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd); @@ -11252,6 +11273,8 @@ void pim_cmd_init(void) install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd); install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd); + install_element(ENABLE_NODE, &show_debugging_pim_cmd); + install_element(ENABLE_NODE, &debug_igmp_cmd); install_element(ENABLE_NODE, &no_debug_igmp_cmd); install_element(ENABLE_NODE, &debug_igmp_events_cmd); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 0caa360df9..cff237f965 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -518,15 +518,12 @@ void pim_if_addr_add(struct connected *ifc) if (!if_is_operative(ifp)) return; - if (PIM_DEBUG_ZEBRA) { - char buf[BUFSIZ]; - prefix2str(ifc->address, buf, BUFSIZ); - zlog_debug("%s: %s ifindex=%d connected IP address %s %s", - __func__, ifp->name, ifp->ifindex, buf, + if (PIM_DEBUG_ZEBRA) + zlog_debug("%s: %s ifindex=%d connected IP address %pFX %s", + __func__, ifp->name, ifp->ifindex, ifc->address, CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); - } ifaddr = ifc->address->u.prefix4; @@ -715,15 +712,12 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any) ifp = ifc->ifp; zassert(ifp); - if (PIM_DEBUG_ZEBRA) { - char buf[BUFSIZ]; - prefix2str(ifc->address, buf, BUFSIZ); - zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s", - __func__, ifp->name, ifp->ifindex, buf, + if (PIM_DEBUG_ZEBRA) + zlog_debug("%s: %s ifindex=%d disconnected IP address %pFX %s", + __func__, ifp->name, ifp->ifindex, ifc->address, CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); - } detect_address_change(ifp, force_prim_as_any, __func__); diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 212c77c039..b2971e5f1f 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -950,14 +950,44 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr, pim_ifchannel_ifjoin_handler(ch, pim_ifp); break; case PIM_IFJOIN_PRUNE_PENDING: + /* + * Transitions from Prune-Pending State (Receive Join) + * RFC 7761 Sec 4.5.2: + * The (S,G) downstream state machine on interface I + * transitions to the Join state. The Prune-Pending Timer is + * canceled (without triggering an expiry event). The + * Expiry Timer (ET) is restarted and is then set to the + * maximum of its current value and the HoldTime from the + * triggering Join/Prune message. + */ THREAD_OFF(ch->t_ifjoin_prune_pending_timer); - if (source_flags & PIM_ENCODE_RPT_BIT) { + + /* Check if SGRpt join Received */ + if ((source_flags & PIM_ENCODE_RPT_BIT) + && (sg->src.s_addr != INADDR_ANY)) { + /* + * Transitions from Prune-Pending State (Rcv SGRpt Join) + * RFC 7761 Sec 4.5.3: + * The (S,G,rpt) downstream state machine on interface + * I transitions to the NoInfo state.The ET and PPT are + * cancelled. + */ THREAD_OFF(ch->t_ifjoin_expiry_timer); pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO); - } else { - pim_ifchannel_ifjoin_handler(ch, pim_ifp); + return; } + + pim_ifchannel_ifjoin_handler(ch, pim_ifp); + + if (ch->t_ifjoin_expiry_timer) { + unsigned long remain = thread_timer_remain_second( + ch->t_ifjoin_expiry_timer); + + if (remain > holdtime) + return; + } + break; case PIM_IFJOIN_PRUNE_TMP: break; @@ -1034,7 +1064,14 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, /* nothing to do */ break; case PIM_IFJOIN_JOIN: - THREAD_OFF(ch->t_ifjoin_expiry_timer); + /* + * The (S,G) downstream state machine on interface I + * transitions to the Prune-Pending state. The + * Prune-Pending Timer is started. It is set to the + * J/P_Override_Interval(I) if the router has more than one + * neighbor on that interface; otherwise, it is set to zero, + * causing it to expire immediately. + */ pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_PRUNE_PENDING); diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 04ece6dbb0..19d7817577 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -63,8 +63,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, ++join; } else { zlog_warn( - "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s", - __FILE__, __func__, fd, inet_ntoa(ifaddr), + "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s", + __FILE__, __func__, fd, &ifaddr, PIM_ALL_ROUTERS, errno, safe_strerror(errno)); } } @@ -79,8 +79,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, ++join; } else { zlog_warn( - "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s", - __FILE__, __func__, fd, inet_ntoa(ifaddr), + "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s", + __FILE__, __func__, fd, &ifaddr, PIM_ALL_SYSTEMS, errno, safe_strerror(errno)); } @@ -90,16 +90,16 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, } } else { zlog_warn( - "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s", - __FILE__, __func__, fd, inet_ntoa(ifaddr), + "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s", + __FILE__, __func__, fd, &ifaddr, PIM_ALL_IGMP_ROUTERS, errno, safe_strerror(errno)); } if (!join) { flog_err_sys( EC_LIB_SOCKET, - "IGMP socket fd=%d could not join any group on interface address %s", - fd, inet_ntoa(ifaddr)); + "IGMP socket fd=%d could not join any group on interface address %pI4", + fd, &ifaddr); close(fd); fd = -1; } @@ -117,8 +117,8 @@ static void igmp_sock_dump(array_t *igmp_sock_array) struct igmp_sock *igmp = array_get(igmp_sock_array, i); - zlog_debug("%s %s: [%d/%d] igmp_addr=%s fd=%d", __FILE__, - __func__, i, size, inet_ntoa(igmp->ifaddr), + zlog_debug("%s %s: [%d/%d] igmp_addr=%pI4 fd=%d", __FILE__, + __func__, i, size, &igmp->ifaddr, igmp->fd); } } @@ -701,8 +701,8 @@ static void sock_close(struct igmp_sock *igmp) if (PIM_DEBUG_IGMP_TRACE_DETAIL) { if (igmp->t_igmp_read) { zlog_debug( - "Cancelling READ event on IGMP socket %s fd=%d on interface %s", - inet_ntoa(igmp->ifaddr), igmp->fd, + "Cancelling READ event on IGMP socket %pI4 fd=%d on interface %s", + &igmp->ifaddr, igmp->fd, igmp->interface->name); } } @@ -711,14 +711,14 @@ static void sock_close(struct igmp_sock *igmp) if (close(igmp->fd)) { flog_err( EC_LIB_SOCKET, - "Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s", - inet_ntoa(igmp->ifaddr), igmp->fd, + "Failure closing IGMP socket %pI4 fd=%d on interface %s: errno=%d: %s", + &igmp->ifaddr, igmp->fd, igmp->interface->name, errno, safe_strerror(errno)); } if (PIM_DEBUG_IGMP_TRACE_DETAIL) { - zlog_debug("Deleted IGMP socket %s fd=%d on interface %s", - inet_ntoa(igmp->ifaddr), igmp->fd, + zlog_debug("Deleted IGMP socket %pI4 fd=%d on interface %s", + &igmp->ifaddr, igmp->fd, igmp->interface->name); } } @@ -804,9 +804,7 @@ void igmp_group_delete(struct igmp_group *group) igmp_source_delete(src); } - if (group->t_group_query_retransmit_timer) { - THREAD_OFF(group->t_group_query_retransmit_timer); - } + THREAD_OFF(group->t_group_query_retransmit_timer); group_timer_off(group); igmp_group_count_decr(group->group_igmp_sock); @@ -902,8 +900,8 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, if (PIM_DEBUG_IGMP_TRACE) { zlog_debug( - "Creating IGMP socket fd=%d for address %s on interface %s", - fd, inet_ntoa(ifaddr), ifp->name); + "Creating IGMP socket fd=%d for address %pI4 on interface %s", + fd, &ifaddr, ifp->name); } igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp)); @@ -1002,8 +1000,8 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, fd = igmp_sock_open(ifaddr, ifp, pim_ifp->options); if (fd < 0) { - zlog_warn("Could not open IGMP socket for %s on %s", - inet_ntoa(ifaddr), ifp->name); + zlog_warn("Could not open IGMP socket for %pI4 on %s", + &ifaddr, ifp->name); return NULL; } @@ -1011,8 +1009,8 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list, sin.sin_addr = ifaddr; sin.sin_port = 0; if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) != 0) { - zlog_warn("Could not bind IGMP socket for %s on %s", - inet_ntoa(ifaddr), ifp->name); + zlog_warn("Could not bind IGMP socket for %pI4 on %s", + &ifaddr, ifp->name); close(fd); return NULL; @@ -1155,8 +1153,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, if (pim_is_group_224_0_0_0_24(group_addr)) { if (PIM_DEBUG_IGMP_TRACE) zlog_debug( - "%s: Group specified %s is part of 224.0.0.0/24", - __func__, inet_ntoa(group_addr)); + "%s: Group specified %pI4 is part of 224.0.0.0/24", + __func__, &group_addr); return NULL; } /* diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c index 9e78b76008..941d067619 100644 --- a/pimd/pim_igmp_mtrace.c +++ b/pimd/pim_igmp_mtrace.c @@ -82,10 +82,10 @@ static bool mtrace_fwd_info_weak(struct pim_instance *pim, zlog_debug("mtrace pim_nexthop_lookup OK"); if (PIM_DEBUG_MTRACE) - zlog_warn("mtrace next_hop=%s", - inet_ntop(nexthop.mrib_nexthop_addr.family, - &nexthop.mrib_nexthop_addr.u.prefix, - nexthop_str, sizeof(nexthop_str))); + zlog_debug("mtrace next_hop=%s", + inet_ntop(nexthop.mrib_nexthop_addr.family, + &nexthop.mrib_nexthop_addr.u.prefix, + nexthop_str, sizeof(nexthop_str))); if (nexthop.mrib_nexthop_addr.family == AF_INET) nh_addr = nexthop.mrib_nexthop_addr.u.prefix4; @@ -270,8 +270,8 @@ static uint32_t query_arrival_time(void) if (gettimeofday(&tv, NULL) < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn("Query arrival time lookup failed: errno=%d: %s", - errno, safe_strerror(errno)); + zlog_debug("Query arrival time lookup failed: errno=%d: %s", + errno, safe_strerror(errno)); return 0; } /* not sure second offset correct, as I get different value */ @@ -336,7 +336,7 @@ static int mtrace_send_packet(struct interface *ifp, if (ret < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn("Failed to set socket multicast TTL"); + zlog_debug("Failed to set socket multicast TTL"); ret = -1; goto close_fd; } @@ -354,14 +354,14 @@ static int mtrace_send_packet(struct interface *ifp, sizeof(group_str)); if (sent < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Send mtrace request failed for %s on%s: group=%s msg_size=%zd: errno=%d: %s", dst_str, ifp->name, group_str, mtrace_buf_len, errno, safe_strerror(errno)); } else { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Send mtrace request failed for %s on %s: group=%s msg_size=%zd: sent=%zd", dst_str, ifp->name, group_str, mtrace_buf_len, sent); @@ -411,7 +411,7 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr, if (!pim_nexthop_lookup(pim, &nexthop, ip_hdr->ip_dst, 0)) { close(fd); if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Dropping mtrace packet, no route to destination"); return -1; } @@ -440,15 +440,15 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr, if (sent < 0) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Failed to forward mtrace packet: sendto errno=%d, %s", errno, safe_strerror(errno)); return -1; } if (PIM_DEBUG_MTRACE) { - zlog_debug("Fwd mtrace packet len=%u to %s ttl=%u", - ntohs(ip_hdr->ip_len), inet_ntoa(ip_hdr->ip_dst), + zlog_debug("Fwd mtrace packet len=%u to %pI4 ttl=%u", + ntohs(ip_hdr->ip_len), &ip_hdr->ip_dst, ip_hdr->ip_ttl); } @@ -472,9 +472,9 @@ static int mtrace_mc_forward_packet(struct pim_instance *pim, struct ip *ip_hdr) if (c_oil == NULL) { if (PIM_DEBUG_MTRACE) { zlog_debug( - "Dropping mtrace multicast packet len=%u to %s ttl=%u", + "Dropping mtrace multicast packet len=%u to %pI4 ttl=%u", ntohs(ip_hdr->ip_len), - inet_ntoa(ip_hdr->ip_dst), ip_hdr->ip_ttl); + &ip_hdr->ip_dst, ip_hdr->ip_ttl); } return -1; } @@ -514,6 +514,7 @@ static int mtrace_send_mc_response(struct pim_instance *pim, struct listnode *chnextnode; struct pim_ifchannel *ch = NULL; int ret = -1; + char buf[PREFIX_STRLEN]; memset(&sg, 0, sizeof(struct prefix_sg)); sg.grp = mtracep->rsp_addr; @@ -525,7 +526,8 @@ static int mtrace_send_mc_response(struct pim_instance *pim, zlog_debug( "Dropping mtrace multicast response packet len=%u to %s", (unsigned int)mtrace_len, - inet_ntoa(mtracep->rsp_addr)); + inet_ntop(AF_INET, &mtracep->rsp_addr, + buf, sizeof(buf))); } return -1; } @@ -570,10 +572,10 @@ static int mtrace_send_response(struct pim_instance *pim, if (p_rpf == NULL) { if (PIM_DEBUG_MTRACE) - zlog_warn("mtrace no RP for %s", - inet_ntop(AF_INET, - &(mtracep->rsp_addr), - grp_str, sizeof(grp_str))); + zlog_debug("mtrace no RP for %s", + inet_ntop(AF_INET, + &(mtracep->rsp_addr), + grp_str, sizeof(grp_str))); return -1; } nexthop = p_rpf->source_nexthop; @@ -584,7 +586,7 @@ static int mtrace_send_response(struct pim_instance *pim, /* TODO: should use unicast rib lookup */ if (!pim_nexthop_lookup(pim, &nexthop, mtracep->rsp_addr, 1)) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Dropped response qid=%ud, no route to response address", mtracep->qry_id); return -1; @@ -633,7 +635,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: too short, len=%d, min=%zu", from_str, ifp->name, igmp_msg_len, sizeof(struct igmp_mtrace)); @@ -650,7 +652,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, if (recv_checksum != checksum) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: checksum mismatch: received=%x computed=%x", from_str, ifp->name, recv_checksum, checksum); return -1; @@ -700,12 +702,12 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, last_rsp_ind = r_len / sizeof(struct igmp_mtrace_rsp); if (last_rsp_ind > MTRACE_MAX_HOPS) { if (PIM_DEBUG_MTRACE) - zlog_warn("Mtrace request of excessive size"); + zlog_debug("Mtrace request of excessive size"); return -1; } } else { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: invalid length %d", from_str, ifp->name, igmp_msg_len); return -1; @@ -715,9 +717,9 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr, if (IPV4_CLASS_DE(ntohl(ip_hdr->ip_dst.s_addr)) && !IPV4_MC_LINKLOCAL(ntohl(ip_hdr->ip_dst.s_addr))) { if (PIM_DEBUG_MTRACE) - zlog_warn( - "Recv mtrace packet from %s on %s: not link-local multicast %s", - from_str, ifp->name, inet_ntoa(ip_hdr->ip_dst)); + zlog_debug( + "Recv mtrace packet from %s on %s: not link-local multicast %pI4", + from_str, ifp->name, &ip_hdr->ip_dst); return -1; } @@ -848,7 +850,7 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr, if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace packet from %s on %s: too short, len=%d, min=%zu", from_str, ifp->name, igmp_msg_len, sizeof(struct igmp_mtrace)); @@ -865,7 +867,7 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr, if (recv_checksum != checksum) { if (PIM_DEBUG_MTRACE) - zlog_warn( + zlog_debug( "Recv mtrace response from %s on %s: checksum mismatch: received=%x computed=%x", from_str, ifp->name, recv_checksum, checksum); return -1; diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 8eaca75821..22767a8629 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -1921,10 +1921,10 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from, if (PIM_DEBUG_IGMP_PACKETS) { zlog_debug( - " Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%s", + " Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%pI4", from_str, ifp->name, i, rec_type, rec_auxdatalen, rec_num_sources, - inet_ntoa(rec_group)); + &rec_group); } /* Scan sources */ @@ -1949,9 +1949,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from, "<source?>"); zlog_debug( - " Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s", + " Recv IGMP report v3 from %s on %s: record=%d group=%pI4 source=%s", from_str, ifp->name, i, - inet_ntoa(rec_group), src_str); + &rec_group, src_str); } } /* for (sources) */ @@ -1969,8 +1969,8 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from, if (PIM_DEBUG_IGMP_PACKETS && filtered) zlog_debug( - "Filtering IGMPv3 group record %s from %s on %s per prefix-list %s", - inet_ntoa(rec_group), from_str, ifp->name, + "Filtering IGMPv3 group record %pI4 from %s on %s per prefix-list %s", + &rec_group, from_str, ifp->name, pim_ifp->boundary_oil_plist); /* diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 3a88de2070..f54d5bf9bf 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -173,6 +173,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, uint8_t *pastend; int remain; int group; + struct pim_ifchannel *child = NULL; + struct listnode *ch_node, *nch_node; buf = tlv_buf; pastend = tlv_buf + tlv_buf_size; @@ -337,9 +339,24 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, */ sg_ch = pim_ifchannel_find(ifp, &sg); + if (!sg_ch) + continue; + + /* (*,G) prune received */ + for (ALL_LIST_ELEMENTS(sg_ch->sources, ch_node, + nch_node, child)) { + if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) { + if (child->ifjoin_state + == PIM_IFJOIN_PRUNE_PENDING_TMP) + THREAD_OFF( + child->t_ifjoin_prune_pending_timer); + PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); + child->ifjoin_state = PIM_IFJOIN_NOINFO; + } + } + /* Received SG-RPT Prune delete oif from specific S,G */ - if (starg_ch && sg_ch - && (msg_source_flags & PIM_RPT_BIT_MASK) + if (starg_ch && (msg_source_flags & PIM_RPT_BIT_MASK) && !(msg_source_flags & PIM_WILDCARD_BIT_MASK)) { struct pim_upstream *up = sg_ch->upstream; PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags); diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c index 2dfc0af1de..a06c0a6f4e 100644 --- a/pimd/pim_mlag.c +++ b/pimd/pim_mlag.c @@ -96,7 +96,7 @@ static void pim_mlag_inherit_mlag_flags(struct pim_upstream *up, bool is_df) struct channel_oil *ch_oil = NULL; if (PIM_DEBUG_MLAG) - zlog_debug("%s: Updating DF for uptream:%s childs", __func__, + zlog_debug("%s: Updating DF for uptream:%s children", __func__, up->sg_str); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index b42092a464..7336cdfef8 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -423,6 +423,7 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, sa->sg_str); } /* send an immediate SA update to peers */ + sa->rp = pim->msdp.originator_id; pim_msdp_pkt_sa_tx_one(sa); } sa->flags &= ~PIM_MSDP_SAF_STALE; @@ -721,10 +722,18 @@ static int pim_msdp_sa_comp(const void *p1, const void *p2) /* XXX: this can use a bit of refining and extensions */ bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp) { + struct pim_nexthop nexthop; + if (mp->peer.s_addr == rp.s_addr) { return true; } + /* check if the MSDP peer is the nexthop for the RP */ + if (pim_nexthop_lookup(mp->pim, &nexthop, rp, 0) + && nexthop.mrib_nexthop_addr.u.prefix4.s_addr == mp->peer.s_addr) { + return true; + } + return false; } diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index 6caa3181e7..15a1041e21 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -208,8 +208,8 @@ struct pim_msdp { thread_add_write(mp->pim->msdp.master, pim_msdp_write, mp, mp->fd, \ &mp->t_write) -#define PIM_MSDP_PEER_READ_OFF(mp) THREAD_READ_OFF(mp->t_read) -#define PIM_MSDP_PEER_WRITE_OFF(mp) THREAD_WRITE_OFF(mp->t_write) +#define PIM_MSDP_PEER_READ_OFF(mp) thread_cancel(&mp->t_read) +#define PIM_MSDP_PEER_WRITE_OFF(mp) thread_cancel(&mp->t_write) // struct pim_msdp *msdp; struct pim_instance; diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 39e39b9557..4aaf0f53d1 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -348,7 +348,8 @@ static void pim_msdp_pkt_sa_push(struct pim_instance *pim, } } -static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt) +static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt, + struct in_addr rp) { int curr_tlv_ecnt; @@ -361,7 +362,7 @@ static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt) stream_putw(pim->msdp.work_obuf, PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt)); stream_putc(pim->msdp.work_obuf, curr_tlv_ecnt); - stream_put_ipv4(pim->msdp.work_obuf, pim->msdp.originator_id.s_addr); + stream_put_ipv4(pim->msdp.work_obuf, rp.s_addr); return local_cnt; } @@ -387,7 +388,8 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, zlog_debug(" sa gen %d", local_cnt); } - local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt); + local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt, + pim->msdp.originator_id); for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) { if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) { @@ -408,7 +410,8 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, zlog_debug(" sa gen for remainder %d", local_cnt); } - local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt); + local_cnt = pim_msdp_pkt_sa_fill_hdr( + pim, local_cnt, pim->msdp.originator_id); } } @@ -441,7 +444,7 @@ void pim_msdp_pkt_sa_tx(struct pim_instance *pim) void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa) { - pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */); + pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */, sa->rp); pim_msdp_pkt_sa_fill_one(sa); pim_msdp_pkt_sa_push(sa->pim, NULL); pim_msdp_pkt_sa_tx_done(sa->pim); @@ -454,6 +457,24 @@ void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp) pim_msdp_pkt_sa_tx_done(mp->pim); } +void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, + struct in_addr rp, struct prefix_sg sg) +{ + struct pim_msdp_sa sa; + + /* Fills the SA header. */ + pim_msdp_pkt_sa_fill_hdr(mp->pim, 1, rp); + + /* Fills the message contents. */ + sa.pim = mp->pim; + sa.sg = sg; + pim_msdp_pkt_sa_fill_one(&sa); + + /* Pushes the message. */ + pim_msdp_pkt_sa_push(sa.pim, mp); + pim_msdp_pkt_sa_tx_done(sa.pim); +} + static void pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp) { pim_msdp_peer_reset_tcp_conn(mp, "invalid-pkt-rx"); @@ -473,6 +494,8 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) { int prefix_len; struct prefix_sg sg; + struct listnode *peer_node; + struct pim_msdp_peer *peer; /* just throw away the three reserved bytes */ stream_get3(mp->ibuf); @@ -493,6 +516,18 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) zlog_debug(" sg %s", pim_str_sg_dump(&sg)); } pim_msdp_sa_ref(mp->pim, mp, &sg, rp); + + /* Forwards the SA to the peers that are not in the RPF to the RP nor in + * the same mesh group as the peer from which we received the message. + * If the message group is not set, i.e. "default", then we assume that + * the message must be forwarded.*/ + for (ALL_LIST_ELEMENTS_RO(mp->pim->msdp.peer_list, peer_node, peer)) { + if (!pim_msdp_peer_rpf_check(peer, rp) + && (strcmp(mp->mesh_group_name, peer->mesh_group_name) + || !strcmp(mp->mesh_group_name, "default"))) { + pim_msdp_pkt_sa_tx_one_to_one_peer(peer, rp, sg); + } + } } static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) @@ -510,10 +545,9 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) entry_cnt = stream_getc(mp->ibuf); /* some vendors include the actual multicast data in the tlv (at the - * end). - * we will ignore such data. in the future we may consider pushing it - * down - * the RPT */ + * end). we will ignore such data. in the future we may consider pushing + * it down the RPT + */ if (len < PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt)) { pim_msdp_pkt_rxed_with_fatal_error(mp); return; @@ -526,6 +560,8 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str); } + pim_msdp_peer_pkt_rxed(mp); + if (!pim_msdp_peer_rpf_check(mp, rp)) { /* if peer-RPF check fails don't process the packet any further */ @@ -535,8 +571,6 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len) return; } - pim_msdp_peer_pkt_rxed(mp); - /* update SA cache */ for (i = 0; i < entry_cnt; ++i) { pim_msdp_pkt_sa_rx_one(mp, rp); diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h index d922fa50df..f5af8d1140 100644 --- a/pimd/pim_msdp_packet.h +++ b/pimd/pim_msdp_packet.h @@ -67,5 +67,7 @@ int pim_msdp_read(struct thread *thread); void pim_msdp_pkt_sa_tx(struct pim_instance *pim); void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa); void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp); +void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, + struct in_addr rp, struct prefix_sg sg); #endif diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 4d6625bf6f..167aa3c604 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -294,7 +294,7 @@ static int on_neighbor_jp_timer(struct thread *t) static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh) { - THREAD_TIMER_OFF(neigh->jp_timer); + THREAD_OFF(neigh->jp_timer); thread_add_timer(router->master, on_neighbor_jp_timer, neigh, router->t_periodic, &neigh->jp_timer); } diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index f06d4ae605..f691e8b755 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -26,6 +26,8 @@ #include "hash.h" #include "jhash.h" +#include "lib/printfrr.h" + #include "pimd.h" #include "pimd/pim_nht.h" #include "log.h" @@ -56,15 +58,12 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient, if (ret < 0) zlog_warn("sendmsg_nexthop: zclient_send_message() failed"); - if (PIM_DEBUG_PIM_NHT) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(p, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: NHT %sregistered addr %s(%s) with Zebra ret:%d ", + "%s: NHT %sregistered addr %pFX(%s) with Zebra ret:%d ", __func__, - (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", buf, + (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", p, pim->vrf->name, ret); - } return; } @@ -89,7 +88,6 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim, { struct pim_nexthop_cache *pnc; char hash_name[64]; - char buf1[64]; pnc = XCALLOC(MTYPE_PIM_NEXTHOP_CACHE, sizeof(struct pim_nexthop_cache)); @@ -103,8 +101,8 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim, pnc->rp_list = list_new(); pnc->rp_list->cmp = pim_rp_list_cmp; - snprintf(hash_name, sizeof(hash_name), "PNC %s(%s) Upstream Hash", - prefix2str(&pnc->rpf.rpf_addr, buf1, 64), pim->vrf->name); + snprintfrr(hash_name, sizeof(hash_name), "PNC %pFX(%s) Upstream Hash", + &pnc->rpf.rpf_addr, pim->vrf->name); pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key, pim_upstream_equal, hash_name); @@ -140,13 +138,10 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr, pnc = pim_nexthop_cache_add(pim, &rpf); pim_sendmsg_zebra_rnh(pim, zclient, pnc, ZEBRA_NEXTHOP_REGISTER); - if (PIM_DEBUG_PIM_NHT) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(addr, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: NHT cache and zebra notification added for %s(%s)", - __func__, buf, pim->vrf->name); - } + "%s: NHT cache and zebra notification added for %pFX(%s)", + __func__, addr, pim->vrf->name); } if (rp != NULL) { @@ -215,14 +210,11 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr, if (del_bsr_tracking) pnc->bsr_tracking = false; - if (PIM_DEBUG_PIM_NHT) { - char buf[PREFIX_STRLEN]; - prefix2str(addr, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: NHT %s(%s) rp_list count:%d upstream count:%ld", - __func__, buf, pim->vrf->name, + "%s: NHT %pFX(%s) rp_list count:%d upstream count:%ld", + __func__, addr, pim->vrf->name, pnc->rp_list->count, pnc->upstream_hash->count); - } if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0 @@ -744,13 +736,10 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) prefix_copy(&rpf.rpf_addr, &nhr.prefix); pnc = pim_nexthop_cache_find(pim, &rpf); if (!pnc) { - if (PIM_DEBUG_PIM_NHT) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&rpf.rpf_addr, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: Skipping NHT update, addr %s is not in local cached DB.", - __func__, buf); - } + "%s: Skipping NHT update, addr %pFX is not in local cached DB.", + __func__, &rpf.rpf_addr); return 0; } } else { @@ -819,17 +808,13 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) continue; } - if (PIM_DEBUG_PIM_NHT) { - char p_str[PREFIX2STR_BUFFER]; - - prefix2str(&nhr.prefix, p_str, sizeof(p_str)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: NHT addr %s(%s) %d-nhop via %s(%s) type %d distance:%u metric:%u ", - __func__, p_str, pim->vrf->name, i + 1, - inet_ntoa(nexthop->gate.ipv4), + "%s: NHT addr %pFX(%s) %d-nhop via %pI4(%s) type %d distance:%u metric:%u ", + __func__, &nhr.prefix, pim->vrf->name, + i + 1, &nexthop->gate.ipv4, ifp->name, nexthop->type, nhr.distance, nhr.metric); - } if (!ifp->info) { /* @@ -879,15 +864,12 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) } SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED); - if (PIM_DEBUG_PIM_NHT) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&nhr.prefix, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: NHT Update for %s(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d", - __func__, buf, pim->vrf->name, nhr.nexthop_num, + "%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d", + __func__, &nhr.prefix, pim->vrf->name, nhr.nexthop_num, pnc->nexthop_num, vrf_id, pnc->upstream_hash->count, listcount(pnc->rp_list)); - } pim_rpf_set_refresh_time(pim); diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 19e15f3ede..90b69a54f2 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -75,8 +75,8 @@ void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg, struct prefix p; if (PIM_DEBUG_PIM_REG) { - zlog_debug("Sending Register stop for %s to %s on %s", - pim_str_sg_dump(sg), inet_ntoa(originator), + zlog_debug("Sending Register stop for %s to %pI4 on %s", + pim_str_sg_dump(sg), &originator, ifp->name); } @@ -170,9 +170,9 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src, struct interface *ifp; if (PIM_DEBUG_PIM_REG) { - zlog_debug("Sending %s %sRegister Packet to %s", up->sg_str, + zlog_debug("Sending %s %sRegister Packet to %pI4", up->sg_str, null_register ? "NULL " : "", - inet_ntoa(rpg->rpf_addr.u.prefix4)); + &rpg->rpf_addr.u.prefix4); } ifp = rpg->source_nexthop.interface; @@ -192,12 +192,9 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src, } if (PIM_DEBUG_PIM_REG) { - char rp_str[INET_ADDRSTRLEN]; - strlcpy(rp_str, inet_ntoa(rpg->rpf_addr.u.prefix4), - sizeof(rp_str)); - zlog_debug("%s: Sending %s %sRegister Packet to %s on %s", + zlog_debug("%s: Sending %s %sRegister Packet to %pI4 on %s", __func__, up->sg_str, null_register ? "NULL " : "", - rp_str, ifp->name); + &rpg->rpf_addr.u.prefix4, ifp->name); } memset(buffer, 0, 10000); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 93fe787a93..7246482f02 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -134,7 +134,7 @@ void pim_rp_init(struct pim_instance *pim) if (PIM_DEBUG_PIM_TRACE) zlog_debug( "Allocated: %p for rp_info: %p(224.0.0.0/4) Lock: %d", - rn, rp_info, rn->lock); + rn, rp_info, route_node_get_lock_count(rn)); } void pim_rp_free(struct pim_instance *pim) @@ -248,14 +248,10 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, } rp_info = rn->info; - if (PIM_DEBUG_PIM_TRACE) { - char buf[PREFIX_STRLEN]; - - zlog_debug("Lookedup: %p for rp_info: %p(%s) Lock: %d", rn, - rp_info, - prefix2str(&rp_info->group, buf, sizeof(buf)), - rn->lock); - } + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("Lookedup: %p for rp_info: %p(%pFX) Lock: %d", rn, + rp_info, &rp_info->group, + route_node_get_lock_count(rn)); route_unlock_node(rn); @@ -354,8 +350,8 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up) up->sg.grp); if (PIM_DEBUG_PIM_TRACE) - zlog_debug("%s: pim upstream update for old upstream %s", - __func__, inet_ntoa(old_upstream_addr)); + zlog_debug("%s: pim upstream update for old upstream %pI4", + __func__, &old_upstream_addr); if (old_upstream_addr.s_addr == new_upstream_addr.s_addr) return; @@ -370,14 +366,10 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up) nht_p.family = AF_INET; nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = old_upstream_addr; - if (PIM_DEBUG_PIM_TRACE) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&nht_p, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_TRACE) zlog_debug( - "%s: Deregister upstream %s addr %s with Zebra NHT", - __func__, up->sg_str, buf); - } + "%s: Deregister upstream %s addr %pFX with Zebra NHT", + __func__, up->sg_str, &nht_p); pim_delete_tracked_nexthop(pim, &nht_p, up, NULL, false); } @@ -547,15 +539,10 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = rp_all->rp.rpf_addr.u.prefix4; // RP address - if (PIM_DEBUG_PIM_NHT_RP) { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str(&nht_p, buf, sizeof(buf)); - prefix2str(&rp_all->group, buf1, sizeof(buf1)); + if (PIM_DEBUG_PIM_NHT_RP) zlog_debug( - "%s: NHT Register rp_all addr %s grp %s ", - __func__, buf, buf1); - } + "%s: NHT Register rp_all addr %pFX grp %pFX ", + __func__, &nht_p, &rp_all->group); frr_each (rb_pim_upstream, &pim->upstream_head, up) { /* Find (*, G) upstream whose RP is not @@ -643,14 +630,10 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, rn = route_node_get(pim->rp_table, &rp_info->group); rn->info = rp_info; - if (PIM_DEBUG_PIM_TRACE) { - char buf[PREFIX_STRLEN]; - - zlog_debug("Allocated: %p for rp_info: %p(%s) Lock: %d", rn, - rp_info, - prefix2str(&rp_info->group, buf, sizeof(buf)), - rn->lock); - } + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("Allocated: %p for rp_info: %p(%pFX) Lock: %d", rn, + rp_info, &rp_info->group, + route_node_get_lock_count(rn)); frr_each (rb_pim_upstream, &pim->upstream_head, up) { if (up->sg.src.s_addr == INADDR_ANY) { @@ -674,14 +657,9 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr, nht_p.family = AF_INET; nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_NHT_RP) { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str(&nht_p, buf, sizeof(buf)); - prefix2str(&rp_info->group, buf1, sizeof(buf1)); - zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ", - __func__, buf, buf1); - } + if (PIM_DEBUG_PIM_NHT_RP) + zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ", + __func__, &nht_p, &rp_info->group); pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL); if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p, &rp_info->group, 1)) @@ -727,12 +705,10 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, struct pim_upstream *up; struct bsgrp_node *bsgrp = NULL; struct bsm_rpinfo *bsrp = NULL; - char grp_str[PREFIX2STR_BUFFER]; char rp_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str))) snprintf(rp_str, sizeof(rp_str), "<rp?>"); - prefix2str(&group, grp_str, sizeof(grp_str)); if (plist) rp_info = pim_rp_find_prefix_list(pim, rp_addr, plist); @@ -748,8 +724,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, } if (PIM_DEBUG_PIM_TRACE) - zlog_debug("%s: Delete RP %s for the group %s", __func__, - rp_str, grp_str); + zlog_debug("%s: Delete RP %s for the group %pFX", __func__, + rp_str, &group); /* While static RP is getting deleted, we need to check if dynamic RP * present for the same group in BSM RP table, then install the dynamic @@ -771,8 +747,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, "<bsrp?>"); zlog_debug( - "%s: BSM RP %s found for the group %s", - __func__, bsrp_str, grp_str); + "%s: BSM RP %s found for the group %pFX", + __func__, bsrp_str, &group); } return pim_rp_change(pim, bsrp->rp_address, group, RP_SRC_BSR); @@ -780,8 +756,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, } else { if (PIM_DEBUG_PIM_TRACE) zlog_debug( - "%s: BSM RP not found for the group %s", - __func__, grp_str); + "%s: BSM RP not found for the group %pFX", + __func__, &group); } } @@ -789,12 +765,9 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, nht_p.family = AF_INET; nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_NHT_RP) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&nht_p, buf, sizeof(buf)); - zlog_debug("%s: Deregister RP addr %s with Zebra ", __func__, - buf); - } + if (PIM_DEBUG_PIM_NHT_RP) + zlog_debug("%s: Deregister RP addr %pFX with Zebra ", __func__, + &nht_p); pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false); if (!str2prefix("224.0.0.0/4", &g_all)) @@ -837,16 +810,12 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, EC_LIB_DEVELOPMENT, "Expected rn->info to be equal to rp_info"); - if (PIM_DEBUG_PIM_TRACE) { - char buf[PREFIX_STRLEN]; - + if (PIM_DEBUG_PIM_TRACE) zlog_debug( - "%s:Found for Freeing: %p for rp_info: %p(%s) Lock: %d", - __func__, rn, rp_info, - prefix2str(&rp_info->group, buf, - sizeof(buf)), - rn->lock); - } + "%s:Found for Freeing: %p for rp_info: %p(%pFX) Lock: %d", + __func__, rn, rp_info, &rp_info->group, + route_node_get_lock_count(rn)); + rn->info = NULL; route_unlock_node(rn); route_unlock_node(rn); @@ -925,13 +894,9 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr, /* Deregister old RP addr with Zebra NHT */ if (rp_info->rp.rpf_addr.u.prefix4.s_addr != INADDR_ANY) { nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_NHT_RP) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(&nht_p, buf, sizeof(buf)); - zlog_debug("%s: Deregister RP addr %s with Zebra ", - __func__, buf); - } + if (PIM_DEBUG_PIM_NHT_RP) + zlog_debug("%s: Deregister RP addr %pFX with Zebra ", + __func__, &nht_p); pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false); } @@ -961,15 +926,9 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr, /* Register new RP addr with Zebra NHT */ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_NHT_RP) { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - - prefix2str(&nht_p, buf, sizeof(buf)); - prefix2str(&rp_info->group, buf1, sizeof(buf1)); - zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ", - __func__, buf, buf1); - } + if (PIM_DEBUG_PIM_NHT_RP) + zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ", + __func__, &nht_p, &rp_info->group); pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL); if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p, @@ -1145,15 +1104,10 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group) nht_p.family = AF_INET; nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4; - if (PIM_DEBUG_PIM_NHT_RP) { - char buf[PREFIX2STR_BUFFER]; - char buf1[PREFIX2STR_BUFFER]; - prefix2str(&nht_p, buf, sizeof(buf)); - prefix2str(&rp_info->group, buf1, sizeof(buf1)); + if (PIM_DEBUG_PIM_NHT_RP) zlog_debug( - "%s: NHT Register RP addr %s grp %s with Zebra", - __func__, buf, buf1); - } + "%s: NHT Register RP addr %pFX grp %pFX with Zebra", + __func__, &nht_p, &rp_info->group); pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL); pim_rpf_set_refresh_time(pim); @@ -1208,7 +1162,6 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty, struct listnode *node; struct rp_info *rp_info; char rp_buffer[32]; - char group_buffer[32]; int count = 0; for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) { @@ -1225,11 +1178,11 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty, rp_buffer, 32), rp_info->plist); else - vty_out(vty, "%sip pim rp %s %s\n", spaces, + vty_out(vty, "%sip pim rp %s %pFX\n", spaces, inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32), - prefix2str(&rp_info->group, group_buffer, 32)); + &rp_info->group); count++; } @@ -1251,6 +1204,7 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) struct rp_info *prev_rp_info = NULL; struct listnode *node; char source[7]; + char buf[PREFIX_STRLEN]; json_object *json = NULL; json_object *json_rp_rows = NULL; @@ -1283,9 +1237,11 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) .s_addr) { json_object_object_add( json, - inet_ntoa(prev_rp_info->rp + inet_ntop(AF_INET, + &prev_rp_info->rp .rpf_addr.u - .prefix4), + .prefix4, + buf, sizeof(buf)), json_rp_rows); json_rp_rows = NULL; } @@ -1296,8 +1252,10 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) json_row = json_object_new_object(); json_object_string_add( json_row, "rpAddress", - inet_ntoa(rp_info->rp.rpf_addr.u - .prefix4)); + inet_ntop(AF_INET, + &rp_info->rp.rpf_addr.u + .prefix4, + buf, sizeof(buf))); if (rp_info->rp.source_nexthop.interface) json_object_string_add( json_row, "outboundInterface", @@ -1329,15 +1287,16 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) json_object_array_add(json_rp_rows, json_row); } else { vty_out(vty, "%-15s ", - inet_ntoa(rp_info->rp.rpf_addr.u - .prefix4)); + inet_ntop(AF_INET, + &rp_info->rp.rpf_addr.u + .prefix4, + buf, sizeof(buf))); if (rp_info->plist) vty_out(vty, "%-18s ", rp_info->plist); else - vty_out(vty, "%-18s ", - prefix2str(&rp_info->group, buf, - 48)); + vty_out(vty, "%-18pFX ", + &rp_info->group); if (rp_info->rp.source_nexthop.interface) vty_out(vty, "%-16s ", @@ -1361,7 +1320,9 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) if (prev_rp_info && json_rp_rows) json_object_object_add( json, - inet_ntoa(prev_rp_info->rp.rpf_addr.u.prefix4), + inet_ntop(AF_INET, + &prev_rp_info->rp.rpf_addr.u.prefix4, + buf, sizeof(buf)), json_rp_rows); vty_out(vty, "%s\n", json_object_to_json_string_ext( diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index d3fb0d46de..d95b092d94 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -267,13 +267,10 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim, nht_p.family = AF_INET; nht_p.prefixlen = IPV4_MAX_BITLEN; nht_p.u.prefix4 = up->upstream_addr; - if (PIM_DEBUG_PIM_TRACE) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&nht_p, buf, sizeof(buf)); + if (PIM_DEBUG_PIM_TRACE) zlog_debug( - "%s: Deregister upstream %s addr %s with Zebra NHT", - __func__, up->sg_str, buf); - } + "%s: Deregister upstream %s addr %pFX with Zebra NHT", + __func__, up->sg_str, &nht_p); pim_delete_tracked_nexthop(pim, &nht_p, up, NULL, false); } @@ -954,8 +951,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, if (PIM_DEBUG_PIM_TRACE) { zlog_debug( - "%s: Created Upstream %s upstream_addr %s ref count %d increment", - __func__, up->sg_str, inet_ntoa(up->upstream_addr), + "%s: Created Upstream %s upstream_addr %pI4 ref count %d increment", + __func__, up->sg_str, &up->upstream_addr, up->ref_count); } @@ -1062,15 +1059,13 @@ struct pim_upstream *pim_upstream_add(struct pim_instance *pim, } if (PIM_DEBUG_PIM_TRACE) { - if (up) { - char buf[PREFIX2STR_BUFFER]; - prefix2str(&up->rpf.rpf_addr, buf, sizeof(buf)); - zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d", + if (up) + zlog_debug("%s(%s): %s, iif %pFX (%s) found: %d: ref_count: %d", __func__, name, - up->sg_str, buf, up->rpf.source_nexthop.interface ? + up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ? up->rpf.source_nexthop.interface->name : "Unknown" , found, up->ref_count); - } else + else zlog_debug("%s(%s): (%s) failure to create", __func__, name, pim_str_sg_dump(sg)); } @@ -1773,7 +1768,7 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up, { uint32_t time; - THREAD_TIMER_OFF(up->t_rs_timer); + THREAD_OFF(up->t_rs_timer); if (!null_register) { uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index d089dfda51..f0eae955cc 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -98,8 +98,8 @@ static void dump_if_address(struct interface *ifp) if (p->family != AF_INET) continue; - zlog_debug("%s %s: interface %s address %s %s", __FILE__, - __func__, ifp->name, inet_ntoa(p->u.prefix4), + zlog_debug("%s %s: interface %s address %pI4 %s", __FILE__, + __func__, ifp->name, &p->u.prefix4, CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); @@ -130,10 +130,8 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS) p = c->address; if (PIM_DEBUG_ZEBRA) { - char buf[BUFSIZ]; - prefix2str(p, buf, BUFSIZ); - zlog_debug("%s: %s(%u) connected IP address %s flags %u %s", - __func__, c->ifp->name, vrf_id, buf, c->flags, + zlog_debug("%s: %s(%u) connected IP address %pFX flags %u %s", + __func__, c->ifp->name, vrf_id, p, c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); @@ -149,17 +147,10 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS) struct in_addr primary_addr = pim_find_primary_addr(c->ifp); if (p->family != AF_INET || primary_addr.s_addr != p->u.prefix4.s_addr) { - if (PIM_DEBUG_ZEBRA) { - /* but we had a primary address already */ - - char buf[BUFSIZ]; - - prefix2str(p, buf, BUFSIZ); - + if (PIM_DEBUG_ZEBRA) zlog_warn( - "%s: %s : forcing secondary flag on %s", - __func__, c->ifp->name, buf); - } + "%s: %s : forcing secondary flag on %pFX", + __func__, c->ifp->name, p); SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY); } } @@ -211,11 +202,9 @@ static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS) p = c->address; if (p->family == AF_INET) { if (PIM_DEBUG_ZEBRA) { - char buf[BUFSIZ]; - prefix2str(p, buf, BUFSIZ); zlog_debug( - "%s: %s(%u) disconnected IP address %s flags %u %s", - __func__, c->ifp->name, vrf_id, buf, c->flags, + "%s: %s(%u) disconnected IP address %pFX flags %u %s", + __func__, c->ifp->name, vrf_id, p, c->flags, CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); @@ -848,9 +837,9 @@ void pim_forward_start(struct pim_ifchannel *ch) sizeof(group_str)); pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str)); - zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", __func__, + zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%pI4)", __func__, source_str, group_str, ch->interface->name, - inet_ntoa(up->upstream_addr)); + &up->upstream_addr); } if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags)) diff --git a/python/callgraph-dot.py b/python/callgraph-dot.py index 4faf1dae16..f80766a080 100644 --- a/python/callgraph-dot.py +++ b/python/callgraph-dot.py @@ -20,6 +20,7 @@ import re import sys import json + class FunctionNode(object): funcs = {} @@ -39,7 +40,7 @@ class FunctionNode(object): def define(self, attrs): self.defined = True - self.defs.append((attrs['filename'], attrs['line'])) + self.defs.append((attrs["filename"], attrs["line"])) return self def add_call(self, called, attrs): @@ -63,11 +64,12 @@ class FunctionNode(object): return cls.funcs[name] return FunctionNode(name) + class CallEdge(object): def __init__(self, i, o, attrs): self.i = i self.o = o - self.is_external = attrs['is_external'] + self.is_external = attrs["is_external"] self.attrs = attrs i.out.append(self) @@ -76,11 +78,13 @@ class CallEdge(object): def __repr__(self): return '<"%s()" -> "%s()">' % (self.i.name, self.o.name) + def nameclean(n): - if '.' in n: - return n.split('.', 1)[0] + if "." in n: + return n.split(".", 1)[0] return n + def calc_rank(queue, direction): nextq = queue @@ -98,7 +102,7 @@ def calc_rank(queue, direction): queue = nextq nextq = [] - #sys.stderr.write('rank %d\n' % currank) + # sys.stderr.write('rank %d\n' % currank) cont = False @@ -123,6 +127,7 @@ def calc_rank(queue, direction): return nextq + class Graph(dict): class Subgraph(set): def __init__(self): @@ -166,6 +171,7 @@ class Graph(dict): def calls(self): return self._calls + def calld(self): return self._calld @@ -245,7 +251,7 @@ class Graph(dict): else: evalset.add(evnode) - #if len(candidates) > 1: + # if len(candidates) > 1: # for candidate in candidates: # if candidate != node: # #node.merge(candidate) @@ -266,7 +272,7 @@ class Graph(dict): self._linear_nodes = [] while len(nodes): - sys.stderr.write('%d\n' % len(nodes)) + sys.stderr.write("%d\n" % len(nodes)) node = nodes.pop(0) down[node] = set() @@ -304,106 +310,90 @@ class Graph(dict): return self._subgraphs, self._linear_nodes -with open(sys.argv[1], 'r') as fd: +with open(sys.argv[1], "r") as fd: data = json.load(fd) extra_info = { # zebra - LSP WQ - ('lsp_processq_add', 'work_queue_add'): [ - 'lsp_process', - 'lsp_processq_del', - 'lsp_processq_complete', + ("lsp_processq_add", "work_queue_add"): [ + "lsp_process", + "lsp_processq_del", + "lsp_processq_complete", ], # zebra - main WQ - ('mq_add_handler', 'work_queue_add'): [ - 'meta_queue_process', - ], - ('meta_queue_process', 'work_queue_add'): [ - 'meta_queue_process', - ], + ("mq_add_handler", "work_queue_add"): ["meta_queue_process",], + ("meta_queue_process", "work_queue_add"): ["meta_queue_process",], # bgpd - label pool WQ - ('bgp_lp_get', 'work_queue_add'): [ - 'lp_cbq_docallback', - ], - ('bgp_lp_event_chunk', 'work_queue_add'): [ - 'lp_cbq_docallback', - ], - ('bgp_lp_event_zebra_up', 'work_queue_add'): [ - 'lp_cbq_docallback', - ], + ("bgp_lp_get", "work_queue_add"): ["lp_cbq_docallback",], + ("bgp_lp_event_chunk", "work_queue_add"): ["lp_cbq_docallback",], + ("bgp_lp_event_zebra_up", "work_queue_add"): ["lp_cbq_docallback",], # bgpd - main WQ - ('bgp_process', 'work_queue_add'): [ - 'bgp_process_wq', - 'bgp_processq_del', - ], - ('bgp_add_eoiu_mark', 'work_queue_add'): [ - 'bgp_process_wq', - 'bgp_processq_del', - ], + ("bgp_process", "work_queue_add"): ["bgp_process_wq", "bgp_processq_del",], + ("bgp_add_eoiu_mark", "work_queue_add"): ["bgp_process_wq", "bgp_processq_del",], # clear node WQ - ('bgp_clear_route_table', 'work_queue_add'): [ - 'bgp_clear_route_node', - 'bgp_clear_node_queue_del', - 'bgp_clear_node_complete', + ("bgp_clear_route_table", "work_queue_add"): [ + "bgp_clear_route_node", + "bgp_clear_node_queue_del", + "bgp_clear_node_complete", ], # rfapi WQs - ('rfapi_close', 'work_queue_add'): [ - 'rfapi_deferred_close_workfunc', - ], - ('rfapiRibUpdatePendingNode', 'work_queue_add'): [ - 'rfapiRibDoQueuedCallback', - 'rfapiRibQueueItemDelete', + ("rfapi_close", "work_queue_add"): ["rfapi_deferred_close_workfunc",], + ("rfapiRibUpdatePendingNode", "work_queue_add"): [ + "rfapiRibDoQueuedCallback", + "rfapiRibQueueItemDelete", ], } -for func, fdata in data['functions'].items(): +for func, fdata in data["functions"].items(): func = nameclean(func) fnode = FunctionNode.get(func).define(fdata) - for call in fdata['calls']: - if call.get('type') in [None, 'unnamed', 'thread_sched']: - if call.get('target') is None: + for call in fdata["calls"]: + if call.get("type") in [None, "unnamed", "thread_sched"]: + if call.get("target") is None: continue - tgt = nameclean(call['target']) + tgt = nameclean(call["target"]) fnode.add_call(FunctionNode.get(tgt), call) - for fptr in call.get('funcptrs', []): + for fptr in call.get("funcptrs", []): fnode.add_call(FunctionNode.get(nameclean(fptr)), call) - if tgt == 'work_queue_add': + if tgt == "work_queue_add": if (func, tgt) not in extra_info: - sys.stderr.write('%s:%d:%s(): work_queue_add() not handled\n' % ( - call['filename'], call['line'], func)) + sys.stderr.write( + "%s:%d:%s(): work_queue_add() not handled\n" + % (call["filename"], call["line"], func) + ) else: attrs = dict(call) - attrs.update({'is_external': False, 'type': 'workqueue'}) + attrs.update({"is_external": False, "type": "workqueue"}) for dst in extra_info[func, tgt]: fnode.add_call(FunctionNode.get(dst), call) - elif call['type'] == 'install_element': - vty_node = FunctionNode.get('VTY_NODE_%d' % call['vty_node']) - vty_node.add_call(FunctionNode.get(nameclean(call['target'])), call) - elif call['type'] == 'hook': + elif call["type"] == "install_element": + vty_node = FunctionNode.get("VTY_NODE_%d" % call["vty_node"]) + vty_node.add_call(FunctionNode.get(nameclean(call["target"])), call) + elif call["type"] == "hook": # TODO: edges for hooks from data['hooks'] pass n = FunctionNode.funcs # fix some very low end functions cycling back very far to the top -if 'peer_free' in n: - n['peer_free'].unlink(n['bgp_timer_set']) - n['peer_free'].unlink(n['bgp_addpath_set_peer_type']) -if 'bgp_path_info_extra_free' in n: - n['bgp_path_info_extra_free'].rank = 0 +if "peer_free" in n: + n["peer_free"].unlink(n["bgp_timer_set"]) + n["peer_free"].unlink(n["bgp_addpath_set_peer_type"]) +if "bgp_path_info_extra_free" in n: + n["bgp_path_info_extra_free"].rank = 0 -if 'zlog_ref' in n: - n['zlog_ref'].rank = 0 -if 'mt_checkalloc' in n: - n['mt_checkalloc'].rank = 0 +if "zlog_ref" in n: + n["zlog_ref"].rank = 0 +if "mt_checkalloc" in n: + n["mt_checkalloc"].rank = 0 queue = list(FunctionNode.funcs.values()) queue = calc_rank(queue, 1) queue = calc_rank(queue, -1) -sys.stderr.write('%d functions in cyclic set\n' % len(queue)) +sys.stderr.write("%d functions in cyclic set\n" % len(queue)) graph = Graph(queue) graph.automerge() @@ -411,10 +401,12 @@ graph.automerge() gv_nodes = [] gv_edges = [] -sys.stderr.write('%d groups after automerge\n' % len(graph._groups)) +sys.stderr.write("%d groups after automerge\n" % len(graph._groups)) + def is_vnc(n): - return n.startswith('rfapi') or n.startswith('vnc') or ('_vnc_' in n) + return n.startswith("rfapi") or n.startswith("vnc") or ("_vnc_" in n) + _vncstyle = ',fillcolor="#ffffcc",style=filled' cyclic_set_names = set([fn.name for fn in graph.values()]) @@ -422,55 +414,76 @@ cyclic_set_names = set([fn.name for fn in graph.values()]) for i, group in enumerate(graph._groups): if len(group) > 1: group.num = i - gv_nodes.append('\tsubgraph cluster_%d {' % i) - gv_nodes.append('\t\tcolor=blue;') + gv_nodes.append("\tsubgraph cluster_%d {" % i) + gv_nodes.append("\t\tcolor=blue;") for gn in group: has_cycle_callers = set(gn.calld()) - group - has_ext_callers = set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names + has_ext_callers = ( + set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names + ) - style = '' - etext = '' + style = "" + etext = "" if is_vnc(gn.name): style += _vncstyle if has_cycle_callers: - style += ',color=blue,penwidth=3' + style += ",color=blue,penwidth=3" if has_ext_callers: style += ',fillcolor="#ffeebb",style=filled' - etext += '<br/><font point-size="10">(%d other callers)</font>' % (len(has_ext_callers)) - - gv_nodes.append('\t\t"%s" [shape=box,label=<%s%s>%s];' % (gn.name, '<br/>'.join([fn.name for fn in gn._fns]), etext, style)) - gv_nodes.append('\t}') + etext += '<br/><font point-size="10">(%d other callers)</font>' % ( + len(has_ext_callers) + ) + + gv_nodes.append( + '\t\t"%s" [shape=box,label=<%s%s>%s];' + % (gn.name, "<br/>".join([fn.name for fn in gn._fns]), etext, style) + ) + gv_nodes.append("\t}") else: for gn in group: - has_ext_callers = set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names + has_ext_callers = ( + set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names + ) - style = '' - etext = '' + style = "" + etext = "" if is_vnc(gn.name): style += _vncstyle if has_ext_callers: style += ',fillcolor="#ffeebb",style=filled' - etext += '<br/><font point-size="10">(%d other callers)</font>' % (len(has_ext_callers)) - gv_nodes.append('\t"%s" [shape=box,label=<%s%s>%s];' % (gn.name, '<br/>'.join([fn.name for fn in gn._fns]), etext, style)) + etext += '<br/><font point-size="10">(%d other callers)</font>' % ( + len(has_ext_callers) + ) + gv_nodes.append( + '\t"%s" [shape=box,label=<%s%s>%s];' + % (gn.name, "<br/>".join([fn.name for fn in gn._fns]), etext, style) + ) edges = set() for gn in graph.values(): for calls in gn.calls(): if gn._group == calls._group: - gv_edges.append('\t"%s" -> "%s" [color="#55aa55",style=dashed];' % (gn.name, calls.name)) + gv_edges.append( + '\t"%s" -> "%s" [color="#55aa55",style=dashed];' % (gn.name, calls.name) + ) else: + def xname(nn): if len(nn._group) > 1: - return 'cluster_%d' % nn._group.num + return "cluster_%d" % nn._group.num else: return nn.name + tup = xname(gn), calls.name if tup[0] != tup[1] and tup not in edges: gv_edges.append('\t"%s" -> "%s" [weight=0.0,w=0.0,color=blue];' % tup) edges.add(tup) -with open(sys.argv[2], 'w') as fd: - fd.write('''digraph { +with open(sys.argv[2], "w") as fd: + fd.write( + """digraph { node [fontsize=13,fontname="Fira Sans"]; %s -}''' % '\n'.join(gv_nodes + [''] + gv_edges)) +}""" + % "\n".join(gv_nodes + [""] + gv_edges) + ) diff --git a/python/clidef.py b/python/clidef.py index baa6ed52b2..a47cee2d6b 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -26,39 +26,49 @@ from io import StringIO # the various handlers generate output C code for a particular type of # CLI token, choosing the most useful output C type. + class RenderHandler(object): def __init__(self, token): pass + def combine(self, other): if type(self) == type(other): return other return StringHandler(None) - deref = '' + deref = "" drop_str = False canfail = True canassert = False + class StringHandler(RenderHandler): - argtype = 'const char *' - decl = Template('const char *$varname = NULL;') - code = Template('$varname = (argv[_i]->type == WORD_TKN) ? argv[_i]->text : argv[_i]->arg;') + argtype = "const char *" + decl = Template("const char *$varname = NULL;") + code = Template( + "$varname = (argv[_i]->type == WORD_TKN) ? argv[_i]->text : argv[_i]->arg;" + ) drop_str = True canfail = False canassert = True + class LongHandler(RenderHandler): - argtype = 'long' - decl = Template('long $varname = 0;') - code = Template('''\ + argtype = "long" + decl = Template("long $varname = 0;") + code = Template( + """\ char *_end; $varname = strtol(argv[_i]->arg, &_end, 10); -_fail = (_end == argv[_i]->arg) || (*_end != '\\0');''') +_fail = (_end == argv[_i]->arg) || (*_end != '\\0');""" + ) + # A.B.C.D/M (prefix_ipv4) and # X:X::X:X/M (prefix_ipv6) are "compatible" and can merge into a # struct prefix: + class PrefixBase(RenderHandler): def combine(self, other): if type(self) == type(other): @@ -66,23 +76,33 @@ class PrefixBase(RenderHandler): if isinstance(other, PrefixBase): return PrefixGenHandler(None) return StringHandler(None) - deref = '&' + + deref = "&" + + class Prefix4Handler(PrefixBase): - argtype = 'const struct prefix_ipv4 *' - decl = Template('struct prefix_ipv4 $varname = { };') - code = Template('_fail = !str2prefix_ipv4(argv[_i]->arg, &$varname);') + argtype = "const struct prefix_ipv4 *" + decl = Template("struct prefix_ipv4 $varname = { };") + code = Template("_fail = !str2prefix_ipv4(argv[_i]->arg, &$varname);") + + class Prefix6Handler(PrefixBase): - argtype = 'const struct prefix_ipv6 *' - decl = Template('struct prefix_ipv6 $varname = { };') - code = Template('_fail = !str2prefix_ipv6(argv[_i]->arg, &$varname);') + argtype = "const struct prefix_ipv6 *" + decl = Template("struct prefix_ipv6 $varname = { };") + code = Template("_fail = !str2prefix_ipv6(argv[_i]->arg, &$varname);") + + class PrefixEthHandler(PrefixBase): - argtype = 'struct prefix_eth *' - decl = Template('struct prefix_eth $varname = { };') - code = Template('_fail = !str2prefix_eth(argv[_i]->arg, &$varname);') + argtype = "struct prefix_eth *" + decl = Template("struct prefix_eth $varname = { };") + code = Template("_fail = !str2prefix_eth(argv[_i]->arg, &$varname);") + + class PrefixGenHandler(PrefixBase): - argtype = 'const struct prefix *' - decl = Template('struct prefix $varname = { };') - code = Template('_fail = !str2prefix(argv[_i]->arg, &$varname);') + argtype = "const struct prefix *" + decl = Template("struct prefix $varname = { };") + code = Template("_fail = !str2prefix(argv[_i]->arg, &$varname);") + # same for IP addresses. result is union sockunion. class IPBase(RenderHandler): @@ -92,18 +112,27 @@ class IPBase(RenderHandler): if type(other) in [IP4Handler, IP6Handler, IPGenHandler]: return IPGenHandler(None) return StringHandler(None) + + class IP4Handler(IPBase): - argtype = 'struct in_addr' - decl = Template('struct in_addr $varname = { INADDR_ANY };') - code = Template('_fail = !inet_aton(argv[_i]->arg, &$varname);') + argtype = "struct in_addr" + decl = Template("struct in_addr $varname = { INADDR_ANY };") + code = Template("_fail = !inet_aton(argv[_i]->arg, &$varname);") + + class IP6Handler(IPBase): - argtype = 'struct in6_addr' - decl = Template('struct in6_addr $varname = {};') - code = Template('_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);') + argtype = "struct in6_addr" + decl = Template("struct in6_addr $varname = {};") + code = Template("_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);") + + class IPGenHandler(IPBase): - argtype = 'const union sockunion *' - decl = Template('''union sockunion s__$varname = { .sa.sa_family = AF_UNSPEC }, *$varname = NULL;''') - code = Template('''\ + argtype = "const union sockunion *" + decl = Template( + """union sockunion s__$varname = { .sa.sa_family = AF_UNSPEC }, *$varname = NULL;""" + ) + code = Template( + """\ if (argv[_i]->text[0] == 'X') { s__$varname.sa.sa_family = AF_INET6; _fail = !inet_pton(AF_INET6, argv[_i]->arg, &s__$varname.sin6.sin6_addr); @@ -112,26 +141,30 @@ if (argv[_i]->text[0] == 'X') { s__$varname.sa.sa_family = AF_INET; _fail = !inet_aton(argv[_i]->arg, &s__$varname.sin.sin_addr); $varname = &s__$varname; -}''') +}""" + ) canassert = True + def mix_handlers(handlers): def combine(a, b): if a is None: return b return a.combine(b) + return reduce(combine, handlers, None) + handlers = { - 'WORD_TKN': StringHandler, - 'VARIABLE_TKN': StringHandler, - 'RANGE_TKN': LongHandler, - 'IPV4_TKN': IP4Handler, - 'IPV4_PREFIX_TKN': Prefix4Handler, - 'IPV6_TKN': IP6Handler, - 'IPV6_PREFIX_TKN': Prefix6Handler, - 'MAC_TKN': PrefixEthHandler, - 'MAC_PREFIX_TKN': PrefixEthHandler, + "WORD_TKN": StringHandler, + "VARIABLE_TKN": StringHandler, + "RANGE_TKN": LongHandler, + "IPV4_TKN": IP4Handler, + "IPV4_PREFIX_TKN": Prefix4Handler, + "IPV6_TKN": IP6Handler, + "IPV6_PREFIX_TKN": Prefix6Handler, + "MAC_TKN": PrefixEthHandler, + "MAC_PREFIX_TKN": PrefixEthHandler, } # core template invoked for each occurence of DEFPY. @@ -139,7 +172,8 @@ handlers = { # the "#if $..." bits are there to keep this template unified into one # common form, without requiring a more advanced template engine (e.g. # jinja2) -templ = Template('''/* $fnname => "$cmddef" */ +templ = Template( + """/* $fnname => "$cmddef" */ DEFUN_CMD_FUNC_DECL($fnname) #define funcdecl_$fnname static int ${fnname}_magic(\\ const struct cmd_element *self __attribute__ ((unused)),\\ @@ -178,18 +212,22 @@ $argassert return ${fnname}_magic(self, vty, argc, argv$arglist); } -''') +""" +) # invoked for each named parameter -argblock = Template(''' +argblock = Template( + """ if (!strcmp(argv[_i]->varname, \"$varname\")) {$strblock $code - }''') + }""" +) -def get_always_args(token, always_args, args = [], stack = []): + +def get_always_args(token, always_args, args=[], stack=[]): if token in stack: return - if token.type == 'END_TKN': + if token.type == "END_TKN": for arg in list(always_args): if arg not in args: always_args.remove(arg) @@ -201,38 +239,45 @@ def get_always_args(token, always_args, args = [], stack = []): for nexttkn in token.next(): get_always_args(nexttkn, always_args, args, stack) + class Macros(dict): def load(self, filename): filedata = clippy.parse(filename) - for entry in filedata['data']: - if entry['type'] != 'PREPROC': + for entry in filedata["data"]: + if entry["type"] != "PREPROC": continue - ppdir = entry['line'].lstrip().split(None, 1) - if ppdir[0] != 'define' or len(ppdir) != 2: + ppdir = entry["line"].lstrip().split(None, 1) + if ppdir[0] != "define" or len(ppdir) != 2: continue ppdef = ppdir[1].split(None, 1) name = ppdef[0] - if '(' in name: + if "(" in name: continue - val = ppdef[1] if len(ppdef) == 2 else '' + val = ppdef[1] if len(ppdef) == 2 else "" - val = val.strip(' \t\n\\') + val = val.strip(" \t\n\\") if name in self: - sys.stderr.write('warning: macro %s redefined!\n' % (name)) + sys.stderr.write("warning: macro %s redefined!\n" % (name)) self[name] = val + def process_file(fn, ofd, dumpfd, all_defun, macros): errors = 0 filedata = clippy.parse(fn) - for entry in filedata['data']: - if entry['type'].startswith('DEFPY') or (all_defun and entry['type'].startswith('DEFUN')): - if len(entry['args'][0]) != 1: - sys.stderr.write('%s:%d: DEFPY function name not parseable (%r)\n' % (fn, entry['lineno'], entry['args'][0])) + for entry in filedata["data"]: + if entry["type"].startswith("DEFPY") or ( + all_defun and entry["type"].startswith("DEFUN") + ): + if len(entry["args"][0]) != 1: + sys.stderr.write( + "%s:%d: DEFPY function name not parseable (%r)\n" + % (fn, entry["lineno"], entry["args"][0]) + ) errors += 1 continue - cmddef = entry['args'][2] + cmddef = entry["args"][2] cmddefx = [] for i in cmddef: while i in macros: @@ -241,13 +286,16 @@ def process_file(fn, ofd, dumpfd, all_defun, macros): cmddefx.append(i[1:-1]) continue - sys.stderr.write('%s:%d: DEFPY command string not parseable (%r)\n' % (fn, entry['lineno'], cmddef)) + sys.stderr.write( + "%s:%d: DEFPY command string not parseable (%r)\n" + % (fn, entry["lineno"], cmddef) + ) errors += 1 cmddefx = None break if cmddefx is None: continue - cmddef = ''.join([i for i in cmddefx]) + cmddef = "".join([i for i in cmddefx]) graph = clippy.Graph(cmddef) args = OrderedDict() @@ -263,12 +311,12 @@ def process_file(fn, ofd, dumpfd, all_defun, macros): get_always_args(graph.first(), always_args) - #print('-' * 76) - #pprint(entry) - #clippy.dump(graph) - #pprint(args) + # print('-' * 76) + # pprint(entry) + # clippy.dump(graph) + # pprint(args) - params = { 'cmddef': cmddef, 'fnname': entry['args'][0][0] } + params = {"cmddef": cmddef, "fnname": entry["args"][0][0]} argdefs = [] argdecls = [] arglist = [] @@ -277,63 +325,96 @@ def process_file(fn, ofd, dumpfd, all_defun, macros): doc = [] canfail = 0 - def do_add(handler, basename, varname, attr = ''): - argdefs.append(',\\\n\t%s %s%s' % (handler.argtype, varname, attr)) - argdecls.append('\t%s\n' % (handler.decl.substitute({'varname': varname}).replace('\n', '\n\t'))) - arglist.append(', %s%s' % (handler.deref, varname)) + def do_add(handler, basename, varname, attr=""): + argdefs.append(",\\\n\t%s %s%s" % (handler.argtype, varname, attr)) + argdecls.append( + "\t%s\n" + % ( + handler.decl.substitute({"varname": varname}).replace( + "\n", "\n\t" + ) + ) + ) + arglist.append(", %s%s" % (handler.deref, varname)) if basename in always_args and handler.canassert: - argassert.append('''\tif (!%s) { + argassert.append( + """\tif (!%s) { \t\tvty_out(vty, "Internal CLI error [%%s]\\n", "%s"); \t\treturn CMD_WARNING; -\t}\n''' % (varname, varname)) - if attr == '': +\t}\n""" + % (varname, varname) + ) + if attr == "": at = handler.argtype - if not at.startswith('const '): - at = '. . . ' + at - doc.append('\t%-26s %s %s' % (at, 'alw' if basename in always_args else 'opt', varname)) + if not at.startswith("const "): + at = ". . . " + at + doc.append( + "\t%-26s %s %s" + % (at, "alw" if basename in always_args else "opt", varname) + ) for varname in args.keys(): handler = mix_handlers(args[varname]) - #print(varname, handler) - if handler is None: continue + # print(varname, handler) + if handler is None: + continue do_add(handler, varname, varname) - code = handler.code.substitute({'varname': varname}).replace('\n', '\n\t\t\t') + code = handler.code.substitute({"varname": varname}).replace( + "\n", "\n\t\t\t" + ) if handler.canfail: canfail = 1 - strblock = '' + strblock = "" if not handler.drop_str: - do_add(StringHandler(None), varname, '%s_str' % (varname), ' __attribute__ ((unused))') - strblock = '\n\t\t\t%s_str = argv[_i]->arg;' % (varname) - argblocks.append(argblock.substitute({'varname': varname, 'strblock': strblock, 'code': code})) + do_add( + StringHandler(None), + varname, + "%s_str" % (varname), + " __attribute__ ((unused))", + ) + strblock = "\n\t\t\t%s_str = argv[_i]->arg;" % (varname) + argblocks.append( + argblock.substitute( + {"varname": varname, "strblock": strblock, "code": code} + ) + ) if dumpfd is not None: if len(arglist) > 0: - dumpfd.write('"%s":\n%s\n\n' % (cmddef, '\n'.join(doc))) + dumpfd.write('"%s":\n%s\n\n' % (cmddef, "\n".join(doc))) else: dumpfd.write('"%s":\n\t---- no magic arguments ----\n\n' % (cmddef)) - params['argdefs'] = ''.join(argdefs) - params['argdecls'] = ''.join(argdecls) - params['arglist'] = ''.join(arglist) - params['argblocks'] = ''.join(argblocks) - params['canfail'] = canfail - params['nonempty'] = len(argblocks) - params['argassert'] = ''.join(argassert) + params["argdefs"] = "".join(argdefs) + params["argdecls"] = "".join(argdecls) + params["arglist"] = "".join(arglist) + params["argblocks"] = "".join(argblocks) + params["canfail"] = canfail + params["nonempty"] = len(argblocks) + params["argassert"] = "".join(argassert) ofd.write(templ.substitute(params)) return errors -if __name__ == '__main__': + +if __name__ == "__main__": import argparse - argp = argparse.ArgumentParser(description = 'FRR CLI preprocessor in Python') - argp.add_argument('--all-defun', action = 'store_const', const = True, - help = 'process DEFUN() statements in addition to DEFPY()') - argp.add_argument('--show', action = 'store_const', const = True, - help = 'print out list of arguments and types for each definition') - argp.add_argument('-o', type = str, metavar = 'OUTFILE', - help = 'output C file name') - argp.add_argument('cfile', type = str) + argp = argparse.ArgumentParser(description="FRR CLI preprocessor in Python") + argp.add_argument( + "--all-defun", + action="store_const", + const=True, + help="process DEFUN() statements in addition to DEFPY()", + ) + argp.add_argument( + "--show", + action="store_const", + const=True, + help="print out list of arguments and types for each definition", + ) + argp.add_argument("-o", type=str, metavar="OUTFILE", help="output C file name") + argp.add_argument("cfile", type=str) args = argp.parse_args() dumpfd = None @@ -349,15 +430,17 @@ if __name__ == '__main__': basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) macros = Macros() - macros.load('lib/route_types.h') - macros.load(os.path.join(basepath, 'lib/command.h')) - macros.load(os.path.join(basepath, 'bgpd/bgp_vty.h')) + macros.load("lib/route_types.h") + macros.load(os.path.join(basepath, "lib/command.h")) + macros.load(os.path.join(basepath, "bgpd/bgp_vty.h")) # sigh :( - macros['PROTO_REDIST_STR'] = 'FRR_REDIST_STR_ISISD' + macros["PROTO_REDIST_STR"] = "FRR_REDIST_STR_ISISD" errors = process_file(args.cfile, ofd, dumpfd, args.all_defun, macros) if errors != 0: sys.exit(1) if args.o is not None: - clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable]) + clippy.wrdiff( + args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable] + ) diff --git a/python/clippy/__init__.py b/python/clippy/__init__.py index 41aeae6b4d..d6865ff484 100644 --- a/python/clippy/__init__.py +++ b/python/clippy/__init__.py @@ -20,11 +20,12 @@ import os, stat import _clippy from _clippy import parse, Graph, GraphNode + def graph_iterate(graph): - '''iterator yielding all nodes of a graph + """iterator yielding all nodes of a graph nodes arrive in input/definition order, graph circles are avoided. - ''' + """ queue = [(graph.first(), frozenset(), 0)] while len(queue) > 0: @@ -42,21 +43,25 @@ def graph_iterate(graph): if n not in stop and n is not node: queue.insert(0, (n, stop, depth + 1)) + def dump(graph): - '''print out clippy.Graph''' + """print out clippy.Graph""" for i, depth in graph_iterate(graph): - print('\t%s%s %r' % (' ' * (depth * 2), i.type, i.text)) + print("\t%s%s %r" % (" " * (depth * 2), i.type, i.text)) + -def wrdiff(filename, buf, reffiles = []): - '''write buffer to file if contents changed''' +def wrdiff(filename, buf, reffiles=[]): + """write buffer to file if contents changed""" - expl = '' - if hasattr(buf, 'getvalue'): + expl = "" + if hasattr(buf, "getvalue"): buf = buf.getvalue() old = None - try: old = open(filename, 'r').read() - except: pass + try: + old = open(filename, "r").read() + except: + pass if old == buf: for reffile in reffiles: # ensure output timestamp is newer than inputs, for make @@ -67,7 +72,7 @@ def wrdiff(filename, buf, reffiles = []): # sys.stderr.write('%s unchanged, not written\n' % (filename)) return - newname = '%s.new-%d' % (filename, os.getpid()) - with open(newname, 'w') as out: + newname = "%s.new-%d" % (filename, os.getpid()) + with open(newname, "w") as out: out.write(buf) os.rename(newname, filename) diff --git a/python/firstheader.py b/python/firstheader.py index 19a85b63e5..bf50f33a33 100644 --- a/python/firstheader.py +++ b/python/firstheader.py @@ -9,21 +9,21 @@ include_re = re.compile('^#\s*include\s+["<]([^ ">]+)[">]', re.M) errors = 0 -files = subprocess.check_output(['git', 'ls-files']).decode('ASCII') +files = subprocess.check_output(["git", "ls-files"]).decode("ASCII") for fn in files.splitlines(): - if not fn.endswith('.c'): + if not fn.endswith(".c"): continue - if fn.startswith('tools/'): + if fn.startswith("tools/"): continue - with open(fn, 'r') as fd: + with open(fn, "r") as fd: data = fd.read() m = include_re.search(data) if m is None: - #sys.stderr.write('no #include in %s?\n' % (fn)) + # sys.stderr.write('no #include in %s?\n' % (fn)) continue - if m.group(1) in ['config.h', 'zebra.h', 'lib/zebra.h']: + if m.group(1) in ["config.h", "zebra.h", "lib/zebra.h"]: continue - sys.stderr.write('%s: %s\n' % (fn, m.group(0))) + sys.stderr.write("%s: %s\n" % (fn, m.group(0))) errors += 1 if errors: diff --git a/python/makefile.py b/python/makefile.py index fe20945ccc..10c73df72d 100644 --- a/python/makefile.py +++ b/python/makefile.py @@ -13,69 +13,91 @@ import argparse from string import Template from makevars import MakeReVars -argp = argparse.ArgumentParser(description = 'FRR Makefile extensions') -argp.add_argument('--dev-build', action = 'store_const', const = True, - help = 'run additional developer checks') +argp = argparse.ArgumentParser(description="FRR Makefile extensions") +argp.add_argument( + "--dev-build", + action="store_const", + const=True, + help="run additional developer checks", +) args = argp.parse_args() -with open('Makefile', 'r') as fd: +with open("Makefile", "r") as fd: before = fd.read() mv = MakeReVars(before) -clippy_scan = mv['clippy_scan'].strip().split() +clippy_scan = mv["clippy_scan"].strip().split() for clippy_file in clippy_scan: - assert clippy_file.endswith('.c') + assert clippy_file.endswith(".c") # check for files using clippy but not listed in clippy_scan if args.dev_build: basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - if os.path.exists(os.path.join(basepath, '.git')): - clippy_ref = subprocess.check_output([ - 'git', '-C', basepath, 'grep', '-l', '-P', '^#\s*include.*_clippy.c', '--', '**.c']).decode('US-ASCII') + if os.path.exists(os.path.join(basepath, ".git")): + clippy_ref = subprocess.check_output( + [ + "git", + "-C", + basepath, + "grep", + "-l", + "-P", + "^#\s*include.*_clippy.c", + "--", + "**.c", + ] + ).decode("US-ASCII") clippy_ref = set(clippy_ref.splitlines()) missing = clippy_ref - set(clippy_scan) if len(missing) > 0: - sys.stderr.write('error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n' % ('\n\t'.join(sorted(missing)))) + sys.stderr.write( + 'error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n' + % ("\n\t".join(sorted(missing))) + ) sys.exit(1) -clippydep = Template(''' +clippydep = Template( + """ ${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c ${clippybase}.lo: ${clippybase}_clippy.c -${clippybase}_clippy.c: $$(CLIPPY_DEPS)''') +${clippybase}_clippy.c: $$(CLIPPY_DEPS)""" +) -clippyauxdep = Template('''# clippy{ +clippyauxdep = Template( + """# clippy{ # auxiliary clippy target ${target}: ${clippybase}_clippy.c -# }clippy''') +# }clippy""" +) lines = before.splitlines() -autoderp = '#AUTODERP# ' +autoderp = "#AUTODERP# " out_lines = [] bcdeps = [] -make_rule_re = re.compile('^([^:\s]+):\s*([^:\s]+)\s*($|\n)') +make_rule_re = re.compile("^([^:\s]+):\s*([^:\s]+)\s*($|\n)") while lines: line = lines.pop(0) if line.startswith(autoderp): - line = line[len(autoderp):] + line = line[len(autoderp) :] - if line == '# clippy{': + if line == "# clippy{": while lines: line = lines.pop(0) - if line == '# }clippy': + if line == "# }clippy": break continue - if line.startswith('#'): + if line.startswith("#"): out_lines.append(line) continue full_line = line full_lines = lines[:] - while full_line.endswith('\\'): + while full_line.endswith("\\"): full_line = full_line[:-1] + full_lines.pop(0) m = make_rule_re.match(full_line) @@ -87,43 +109,51 @@ while lines: target, dep = m.group(1), m.group(2) - if target.endswith('.lo') or target.endswith('.o'): - if not dep.endswith('.h'): - bcdeps.append('%s.bc: %s' % (target, target)) - bcdeps.append('\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s' % (dep)) + if target.endswith(".lo") or target.endswith(".o"): + if not dep.endswith(".h"): + bcdeps.append("%s.bc: %s" % (target, target)) + bcdeps.append("\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s" % (dep)) if m.group(2) in clippy_scan: - out_lines.append(clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2])) + out_lines.append( + clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2]) + ) out_lines.append(line) -out_lines.append('# clippy{\n# main clippy targets') +out_lines.append("# clippy{\n# main clippy targets") for clippy_file in clippy_scan: - out_lines.append(clippydep.substitute(clippybase = clippy_file[:-2])) + out_lines.append(clippydep.substitute(clippybase=clippy_file[:-2])) -out_lines.append('') +out_lines.append("") out_lines.extend(bcdeps) -out_lines.append('') +out_lines.append("") bc_targets = [] -for varname in ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES', 'noinst_LIBRARIES']: +for varname in [ + "bin_PROGRAMS", + "sbin_PROGRAMS", + "lib_LTLIBRARIES", + "module_LTLIBRARIES", + "noinst_LIBRARIES", +]: bc_targets.extend(mv[varname].strip().split()) for target in bc_targets: - amtgt = target.replace('/', '_').replace('.', '_').replace('-', '_') - objs = mv[amtgt + '_OBJECTS'].strip().split() - objs = [obj + '.bc' for obj in objs] - deps = mv.get(amtgt + '_DEPENDENCIES', '').strip().split() - deps = [d + '.bc' for d in deps if d.endswith('.a')] + amtgt = target.replace("/", "_").replace(".", "_").replace("-", "_") + objs = mv[amtgt + "_OBJECTS"].strip().split() + objs = [obj + ".bc" for obj in objs] + deps = mv.get(amtgt + "_DEPENDENCIES", "").strip().split() + deps = [d + ".bc" for d in deps if d.endswith(".a")] objs.extend(deps) - out_lines.append('%s.bc: %s' % (target, ' '.join(objs))) - out_lines.append('\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^') - out_lines.append('') + out_lines.append("%s.bc: %s" % (target, " ".join(objs))) + out_lines.append("\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^") + out_lines.append("") -out_lines.append('# }clippy') -out_lines.append('') +out_lines.append("# }clippy") +out_lines.append("") -after = '\n'.join(out_lines) +after = "\n".join(out_lines) if after == before: sys.exit(0) -with open('Makefile.pyout', 'w') as fd: +with open("Makefile.pyout", "w") as fd: fd.write(after) -os.rename('Makefile.pyout', 'Makefile') +os.rename("Makefile.pyout", "Makefile") diff --git a/python/makevars.py b/python/makevars.py index 63bf8c5eeb..951cd3438b 100644 --- a/python/makevars.py +++ b/python/makevars.py @@ -6,10 +6,12 @@ import os import subprocess import re + class MakeVarsBase(object): - ''' + """ common code between MakeVars and MakeReVars - ''' + """ + def __init__(self): self._data = dict() @@ -18,31 +20,35 @@ class MakeVarsBase(object): self.getvars([k]) return self._data[k] - def get(self, k, defval = None): + def get(self, k, defval=None): if k not in self._data: self.getvars([k]) return self._data.get(k) or defval + class MakeVars(MakeVarsBase): - ''' + """ makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile This variant works by invoking make as a subprocess, i.e. Makefile must be valid and working. (This is sometimes a problem if depfiles have not been generated.) - ''' + """ + def getvars(self, varlist): - ''' + """ get a batch list of variables from make. faster than individual calls. - ''' + """ rdfd, wrfd = os.pipe() - shvars = ['shvar-%s' % s for s in varlist] - make = subprocess.Popen(['make', '-s', 'VARFD=%d' % wrfd] + shvars, pass_fds = [wrfd]) + shvars = ["shvar-%s" % s for s in varlist] + make = subprocess.Popen( + ["make", "-s", "VARFD=%d" % wrfd] + shvars, pass_fds=[wrfd] + ) os.close(wrfd) - data = b'' + data = b"" - rdf = os.fdopen(rdfd, 'rb') + rdf = os.fdopen(rdfd, "rb") while True: rdata = rdf.read() if len(rdata) == 0: @@ -52,30 +58,34 @@ class MakeVars(MakeVarsBase): del rdf make.wait() - data = data.decode('US-ASCII').strip().split('\n') + data = data.decode("US-ASCII").strip().split("\n") for row in data: - k, v = row.split('=', 1) + k, v = row.split("=", 1) v = v[1:-1] self._data[k] = v + class MakeReVars(MakeVarsBase): - ''' + """ makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile This variant works by regexing through Makefile. This means the Makefile does not need to be fully working, but on the other hand it doesn't support fancy complicated make expressions. - ''' - var_re = re.compile(r'^([^=#\n\s]+)[ \t]*=[ \t]*([^#\n]*)(?:#.*)?$', flags=re.MULTILINE) - repl_re = re.compile(r'\$(?:([A-Za-z])|\(([^\)]+)\))') + """ + + var_re = re.compile( + r"^([^=#\n\s]+)[ \t]*=[ \t]*([^#\n]*)(?:#.*)?$", flags=re.MULTILINE + ) + repl_re = re.compile(r"\$(?:([A-Za-z])|\(([^\)]+)\))") def __init__(self, maketext): super(MakeReVars, self).__init__() - self._vars = dict(self.var_re.findall(maketext.replace('\\\n', ''))) + self._vars = dict(self.var_re.findall(maketext.replace("\\\n", ""))) def replacevar(self, match): varname = match.group(1) or match.group(2) - return self._vars.get(varname, '') + return self._vars.get(varname, "") def getvars(self, varlist): for varname in varlist: diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index bd0d5b27f4..e72d2e3f36 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -25,7 +25,6 @@ %{!?with_pbrd: %global with_pbrd 1 } %{!?with_pimd: %global with_pimd 1 } %{!?with_vrrpd: %global with_vrrpd 1 } -%{!?with_rpki: %global with_rpki 0 } %{!?with_rtadv: %global with_rtadv 1 } %{!?with_watchfrr: %global with_watchfrr 1 } @@ -192,9 +191,6 @@ Requires: initscripts %if %{with_pam} BuildRequires: pam-devel %endif -%if %{with_rpki} -BuildRequires: librtr-devel >= 0.5 -%endif %if "%{initsystem}" == "systemd" BuildRequires: systemd BuildRequires: systemd-devel @@ -261,6 +257,32 @@ The frr-devel package contains the header and object files neccessary for developing OSPF-API and frr applications. +%package rpki-rtrlib +Summary: BGP RPKI support (rtrlib) +Group: System Environment/Daemons +BuildRequires: librtr-devel >= 0.5 +Requires: %{name} = %{version}-%{release} + +%description rpki-rtrlib +Adds RPKI support to FRR's bgpd, allowing validation of BGP routes +against cryptographic information stored in WHOIS databases. This is +used to prevent hijacking of networks on the wider internet. It is only +relevant to internet service providers using their own autonomous system +number. + + +%package snmp +Summary: SNMP support +Group: System Environment/Daemons +BuildRequires: net-snmp-devel +Requires: %{name} = %{version}-%{release} + +%description snmp +Adds SNMP support to FRR's daemons by attaching to net-snmp's snmpd +through the AgentX protocol. Provides read-only access to current +routing state through standard SNMP MIBs. + + %prep %setup -q -n frr-%{frrversion} @@ -370,16 +392,13 @@ developing OSPF-API and frr applications. %if "%{initsystem}" == "systemd" --enable-systemd \ %endif -%if %{with_rpki} --enable-rpki \ -%else - --disable-rpki \ -%endif %if %{with_bfdd} --enable-bfdd \ %else --disable-bfdd \ %endif + --enable-snmp # end make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" @@ -425,10 +444,6 @@ ln -s %{_sbindir}/frrinit.sh %{buildroot}%{_initddir}/frr %endif install %{zeb_src}/tools/etc/frr/daemons %{buildroot}%{_sysconfdir}/frr -# add rpki module to daemon -%if %{with_rpki} - sed -i -e 's/^\(bgpd_options=\)\(.*\)\(".*\)/\1\2 -M rpki\3/' %{buildroot}%{_sysconfdir}/frr/daemons -%endif install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr install -m644 %{zeb_rh_src}/frr.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/frr install -d -m750 %{buildroot}%{rundir} @@ -666,14 +681,12 @@ fi %if %{with_bfdd} %{_sbindir}/bfdd %endif -%{_libdir}/lib*.so.0 -%{_libdir}/lib*.so.0.* +%{_libdir}/libfrr.so* +%{_libdir}/libfrrcares* +%{_libdir}/libfrrospf* %if %{with_fpm} %{_libdir}/frr/modules/zebra_fpm.so %endif -%if %{with_rpki} - %{_libdir}/frr/modules/bgpd_rpki.so -%endif %{_libdir}/frr/modules/zebra_cumulus_mlag.so %{_libdir}/frr/modules/dplane_fpm_nl.so %{_libdir}/frr/modules/zebra_irdp.so @@ -706,12 +719,28 @@ fi %else %{_sbindir}/generate_support_bundle.pyc %{_sbindir}/generate_support_bundle.pyo -%{_sbindir}/frr-reload.py %{_sbindir}/frr-reload.pyc %{_sbindir}/frr-reload.pyo %endif +%post rpki-rtrlib +# add rpki module to daemons +sed -i -e 's/^\(bgpd_options=\)\(.*\)\(".*\)/\1\2 -M rpki\3/' %{_sysconfdir}/frr/daemons + +%postun rpki-rtrlib +# remove rpki module from daemons +sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons + +%files rpki-rtrlib +%{_libdir}/frr/modules/bgpd_rpki.so + + +%files snmp +%{_libdir}/libfrrsnmp.so* +%{_libdir}/frr/modules/*snmp.so + + %files devel %{_libdir}/lib*.so %dir %{_includedir}/%{name} @@ -729,10 +758,288 @@ fi %changelog +* Fri Oct 30 2020 Martin Winter <mwinter@opensourcerouting.org> - %{version} +- Moved RPKI to subpackage +- Added SNMP subpackage + +* Tue Jun 30 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.4 +- BGPd +- Use sequence numbers for community lists +- Fixes to nexthop groups +- Add feature to limit outgoing number of routes +- Per Neighbor Graceful Restart +- Multiple Graceful Restart fixes +- Support sub-Type-4 and sub-Type-5 for the VPNv4 SRv6 backend +- rfc7606 support: treat certain malformed routes as withdraw +- allow origin override for route aggregates +- rfc6608 support: Subcodes for BGP Finite State Machine Error +- rfc7607 support: Codification of AS 0 Processing +- rfc6286 support: Autonomous-System-Wide Unique BGP Identifier for BGP-4 +- Unequal cost multipath (a.ka. weighted ECMP) with BGP link-bandwidth +- Enable rfc8212 by default except datacenter profile +- staticd +- Add debug support +- vtysh +- Add copy command to copy config from file into running config +- LDPd +- adding support for LDP ordered label distribution control +- ISISd +- IS-IS Segment Routing support +- SHARPd +- add initial support to add/remove lsps +- Zebra +- fix broadcast address in IPv4 networks with /31 mask +- Add Graceful Restart support for Protocol Daemon restarts +- lib +- migrate route-maps to use northbound interface +- plus countless bug fixes and other improvements + +* Wed May 06 2020 David Lamparter <equinox@opensourcerouting.org> - 7.3.1 +- upstream 7.3.1 + +* Fri Feb 14 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.3 +- BGPd +- EVPN PIP Support +- Route Aggregation code speed ups +- BGP Vector I/O speed ups +- New CLI: `set distance XXX` +- New CLI: `aggregate-address A.B.C.D/M route-map WORD` +- New CLI: `bgp reject-as-sets` +- New CLI: `advertise pip ...` +- New CLI: `match evpn rd ASN:NN_OR_IP-ADDRESS:NN` +- New CLI: `show bgp l2vpn evpn community|large-community X` +- New CLI: `show bgp l2vpn evpn A.B.C.D` +- Auto-completion for clear bgp command +- Add ability to set tcp socket buffer size +- OSPFd +- Partial MPLS TE support +- PBRd +- New CLI: `set vrf unchanged|NAME` +- BFDd +- VRF Support +- New CLI: 'show bfd peers brief' +- New CLI: 'clear bfd peer ...' +- PIMd +- Significant Speedups in accessing Internal Data for higher scale +- Support for joining any-source Multicast +- Updated CLI: 'show ip pim upstream-join-desired' +- New CLI: 'show ip pim channel' +- Debug Cleanup +- MLAG experimental support +- VRRPd +- VRF Support +- Northbound Conversion- NHRPd +- LDPd +- vtysh +- New CLI: `banner motd line LINE...` +- yang +- New CLI: `show yang operational-data XPATH` +- New CLI: `debug northbound` +- Zebra +- Nexthop Group support +- New CLI: 'debug zebra nexthop [detail]' +- New CLI: 'show router-id' +- MLAG experimental support +- watchfrr +- Additional status messages of system state to systemd +- New CLI: `watchfrr ignore DAEMON` +- Others +- As always all daemons have received too many bug fixes to fully list +- There has been a significant focus on increasing test coverage +- Change in Behavior: +- ISISd +- All areas created default automatically to level-1-2 +- Zebra +- Nexthop Group Installation in Kernel is turned on by default + if the kernel supports- New CLI: 'show nexthop-group rib [singleton]' +- Man Pages +- Renamed to frr-* to remove collision with other packages + +* Fri Jan 17 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.2.1 +- BGPd +- Fix Addpath issue +- Do not apply eBGP policy for iBGP peers +- Show `ip` and `fqdn` in json output for `show [ip] bgp <route> json` +- Fix large route-distinguisher's format +- Fix `no bgp listen range ...` configuration command +- Autocomplete neighbor for clear bgp +- Reflect the distance in RIB when it is changed for an arbitrary afi/safi +- Notify "Peer De-configured" after entering 'no neighbor <neighbor> cmd +- Fix per afi/safi addpath peer counting +- Rework BGP dampening to be per AFI/SAFI +- Do not send next-hop as :: in MP_REACH_NLRI if no link-local exists +- Override peer's TTL only if peer-group is configured with TTL +- Remove error message for unkown afi/safi combination +- Keep the session down if maximum-prefix is reached +- OSPFd +- Fix BFD down not tearing down OSPF adjacency for point-to-point net +- BFDd +- Fix multiple VRF handling +- VRF security improvement +- PIMd +- Fix rp crash +- NHRPd +- Make sure `no ip nhrp map <something>` works as expected +- LDPd +- Add missing sanity check in the parsing of label messages +- Zebra +- Use correct state when installing evpn macs +- Capture dplane plugin flags +- lib +- Fix interface config when vrf changes +- Fix Interface Infinite Loop Walk (for special interfaces such as bond) +- snapcraft +- fix missing vrrpd daemon +- Others +- Rename man pages (to avoid conflicts with other packages) +- Various other fixes for code cleanup and memory leaks + * Fri Dec 27 2019 Donatas Abraitis <donatas.abraitis@gmail.com> - Add CentOS 8 support -* Mon May 28 2018 Rafael Zalamena <rzalamena@opensourcerouting.org> - %{version} +* Tue Oct 15 2019 Martin Winter <mwinter@opensourcerouting.org> - 7.2 +- ALL Daemons +- -N <namespace> to allow for config file locating when running FRR inside + of a namespace +- Impoved Testing across all daemons +- BFD +- VRF Support +- Conversion to Northbound interface +- BGP +- Aggregate-address add route-map support +- BMP Support +- Improved JSON output for many commands +- `show bgp afi safi summary failed` command +- `clear bop *` clears all peers +- Show FQDN for `show bgp ipv4 uni` commands +- Display BestPath selection reason as part of show commands +- EIGRP +- Infrastructure changes to allow VRF's +- SIGHUP signals the config reload +- Conversion to Northbound interface +- ISIS +- BFD Support +- Support for circuits with MTU > 8192 +- PBRD +- fwmark support as part of match criteria +- autocompletion of PBRMAPS +- Improved Nexthop Support +- PIMD +- PIM-BSM receive support +- Improved debugging support +- Store ECMP paths that are not currently legal for use +- Disallow igmp query from a non-connected source +- Many new cli improvements and changes +- VRRPD +- Add Support for RFC 3768 and RFC 5798 +- Route-Maps +- Add sequence numbers to access-lists +- Add `match ip next-hop type blackhole` +- Improved ability to notice dependency changes +- SHARPD +- `sharp watch [import|nexthop]` you can now specify a prefix instead + of assuming a /32 +- STATICD +- Significantly Improved NHT +- ZEBRA +- Many dataplane improvements for routes, neighbor table and EVPN +- NHT cli can now be specified per VRF and improved ability to control + NHT data being shown +- Removed duplicate processing of routes +- Improved debugablility +- RMAC and VxLan support for the FPM +- LIB +- RCU support +- Nexthop Group Improvements +- `log-filter WORD` added +- Building +- openssl support +- libcap should be used as part of build or significant slowdowns + will be experienced +- Lua builds have been fixed +- Improved Cross building + +* Mon Jun 17 2019 David Lamparter <equinox@opensourcerouting.org> - 7.1 +- gRPC northbound plugin +- "table NNN" removed from zebra +- more dataplane MT work +- EVPN in non-default VRFs +- RFC 8212 (default deny policy for eBGP) +- RFC 8106 (IPv6 RA DNS options) + +* Wed May 8 2019 Martin Winter <mwinter@opensourcerouting.org> - 7.0.1 +- bgp: +- Don't send Updates with BGP Max-Prefix Overflow +- Make sure `next-hop-self all` backward compatible with force +- Fix as-path validation in "show bgp regexp" +- Fix interface-based peers to override peergroups +- Fix removing private AS numbers if local-as is used +- Fix show bgp labeled_unicast +- Add command to lookup prefixes in rpki table +- Fix peer count in "show bgp ipv6 summary" +- Add missing ipv6 only peer flag action +- Fix address family output in "show bgp [ipv4|ipv6] neighbors" +- Add missing checks for vpnv6 nexthops +- Fix nexthop for ipv6 vpn case +- rip: Fix removal of passive interfaces +- ospf: +- Fix json timer output +- Fix milliseconds in json output +- bfd: +- Fix source port according RFC 5881, Sec 4 +- Fix IPv6 link-local peer removal +- Fix interface clean up when deleting interface +- pim: Fix interface clean up when deleting interface +- nhrp: Fix interface clean up when deleting interface +- lib: +- Workaround to get FRR building with libyang 0.x and 1.x +- Fix in priv handling +- Make priv elevation thread-safe +- zebra: +- Pseudowire event recovery +- Fix race condition in label manager +- Fix system routes selection and next-hop tracking +- Set connected route metric based on devaddr metric +- Display metric for connected routes +- Add selected fib details to json output +- Always use replace if installing new route +- watchfrr: Silently ignore declare failures (for backward compatibility) +- RPM packages: Switch to new init script + +* Thu Feb 28 2019 Martin Winter <mwinter@opensourcerouting.org> - 7.0 +- Added libyang dependency: New work for northbound interface based on libyang +- Fabricd: New Daemon based on https://datatracker.ietf.org/doc/draft-white-openfabric/ +- various bug fixes and other enhancements + +* Sun Oct 7 2018 Martin Winter <mwinter@opensourcerouting.org> - 6.0 +- Staticd: New daemon responsible for management of static routes +- ISISd: Implement dst-src routing as per draft-ietf-isis-ipv6-dst-src-routing +- BFDd: new daemon for BFD (Bidrectional Forwarding Detection). Responsible + for notifying link changes to make routing protocols converge faster. +- various bug fixes + +* Thu Jul 5 2018 Martin Winter <mwinter@opensourcerouting.org> - 5.0.1 +- Support Automake 1.16.1 +- BGPd: Support for flowspec ICMP, DSCP, packet length, fragment and tcp flags +- BGPd: fix rpki validation for ipv6 +- VRF: Workaround for kernel bug on Linux 4.14 and newer +- Zebra: Fix interface based routes from zebra not marked up +- Zebra: Fix large zebra memory usage when redistribute between protocols +- Zebra: Allow route-maps to match on source instance +- BGPd: Backport peer-attr overrides, peer-level enforce-first-as and filtered-routes fix +- BGPd: fix for crash during display of filtered-routes +- BGPd: Actually display labeled unicast routes received +- Label Manager: Fix to work correctly behind a label manager proxy + +* Thu Jun 7 2018 Martin Winter <mwinter@opensourcerouting.org> - 5.0 +- PIM: Add a Multicast Trace Command draft-ietf-idmr-traceroute-ipm-05 +- IS-IS: Implement Three-Way Handshake as per RFC5303 +- BGPD: Implement VPN-VRF route leaking per RFC4364. +- BGPD: Implement VRF with NETNS backend +- BGPD: Flowspec +- PBRD: Add a new Policy Based Routing Daemon + +* Mon May 28 2018 Rafael Zalamena <rzalamena@opensourcerouting.org> - Add BFDd support * Sun May 20 2018 Martin Winter <mwinter@opensourcerouting.org> diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 5e64b7afdb..87098ece64 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -1012,7 +1012,7 @@ DEFPY_YANG (clear_ip_rip, listnode_add(input, yang_vrf); } - ret = nb_cli_rpc("/frr-ripd:clear-rip-route", input, NULL); + ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL); list_delete(&input); diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index aab756aee9..c601ab4047 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -172,8 +172,8 @@ static void rip_request_interface_send(struct interface *ifp, uint8_t version) continue; if (IS_RIP_DEBUG_EVENT) - zlog_debug("SEND request to %s", - inet_ntoa(to.sin_addr)); + zlog_debug("SEND request to %pI4", + &to.sin_addr); rip_request_send(&to, ifp, version, connected); } @@ -468,10 +468,7 @@ static void rip_interface_clean(struct rip_interface *ri) ri->enable_interface = 0; ri->running = 0; - if (ri->t_wakeup) { - thread_cancel(ri->t_wakeup); - ri->t_wakeup = NULL; - } + thread_cancel(&ri->t_wakeup); } void rip_interfaces_clean(struct rip *rip) @@ -603,8 +600,7 @@ int rip_interface_address_add(ZAPI_CALLBACK_ARGS) if (p->family == AF_INET) { if (IS_RIP_DEBUG_ZEBRA) - zlog_debug("connected address %s/%d is added", - inet_ntoa(p->u.prefix4), p->prefixlen); + zlog_debug("connected address %pFX is added", p); rip_enable_apply(ifc->ifp); /* Check if this prefix needs to be redistributed */ @@ -653,9 +649,8 @@ int rip_interface_address_delete(ZAPI_CALLBACK_ARGS) p = ifc->address; if (p->family == AF_INET) { if (IS_RIP_DEBUG_ZEBRA) - zlog_debug("connected address %s/%d is deleted", - inet_ntoa(p->u.prefix4), - p->prefixlen); + zlog_debug("connected address %pFX is deleted", + p); hook_call(rip_ifaddr_del, ifc); @@ -1176,9 +1171,7 @@ int rip_show_network_config(struct vty *vty, struct rip *rip) for (node = route_top(rip->enable_network); node; node = route_next(node)) if (node->info) - vty_out(vty, " %s/%u\n", - inet_ntoa(node->p.u.prefix4), - node->p.prefixlen); + vty_out(vty, " %pFX\n", &node->p); /* Interface name RIP enable statement. */ for (i = 0; i < vector_active(rip->enable_interface); i++) @@ -1188,7 +1181,7 @@ int rip_show_network_config(struct vty *vty, struct rip *rip) /* RIP neighbors listing. */ for (node = route_top(rip->neighbor); node; node = route_next(node)) if (node->info) - vty_out(vty, " %s\n", inet_ntoa(node->p.u.prefix4)); + vty_out(vty, " %pI4\n", &node->p.u.prefix4); return 0; } diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c index 77c73ab398..23599f0877 100644 --- a/ripd/rip_peer.c +++ b/ripd/rip_peer.c @@ -86,8 +86,7 @@ static struct rip_peer *rip_peer_get(struct rip *rip, struct in_addr *addr) peer = rip_peer_lookup(rip, addr); if (peer) { - if (peer->t_timeout) - thread_cancel(peer->t_timeout); + thread_cancel(&peer->t_timeout); } else { peer = rip_peer_new(); peer->rip = rip; @@ -155,8 +154,8 @@ void rip_peer_display(struct vty *vty, struct rip *rip) char timebuf[RIP_UPTIME_LEN]; for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) { - vty_out(vty, " %-16s %9d %9d %9d %s\n", - inet_ntoa(peer->addr), peer->recv_badpackets, + vty_out(vty, " %-16pI4 %9d %9d %9d %s\n", + &peer->addr, peer->recv_badpackets, peer->recv_badroutes, ZEBRA_RIP_DISTANCE_DEFAULT, rip_peer_uptime(peer, timebuf, RIP_UPTIME_LEN)); } diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index e07d218860..074370dc26 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -88,18 +88,16 @@ static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp, if (IS_RIP_DEBUG_ZEBRA) { if (rip->ecmp) - zlog_debug("%s: %s/%d nexthops %d", + zlog_debug("%s: %pFX nexthops %d", (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" : "Delete from zebra", - inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen, - count); + &rp->p, count); else - zlog_debug("%s: %s/%d", + zlog_debug("%s: %pFX", (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra" - : "Delete from zebra", - inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen); + : "Delete from zebra", &rp->p); } rip->counters.route_changes++; diff --git a/ripd/ripd.c b/ripd/ripd.c index bcf73e8f89..059a0e2efd 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -45,6 +45,7 @@ #include "lib_errors.h" #include "northbound_cli.h" #include "network.h" +#include "lib/printfrr.h" #include "ripd/ripd.h" #include "ripd/rip_nb.h" @@ -337,8 +338,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, (struct prefix *)p) == FILTER_DENY) { if (IS_RIP_DEBUG_PACKET) - zlog_debug("%s/%d filtered by distribute %s", - inet_ntoa(p->prefix), p->prefixlen, + zlog_debug("%pFX filtered by distribute %s", p, inout); return -1; } @@ -348,8 +348,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, (struct prefix *)p) == PREFIX_DENY) { if (IS_RIP_DEBUG_PACKET) - zlog_debug("%s/%d filtered by prefix-list %s", - inet_ntoa(p->prefix), p->prefixlen, + zlog_debug("%pFX filtered by prefix-list %s", p, inout); return -1; } @@ -367,9 +366,8 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, == FILTER_DENY) { if (IS_RIP_DEBUG_PACKET) zlog_debug( - "%s/%d filtered by distribute %s", - inet_ntoa(p->prefix), - p->prefixlen, inout); + "%pFX filtered by distribute %s", + p, inout); return -1; } } @@ -383,9 +381,8 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, == PREFIX_DENY) { if (IS_RIP_DEBUG_PACKET) zlog_debug( - "%s/%d filtered by prefix-list %s", - inet_ntoa(p->prefix), - p->prefixlen, inout); + "%pFX filtered by prefix-list %s", + p, inout); return -1; } } @@ -470,8 +467,8 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, if (ret == RMAP_DENYMATCH) { if (IS_RIP_DEBUG_PACKET) zlog_debug( - "RIP %s/%d is filtered by route-map in", - inet_ntoa(p.prefix), p.prefixlen); + "RIP %pFX is filtered by route-map in", + &p); return; } @@ -506,8 +503,8 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, /* Check if nexthop address is myself, then do nothing. */ if (rip_nexthop_check(rip, nexthop) < 0) { if (IS_RIP_DEBUG_PACKET) - zlog_debug("Nexthop address %s is myself", - inet_ntoa(*nexthop)); + zlog_debug("Nexthop address %pI4 is myself", + nexthop); return; } @@ -834,8 +831,8 @@ static int rip_auth_simple_password(struct rte *rte, struct sockaddr_in *from, } if (IS_RIP_DEBUG_EVENT) - zlog_debug("RIPv2 simple password authentication from %s", - inet_ntoa(from->sin_addr)); + zlog_debug("RIPv2 simple password authentication from %pI4", + &from->sin_addr); ri = ifp->info; @@ -882,8 +879,8 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from, char auth_str[RIP_AUTH_MD5_SIZE] = {}; if (IS_RIP_DEBUG_EVENT) - zlog_debug("RIPv2 MD5 authentication from %s", - inet_ntoa(from->sin_addr)); + zlog_debug("RIPv2 MD5 authentication from %pI4", + &from->sin_addr); ri = ifp->info; md5 = (struct rip_md5_info *)&packet->rte; @@ -1164,8 +1161,8 @@ static void rip_response_process(struct rip_packet *packet, int size, rip->vrf->vrf_id) == NULL) { zlog_info( - "This datagram doesn't came from a valid neighbor: %s", - inet_ntoa(from->sin_addr)); + "This datagram doesn't come from a valid neighbor: %pI4", + &from->sin_addr); rip_peer_bad_packet(rip, from); return; } @@ -1194,9 +1191,9 @@ static void rip_response_process(struct rip_packet *packet, int size, if (rte->family != htons(AF_INET)) { /* Address family check. RIP only supports AF_INET. */ - zlog_info("Unsupported family %d from %s.", + zlog_info("Unsupported family %d from %pI4", ntohs(rte->family), - inet_ntoa(from->sin_addr)); + &from->sin_addr); continue; } @@ -1222,8 +1219,8 @@ static void rip_response_process(struct rip_packet *packet, int size, /* RIPv1 does not have nexthop value. */ if (packet->version == RIPv1 && rte->nexthop.s_addr != INADDR_ANY) { - zlog_info("RIPv1 packet with nexthop value %s", - inet_ntoa(rte->nexthop)); + zlog_info("RIPv1 packet with nexthop value %pI4", + &rte->nexthop); rip_peer_bad_route(rip, from); continue; } @@ -1240,8 +1237,8 @@ static void rip_response_process(struct rip_packet *packet, int size, addrval = ntohl(rte->nexthop.s_addr); if (IN_CLASSD(addrval)) { zlog_info( - "Nexthop %s is multicast address, skip this rte", - inet_ntoa(rte->nexthop)); + "Nexthop %pI4 is multicast address, skip this rte", + &rte->nexthop); continue; } @@ -1261,16 +1258,14 @@ static void rip_response_process(struct rip_packet *packet, int size, == RIP_ROUTE_RTE) { if (IS_RIP_DEBUG_EVENT) zlog_debug( - "Next hop %s is on RIP network. Set nexthop to the packet's originator", - inet_ntoa( - rte->nexthop)); + "Next hop %pI4 is on RIP network. Set nexthop to the packet's originator", + &rte->nexthop); rte->nexthop = rinfo->from; } else { if (IS_RIP_DEBUG_EVENT) zlog_debug( - "Next hop %s is not directly reachable. Treat it as 0.0.0.0", - inet_ntoa( - rte->nexthop)); + "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0", + &rte->nexthop); rte->nexthop.s_addr = INADDR_ANY; } @@ -1279,9 +1274,8 @@ static void rip_response_process(struct rip_packet *packet, int size, } else { if (IS_RIP_DEBUG_EVENT) zlog_debug( - "Next hop %s is not directly reachable. Treat it as 0.0.0.0", - inet_ntoa( - rte->nexthop)); + "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0", + &rte->nexthop); rte->nexthop.s_addr = INADDR_ANY; } } @@ -1335,8 +1329,8 @@ static void rip_response_process(struct rip_packet *packet, int size, != rte->prefix.s_addr) masklen2ip(32, &rte->mask); if (IS_RIP_DEBUG_EVENT) - zlog_debug("Subnetted route %s", - inet_ntoa(rte->prefix)); + zlog_debug("Subnetted route %pI4", + &rte->prefix); } else { if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr) @@ -1344,10 +1338,10 @@ static void rip_response_process(struct rip_packet *packet, int size, } if (IS_RIP_DEBUG_EVENT) { - zlog_debug("Resultant route %s", - inet_ntoa(rte->prefix)); - zlog_debug("Resultant mask %s", - inet_ntoa(rte->mask)); + zlog_debug("Resultant route %pI4", + &rte->prefix); + zlog_debug("Resultant mask %pI4", + &rte->mask); } } @@ -1358,8 +1352,8 @@ static void rip_response_process(struct rip_packet *packet, int size, && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)) { zlog_warn( - "RIPv2 address %s is not mask /%d applied one", - inet_ntoa(rte->prefix), ip_masklen(rte->mask)); + "RIPv2 address %pI4 is not mask /%d applied one", + &rte->prefix, ip_masklen(rte->mask)); rip_peer_bad_route(rip, from); continue; } @@ -1422,8 +1416,8 @@ int rip_create_socket(struct vrf *vrf) frr_with_privs(&ripd_privs) { if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) { - zlog_err("%s: Can't bind socket %d to %s port %d: %s", - __func__, sock, inet_ntoa(addr.sin_addr), + zlog_err("%s: Can't bind socket %d to %pI4 port %d: %s", + __func__, sock, &addr.sin_addr, (int)ntohs(addr.sin_port), safe_strerror(errno)); @@ -1463,14 +1457,14 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to, char dst[ADDRESS_SIZE]; if (to) { - strlcpy(dst, inet_ntoa(to->sin_addr), sizeof(dst)); + inet_ntop(AF_INET, &to->sin_addr, dst, sizeof(dst)); } else { sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP); - strlcpy(dst, inet_ntoa(sin.sin_addr), sizeof(dst)); + inet_ntop(AF_INET, &sin.sin_addr, dst, sizeof(dst)); } #undef ADDRESS_SIZE - zlog_debug("rip_send_packet %s > %s (%s)", - inet_ntoa(ifc->address->u.prefix4), dst, + zlog_debug("rip_send_packet %pI4 > %s (%s)", + &ifc->address->u.prefix4, dst, ifc->ifp->name); } @@ -1537,7 +1531,7 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to, ret = sendmsg(rip->sock, &msg, 0); if (IS_RIP_DEBUG_EVENT) - zlog_debug("SEND to %s.%d", inet_ntoa(sin.sin_addr), + zlog_debug("SEND to %pI4%d", &sin.sin_addr, ntohs(sin.sin_port)); if (ret < 0) @@ -1603,8 +1597,7 @@ void rip_redistribute_add(struct rip *rip, int type, int sub_type, (void)rip_ecmp_add(rip, &newinfo); if (IS_RIP_DEBUG_EVENT) { - zlog_debug("Redistribute new prefix %s/%d", - inet_ntoa(p->prefix), p->prefixlen); + zlog_debug("Redistribute new prefix %pFX", p); } rip_event(rip, RIP_TRIGGERED_UPDATE, 0); @@ -1641,9 +1634,8 @@ void rip_redistribute_delete(struct rip *rip, int type, int sub_type, if (IS_RIP_DEBUG_EVENT) zlog_debug( - "Poison %s/%d on the interface %s with an infinity metric [delete]", - inet_ntoa(p->prefix), - p->prefixlen, + "Poison %pFX on the interface %s with an infinity metric [delete]", + p, ifindex2ifname( ifindex, rip->vrf->vrf_id)); @@ -1788,15 +1780,15 @@ static int rip_read(struct thread *t) /* RIP packet received */ if (IS_RIP_DEBUG_EVENT) - zlog_debug("RECV packet from %s port %d on %s (VRF %s)", - inet_ntoa(from.sin_addr), ntohs(from.sin_port), + zlog_debug("RECV packet from %pI4 port %d on %s (VRF %s)", + &from.sin_addr, ntohs(from.sin_port), ifp ? ifp->name : "unknown", rip->vrf_name); /* If this packet come from unknown interface, ignore it. */ if (ifp == NULL) { zlog_info( - "rip_read: cannot find interface for packet from %s port %d (VRF %s)", - inet_ntoa(from.sin_addr), ntohs(from.sin_port), + "rip_read: cannot find interface for packet from %pI4 port %d (VRF %s)", + &from.sin_addr, ntohs(from.sin_port), rip->vrf_name); return -1; } @@ -1809,8 +1801,8 @@ static int rip_read(struct thread *t) if (ifc == NULL) { zlog_info( - "rip_read: cannot find connected address for packet from %s port %d on interface %s (VRF %s)", - inet_ntoa(from.sin_addr), ntohs(from.sin_port), + "rip_read: cannot find connected address for packet from %pI4 port %d on interface %s (VRF %s)", + &from.sin_addr, ntohs(from.sin_port), ifp->name, rip->vrf_name); return -1; } @@ -2083,8 +2075,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, /* Logging output event. */ if (IS_RIP_DEBUG_EVENT) { if (to) - zlog_debug("update routes to neighbor %s", - inet_ntoa(to->sin_addr)); + zlog_debug("update routes to neighbor %pI4", + &to->sin_addr); else zlog_debug("update routes on interface %s ifindex %d", ifc->ifp->name, ifc->ifp->ifindex); @@ -2149,9 +2141,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, if (IS_RIP_DEBUG_PACKET) zlog_debug( - "RIPv1 mask check, %s/%d considered for output", - inet_ntoa(rp->p.u.prefix4), - rp->p.prefixlen); + "RIPv1 mask check, %pFX considered for output", + &rp->p); if (subnetted && prefix_match( @@ -2172,9 +2163,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, } if (IS_RIP_DEBUG_PACKET) zlog_debug( - "RIPv1 mask check, %s/%d made it through", - inet_ntoa(rp->p.u.prefix4), - rp->p.prefixlen); + "RIPv1 mask check, %pFX made it through", + &rp->p); } else p = (struct prefix_ipv4 *)&rp->p; @@ -2266,9 +2256,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, if (ret == RMAP_DENYMATCH) { if (IS_RIP_DEBUG_PACKET) zlog_debug( - "RIP %s/%d is filtered by route-map out", - inet_ntoa(p->prefix), - p->prefixlen); + "RIP %pFX is filtered by route-map out", + p); continue; } } @@ -2283,9 +2272,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, if (ret == RMAP_DENYMATCH) { if (IS_RIP_DEBUG_PACKET) zlog_debug( - "%s/%d is filtered by route-map", - inet_ntoa(p->prefix), - p->prefixlen); + "%pFX is filtered by route-map", + p); continue; } } @@ -2460,10 +2448,10 @@ static void rip_update_interface(struct connected *ifc, uint8_t version, to.sin_port = htons(RIP_PORT_DEFAULT); if (IS_RIP_DEBUG_EVENT) - zlog_debug("%s announce to %s on %s", + zlog_debug("%s announce to %pI4 on %s", CONNECTED_PEER(ifc) ? "unicast" : "broadcast", - inet_ntoa(to.sin_addr), ifp->name); + &to.sin_addr, ifp->name); rip_output_process(ifc, &to, route_type, version); } @@ -2538,8 +2526,8 @@ static void rip_update_process(struct rip *rip, int route_type) rip->vrf->vrf_id); if (!connected) { zlog_warn( - "Neighbor %s doesn't have connected interface!", - inet_ntoa(p->u.prefix4)); + "Neighbor %pI4 doesn't have connected interface!", + &p->u.prefix4); continue; } @@ -2674,9 +2662,8 @@ void rip_redistribute_withdraw(struct rip *rip, int type) (struct prefix_ipv4 *)&rp->p; zlog_debug( - "Poisone %s/%d on the interface %s with an infinity metric [withdraw]", - inet_ntoa(p->prefix), - p->prefixlen, + "Poisone %pFX on the interface %s with an infinity metric [withdraw]", + p, ifindex2ifname( rinfo->nh.ifindex, rip->vrf->vrf_id)); @@ -2966,8 +2953,7 @@ static void rip_distance_show(struct vty *vty, struct rip *rip) " Address Distance List\n"); header = 0; } - snprintf(buf, sizeof(buf), "%s/%d", - inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); + snprintfrr(buf, sizeof(buf), "%pFX", &rn->p); vty_out(vty, " %-20s %4d %s\n", buf, rdistance->distance, rdistance->access_list ? rdistance->access_list @@ -3094,12 +3080,11 @@ DEFUN (show_ip_rip, int len; len = vty_out( - vty, "%c(%s) %s/%d", + vty, "%c(%s) %pFX", /* np->lock, For debugging. */ zebra_route_char(rinfo->type), rip_route_type_print(rinfo->sub_type), - inet_ntoa(np->p.u.prefix4), - np->p.prefixlen); + &np->p); len = 24 - len; @@ -3109,8 +3094,8 @@ DEFUN (show_ip_rip, switch (rinfo->nh.type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, "%-20s %2d ", - inet_ntoa(rinfo->nh.gate.ipv4), + vty_out(vty, "%-20pI4 %2d ", + &rinfo->nh.gate.ipv4, rinfo->metric); break; case NEXTHOP_TYPE_IFINDEX: @@ -3134,8 +3119,8 @@ DEFUN (show_ip_rip, /* Route which exist in kernel routing table. */ if ((rinfo->type == ZEBRA_ROUTE_RIP) && (rinfo->sub_type == RIP_ROUTE_RTE)) { - vty_out(vty, "%-15s ", - inet_ntoa(rinfo->from)); + vty_out(vty, "%-15pI4 ", + &rinfo->from); vty_out(vty, "%3" ROUTE_TAG_PRI " ", (route_tag_t)rinfo->tag); rip_vty_out_uptime(vty, rinfo); @@ -3422,6 +3407,8 @@ static void rip_distribute_update_all_wrapper(struct access_list *notused) /* Delete all added rip route. */ void rip_clean(struct rip *rip) { + rip_interfaces_clean(rip); + if (rip->enabled) rip_instance_disable(rip); @@ -3443,7 +3430,6 @@ void rip_clean(struct rip *rip) route_table_finish(rip->enable_network); vector_free(rip->passive_nondefault); list_delete(&rip->offset_list_master); - rip_interfaces_clean(rip); route_table_finish(rip->distance_table); RB_REMOVE(rip_instance_head, &rip_instances, rip); @@ -3610,7 +3596,7 @@ static void rip_instance_disable(struct rip *rip) RIP_TIMER_OFF(rip->t_triggered_interval); /* Cancel read thread. */ - THREAD_READ_OFF(rip->t_read); + thread_cancel(&rip->t_read); /* Close RIP socket. */ close(rip->sock); diff --git a/ripd/ripd.h b/ripd/ripd.h index 417bd5b3b1..99718f7b9e 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -405,7 +405,7 @@ enum rip_event { #define RIP_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T)) /* Macro for timer turn off. */ -#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X) +#define RIP_TIMER_OFF(X) thread_cancel(&(X)) #define RIP_OFFSET_LIST_IN 0 #define RIP_OFFSET_LIST_OUT 1 diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index f66de175fa..365082f806 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -496,7 +496,7 @@ DEFPY_YANG (clear_ipv6_rip, listnode_add(input, yang_vrf); } - ret = nb_cli_rpc("/frr-ripngd:clear-ripng-route", input, NULL); + ret = nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", input, NULL); list_delete(&input); diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c index 54edb17ecc..539c01b3ec 100644 --- a/ripngd/ripng_debug.c +++ b/ripngd/ripng_debug.c @@ -218,7 +218,7 @@ void ripng_debug_init(void) install_node(&debug_node); - install_element(VIEW_NODE, &show_debugging_ripng_cmd); + install_element(ENABLE_NODE, &show_debugging_ripng_cmd); install_element(ENABLE_NODE, &debug_ripng_events_cmd); install_element(ENABLE_NODE, &debug_ripng_packet_cmd); diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index 03c93668b9..115d7a6b99 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -321,10 +321,7 @@ void ripng_interface_clean(struct ripng *ripng) ri->enable_interface = 0; ri->running = 0; - if (ri->t_wakeup) { - thread_cancel(ri->t_wakeup); - ri->t_wakeup = NULL; - } + thread_cancel(&ri->t_wakeup); } } @@ -375,8 +372,7 @@ int ripng_interface_address_add(ZAPI_CALLBACK_ARGS) struct ripng_interface *ri = c->ifp->info; if (IS_RIPNG_DEBUG_ZEBRA) - zlog_debug("RIPng connected address %s/%d add", - inet6_ntoa(p->u.prefix6), p->prefixlen); + zlog_debug("RIPng connected address %pFX add", p); /* Check is this prefix needs to be redistributed. */ ripng_apply_address_add(c); @@ -428,7 +424,6 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS) { struct connected *ifc; struct prefix *p; - char buf[INET6_ADDRSTRLEN]; ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf, vrf_id); @@ -439,10 +434,8 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS) if (p->family == AF_INET6) { if (IS_RIPNG_DEBUG_ZEBRA) zlog_debug( - "RIPng connected address %s/%d delete", - inet_ntop(AF_INET6, &p->u.prefix6, buf, - INET6_ADDRSTRLEN), - p->prefixlen); + "RIPng connected address %pFX delete", + p); /* Check wether this prefix needs to be removed. */ ripng_apply_address_del(ifc); diff --git a/ripngd/ripng_nb_config.c b/ripngd/ripng_nb_config.c index 85f378bc9e..25bf65f7aa 100644 --- a/ripngd/ripng_nb_config.c +++ b/ripngd/ripng_nb_config.c @@ -163,7 +163,7 @@ int ripngd_instance_default_information_originate_modify( ripng = nb_running_get_entry(args->dnode, NULL, true); default_information = yang_dnode_get_bool(args->dnode, NULL); - str2prefix_ipv6("::/0", &p); + (void)str2prefix_ipv6("::/0", &p); if (default_information) { ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_DEFAULT, &p, 0, NULL, 0); diff --git a/ripngd/ripng_peer.c b/ripngd/ripng_peer.c index e6ff58dd0c..0ac489c67e 100644 --- a/ripngd/ripng_peer.c +++ b/ripngd/ripng_peer.c @@ -95,8 +95,7 @@ static struct ripng_peer *ripng_peer_get(struct ripng *ripng, peer = ripng_peer_lookup(ripng, addr); if (peer) { - if (peer->t_timeout) - thread_cancel(peer->t_timeout); + thread_cancel(&peer->t_timeout); } else { peer = ripng_peer_new(); peer->ripng = ripng; @@ -105,7 +104,6 @@ static struct ripng_peer *ripng_peer_get(struct ripng *ripng, } /* Update timeout thread. */ - peer->t_timeout = NULL; thread_add_timer(master, ripng_peer_timeout, peer, RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout); diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 8a7950daf4..8d9249e4ae 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -643,8 +643,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p, (struct prefix *)p) == FILTER_DENY) { if (IS_RIPNG_DEBUG_PACKET) - zlog_debug("%s/%d filtered by distribute %s", - inet6_ntoa(p->prefix), p->prefixlen, + zlog_debug("%pFX filtered by distribute %s", p, inout); return -1; } @@ -654,8 +653,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p, (struct prefix *)p) == PREFIX_DENY) { if (IS_RIPNG_DEBUG_PACKET) - zlog_debug("%s/%d filtered by prefix-list %s", - inet6_ntoa(p->prefix), p->prefixlen, + zlog_debug("%pFX filtered by prefix-list %s", p, inout); return -1; } @@ -673,9 +671,8 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p, == FILTER_DENY) { if (IS_RIPNG_DEBUG_PACKET) zlog_debug( - "%s/%d filtered by distribute %s", - inet6_ntoa(p->prefix), - p->prefixlen, inout); + "%pFX filtered by distribute %s", + p, inout); return -1; } } @@ -689,9 +686,8 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p, == PREFIX_DENY) { if (IS_RIPNG_DEBUG_PACKET) zlog_debug( - "%s/%d filtered by prefix-list %s", - inet6_ntoa(p->prefix), - p->prefixlen, inout); + "%pFX filtered by prefix-list %s", + p, inout); return -1; } } @@ -997,14 +993,12 @@ void ripng_redistribute_add(struct ripng *ripng, int type, int sub_type, if (IS_RIPNG_DEBUG_EVENT) { if (!nexthop) zlog_debug( - "Redistribute new prefix %s/%d on the interface %s", - inet6_ntoa(p->prefix), p->prefixlen, - ifindex2ifname(ifindex, ripng->vrf->vrf_id)); + "Redistribute new prefix %pFX on the interface %s", + p, ifindex2ifname(ifindex, ripng->vrf->vrf_id)); else zlog_debug( - "Redistribute new prefix %s/%d with nexthop %s on the interface %s", - inet6_ntoa(p->prefix), p->prefixlen, - inet6_ntoa(*nexthop), + "Redistribute new prefix %pFX with nexthop %s on the interface %s", + p, inet6_ntoa(*nexthop), ifindex2ifname(ifindex, ripng->vrf->vrf_id)); } @@ -1047,9 +1041,8 @@ void ripng_redistribute_delete(struct ripng *ripng, int type, int sub_type, if (IS_RIPNG_DEBUG_EVENT) zlog_debug( - "Poisone %s/%d on the interface %s with an infinity metric [delete]", - inet6_ntoa(p->prefix), - p->prefixlen, + "Poisone %pFX on the interface %s with an infinity metric [delete]", + p, ifindex2ifname( ifindex, ripng->vrf->vrf_id)); @@ -1091,9 +1084,8 @@ void ripng_redistribute_withdraw(struct ripng *ripng, int type) agg_node_get_prefix(rp); zlog_debug( - "Poisone %s/%d on the interface %s [withdraw]", - inet6_ntoa(p->prefix), - p->prefixlen, + "Poisone %pFX on the interface %s [withdraw]", + p, ifindex2ifname( rinfo->ifindex, ripng->vrf->vrf_id)); @@ -1471,10 +1463,7 @@ static int ripng_update(struct thread *t) /* Triggered updates may be suppressed if a regular update is due by the time the triggered update would be sent. */ - if (ripng->t_triggered_interval) { - thread_cancel(ripng->t_triggered_interval); - ripng->t_triggered_interval = NULL; - } + thread_cancel(&ripng->t_triggered_interval); ripng->trigger = 0; /* Reset flush event. */ @@ -1508,10 +1497,7 @@ int ripng_triggered_update(struct thread *t) ripng->t_triggered_update = NULL; /* Cancel interval timer. */ - if (ripng->t_triggered_interval) { - thread_cancel(ripng->t_triggered_interval); - ripng->t_triggered_interval = NULL; - } + thread_cancel(&ripng->t_triggered_interval); ripng->trigger = 0; /* Logging triggered update. */ @@ -1680,9 +1666,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, if (ret == RMAP_DENYMATCH) { if (IS_RIPNG_DEBUG_PACKET) zlog_debug( - "RIPng %s/%d is filtered by route-map out", - inet6_ntoa(p->prefix), - p->prefixlen); + "RIPng %pFX is filtered by route-map out", + p); continue; } } @@ -1697,9 +1682,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, if (ret == RMAP_DENYMATCH) { if (IS_RIPNG_DEBUG_PACKET) zlog_debug( - "RIPng %s/%d is filtered by route-map", - inet6_ntoa(p->prefix), - p->prefixlen); + "RIPng %pFX is filtered by route-map", + p); continue; } } @@ -1795,9 +1779,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, if (ret == RMAP_DENYMATCH) { if (IS_RIPNG_DEBUG_PACKET) zlog_debug( - "RIPng %s/%d is filtered by route-map out", - inet6_ntoa(p->prefix), - p->prefixlen); + "RIPng %pFX is filtered by route-map out", + p); continue; } @@ -1963,10 +1946,8 @@ void ripng_event(struct ripng *ripng, enum ripng_event event, int sock) &ripng->t_read); break; case RIPNG_UPDATE_EVENT: - if (ripng->t_update) { - thread_cancel(ripng->t_update); - ripng->t_update = NULL; - } + thread_cancel(&ripng->t_update); + /* Update timer jitter. */ jitter = ripng_update_jitter(ripng->update_time); @@ -2533,6 +2514,8 @@ static void ripng_distribute_update_all_wrapper(struct access_list *notused) /* delete all the added ripng routes. */ void ripng_clean(struct ripng *ripng) { + ripng_interface_clean(ripng); + if (ripng->enabled) ripng_instance_disable(ripng); @@ -2554,7 +2537,6 @@ void ripng_clean(struct ripng *ripng) agg_table_finish(ripng->enable_network); vector_free(ripng->passive_interface); list_delete(&ripng->offset_list_master); - ripng_interface_clean(ripng); RB_REMOVE(ripng_instance_head, &ripng_instances, ripng); XFREE(MTYPE_RIPNG_VRF_NAME, ripng->vrf_name); @@ -2729,10 +2711,7 @@ static void ripng_instance_disable(struct ripng *ripng) RIPNG_TIMER_OFF(ripng->t_triggered_interval); /* Cancel the read thread */ - if (ripng->t_read) { - thread_cancel(ripng->t_read); - ripng->t_read = NULL; - } + thread_cancel(&ripng->t_read); /* Close the RIPng socket */ if (ripng->sock >= 0) { diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 70508d5cb0..a42c32ebb7 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -351,13 +351,7 @@ enum ripng_event { /* RIPng timer on/off macro. */ #define RIPNG_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T)) -#define RIPNG_TIMER_OFF(T) \ - do { \ - if (T) { \ - thread_cancel(T); \ - (T) = NULL; \ - } \ - } while (0) +#define RIPNG_TIMER_OFF(T) thread_cancel(&(T)) #define RIPNG_OFFSET_LIST_IN 0 #define RIPNG_OFFSET_LIST_OUT 1 diff --git a/sharpd/sharp_nht.c b/sharpd/sharp_nht.c index 7484dd3b06..bed0ebfa27 100644 --- a/sharpd/sharp_nht.c +++ b/sharpd/sharp_nht.c @@ -60,14 +60,9 @@ void sharp_nh_tracker_dump(struct vty *vty) struct listnode *node; struct sharp_nh_tracker *nht; - for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) { - char buf[PREFIX_STRLEN]; - - vty_out(vty, "%s: Nexthops: %u Updates: %u\n", - prefix2str(&nht->p, buf, sizeof(buf)), - nht->nhop_num, - nht->updates); - } + for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) + vty_out(vty, "%pFX: Nexthops: %u Updates: %u\n", &nht->p, + nht->nhop_num, nht->updates); } PREDECL_RBTREE_UNIQ(sharp_nhg_rb); @@ -77,7 +72,8 @@ struct sharp_nhg { uint32_t id; - char name[256]; +#define NHG_NAME_LEN 256 + char name[NHG_NAME_LEN]; bool installed; }; @@ -95,7 +91,7 @@ struct sharp_nhg_rb_head nhg_head; static int sharp_nhg_compare_func(const struct sharp_nhg *a, const struct sharp_nhg *b) { - return strncmp(a->name, b->name, strlen(a->name)); + return strncmp(a->name, b->name, NHG_NAME_LEN); } DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem, diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index d062f027ab..45c0799fa7 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -146,16 +146,12 @@ DEFPY (install_routes_data_dump, "Data about what is going on\n" "Route Install/Removal Information\n") { - char buf[PREFIX_STRLEN]; struct timeval r; timersub(&sg.r.t_end, &sg.r.t_start, &r); - vty_out(vty, "Prefix: %s Total: %u %u %u Time: %jd.%ld\n", - prefix2str(&sg.r.orig_prefix, buf, sizeof(buf)), - sg.r.total_routes, - sg.r.installed_routes, - sg.r.removed_routes, - (intmax_t)r.tv_sec, (long)r.tv_usec); + vty_out(vty, "Prefix: %pFX Total: %u %u %u Time: %jd.%ld\n", + &sg.r.orig_prefix, sg.r.total_routes, sg.r.installed_routes, + sg.r.removed_routes, (intmax_t)r.tv_sec, (long)r.tv_usec); return CMD_SUCCESS; } @@ -716,7 +712,7 @@ void sharp_vty_init(void) install_element(ENABLE_NODE, &send_opaque_reg_cmd); install_element(ENABLE_NODE, &neigh_discover_cmd); - install_element(VIEW_NODE, &show_debugging_sharpd_cmd); + install_element(ENABLE_NODE, &show_debugging_sharpd_cmd); return; } diff --git a/staticd/static_routes.c b/staticd/static_routes.c index d6aab296c9..d105b2123f 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -283,6 +283,7 @@ static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi, break; case STATIC_BLACKHOLE: + nh->bh_type = STATIC_BLACKHOLE_NULL; break; case STATIC_IFNAME: ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id); diff --git a/staticd/static_vty.c b/staticd/static_vty.c index f5bc9df649..c3c453f42d 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -365,8 +365,7 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi, switch (nh->type) { case STATIC_IPV4_GATEWAY: - vty_out(vty, " %s", - inet_ntoa(nh->addr.ipv4)); + vty_out(vty, " %pI4", &nh->addr.ipv4); break; case STATIC_IPV6_GATEWAY: vty_out(vty, " %s", @@ -500,12 +499,6 @@ DEFPY_YANG(ip_route_blackhole, "Table to configure\n" "The table number to configure\n") { - if (table_str && vrf && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, NULL, NULL, flag, tag_str, distance_str, vrf, label, table_str); @@ -819,12 +812,6 @@ DEFPY_YANG(ipv6_route_blackhole, "Table to configure\n" "The table number to configure\n") { - if (table_str && vrf && !vrf_is_backend_netns()) { - vty_out(vty, - "%% table param only available when running on netns-based vrfs\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, NULL, NULL, flag, tag_str, distance_str, vrf, label, table_str); @@ -1167,7 +1154,7 @@ void static_vty_init(void) install_element(CONFIG_NODE, &ipv6_route_cmd); install_element(VRF_NODE, &ipv6_route_vrf_cmd); - install_element(VIEW_NODE, &show_debugging_static_cmd); - install_element(VIEW_NODE, &debug_staticd_cmd); + install_element(ENABLE_NODE, &show_debugging_static_cmd); + install_element(ENABLE_NODE, &debug_staticd_cmd); install_element(CONFIG_NODE, &debug_staticd_cmd); } diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index efde3babd1..a9b570de83 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -109,24 +109,21 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS) struct prefix p; enum zapi_route_notify_owner note; uint32_t table_id; - char buf[PREFIX_STRLEN]; if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, ¬e)) return -1; - prefix2str(&p, buf, sizeof(buf)); - switch (note) { case ZAPI_ROUTE_FAIL_INSTALL: static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED); - zlog_warn("%s: Route %s failed to install for table: %u", - __func__, buf, table_id); + zlog_warn("%s: Route %pFX failed to install for table: %u", + __func__, &p, table_id); break; case ZAPI_ROUTE_BETTER_ADMIN_WON: static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED); zlog_warn( - "%s: Route %s over-ridden by better route for table: %u", - __func__, buf, table_id); + "%s: Route %pFX over-ridden by better route for table: %u", + __func__, &p, table_id); break; case ZAPI_ROUTE_INSTALLED: static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED); @@ -136,8 +133,8 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS) break; case ZAPI_ROUTE_REMOVE_FAIL: static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED); - zlog_warn("%s: Route %s failure to remove for table: %u", - __func__, buf, table_id); + zlog_warn("%s: Route %pFX failure to remove for table: %u", + __func__, &p, table_id); break; } diff --git a/tests/bgpd/test_aspath.py b/tests/bgpd/test_aspath.py index 5fa1f11629..88579ad3e4 100644 --- a/tests/bgpd/test_aspath.py +++ b/tests/bgpd/test_aspath.py @@ -1,14 +1,16 @@ import frrtest import re -re_okfail = re.compile(r'^(?:\x1b\[3[12]m)?(?P<ret>OK|failed)'.encode('utf8'), - re.MULTILINE) +re_okfail = re.compile( + r"^(?:\x1b\[3[12]m)?(?P<ret>OK|failed)".encode("utf8"), re.MULTILINE +) + class TestAspath(frrtest.TestMultiOut): - program = './test_aspath' + program = "./test_aspath" def _parsertest(self, line): - if not hasattr(self, 'parserno'): + if not hasattr(self, "parserno"): self.parserno = -1 self.parserno += 1 @@ -17,13 +19,14 @@ class TestAspath(frrtest.TestMultiOut): self._okfail("empty prepend %s:" % line, okfail=re_okfail) def _attrtest(self, line): - if not hasattr(self, 'attrno'): + if not hasattr(self, "attrno"): self.attrno = -1 self.attrno += 1 self._onesimple("aspath_attr test %d" % self.attrno) self._okfail(line, okfail=re_okfail) + TestAspath.parsertest("seq1") TestAspath.parsertest("seq2") TestAspath.parsertest("seq3") diff --git a/tests/bgpd/test_bgp_table.c b/tests/bgpd/test_bgp_table.c index 4eb132df55..e899e5b359 100644 --- a/tests/bgpd/test_bgp_table.c +++ b/tests/bgpd/test_bgp_table.c @@ -109,10 +109,7 @@ static void check_lookup_result(struct bgp_dest *match, va_list arglist) if (bgp_dest_has_bgp_path_info_data(dest) && !prefix_in_array(dest_p, prefixes, prefix_count)) { - char buf[PREFIX2STR_BUFFER]; - - prefix2str(dest_p, buf, PREFIX2STR_BUFFER); - printf("prefix %s was not expected!\n", buf); + printf("prefix %pFX was not expected!\n", dest_p); assert(0); } } diff --git a/tests/bgpd/test_bgp_table.py b/tests/bgpd/test_bgp_table.py index 53bd37233a..8f0544249c 100644 --- a/tests/bgpd/test_bgp_table.py +++ b/tests/bgpd/test_bgp_table.py @@ -1,7 +1,9 @@ import frrtest + class TestTable(frrtest.TestMultiOut): - program = './test_bgp_table' + program = "./test_bgp_table" + for i in range(7): - TestTable.onesimple('Checks successfull') + TestTable.onesimple("Checks successfull") diff --git a/tests/bgpd/test_capability.py b/tests/bgpd/test_capability.py index 872fcb6d12..e275195537 100644 --- a/tests/bgpd/test_capability.py +++ b/tests/bgpd/test_capability.py @@ -1,7 +1,9 @@ import frrtest + class TestCapability(frrtest.TestMultiOut): - program = './test_capability' + program = "./test_capability" + TestCapability.okfail("MP4: MP IP/Uni") TestCapability.okfail("MPv6: MP IPv6/Uni") @@ -43,5 +45,9 @@ TestCapability.okfail("AS4real2: AS4 capability, in series of capabilities") TestCapability.okfail("DynCap: Dynamic Capability Message, IP/Multicast") TestCapability.okfail("DynCapLong: Dynamic Capability Message, IP/Multicast, truncated") TestCapability.okfail("DynCapPadded: Dynamic Capability Message, IP/Multicast, padded") -TestCapability.okfail("DynCapMPCpadded: Dynamic Capability Message, IP/Multicast, cap data padded") -TestCapability.okfail("DynCapMPCoverflow: Dynamic Capability Message, IP/Multicast, cap data != length") +TestCapability.okfail( + "DynCapMPCpadded: Dynamic Capability Message, IP/Multicast, cap data padded" +) +TestCapability.okfail( + "DynCapMPCoverflow: Dynamic Capability Message, IP/Multicast, cap data != length" +) diff --git a/tests/bgpd/test_ecommunity.py b/tests/bgpd/test_ecommunity.py index 3a17ec9e31..1499294f7b 100644 --- a/tests/bgpd/test_ecommunity.py +++ b/tests/bgpd/test_ecommunity.py @@ -1,9 +1,11 @@ import frrtest + class TestEcommunity(frrtest.TestMultiOut): - program = './test_ecommunity' + program = "./test_ecommunity" + -TestEcommunity.okfail('ipaddr') -TestEcommunity.okfail('ipaddr-so') -TestEcommunity.okfail('asn') -TestEcommunity.okfail('asn4') +TestEcommunity.okfail("ipaddr") +TestEcommunity.okfail("ipaddr-so") +TestEcommunity.okfail("asn") +TestEcommunity.okfail("asn4") diff --git a/tests/bgpd/test_mp_attr.py b/tests/bgpd/test_mp_attr.py index 46d0c42402..d9612bb8d3 100644 --- a/tests/bgpd/test_mp_attr.py +++ b/tests/bgpd/test_mp_attr.py @@ -1,7 +1,9 @@ import frrtest + class TestMpAttr(frrtest.TestMultiOut): - program = './test_mp_attr' + program = "./test_mp_attr" + TestMpAttr.okfail("IPv6: IPV6 MP Reach, global nexthop, 1 NLRI") TestMpAttr.okfail("IPv6-2: IPV6 MP Reach, global nexthop, 2 NLRIs") @@ -16,13 +18,27 @@ TestMpAttr.okfail("IPv4: IPv4 MP Reach, 2 NLRIs + default") TestMpAttr.okfail("IPv4-nhlen: IPv4 MP Reach, nexthop lenth overflow") TestMpAttr.okfail("IPv4-nlrilen: IPv4 MP Reach, nlri lenth overflow") TestMpAttr.okfail("IPv4-VPNv4: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs") -TestMpAttr.okfail("IPv4-VPNv4-bogus-plen: IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len") -TestMpAttr.okfail("IPv4-VPNv4-plen1-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short") -TestMpAttr.okfail("IPv4-VPNv4-plen1-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long") -TestMpAttr.okfail("IPv4-VPNv4-plenn-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long") -TestMpAttr.okfail("IPv4-VPNv4-plenn-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short") -TestMpAttr.okfail("IPv4-VPNv4-bogus-rd-type: IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)") -TestMpAttr.okfail("IPv4-VPNv4-0-nlri: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus") +TestMpAttr.okfail( + "IPv4-VPNv4-bogus-plen: IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len" +) +TestMpAttr.okfail( + "IPv4-VPNv4-plen1-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short" +) +TestMpAttr.okfail( + "IPv4-VPNv4-plen1-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long" +) +TestMpAttr.okfail( + "IPv4-VPNv4-plenn-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long" +) +TestMpAttr.okfail( + "IPv4-VPNv4-plenn-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short" +) +TestMpAttr.okfail( + "IPv4-VPNv4-bogus-rd-type: IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)" +) +TestMpAttr.okfail( + "IPv4-VPNv4-0-nlri: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus" +) TestMpAttr.okfail("IPv6-bug: IPv6, global nexthop, 1 default NLRI") TestMpAttr.okfail("IPv6-unreach: IPV6 MP Unreach, 1 NLRI") TestMpAttr.okfail("IPv6-unreach2: IPV6 MP Unreach, 2 NLRIs") diff --git a/tests/bgpd/test_mpath.py b/tests/bgpd/test_mpath.py index ce34ff8436..582fd25c20 100644 --- a/tests/bgpd/test_mpath.py +++ b/tests/bgpd/test_mpath.py @@ -1,9 +1,10 @@ import frrtest + class TestMpath(frrtest.TestMultiOut): - program = './test_mpath' + program = "./test_mpath" + TestMpath.okfail("bgp maximum-paths config") TestMpath.okfail("bgp_mp_list") TestMpath.okfail("bgp_path_info_mpath_update") - diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index 0979622eb3..0a15886c10 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -30,6 +30,8 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_network.h" +#include "lib/routing_nb.h" +#include "bgpd/bgp_nb.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -932,7 +934,7 @@ static struct test *test_new(const char *desc, bool use_ibgp, test->vty = vty_new(); test->vty->type = VTY_TERM; - test->vty->node = CONFIG_NODE; + vty_config_enter(test->vty, true, false); test_initialize(test); @@ -1378,6 +1380,15 @@ static void test_peer_attr(struct test *test, struct test_peer_attr *pa) test_process(test, pa, p, g->conf, true, false); } +static const struct frr_yang_module_info *const bgpd_yang_modules[] = { + &frr_bgp_info, + &frr_filter_info, + &frr_interface_info, + &frr_route_map_info, + &frr_routing_info, + &frr_vrf_info, +}; + static void bgp_startup(void) { cmd_init(1); @@ -1387,7 +1398,7 @@ static void bgp_startup(void) master = thread_master_create(NULL); yang_init(true); - nb_init(master, NULL, 0, false); + nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE); bgp_option_set(BGP_OPT_NO_LISTEN); vrf_init(NULL, NULL, NULL, NULL, NULL); diff --git a/tests/bgpd/test_peer_attr.py b/tests/bgpd/test_peer_attr.py index 44068605ee..16b441b25d 100644 --- a/tests/bgpd/test_peer_attr.py +++ b/tests/bgpd/test_peer_attr.py @@ -1,196 +1,198 @@ import frrtest + class TestFlag(frrtest.TestMultiOut): - program = './test_peer_attr' + program = "./test_peer_attr" + # List of tests can be generated by executing: # $> ./test_peer_attr 2>&1 | sed -n 's/\\/\\\\/g; s/\S\+ \[test\] \(.\+\)/TestFlag.okfail(\x27\1\x27)/pg' # -TestFlag.okfail('peer\\advertisement-interval') -TestFlag.okfail('peer\\capability dynamic') -TestFlag.okfail('peer\\capability extended-nexthop') -#TestFlag.okfail('peer\\capability extended-nexthop') -TestFlag.okfail('peer\\description') -TestFlag.okfail('peer\\disable-connected-check') -TestFlag.okfail('peer\\dont-capability-negotiate') -TestFlag.okfail('peer\\enforce-first-as') -TestFlag.okfail('peer\\local-as') -TestFlag.okfail('peer\\local-as 1 no-prepend') -TestFlag.okfail('peer\\local-as 1 no-prepend replace-as') -TestFlag.okfail('peer\\override-capability') -TestFlag.okfail('peer\\passive') -TestFlag.okfail('peer\\password') -TestFlag.okfail('peer\\shutdown') -TestFlag.okfail('peer\\strict-capability-match') -TestFlag.okfail('peer\\timers') -TestFlag.okfail('peer\\timers connect') -TestFlag.okfail('peer\\update-source') -TestFlag.okfail('peer\\update-source') -TestFlag.okfail('peer\\ipv4-unicast\\addpath') -TestFlag.okfail('peer\\ipv4-multicast\\addpath') -TestFlag.okfail('peer\\ipv6-unicast\\addpath') -TestFlag.okfail('peer\\ipv6-multicast\\addpath') -TestFlag.okfail('peer\\ipv4-unicast\\allowas-in') -TestFlag.okfail('peer\\ipv4-multicast\\allowas-in') -TestFlag.okfail('peer\\ipv6-unicast\\allowas-in') -TestFlag.okfail('peer\\ipv6-multicast\\allowas-in') -TestFlag.okfail('peer\\ipv4-unicast\\allowas-in origin') -TestFlag.okfail('peer\\ipv4-multicast\\allowas-in origin') -TestFlag.okfail('peer\\ipv6-unicast\\allowas-in origin') -TestFlag.okfail('peer\\ipv6-multicast\\allowas-in origin') -TestFlag.okfail('peer\\ipv4-unicast\\as-override') -TestFlag.okfail('peer\\ipv4-multicast\\as-override') -TestFlag.okfail('peer\\ipv6-unicast\\as-override') -TestFlag.okfail('peer\\ipv6-multicast\\as-override') -TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path') -TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path') -TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path') -TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path') -TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged next-hop') -TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged next-hop') -TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged next-hop') -TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged next-hop') -TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged med') -TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged med') -TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged med') -TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged med') -TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path next-hop') -TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path next-hop') -TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path next-hop') -TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path next-hop') -TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path med') -TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path med') -TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path med') -TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path med') -TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path next-hop med') -TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path next-hop med') -TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path next-hop med') -TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path next-hop med') -TestFlag.okfail('peer\\ipv4-unicast\\capability orf prefix-list send') -TestFlag.okfail('peer\\ipv4-multicast\\capability orf prefix-list send') -TestFlag.okfail('peer\\ipv6-unicast\\capability orf prefix-list send') -TestFlag.okfail('peer\\ipv6-multicast\\capability orf prefix-list send') -TestFlag.okfail('peer\\ipv4-unicast\\capability orf prefix-list receive') -TestFlag.okfail('peer\\ipv4-multicast\\capability orf prefix-list receive') -TestFlag.okfail('peer\\ipv6-unicast\\capability orf prefix-list receive') -TestFlag.okfail('peer\\ipv6-multicast\\capability orf prefix-list receive') -TestFlag.okfail('peer\\ipv4-unicast\\capability orf prefix-list both') -TestFlag.okfail('peer\\ipv4-multicast\\capability orf prefix-list both') -TestFlag.okfail('peer\\ipv6-unicast\\capability orf prefix-list both') -TestFlag.okfail('peer\\ipv6-multicast\\capability orf prefix-list both') -TestFlag.okfail('peer\\ipv4-unicast\\default-originate') -TestFlag.okfail('peer\\ipv4-multicast\\default-originate') -TestFlag.okfail('peer\\ipv6-unicast\\default-originate') -TestFlag.okfail('peer\\ipv6-multicast\\default-originate') -TestFlag.okfail('peer\\ipv4-unicast\\default-originate route-map') -TestFlag.okfail('peer\\ipv4-multicast\\default-originate route-map') -TestFlag.okfail('peer\\ipv6-unicast\\default-originate route-map') -TestFlag.okfail('peer\\ipv6-multicast\\default-originate route-map') -TestFlag.okfail('peer\\ipv4-unicast\\distribute-list') -TestFlag.okfail('peer\\ipv4-multicast\\distribute-list') -TestFlag.okfail('peer\\ipv6-unicast\\distribute-list') -TestFlag.okfail('peer\\ipv6-multicast\\distribute-list') -TestFlag.okfail('peer\\ipv4-unicast\\distribute-list') -TestFlag.okfail('peer\\ipv4-multicast\\distribute-list') -TestFlag.okfail('peer\\ipv6-unicast\\distribute-list') -TestFlag.okfail('peer\\ipv6-multicast\\distribute-list') -TestFlag.okfail('peer\\ipv4-unicast\\filter-list') -TestFlag.okfail('peer\\ipv4-multicast\\filter-list') -TestFlag.okfail('peer\\ipv6-unicast\\filter-list') -TestFlag.okfail('peer\\ipv6-multicast\\filter-list') -TestFlag.okfail('peer\\ipv4-unicast\\filter-list') -TestFlag.okfail('peer\\ipv4-multicast\\filter-list') -TestFlag.okfail('peer\\ipv6-unicast\\filter-list') -TestFlag.okfail('peer\\ipv6-multicast\\filter-list') -TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix') -TestFlag.okfail('peer\\ipv4-unicast\\next-hop-self') -TestFlag.okfail('peer\\ipv4-multicast\\next-hop-self') -TestFlag.okfail('peer\\ipv6-unicast\\next-hop-self') -TestFlag.okfail('peer\\ipv6-multicast\\next-hop-self') -TestFlag.okfail('peer\\ipv4-unicast\\next-hop-self force') -TestFlag.okfail('peer\\ipv4-multicast\\next-hop-self force') -TestFlag.okfail('peer\\ipv6-unicast\\next-hop-self force') -TestFlag.okfail('peer\\ipv6-multicast\\next-hop-self force') -TestFlag.okfail('peer\\ipv4-unicast\\prefix-list') -TestFlag.okfail('peer\\ipv4-multicast\\prefix-list') -TestFlag.okfail('peer\\ipv6-unicast\\prefix-list') -TestFlag.okfail('peer\\ipv6-multicast\\prefix-list') -TestFlag.okfail('peer\\ipv4-unicast\\prefix-list') -TestFlag.okfail('peer\\ipv4-multicast\\prefix-list') -TestFlag.okfail('peer\\ipv6-unicast\\prefix-list') -TestFlag.okfail('peer\\ipv6-multicast\\prefix-list') -TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS') -TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS') -TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS') -TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS') -TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS all') -TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS all') -TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS all') -TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS all') -TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS replace-AS') -TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS replace-AS') -TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS replace-AS') -TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS replace-AS') -TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS all replace-AS') -TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS all replace-AS') -TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS all replace-AS') -TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS all replace-AS') -TestFlag.okfail('peer\\ipv4-unicast\\route-map') -TestFlag.okfail('peer\\ipv4-multicast\\route-map') -TestFlag.okfail('peer\\ipv6-unicast\\route-map') -TestFlag.okfail('peer\\ipv6-multicast\\route-map') -TestFlag.okfail('peer\\ipv4-unicast\\route-map') -TestFlag.okfail('peer\\ipv4-multicast\\route-map') -TestFlag.okfail('peer\\ipv6-unicast\\route-map') -TestFlag.okfail('peer\\ipv6-multicast\\route-map') -TestFlag.okfail('peer\\ipv4-unicast\\route-reflector-client') -TestFlag.okfail('peer\\ipv4-multicast\\route-reflector-client') -TestFlag.okfail('peer\\ipv6-unicast\\route-reflector-client') -TestFlag.okfail('peer\\ipv6-multicast\\route-reflector-client') -TestFlag.okfail('peer\\ipv4-unicast\\route-server-client') -TestFlag.okfail('peer\\ipv4-multicast\\route-server-client') -TestFlag.okfail('peer\\ipv6-unicast\\route-server-client') -TestFlag.okfail('peer\\ipv6-multicast\\route-server-client') -TestFlag.okfail('peer\\ipv4-unicast\\send-community') -TestFlag.okfail('peer\\ipv4-multicast\\send-community') -TestFlag.okfail('peer\\ipv6-unicast\\send-community') -TestFlag.okfail('peer\\ipv6-multicast\\send-community') -TestFlag.okfail('peer\\ipv4-unicast\\send-community extended') -TestFlag.okfail('peer\\ipv4-multicast\\send-community extended') -TestFlag.okfail('peer\\ipv6-unicast\\send-community extended') -TestFlag.okfail('peer\\ipv6-multicast\\send-community extended') -TestFlag.okfail('peer\\ipv4-unicast\\send-community large') -TestFlag.okfail('peer\\ipv4-multicast\\send-community large') -TestFlag.okfail('peer\\ipv6-unicast\\send-community large') -TestFlag.okfail('peer\\ipv6-multicast\\send-community large') -TestFlag.okfail('peer\\ipv4-unicast\\soft-reconfiguration inbound') -TestFlag.okfail('peer\\ipv4-multicast\\soft-reconfiguration inbound') -TestFlag.okfail('peer\\ipv6-unicast\\soft-reconfiguration inbound') -TestFlag.okfail('peer\\ipv6-multicast\\soft-reconfiguration inbound') -TestFlag.okfail('peer\\ipv4-unicast\\unsuppress-map') -TestFlag.okfail('peer\\ipv4-multicast\\unsuppress-map') -TestFlag.okfail('peer\\ipv6-unicast\\unsuppress-map') -TestFlag.okfail('peer\\ipv6-multicast\\unsuppress-map') -TestFlag.okfail('peer\\ipv4-unicast\\weight') -TestFlag.okfail('peer\\ipv4-multicast\\weight') -TestFlag.okfail('peer\\ipv6-unicast\\weight') -TestFlag.okfail('peer\\ipv6-multicast\\weight') +TestFlag.okfail("peer\\advertisement-interval") +TestFlag.okfail("peer\\capability dynamic") +TestFlag.okfail("peer\\capability extended-nexthop") +# TestFlag.okfail('peer\\capability extended-nexthop') +TestFlag.okfail("peer\\description") +TestFlag.okfail("peer\\disable-connected-check") +TestFlag.okfail("peer\\dont-capability-negotiate") +TestFlag.okfail("peer\\enforce-first-as") +TestFlag.okfail("peer\\local-as") +TestFlag.okfail("peer\\local-as 1 no-prepend") +TestFlag.okfail("peer\\local-as 1 no-prepend replace-as") +TestFlag.okfail("peer\\override-capability") +TestFlag.okfail("peer\\passive") +TestFlag.okfail("peer\\password") +TestFlag.okfail("peer\\shutdown") +TestFlag.okfail("peer\\strict-capability-match") +TestFlag.okfail("peer\\timers") +TestFlag.okfail("peer\\timers connect") +TestFlag.okfail("peer\\update-source") +TestFlag.okfail("peer\\update-source") +TestFlag.okfail("peer\\ipv4-unicast\\addpath") +TestFlag.okfail("peer\\ipv4-multicast\\addpath") +TestFlag.okfail("peer\\ipv6-unicast\\addpath") +TestFlag.okfail("peer\\ipv6-multicast\\addpath") +TestFlag.okfail("peer\\ipv4-unicast\\allowas-in") +TestFlag.okfail("peer\\ipv4-multicast\\allowas-in") +TestFlag.okfail("peer\\ipv6-unicast\\allowas-in") +TestFlag.okfail("peer\\ipv6-multicast\\allowas-in") +TestFlag.okfail("peer\\ipv4-unicast\\allowas-in origin") +TestFlag.okfail("peer\\ipv4-multicast\\allowas-in origin") +TestFlag.okfail("peer\\ipv6-unicast\\allowas-in origin") +TestFlag.okfail("peer\\ipv6-multicast\\allowas-in origin") +TestFlag.okfail("peer\\ipv4-unicast\\as-override") +TestFlag.okfail("peer\\ipv4-multicast\\as-override") +TestFlag.okfail("peer\\ipv6-unicast\\as-override") +TestFlag.okfail("peer\\ipv6-multicast\\as-override") +TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path") +TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path") +TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path") +TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path") +TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged next-hop") +TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged next-hop") +TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged next-hop") +TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged next-hop") +TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged med") +TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged med") +TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged med") +TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged med") +TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path next-hop") +TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path next-hop") +TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path next-hop") +TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path next-hop") +TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path med") +TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path med") +TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path med") +TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path med") +TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path next-hop med") +TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path next-hop med") +TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path next-hop med") +TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path next-hop med") +TestFlag.okfail("peer\\ipv4-unicast\\capability orf prefix-list send") +TestFlag.okfail("peer\\ipv4-multicast\\capability orf prefix-list send") +TestFlag.okfail("peer\\ipv6-unicast\\capability orf prefix-list send") +TestFlag.okfail("peer\\ipv6-multicast\\capability orf prefix-list send") +TestFlag.okfail("peer\\ipv4-unicast\\capability orf prefix-list receive") +TestFlag.okfail("peer\\ipv4-multicast\\capability orf prefix-list receive") +TestFlag.okfail("peer\\ipv6-unicast\\capability orf prefix-list receive") +TestFlag.okfail("peer\\ipv6-multicast\\capability orf prefix-list receive") +TestFlag.okfail("peer\\ipv4-unicast\\capability orf prefix-list both") +TestFlag.okfail("peer\\ipv4-multicast\\capability orf prefix-list both") +TestFlag.okfail("peer\\ipv6-unicast\\capability orf prefix-list both") +TestFlag.okfail("peer\\ipv6-multicast\\capability orf prefix-list both") +TestFlag.okfail("peer\\ipv4-unicast\\default-originate") +TestFlag.okfail("peer\\ipv4-multicast\\default-originate") +TestFlag.okfail("peer\\ipv6-unicast\\default-originate") +TestFlag.okfail("peer\\ipv6-multicast\\default-originate") +TestFlag.okfail("peer\\ipv4-unicast\\default-originate route-map") +TestFlag.okfail("peer\\ipv4-multicast\\default-originate route-map") +TestFlag.okfail("peer\\ipv6-unicast\\default-originate route-map") +TestFlag.okfail("peer\\ipv6-multicast\\default-originate route-map") +TestFlag.okfail("peer\\ipv4-unicast\\distribute-list") +TestFlag.okfail("peer\\ipv4-multicast\\distribute-list") +TestFlag.okfail("peer\\ipv6-unicast\\distribute-list") +TestFlag.okfail("peer\\ipv6-multicast\\distribute-list") +TestFlag.okfail("peer\\ipv4-unicast\\distribute-list") +TestFlag.okfail("peer\\ipv4-multicast\\distribute-list") +TestFlag.okfail("peer\\ipv6-unicast\\distribute-list") +TestFlag.okfail("peer\\ipv6-multicast\\distribute-list") +TestFlag.okfail("peer\\ipv4-unicast\\filter-list") +TestFlag.okfail("peer\\ipv4-multicast\\filter-list") +TestFlag.okfail("peer\\ipv6-unicast\\filter-list") +TestFlag.okfail("peer\\ipv6-multicast\\filter-list") +TestFlag.okfail("peer\\ipv4-unicast\\filter-list") +TestFlag.okfail("peer\\ipv4-multicast\\filter-list") +TestFlag.okfail("peer\\ipv6-unicast\\filter-list") +TestFlag.okfail("peer\\ipv6-multicast\\filter-list") +TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix") +TestFlag.okfail("peer\\ipv4-unicast\\next-hop-self") +TestFlag.okfail("peer\\ipv4-multicast\\next-hop-self") +TestFlag.okfail("peer\\ipv6-unicast\\next-hop-self") +TestFlag.okfail("peer\\ipv6-multicast\\next-hop-self") +TestFlag.okfail("peer\\ipv4-unicast\\next-hop-self force") +TestFlag.okfail("peer\\ipv4-multicast\\next-hop-self force") +TestFlag.okfail("peer\\ipv6-unicast\\next-hop-self force") +TestFlag.okfail("peer\\ipv6-multicast\\next-hop-self force") +TestFlag.okfail("peer\\ipv4-unicast\\prefix-list") +TestFlag.okfail("peer\\ipv4-multicast\\prefix-list") +TestFlag.okfail("peer\\ipv6-unicast\\prefix-list") +TestFlag.okfail("peer\\ipv6-multicast\\prefix-list") +TestFlag.okfail("peer\\ipv4-unicast\\prefix-list") +TestFlag.okfail("peer\\ipv4-multicast\\prefix-list") +TestFlag.okfail("peer\\ipv6-unicast\\prefix-list") +TestFlag.okfail("peer\\ipv6-multicast\\prefix-list") +TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS") +TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS") +TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS") +TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS") +TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS all") +TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS all") +TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS all") +TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS all") +TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS replace-AS") +TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS replace-AS") +TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS replace-AS") +TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS replace-AS") +TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS all replace-AS") +TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS all replace-AS") +TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS all replace-AS") +TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS all replace-AS") +TestFlag.okfail("peer\\ipv4-unicast\\route-map") +TestFlag.okfail("peer\\ipv4-multicast\\route-map") +TestFlag.okfail("peer\\ipv6-unicast\\route-map") +TestFlag.okfail("peer\\ipv6-multicast\\route-map") +TestFlag.okfail("peer\\ipv4-unicast\\route-map") +TestFlag.okfail("peer\\ipv4-multicast\\route-map") +TestFlag.okfail("peer\\ipv6-unicast\\route-map") +TestFlag.okfail("peer\\ipv6-multicast\\route-map") +TestFlag.okfail("peer\\ipv4-unicast\\route-reflector-client") +TestFlag.okfail("peer\\ipv4-multicast\\route-reflector-client") +TestFlag.okfail("peer\\ipv6-unicast\\route-reflector-client") +TestFlag.okfail("peer\\ipv6-multicast\\route-reflector-client") +TestFlag.okfail("peer\\ipv4-unicast\\route-server-client") +TestFlag.okfail("peer\\ipv4-multicast\\route-server-client") +TestFlag.okfail("peer\\ipv6-unicast\\route-server-client") +TestFlag.okfail("peer\\ipv6-multicast\\route-server-client") +TestFlag.okfail("peer\\ipv4-unicast\\send-community") +TestFlag.okfail("peer\\ipv4-multicast\\send-community") +TestFlag.okfail("peer\\ipv6-unicast\\send-community") +TestFlag.okfail("peer\\ipv6-multicast\\send-community") +TestFlag.okfail("peer\\ipv4-unicast\\send-community extended") +TestFlag.okfail("peer\\ipv4-multicast\\send-community extended") +TestFlag.okfail("peer\\ipv6-unicast\\send-community extended") +TestFlag.okfail("peer\\ipv6-multicast\\send-community extended") +TestFlag.okfail("peer\\ipv4-unicast\\send-community large") +TestFlag.okfail("peer\\ipv4-multicast\\send-community large") +TestFlag.okfail("peer\\ipv6-unicast\\send-community large") +TestFlag.okfail("peer\\ipv6-multicast\\send-community large") +TestFlag.okfail("peer\\ipv4-unicast\\soft-reconfiguration inbound") +TestFlag.okfail("peer\\ipv4-multicast\\soft-reconfiguration inbound") +TestFlag.okfail("peer\\ipv6-unicast\\soft-reconfiguration inbound") +TestFlag.okfail("peer\\ipv6-multicast\\soft-reconfiguration inbound") +TestFlag.okfail("peer\\ipv4-unicast\\unsuppress-map") +TestFlag.okfail("peer\\ipv4-multicast\\unsuppress-map") +TestFlag.okfail("peer\\ipv6-unicast\\unsuppress-map") +TestFlag.okfail("peer\\ipv6-multicast\\unsuppress-map") +TestFlag.okfail("peer\\ipv4-unicast\\weight") +TestFlag.okfail("peer\\ipv4-multicast\\weight") +TestFlag.okfail("peer\\ipv6-unicast\\weight") +TestFlag.okfail("peer\\ipv6-multicast\\weight") diff --git a/tests/helpers/python/frrsix.py b/tests/helpers/python/frrsix.py index 91714f0c67..df737d92ef 100644 --- a/tests/helpers/python/frrsix.py +++ b/tests/helpers/python/frrsix.py @@ -29,24 +29,29 @@ import sys PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 + def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') + slots = orig_vars.get("__slots__") if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) + orig_vars.pop("__dict__", None) + orig_vars.pop("__weakref__", None) return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + if PY3: import builtins - exec_ = getattr(builtins,'exec') + + exec_ = getattr(builtins, "exec") def reraise(tp, value, tb=None): try: @@ -59,7 +64,9 @@ if PY3: value = None tb = None + else: + def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: @@ -72,9 +79,11 @@ else: _locs_ = _globs_ exec("""exec _code_ in _globs_, _locs_""") - exec_("""def reraise(tp, value, tb=None): + exec_( + """def reraise(tp, value, tb=None): try: raise tp, value, tb finally: tb = None -""") +""" + ) diff --git a/tests/helpers/python/frrtest.py b/tests/helpers/python/frrtest.py index 60bee5c88c..0ac54fd900 100644 --- a/tests/helpers/python/frrtest.py +++ b/tests/helpers/python/frrtest.py @@ -39,35 +39,41 @@ import frrsix srcbase = os.path.abspath(inspect.getsourcefile(frrsix)) for i in range(0, 3): srcbase = os.path.dirname(srcbase) + + def binpath(srcpath): return os.path.relpath(os.path.abspath(srcpath), srcbase) + class MultiTestFailure(Exception): pass + class MetaTestMultiOut(type): def __getattr__(cls, name): - if name.startswith('_'): + if name.startswith("_"): raise AttributeError - internal_name = '_{}'.format(name) + internal_name = "_{}".format(name) if internal_name not in dir(cls): raise AttributeError def registrar(*args, **kwargs): - cls._add_test(getattr(cls,internal_name), *args, **kwargs) + cls._add_test(getattr(cls, internal_name), *args, **kwargs) + return registrar + @frrsix.add_metaclass(MetaTestMultiOut) class _TestMultiOut(object): def _run_tests(self): - if 'tests_run' in dir(self.__class__) and self.tests_run: + if "tests_run" in dir(self.__class__) and self.tests_run: return self.__class__.tests_run = True basedir = os.path.dirname(inspect.getsourcefile(type(self))) program = os.path.join(basedir, self.program) proc = subprocess.Popen([binpath(program)], stdout=subprocess.PIPE) - self.output,_ = proc.communicate('') + self.output, _ = proc.communicate("") self.exitcode = proc.wait() self.__class__.testresults = {} @@ -85,13 +91,14 @@ class _TestMultiOut(object): @classmethod def _add_test(cls, method, *args, **kwargs): - if 'tests' not in dir(cls): - setattr(cls,'tests',[]) + if "tests" not in dir(cls): + setattr(cls, "tests", []) if method is not cls._exit_cleanly: cls._add_test(cls._exit_cleanly) def matchfunction(self): method(self, *args, **kwargs) + cls.tests.append(matchfunction) def testfunction(self): @@ -100,17 +107,18 @@ class _TestMultiOut(object): if result is not None: frrsix.reraise(*result) - testname = re.sub(r'[^A-Za-z0-9]', '_', '%r%r' % (args, kwargs)) - testname = re.sub(r'__*', '_', testname) - testname = testname.strip('_') + testname = re.sub(r"[^A-Za-z0-9]", "_", "%r%r" % (args, kwargs)) + testname = re.sub(r"__*", "_", testname) + testname = testname.strip("_") if not testname: - testname = method.__name__.strip('_') + testname = method.__name__.strip("_") if "test_%s" % testname in dir(cls): index = 2 - while "test_%s_%d" % (testname,index) in dir(cls): + while "test_%s_%d" % (testname, index) in dir(cls): index += 1 testname = "%s_%d" % (testname, index) - setattr(cls,"test_%s" % testname, testfunction) + setattr(cls, "test_%s" % testname, testfunction) + # # This class houses the actual TestMultiOut tests types. @@ -127,15 +135,16 @@ class _TestMultiOut(object): # modified according to consumed content. # -re_okfail = re.compile(r'(?:[3[12]m|^)?(?P<ret>OK|failed)'.encode('utf8'), - re.MULTILINE) +re_okfail = re.compile(r"(?:[3[12]m|^)?(?P<ret>OK|failed)".encode("utf8"), re.MULTILINE) + + class TestMultiOut(_TestMultiOut): def _onesimple(self, line): if type(line) is str: - line = line.encode('utf8') + line = line.encode("utf8") idx = self.output.find(line) if idx != -1: - self.output = self.output[idx+len(line):] + self.output = self.output[idx + len(line) :] else: raise MultiTestFailure("%r could not be found" % line) @@ -144,58 +153,67 @@ class TestMultiOut(_TestMultiOut): m = okfail.search(self.output) if m is None: - raise MultiTestFailure('OK/fail not found') - self.output = self.output[m.end():] + raise MultiTestFailure("OK/fail not found") + self.output = self.output[m.end() :] + + if m.group("ret") != "OK".encode("utf8"): + raise MultiTestFailure("Test output indicates failure") - if m.group('ret') != 'OK'.encode('utf8'): - raise MultiTestFailure('Test output indicates failure') # # This class implements a test comparing the output of a program against # an existing reference output # + class TestRefMismatch(Exception): def __init__(self, _test, outtext, reftext): - self.outtext = outtext.decode('utf8') if type(outtext) is bytes else outtext - self.reftext = reftext.decode('utf8') if type(reftext) is bytes else reftext + self.outtext = outtext.decode("utf8") if type(outtext) is bytes else outtext + self.reftext = reftext.decode("utf8") if type(reftext) is bytes else reftext def __str__(self): - rv = 'Expected output and actual output differ:\n' - rv += '\n'.join(difflib.unified_diff(self.reftext.splitlines(), - self.outtext.splitlines(), - 'outtext', 'reftext', - lineterm='')) + rv = "Expected output and actual output differ:\n" + rv += "\n".join( + difflib.unified_diff( + self.reftext.splitlines(), + self.outtext.splitlines(), + "outtext", + "reftext", + lineterm="", + ) + ) return rv + class TestExitNonzero(Exception): pass + class TestRefOut(object): def test_refout(self): basedir = os.path.dirname(inspect.getsourcefile(type(self))) program = os.path.join(basedir, self.program) - if getattr(self, 'built_refin', False): - refin = binpath(program) + '.in' + if getattr(self, "built_refin", False): + refin = binpath(program) + ".in" else: - refin = program + '.in' - if getattr(self, 'built_refout', False): - refout = binpath(program) + '.refout' + refin = program + ".in" + if getattr(self, "built_refout", False): + refout = binpath(program) + ".refout" else: - refout = program + '.refout' + refout = program + ".refout" - intext = '' + intext = "" if os.path.exists(refin): - with open(refin, 'rb') as f: + with open(refin, "rb") as f: intext = f.read() - with open(refout, 'rb') as f: + with open(refout, "rb") as f: reftext = f.read() - proc = subprocess.Popen([binpath(program)], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - outtext,_ = proc.communicate(intext) + proc = subprocess.Popen( + [binpath(program)], stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + outtext, _ = proc.communicate(intext) if outtext != reftext: raise TestRefMismatch(self, outtext, reftext) if proc.wait() != 0: diff --git a/tests/isisd/test_common.c b/tests/isisd/test_common.c index 536847a1da..5fa604c749 100644 --- a/tests/isisd/test_common.c +++ b/tests/isisd/test_common.c @@ -106,6 +106,7 @@ static void lsp_add_ip_reach(struct isis_lsp *lsp, pcfg.sid = *next_sid_index; *next_sid_index = *next_sid_index + 1; pcfg.sid_type = SR_SID_VALUE_TYPE_INDEX; + pcfg.node_sid = true; pcfg.last_hop_behavior = SR_LAST_HOP_BEHAVIOR_PHP; } diff --git a/tests/isisd/test_fuzz_isis_tlv.py b/tests/isisd/test_fuzz_isis_tlv.py index d96e3c4fee..8fd20aabd1 100644 --- a/tests/isisd/test_fuzz_isis_tlv.py +++ b/tests/isisd/test_fuzz_isis_tlv.py @@ -9,18 +9,24 @@ import socket # on musl, ntop compresses a single :0: -> :: which is against RFC ## def inet_ntop_broken(): - addr = '1:2:3:4:0:6:7:8' - return socket.inet_ntop(socket.AF_INET6, - socket.inet_pton(socket.AF_INET6, addr)) != addr + addr = "1:2:3:4:0:6:7:8" + return ( + socket.inet_ntop(socket.AF_INET6, socket.inet_pton(socket.AF_INET6, addr)) + != addr + ) -if platform.uname()[0] == 'SunOS' or inet_ntop_broken(): +if platform.uname()[0] == "SunOS" or inet_ntop_broken(): + class TestFuzzIsisTLV: - @pytest.mark.skipif(True, reason='Test unsupported') + @pytest.mark.skipif(True, reason="Test unsupported") def test_exit_cleanly(self): pass + + else: + class TestFuzzIsisTLV(frrtest.TestMultiOut): - program = './test_fuzz_isis_tlv' + program = "./test_fuzz_isis_tlv" TestFuzzIsisTLV.exit_cleanly() diff --git a/tests/isisd/test_isis_lspdb.py b/tests/isisd/test_isis_lspdb.py index cd0b5345c7..280ed1c328 100644 --- a/tests/isisd/test_isis_lspdb.py +++ b/tests/isisd/test_isis_lspdb.py @@ -1,6 +1,8 @@ import frrtest + class TestIsisLSPDB(frrtest.TestMultiOut): - program = './test_isis_lspdb' + program = "./test_isis_lspdb" + TestIsisLSPDB.exit_cleanly() diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index 73bb531dc0..4c89a5be0a 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -39,6 +39,7 @@ enum test_type { TEST_SPF = 1, TEST_REVERSE_SPF, + TEST_TI_LFA, }; #define F_DISPLAY_LSPDB 0x01 @@ -65,17 +66,78 @@ static void test_run_spf(struct vty *vty, const struct isis_topology *topology, /* Print the SPT and the corresponding routing table. */ isis_print_spftree(vty, spftree); - isis_print_routes(vty, spftree); + isis_print_routes(vty, spftree, false, false); /* Cleanup SPF tree. */ isis_spftree_del(spftree); } +static void test_run_ti_lfa(struct vty *vty, + const struct isis_topology *topology, + const struct isis_test_node *root, + struct isis_area *area, struct lspdb_head *lspdb, + int level, int tree, + struct lfa_protected_resource *protected_resource) +{ + struct isis_spftree *spftree_self; + struct isis_spftree *spftree_reverse; + struct isis_spftree *spftree_pc; + struct isis_spf_node *spf_node, *node; + uint8_t flags; + + /* Run forward SPF in the root node. */ + flags = F_SPFTREE_NO_ADJACENCIES; + spftree_self = isis_spftree_new(area, lspdb, root->sysid, level, tree, + SPF_TYPE_FORWARD, flags); + isis_run_spf(spftree_self); + + /* Run reverse SPF in the root node. */ + spftree_reverse = isis_spf_reverse_run(spftree_self); + + /* Run forward SPF on all adjacent routers. */ + isis_spf_run_neighbors(spftree_self); + + /* Compute the TI-LFA repair paths. */ + spftree_pc = isis_tilfa_compute(area, spftree_self, spftree_reverse, + protected_resource); + + /* Print the extended P-space and Q-space. */ + vty_out(vty, "P-space (self):\n"); + RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.p_space) + vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); + vty_out(vty, "\n"); + RB_FOREACH (spf_node, isis_spf_nodes, &spftree_self->adj_nodes) { + if (RB_EMPTY(isis_spf_nodes, &spf_node->lfa.p_space)) + continue; + vty_out(vty, "P-space (%s):\n", + print_sys_hostname(spf_node->sysid)); + RB_FOREACH (node, isis_spf_nodes, &spf_node->lfa.p_space) + vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); + vty_out(vty, "\n"); + } + vty_out(vty, "Q-space:\n"); + RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.q_space) + vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); + vty_out(vty, "\n"); + + /* Print the post-convergence SPT and the correspoding routing table. */ + isis_print_spftree(vty, spftree_pc); + isis_print_routes(vty, spftree_self, false, true); + + /* Cleanup everything. */ + isis_spftree_del(spftree_self); + isis_spftree_del(spftree_reverse); + isis_spftree_del(spftree_pc); +} + static int test_run(struct vty *vty, const struct isis_topology *topology, const struct isis_test_node *root, enum test_type test_type, - uint8_t flags) + uint8_t flags, enum lfa_protection_type protection_type, + const char *fail_sysid_str, uint8_t fail_pseudonode_id) { struct isis_area *area; + struct lfa_protected_resource protected_resource = {}; + uint8_t fail_id[ISIS_SYS_ID_LEN] = {}; /* Init topology. */ memcpy(isis->sysid, root->sysid, sizeof(isis->sysid)); @@ -87,6 +149,26 @@ static int test_run(struct vty *vty, const struct isis_topology *topology, return CMD_WARNING; } + /* Parse failed link/node. */ + if (fail_sysid_str) { + if (sysid2buff(fail_id, fail_sysid_str) == 0) { + struct isis_dynhn *dynhn; + + dynhn = dynhn_find_by_name(fail_sysid_str); + if (dynhn == NULL) { + vty_out(vty, "Invalid system id %s\n", + fail_sysid_str); + return CMD_WARNING; + } + memcpy(fail_id, dynhn->id, ISIS_SYS_ID_LEN); + } + + protected_resource.type = protection_type; + memcpy(protected_resource.adjacency, fail_id, ISIS_SYS_ID_LEN); + LSP_PSEUDO_ID(protected_resource.adjacency) = + fail_pseudonode_id; + } + for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { if (level == IS_LEVEL_1 && CHECK_FLAG(flags, F_LEVEL2_ONLY)) continue; @@ -120,6 +202,11 @@ static int test_run(struct vty *vty, const struct isis_topology *topology, &area->lspdb[level - 1], level, tree, true); break; + case TEST_TI_LFA: + test_run_ti_lfa(vty, topology, root, area, + &area->lspdb[level - 1], level, + tree, &protected_resource); + break; } } } @@ -138,6 +225,7 @@ DEFUN(test_isis, test_isis_cmd, <\ spf\ |reverse-spf\ + |ti-lfa system-id WORD [pseudonode-id <1-255>] [node-protection]\ >\ [display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]", "Test command\n" @@ -148,6 +236,12 @@ DEFUN(test_isis, test_isis_cmd, "SPF root hostname\n" "Normal Shortest Path First\n" "Reverse Shortest Path First\n" + "Topology Independent LFA\n" + "System ID\n" + "System ID\n" + "Pseudonode-ID\n" + "Pseudonode-ID\n" + "Node protection\n" "Display the LSPDB\n" "Do IPv4 processing only\n" "Do IPv6 processing only\n" @@ -158,6 +252,9 @@ DEFUN(test_isis, test_isis_cmd, const struct isis_topology *topology; const struct isis_test_node *root; enum test_type test_type; + enum lfa_protection_type protection_type = 0; + const char *fail_sysid_str = NULL; + uint8_t fail_pseudonode_id = 0; uint8_t flags = 0; int idx = 0; @@ -184,7 +281,18 @@ DEFUN(test_isis, test_isis_cmd, test_type = TEST_SPF; else if (argv_find(argv, argc, "reverse-spf", &idx)) test_type = TEST_REVERSE_SPF; - else + else if (argv_find(argv, argc, "ti-lfa", &idx)) { + test_type = TEST_TI_LFA; + + fail_sysid_str = argv[idx + 2]->arg; + if (argv_find(argv, argc, "pseudonode-id", &idx)) + fail_pseudonode_id = + strtoul(argv[idx + 1]->arg, NULL, 10); + if (argv_find(argv, argc, "node-protection", &idx)) + protection_type = LFA_NODE_PROTECTION; + else + protection_type = LFA_LINK_PROTECTION; + } else return CMD_WARNING; /* Parse control flags. */ @@ -199,7 +307,8 @@ DEFUN(test_isis, test_isis_cmd, else if (argv_find(argv, argc, "level-2-only", &idx)) SET_FLAG(flags, F_LEVEL2_ONLY); - return test_run(vty, topology, root, test_type, flags); + return test_run(vty, topology, root, test_type, flags, protection_type, + fail_sysid_str, fail_pseudonode_id); } static void vty_do_exit(int isexit) @@ -295,6 +404,7 @@ int main(int argc, char **argv) listnode_add(im->isis, isis); SET_FLAG(im->options, F_ISIS_UNIT_TEST); debug_spf_events |= DEBUG_SPF_EVENTS; + debug_tilfa |= DEBUG_TILFA; debug_events |= DEBUG_EVENTS; debug_rte_events |= DEBUG_RTE_EVENTS; diff --git a/tests/isisd/test_isis_spf.in b/tests/isisd/test_isis_spf.in index d9a61782e9..6bc5442f1e 100644 --- a/tests/isisd/test_isis_spf.in +++ b/tests/isisd/test_isis_spf.in @@ -14,3 +14,27 @@ test isis topology 13 root rt1 spf ipv4-only test isis topology 4 root rt1 reverse-spf ipv4-only test isis topology 11 root rt1 reverse-spf + +test isis topology 1 root rt1 ti-lfa system-id rt2 +test isis topology 2 root rt1 ti-lfa system-id rt3 +test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1 +test isis topology 2 root rt5 ti-lfa system-id rt1 pseudonode-id 1 +test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only +test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only +test isis topology 4 root rt1 ti-lfa system-id rt2 ipv4-only +test isis topology 4 root rt4 ti-lfa system-id rt6 ipv4-only +test isis topology 5 root rt1 ti-lfa system-id rt2 ipv4-only +test isis topology 6 root rt4 ti-lfa system-id rt3 ipv4-only +test isis topology 7 root rt11 ti-lfa system-id rt8 ipv4-only +test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only +test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only +test isis topology 8 root rt2 ti-lfa system-id rt5 ipv4-only +test isis topology 9 root rt1 ti-lfa system-id rt3 +test isis topology 9 root rt1 ti-lfa system-id rt2 +test isis topology 9 root rt9 ti-lfa system-id rt5 +test isis topology 9 root rt9 ti-lfa system-id rt8 +test isis topology 10 root rt1 ti-lfa system-id rt2 +test isis topology 10 root rt1 ti-lfa system-id rt4 +test isis topology 11 root rt2 ti-lfa system-id rt4 +test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only +test isis topology 13 root rt1 ti-lfa system-id rt3 ipv4-only diff --git a/tests/isisd/test_isis_spf.py b/tests/isisd/test_isis_spf.py index 21e7ef6269..f44fa70d6b 100644 --- a/tests/isisd/test_isis_spf.py +++ b/tests/isisd/test_isis_spf.py @@ -1,4 +1,5 @@ import frrtest + class TestIsisSPF(frrtest.TestRefOut): - program = './test_isis_spf' + program = "./test_isis_spf" diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout index ed0569947c..d24176a097 100644 --- a/tests/isisd/test_isis_spf.refout +++ b/tests/isisd/test_isis_spf.refout @@ -18,14 +18,15 @@ rt6 TE-IS 30 rt2 - rt4(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt2 -
- - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ - rt3 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -46,14 +47,15 @@ rt6 TE-IS 30 rt2 - rt4(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------
- 2001:db8::2/128 20 - rt2 -
- 2001:db8::3/128 20 - rt3 -
- 2001:db8::4/128 30 - rt2 -
- 2001:db8::5/128 30 - rt3 -
- 2001:db8::6/128 40 - rt2 -
- - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::2/128 20 - rt2 implicit-null
+ 2001:db8::3/128 20 - rt3 implicit-null
+ 2001:db8::4/128 30 - rt2 16041
+ 2001:db8::5/128 30 - rt3 16051
+ 2001:db8::6/128 40 - rt2 16061
+ - rt3 16061
test# test isis topology 2 root rt1 spf
IS-IS paths to level-1 routers that speak IP
@@ -76,14 +78,15 @@ rt3 TE-IS 30 rt3 - rt1(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 25 - rt2 -
- 10.0.255.3/32 40 - rt3 -
- 10.0.255.4/32 20 - rt4 -
- 10.0.255.5/32 20 - rt5 -
- 10.0.255.6/32 30 - rt4 -
- - rt5 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 25 - rt2 implicit-null
+ 10.0.255.3/32 40 - rt3 implicit-null
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 20 - rt5 implicit-null
+ 10.0.255.6/32 30 - rt4 16060
+ - rt5 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -105,14 +108,15 @@ rt3 TE-IS 30 rt3 - rt1(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------
- 2001:db8::2/128 25 - rt2 -
- 2001:db8::3/128 40 - rt3 -
- 2001:db8::4/128 20 - rt4 -
- 2001:db8::5/128 20 - rt5 -
- 2001:db8::6/128 30 - rt4 -
- - rt5 -
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::2/128 25 - rt2 implicit-null
+ 2001:db8::3/128 40 - rt3 implicit-null
+ 2001:db8::4/128 20 - rt4 implicit-null
+ 2001:db8::5/128 20 - rt5 implicit-null
+ 2001:db8::6/128 30 - rt4 16061
+ - rt5 16061
test# test isis topology 3 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -132,13 +136,14 @@ rt6 TE-IS 30 rt2 - rt4(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 40 - rt2 -
- 10.0.255.6/32 40 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 40 - rt2 16050
+ 10.0.255.6/32 40 - rt2 16060
test# test isis topology 4 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -162,15 +167,16 @@ rt8 TE-IS 40 rt2 - rt6(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt2 -
- 10.0.255.7/32 40 - rt3 -
- 10.0.255.8/32 50 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ 10.0.255.7/32 40 - rt3 16070
+ 10.0.255.8/32 50 - rt2 16080
test# test isis topology 5 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -196,16 +202,17 @@ rt8 TE-IS 40 rt2 - rt6(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt2 -
- 10.0.255.7/32 40 - rt3 -
- 10.0.255.8/32 50 - rt2 -
- - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ 10.0.255.7/32 40 - rt3 16070
+ 10.0.255.8/32 50 - rt2 16080
+ - rt3 16080
test# test isis topology 6 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -239,20 +246,21 @@ rt7 TE-IS 50 rt2 - rt5(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- - rt3 -
- 10.0.255.5/32 50 - rt2 -
- - rt3 -
- 10.0.255.6/32 40 - rt2 -
- - rt3 -
- 10.0.255.7/32 60 - rt2 -
- - rt3 -
- 10.0.255.8/32 50 - rt2 -
- - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ - rt3 16040
+ 10.0.255.5/32 50 - rt2 16050
+ - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ - rt3 16060
+ 10.0.255.7/32 60 - rt2 16070
+ - rt3 16070
+ 10.0.255.8/32 50 - rt2 16080
+ - rt3 16080
test# test isis topology 7 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -287,19 +295,20 @@ rt12 TE-IS 50 rt4 - rt9(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- ------------------------------------------------------
- 10.0.255.2/32 40 - rt4 -
- 10.0.255.3/32 50 - rt4 -
- 10.0.255.4/32 20 - rt4 -
- 10.0.255.5/32 30 - rt4 -
- 10.0.255.6/32 40 - rt4 -
- 10.0.255.7/32 30 - rt4 -
- 10.0.255.8/32 40 - rt4 -
- 10.0.255.9/32 50 - rt4 -
- 10.0.255.10/32 50 - rt4 -
- 10.0.255.11/32 50 - rt4 -
- 10.0.255.12/32 60 - rt4 -
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 40 - rt4 16020
+ 10.0.255.3/32 50 - rt4 16030
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 30 - rt4 16050
+ 10.0.255.6/32 40 - rt4 16060
+ 10.0.255.7/32 30 - rt4 16070
+ 10.0.255.8/32 40 - rt4 16080
+ 10.0.255.9/32 50 - rt4 16090
+ 10.0.255.10/32 50 - rt4 16100
+ 10.0.255.11/32 50 - rt4 16110
+ 10.0.255.12/32 60 - rt4 16120
test# test isis topology 8 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -333,19 +342,20 @@ rt12 TE-IS 50 rt2 - rt9(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- ------------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 30 - rt2 -
- 10.0.255.4/32 20 - rt4 -
- 10.0.255.5/32 30 - rt2 -
- 10.0.255.6/32 40 - rt2 -
- 10.0.255.7/32 30 - rt4 -
- 10.0.255.8/32 40 - rt2 -
- 10.0.255.9/32 50 - rt2 -
- 10.0.255.10/32 40 - rt4 -
- 10.0.255.11/32 50 - rt2 -
- 10.0.255.12/32 60 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 30 - rt2 16030
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 30 - rt2 16050
+ 10.0.255.6/32 40 - rt2 16060
+ 10.0.255.7/32 30 - rt4 16070
+ 10.0.255.8/32 40 - rt2 16080
+ 10.0.255.9/32 50 - rt2 16090
+ 10.0.255.10/32 40 - rt4 16100
+ 10.0.255.11/32 50 - rt2 16110
+ 10.0.255.12/32 60 - rt2 16120
test# test isis topology 9 root rt1 spf
IS-IS paths to level-1 routers that speak IP
@@ -374,16 +384,17 @@ rt8 TE-IS 50 rt2 - rt4(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 40 - rt2 -
- 10.0.255.6/32 60 - rt2 -
- 10.0.255.7/32 60 - rt2 -
- 10.0.255.8/32 60 - rt2 -
- 10.0.255.9/32 50 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 40 - rt2 16050
+ 10.0.255.6/32 60 - rt2 16060
+ 10.0.255.7/32 60 - rt2 16070
+ 10.0.255.8/32 60 - rt2 16080
+ 10.0.255.9/32 50 - rt2 16090
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -411,16 +422,17 @@ rt8 TE-IS 50 rt2 - rt4(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------
- 2001:db8::2/128 20 - rt2 -
- 2001:db8::3/128 20 - rt3 -
- 2001:db8::4/128 30 - rt2 -
- 2001:db8::5/128 40 - rt2 -
- 2001:db8::6/128 60 - rt2 -
- 2001:db8::7/128 60 - rt2 -
- 2001:db8::8/128 60 - rt2 -
- 2001:db8::9/128 50 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::2/128 20 - rt2 implicit-null
+ 2001:db8::3/128 20 - rt3 implicit-null
+ 2001:db8::4/128 30 - rt2 16041
+ 2001:db8::5/128 40 - rt2 16051
+ 2001:db8::6/128 60 - rt2 16061
+ 2001:db8::7/128 60 - rt2 16071
+ 2001:db8::8/128 60 - rt2 16081
+ 2001:db8::9/128 50 - rt2 16091
test# test isis topology 10 root rt1 spf
IS-IS paths to level-1 routers that speak IP
@@ -444,15 +456,16 @@ rt8 TE-IS 30 rt2 - rt5(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 30 - rt3 -
- 10.0.255.4/32 30 - rt4 -
- 10.0.255.5/32 30 - rt2 -
- 10.0.255.6/32 40 - rt3 -
- 10.0.255.7/32 40 - rt4 -
- 10.0.255.8/32 40 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 30 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt4 implicit-null
+ 10.0.255.5/32 30 - rt2 16050
+ 10.0.255.6/32 40 - rt3 20060
+ 10.0.255.7/32 40 - rt4 16070
+ 10.0.255.8/32 40 - rt2 16080
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -475,15 +488,16 @@ rt8 TE-IS 30 rt2 - rt5(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------
- 2001:db8::2/128 20 - rt2 -
- 2001:db8::3/128 30 - rt3 -
- 2001:db8::4/128 30 - rt4 -
- 2001:db8::5/128 30 - rt2 -
- 2001:db8::6/128 40 - rt3 -
- 2001:db8::7/128 40 - rt4 -
- 2001:db8::8/128 40 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::2/128 20 - rt2 implicit-null
+ 2001:db8::3/128 30 - rt3 implicit-null
+ 2001:db8::4/128 30 - rt4 implicit-null
+ 2001:db8::5/128 30 - rt2 16051
+ 2001:db8::6/128 40 - rt3 20061
+ 2001:db8::7/128 40 - rt4 16071
+ 2001:db8::8/128 40 - rt2 16081
test# test isis topology 11 root rt1 spf
IS-IS paths to level-1 routers that speak IP
@@ -506,14 +520,15 @@ rt6 TE-IS 30 rt2 - rt4(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt2 -
- - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ - rt3 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -535,14 +550,15 @@ rt6 TE-IS 30 rt2 - rt4(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------
- 2001:db8::2/128 20 - rt2 -
- 2001:db8::3/128 20 - rt3 -
- 2001:db8::4/128 30 - rt2 -
- 2001:db8::5/128 30 - rt3 -
- 2001:db8::6/128 40 - rt2 -
- - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::2/128 20 - rt2 implicit-null
+ 2001:db8::3/128 20 - rt3 implicit-null
+ 2001:db8::4/128 30 - rt2 16041
+ 2001:db8::5/128 30 - rt3 16051
+ 2001:db8::6/128 40 - rt2 16061
+ - rt3 16061
test# test isis topology 12 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -570,17 +586,18 @@ rt10 TE-IS 50 rt2 - rt8(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- ------------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt2 -
- 10.0.255.7/32 40 - rt3 -
- 10.0.255.8/32 50 - rt2 -
- 10.0.255.9/32 50 - rt3 -
- 10.0.255.10/32 60 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ 10.0.255.7/32 40 - rt3 16070
+ 10.0.255.8/32 50 - rt2 16080
+ 10.0.255.9/32 50 - rt3 16090
+ 10.0.255.10/32 60 - rt2 16100
test# test isis topology 13 root rt1 spf ipv4-only
IS-IS paths to level-1 routers that speak IP
@@ -605,15 +622,16 @@ rt7 TE-IS 30 rt3 - rt5(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- - rt3 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 30 - rt3 -
- 10.0.255.7/32 40 - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ - rt3 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 30 - rt3 16060
+ 10.0.255.7/32 40 - rt3 16070
test#
test# test isis topology 4 root rt1 reverse-spf ipv4-only
@@ -638,15 +656,16 @@ rt8 TE-IS 40 rt2 - rt6(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.2/32 20 - rt2 -
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.4/32 30 - rt2 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt2 -
- 10.0.255.7/32 40 - rt3 -
- 10.0.255.8/32 50 - rt2 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ 10.0.255.7/32 40 - rt3 16070
+ 10.0.255.8/32 50 - rt2 16080
test# test isis topology 11 root rt1 reverse-spf
IS-IS paths to level-1 routers that speak IP
@@ -668,11 +687,12 @@ rt6 TE-IS 30 rt3 - rt4(4) IS-IS L1 IPv4 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -----------------------------------------------------
- 10.0.255.3/32 20 - rt3 -
- 10.0.255.5/32 30 - rt3 -
- 10.0.255.6/32 40 - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt3 16060
IS-IS paths to level-1 routers that speak IPv6
Vertex Type Metric Next-Hop Interface Parent
@@ -693,11 +713,1781 @@ rt6 TE-IS 30 rt3 - rt4(4) IS-IS L1 IPv6 routing table:
- Prefix Metric Interface Nexthop Label(s)
- -------------------------------------------------------
- 2001:db8::3/128 20 - rt3 -
- 2001:db8::5/128 30 - rt3 -
- 2001:db8::6/128 40 - rt3 -
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::3/128 20 - rt3 implicit-null
+ 2001:db8::5/128 30 - rt3 16051
+ 2001:db8::6/128 40 - rt3 16061
+
+test#
+test# test isis topology 1 root rt1 ti-lfa system-id rt2
+P-space (self):
+ rt3
+ rt5
+
+P-space (rt3):
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt2
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt3 - rt5(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt4 TE-IS 40 rt3 - rt6(4)
+10.0.255.6/32 IP TE 40 rt3 - rt6(4)
+rt2 TE-IS 50 rt3 - rt4(4)
+10.0.255.4/32 IP TE 50 rt3 - rt4(4)
+10.0.255.2/32 IP TE 60 rt3 - rt2(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.2/32 60 - rt3 16060/16020
+ 10.0.255.4/32 50 - rt3 16060/16040
+
+P-space (self):
+ rt3
+ rt5
+
+P-space (rt3):
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt2
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt3 - rt5(4)
+2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
+rt4 TE-IS 40 rt3 - rt6(4)
+2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
+rt2 TE-IS 50 rt3 - rt4(4)
+2001:db8::4/128 IP6 internal 50 rt3 - rt4(4)
+2001:db8::2/128 IP6 internal 60 rt3 - rt2(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 2001:db8::2/128 60 - rt3 16061/16021
+ 2001:db8::4/128 50 - rt3 16061/16041
+
+test# test isis topology 2 root rt1 ti-lfa system-id rt3
+P-space (self):
+ rt2
+ rt4
+ rt5
+ rt6
+
+P-space (rt2):
+ rt2
+
+P-space (rt4):
+ rt2
+ rt4
+ rt5
+ rt6
+
+P-space (rt5):
+ rt2
+ rt4
+ rt5
+ rt6
+
+Q-space:
+ rt3
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt4 TE-IS 10 rt4 - rt1(4)
+rt5 TE-IS 10 rt5 - rt1(4)
+rt2 TE-IS 15 rt2 - rt1(4)
+rt1
+rt6 TE-IS 20 rt4 - rt4(4)
+ rt5 - rt5(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.5/32 IP TE 20 rt5 - rt5(4)
+10.0.255.2/32 IP TE 25 rt2 - rt2(4)
+10.0.255.6/32 IP TE 30 rt4 - rt6(4)
+ rt5 -
+rt3 TE-IS 50 rt5 - rt5(4)
+10.0.255.3/32 IP TE 60 rt5 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.3/32 60 - rt5 16050/18/16030
+
+P-space (self):
+ rt2
+ rt4
+ rt5
+ rt6
+
+P-space (rt2):
+ rt2
+
+P-space (rt4):
+ rt2
+ rt4
+ rt5
+ rt6
+
+P-space (rt5):
+ rt2
+ rt4
+ rt5
+ rt6
+
+Q-space:
+ rt3
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt4 TE-IS 10 rt4 - rt1(4)
+rt5 TE-IS 10 rt5 - rt1(4)
+rt2 TE-IS 15 rt2 - rt1(4)
+rt1
+rt6 TE-IS 20 rt4 - rt4(4)
+ rt5 - rt5(4)
+2001:db8::4/128 IP6 internal 20 rt4 - rt4(4)
+2001:db8::5/128 IP6 internal 20 rt5 - rt5(4)
+2001:db8::2/128 IP6 internal 25 rt2 - rt2(4)
+2001:db8::6/128 IP6 internal 30 rt4 - rt6(4)
+ rt5 -
+rt3 TE-IS 50 rt5 - rt5(4)
+2001:db8::3/128 IP6 internal 60 rt5 - rt3(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::3/128 60 - rt5 16051/19/16031
+
+test# test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1
+P-space (self):
+ rt2
+ rt3
+
+P-space (rt2):
+ rt2
+ rt3
+
+P-space (rt3):
+ rt2
+ rt3
+
+Q-space:
+ rt4
+ rt5
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 15 rt2 - rt1(4)
+10.0.255.2/32 IP TE 25 rt2 - rt2(4)
+rt3 TE-IS 30 rt3 - rt1(4)
+10.0.255.3/32 IP TE 40 rt3 - rt3(4)
+rt4 TE-IS 55 rt2 - rt2(4)
+rt1
+rt6 TE-IS 65 rt2 - rt4(4)
+rt5 TE-IS 65 rt2 - rt1(2)
+10.0.255.4/32 IP TE 65 rt2 - rt4(4)
+10.0.255.6/32 IP TE 75 rt2 - rt6(4)
+10.0.255.5/32 IP TE 75 rt2 - rt5(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.4/32 65 - rt2 16020/18/16040
+ 10.0.255.5/32 75 - rt2 16020/18/16050
+ 10.0.255.6/32 75 - rt2 16020/18/16060
+
+P-space (self):
+ rt2
+ rt3
+
+P-space (rt2):
+ rt2
+ rt3
+
+P-space (rt3):
+ rt2
+ rt3
+
+Q-space:
+ rt4
+ rt5
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 15 rt2 - rt1(4)
+2001:db8::2/128 IP6 internal 25 rt2 - rt2(4)
+rt3 TE-IS 30 rt3 - rt1(4)
+2001:db8::3/128 IP6 internal 40 rt3 - rt3(4)
+rt4 TE-IS 55 rt2 - rt2(4)
+rt1
+rt6 TE-IS 65 rt2 - rt4(4)
+rt5 TE-IS 65 rt2 - rt1(2)
+2001:db8::4/128 IP6 internal 65 rt2 - rt4(4)
+2001:db8::6/128 IP6 internal 75 rt2 - rt6(4)
+2001:db8::5/128 IP6 internal 75 rt2 - rt5(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::4/128 65 - rt2 16021/19/16041
+ 2001:db8::5/128 75 - rt2 16021/19/16051
+ 2001:db8::6/128 75 - rt2 16021/19/16061
+
+test# test isis topology 2 root rt5 ti-lfa system-id rt1 pseudonode-id 1
+P-space (self):
+ rt6
+
+P-space (rt3):
+ rt1
+ rt2
+ rt3
+ rt4
+
+P-space (rt6):
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt4 TE-IS 20 rt6 - rt6(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt1 pseudo_TE-IS 30 rt6 - rt4(4)
+rt1 TE-IS 30 rt6 - rt1(2)
+10.0.255.4/32 IP TE 30 rt6 - rt4(4)
+rt3 TE-IS 40 rt3 - rt5(4)
+10.0.255.1/32 IP TE 40 rt6 - rt1(4)
+rt2 TE-IS 45 rt6 - rt1(4)
+10.0.255.3/32 IP TE 50 rt3 - rt3(4)
+10.0.255.2/32 IP TE 55 rt6 - rt2(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.1/32 40 - rt6 16040/16010
+ 10.0.255.2/32 55 - rt6 16040/16020
+ 10.0.255.4/32 30 - rt6 16040
+
+P-space (self):
+ rt6
+
+P-space (rt3):
+ rt1
+ rt2
+ rt3
+ rt4
+
+P-space (rt6):
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+2001:db8::5/128 IP6 internal 0 rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt4 TE-IS 20 rt6 - rt6(4)
+2001:db8::6/128 IP6 internal 20 rt6 - rt6(4)
+rt1 pseudo_TE-IS 30 rt6 - rt4(4)
+rt1 TE-IS 30 rt6 - rt1(2)
+2001:db8::4/128 IP6 internal 30 rt6 - rt4(4)
+rt3 TE-IS 40 rt3 - rt5(4)
+2001:db8::1/128 IP6 internal 40 rt6 - rt1(4)
+rt2 TE-IS 45 rt6 - rt1(4)
+2001:db8::3/128 IP6 internal 50 rt3 - rt3(4)
+2001:db8::2/128 IP6 internal 55 rt6 - rt2(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 2001:db8::1/128 40 - rt6 16041/16011
+ 2001:db8::2/128 55 - rt6 16041/16021
+ 2001:db8::4/128 30 - rt6 16041
+
+test# test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only
+P-space (self):
+ rt6
+
+P-space (rt3):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+P-space (rt6):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt4 TE-IS 20 rt6 - rt6(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt3 TE-IS 30 rt3 - rt5(4)
+rt2 TE-IS 30 rt6 - rt4(4)
+10.0.255.4/32 IP TE 30 rt6 - rt4(4)
+rt1 TE-IS 40 rt3 - rt3(4)
+ rt6 - rt2(4)
+10.0.255.3/32 IP TE 40 rt3 - rt3(4)
+10.0.255.2/32 IP TE 40 rt6 - rt2(4)
+10.0.255.1/32 IP TE 50 rt3 - rt1(4)
+ rt6 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.1/32 50 - rt3 16010
+ - rt6 16010
+ 10.0.255.2/32 40 - rt6 16020
+ 10.0.255.4/32 30 - rt6 16040
+
+test# test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt1
+ rt2
+ rt4
+ rt6
+
+P-space (rt4):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+P-space (rt6):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt4 TE-IS 10 rt4 - rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt2 TE-IS 20 rt4 - rt4(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt1 TE-IS 30 rt4 - rt2(4)
+rt3 TE-IS 30 rt4 - rt2(4)
+10.0.255.2/32 IP TE 30 rt4 - rt2(4)
+10.0.255.1/32 IP TE 40 rt4 - rt1(4)
+10.0.255.3/32 IP TE 40 rt4 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+test# test isis topology 4 root rt1 ti-lfa system-id rt2 ipv4-only
+P-space (self):
+ rt3
+ rt5
+ rt7
+
+P-space (rt3):
+ rt3
+ rt5
+ rt7
+
+Q-space:
+ rt2
+ rt4
+ rt6
+ rt8
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+rt6 TE-IS 70 rt3 - rt5(4)
+rt4 TE-IS 80 rt3 - rt6(4)
+rt8 TE-IS 80 rt3 - rt6(4)
+10.0.255.6/32 IP TE 80 rt3 - rt6(4)
+rt2 TE-IS 90 rt3 - rt4(4)
+10.0.255.4/32 IP TE 90 rt3 - rt4(4)
+10.0.255.8/32 IP TE 90 rt3 - rt8(4)
+10.0.255.2/32 IP TE 100 rt3 - rt2(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.2/32 100 - rt3 16050/17/16020
+ 10.0.255.4/32 90 - rt3 16050/17/16040
+ 10.0.255.6/32 80 - rt3 16050/17/16060
+ 10.0.255.8/32 90 - rt3 16050/17/16080
+
+test# test isis topology 4 root rt4 ti-lfa system-id rt6 ipv4-only
+P-space (self):
+ rt1
+ rt2
+ rt3
+ rt5
+ rt7
+
+P-space (rt2):
+ rt1
+ rt2
+ rt3
+ rt5
+ rt7
+
+Q-space:
+ rt6
+ rt8
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt4
+10.0.255.4/32 IP internal 0 rt4(4)
+rt2 TE-IS 10 rt2 - rt4(4)
+rt1 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt3 TE-IS 30 rt2 - rt1(4)
+10.0.255.1/32 IP TE 30 rt2 - rt1(4)
+rt5 TE-IS 40 rt2 - rt3(4)
+10.0.255.3/32 IP TE 40 rt2 - rt3(4)
+rt7 TE-IS 50 rt2 - rt5(4)
+10.0.255.5/32 IP TE 50 rt2 - rt5(4)
+10.0.255.7/32 IP TE 60 rt2 - rt7(4)
+rt6 TE-IS 90 rt2 - rt5(4)
+rt8 TE-IS 100 rt2 - rt6(4)
+10.0.255.6/32 IP TE 100 rt2 - rt6(4)
+10.0.255.8/32 IP TE 110 rt2 - rt8(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.6/32 100 - rt2 16050/17/16060
+ 10.0.255.8/32 110 - rt2 16050/17/16080
+
+test# test isis topology 5 root rt1 ti-lfa system-id rt2 ipv4-only
+P-space (self):
+ rt3
+ rt5
+ rt7
+
+P-space (rt3):
+ rt3
+ rt5
+ rt7
+ rt8
+
+Q-space:
+ rt2
+ rt4
+ rt6
+ rt8
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt3 - rt7(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+rt6 TE-IS 50 rt3 - rt8(4)
+10.0.255.8/32 IP TE 50 rt3 - rt8(4)
+rt4 TE-IS 60 rt3 - rt6(4)
+10.0.255.6/32 IP TE 60 rt3 - rt6(4)
+rt2 TE-IS 70 rt3 - rt4(4)
+10.0.255.4/32 IP TE 70 rt3 - rt4(4)
+10.0.255.2/32 IP TE 80 rt3 - rt2(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.2/32 80 - rt3 16080/16020
+ 10.0.255.4/32 70 - rt3 16080/16040
+ 10.0.255.6/32 60 - rt3 16080/16060
+
+test# test isis topology 6 root rt4 ti-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt2
+ rt5
+ rt6
+ rt7
+ rt8
+
+P-space (rt2):
+ rt1
+ rt2
+
+P-space (rt6):
+ rt5
+ rt6
+ rt7
+ rt8
+
+Q-space:
+ rt1
+ rt3
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt4
+10.0.255.4/32 IP internal 0 rt4(4)
+rt2 TE-IS 10 rt2 - rt4(4)
+rt6 TE-IS 10 rt6 - rt4(4)
+rt1 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt6 - rt6(4)
+rt8 TE-IS 20 rt6 - rt6(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt3 TE-IS 30 rt2 - rt1(4)
+rt7 TE-IS 30 rt6 - rt5(4)
+ rt8(4)
+10.0.255.1/32 IP TE 30 rt2 - rt1(4)
+10.0.255.5/32 IP TE 30 rt6 - rt5(4)
+10.0.255.8/32 IP TE 30 rt6 - rt8(4)
+10.0.255.3/32 IP TE 40 rt2 - rt3(4)
+10.0.255.7/32 IP TE 40 rt6 - rt7(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.3/32 40 - rt2 16010/16030
+
+test# test isis topology 7 root rt11 ti-lfa system-id rt8 ipv4-only
+P-space (self):
+ rt10
+ rt12
+
+P-space (rt10):
+ rt1
+ rt4
+ rt7
+ rt10
+
+P-space (rt12):
+ rt9
+ rt12
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt11
+10.0.255.11/32 IP internal 0 rt11(4)
+rt10 TE-IS 10 rt10 - rt11(4)
+rt12 TE-IS 10 rt12 - rt11(4)
+rt9 TE-IS 20 rt12 - rt12(4)
+10.0.255.10/32 IP TE 20 rt10 - rt10(4)
+10.0.255.12/32 IP TE 20 rt12 - rt12(4)
+rt7 TE-IS 30 rt10 - rt10(4)
+rt8 TE-IS 30 rt12 - rt9(4)
+10.0.255.9/32 IP TE 30 rt12 - rt9(4)
+rt4 TE-IS 40 rt10 - rt7(4)
+rt5 TE-IS 40 rt12 - rt8(4)
+10.0.255.7/32 IP TE 40 rt10 - rt7(4)
+10.0.255.8/32 IP TE 40 rt12 - rt8(4)
+rt6 TE-IS 50 rt12 - rt9(4)
+ rt5(4)
+rt1 TE-IS 50 rt10 - rt4(4)
+rt2 TE-IS 50 rt12 - rt5(4)
+10.0.255.4/32 IP TE 50 rt10 - rt4(4)
+10.0.255.5/32 IP TE 50 rt12 - rt5(4)
+rt3 TE-IS 60 rt12 - rt6(4)
+ rt2(4)
+10.0.255.6/32 IP TE 60 rt12 - rt6(4)
+10.0.255.1/32 IP TE 60 rt10 - rt1(4)
+10.0.255.2/32 IP TE 60 rt12 - rt2(4)
+10.0.255.3/32 IP TE 70 rt12 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.1/32 60 - rt10 16010
+ 10.0.255.2/32 60 - rt12 16090/16020
+ 10.0.255.3/32 70 - rt12 16090/16030
+ 10.0.255.4/32 50 - rt10 16040
+ 10.0.255.5/32 50 - rt12 16090/16050
+ 10.0.255.6/32 60 - rt12 16090/16060
+ 10.0.255.7/32 40 - rt10 16070
+ 10.0.255.8/32 40 - rt12 16090/16080
+
+test# test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only
+P-space (self):
+ rt3
+
+P-space (rt3):
+ rt2
+ rt3
+
+P-space (rt9):
+ rt1
+ rt2
+ rt4
+ rt5
+ rt7
+ rt8
+ rt9
+ rt10
+ rt11
+ rt12
+
+Q-space:
+ rt1
+ rt2
+ rt4
+ rt5
+ rt7
+ rt8
+ rt9
+ rt10
+ rt11
+ rt12
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt6
+10.0.255.6/32 IP internal 0 rt6(4)
+rt3 TE-IS 10 rt3 - rt6(4)
+rt2 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt9 TE-IS 30 rt9 - rt6(4)
+rt5 TE-IS 30 rt3 - rt2(4)
+10.0.255.2/32 IP TE 30 rt3 - rt2(4)
+rt8 TE-IS 40 rt9 - rt9(4)
+ rt3 - rt5(4)
+rt12 TE-IS 40 rt9 - rt9(4)
+rt4 TE-IS 40 rt3 - rt5(4)
+10.0.255.9/32 IP TE 40 rt9 - rt9(4)
+10.0.255.5/32 IP TE 40 rt3 - rt5(4)
+rt7 TE-IS 50 rt9 - rt8(4)
+ rt3 - rt4(4)
+rt11 TE-IS 50 rt9 - rt8(4)
+ rt3 - rt12(4)
+rt1 TE-IS 50 rt3 - rt4(4)
+10.0.255.8/32 IP TE 50 rt9 - rt8(4)
+ rt3 -
+10.0.255.12/32 IP TE 50 rt9 - rt12(4)
+10.0.255.4/32 IP TE 50 rt3 - rt4(4)
+rt10 TE-IS 60 rt9 - rt11(4)
+ rt3 -
+10.0.255.7/32 IP TE 60 rt9 - rt7(4)
+ rt3 -
+10.0.255.11/32 IP TE 60 rt9 - rt11(4)
+ rt3 -
+10.0.255.1/32 IP TE 60 rt3 - rt1(4)
+10.0.255.10/32 IP TE 70 rt9 - rt10(4)
+ rt3 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ---------------------------------------------------------
+ 10.0.255.1/32 60 - rt3 16020/16010
+ 10.0.255.4/32 50 - rt3 16020/16040
+ 10.0.255.5/32 40 - rt3 16020/16050
+ 10.0.255.7/32 60 - rt9 16070
+ - rt3 16070
+ 10.0.255.8/32 50 - rt9 16080
+ - rt3 16080
+ 10.0.255.10/32 70 - rt9 16100
+ - rt3 16100
+ 10.0.255.11/32 60 - rt9 16110
+ - rt3 16110
+
+test# test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only
+P-space (self):
+ rt3
+ rt5
+ rt6
+ rt8
+ rt9
+ rt11
+ rt12
+
+P-space (rt3):
+ rt3
+ rt6
+
+P-space (rt5):
+ rt5
+ rt6
+ rt8
+ rt9
+ rt11
+ rt12
+
+Q-space:
+ rt1
+ rt4
+ rt7
+ rt10
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt3 TE-IS 10 rt3 - rt2(4)
+rt5 TE-IS 10 rt5 - rt2(4)
+rt6 TE-IS 20 rt3 - rt3(4)
+ rt5 - rt5(4)
+rt8 TE-IS 20 rt5 - rt5(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+10.0.255.5/32 IP TE 20 rt5 - rt5(4)
+rt9 TE-IS 30 rt5 - rt8(4)
+rt11 TE-IS 30 rt5 - rt8(4)
+10.0.255.6/32 IP TE 30 rt3 - rt6(4)
+ rt5 -
+10.0.255.8/32 IP TE 30 rt5 - rt8(4)
+rt12 TE-IS 40 rt5 - rt9(4)
+ rt11(4)
+10.0.255.9/32 IP TE 40 rt5 - rt9(4)
+10.0.255.11/32 IP TE 40 rt5 - rt11(4)
+10.0.255.12/32 IP TE 50 rt5 - rt12(4)
+rt10 TE-IS 60 rt5 - rt11(4)
+rt7 TE-IS 70 rt5 - rt10(4)
+10.0.255.10/32 IP TE 70 rt5 - rt10(4)
+rt4 TE-IS 80 rt5 - rt7(4)
+10.0.255.7/32 IP TE 80 rt5 - rt7(4)
+rt1 TE-IS 90 rt5 - rt4(4)
+10.0.255.4/32 IP TE 90 rt5 - rt4(4)
+10.0.255.1/32 IP TE 100 rt5 - rt1(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 10.0.255.1/32 100 - rt5 16110/17/16010
+ 10.0.255.4/32 90 - rt5 16110/17/16040
+ 10.0.255.7/32 80 - rt5 16110/17/16070
+ 10.0.255.10/32 70 - rt5 16110/17/16100
+
+test# test isis topology 8 root rt2 ti-lfa system-id rt5 ipv4-only
+P-space (self):
+ rt1
+ rt3
+ rt4
+ rt7
+ rt10
+
+P-space (rt1):
+ rt1
+ rt4
+ rt7
+ rt10
+
+P-space (rt3):
+ rt3
+ rt6
+
+Q-space:
+ rt5
+ rt6
+ rt8
+ rt9
+ rt11
+ rt12
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt1 TE-IS 10 rt1 - rt2(4)
+rt3 TE-IS 10 rt3 - rt2(4)
+rt4 TE-IS 20 rt1 - rt1(4)
+rt6 TE-IS 20 rt3 - rt3(4)
+10.0.255.1/32 IP TE 20 rt1 - rt1(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt1 - rt4(4)
+rt5 TE-IS 30 rt3 - rt6(4)
+10.0.255.4/32 IP TE 30 rt1 - rt4(4)
+10.0.255.6/32 IP TE 30 rt3 - rt6(4)
+rt10 TE-IS 40 rt1 - rt7(4)
+rt8 TE-IS 40 rt3 - rt5(4)
+10.0.255.7/32 IP TE 40 rt1 - rt7(4)
+10.0.255.5/32 IP TE 40 rt3 - rt5(4)
+rt9 TE-IS 50 rt3 - rt8(4)
+rt11 TE-IS 50 rt3 - rt8(4)
+10.0.255.10/32 IP TE 50 rt1 - rt10(4)
+10.0.255.8/32 IP TE 50 rt3 - rt8(4)
+rt12 TE-IS 60 rt3 - rt9(4)
+ rt11(4)
+10.0.255.9/32 IP TE 60 rt3 - rt9(4)
+10.0.255.11/32 IP TE 60 rt3 - rt11(4)
+10.0.255.12/32 IP TE 70 rt3 - rt12(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ---------------------------------------------------------
+ 10.0.255.5/32 40 - rt3 16060/16050
+ 10.0.255.8/32 50 - rt3 16060/16080
+ 10.0.255.9/32 60 - rt3 16060/16090
+ 10.0.255.11/32 60 - rt3 16060/16110
+ 10.0.255.12/32 70 - rt3 16060/16120
+
+test# test isis topology 9 root rt1 ti-lfa system-id rt3
+P-space (self):
+ rt2
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+P-space (rt2):
+ rt2
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+Q-space:
+ rt3
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt5 TE-IS 30 rt2 - rt4(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+rt9 TE-IS 40 rt2 - rt5(4)
+10.0.255.5/32 IP TE 40 rt2 - rt5(4)
+rt6 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt7 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt8 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+10.0.255.9/32 IP TE 50 rt2 - rt9(4)
+10.0.255.6/32 IP TE 60 rt2 - rt6(4)
+10.0.255.7/32 IP TE 60 rt2 - rt7(4)
+10.0.255.8/32 IP TE 60 rt2 - rt8(4)
+rt3 TE-IS 120 rt2 - rt4(4)
+10.0.255.3/32 IP TE 130 rt2 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.3/32 130 - rt2 16040/18/16030
+
+P-space (self):
+ rt2
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+P-space (rt2):
+ rt2
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+Q-space:
+ rt3
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+rt5 TE-IS 30 rt2 - rt4(4)
+2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
+rt9 TE-IS 40 rt2 - rt5(4)
+2001:db8::5/128 IP6 internal 40 rt2 - rt5(4)
+rt6 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt7 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt8 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+2001:db8::9/128 IP6 internal 50 rt2 - rt9(4)
+2001:db8::6/128 IP6 internal 60 rt2 - rt6(4)
+2001:db8::7/128 IP6 internal 60 rt2 - rt7(4)
+2001:db8::8/128 IP6 internal 60 rt2 - rt8(4)
+rt3 TE-IS 120 rt2 - rt4(4)
+2001:db8::3/128 IP6 internal 130 rt2 - rt3(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::3/128 130 - rt2 16041/19/16031
+
+test# test isis topology 9 root rt1 ti-lfa system-id rt2
+P-space (self):
+ rt3
+
+P-space (rt3):
+ rt3
+
+Q-space:
+ rt2
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt4 TE-IS 110 rt3 - rt3(4)
+rt2 TE-IS 120 rt3 - rt4(4)
+rt5 TE-IS 120 rt3 - rt4(4)
+10.0.255.4/32 IP TE 120 rt3 - rt4(4)
+rt9 TE-IS 130 rt3 - rt5(4)
+10.0.255.2/32 IP TE 130 rt3 - rt2(4)
+10.0.255.5/32 IP TE 130 rt3 - rt5(4)
+rt6 TE-IS 140 rt3 - rt4(4)
+ rt9(4)
+rt7 TE-IS 140 rt3 - rt4(4)
+ rt9(4)
+rt8 TE-IS 140 rt3 - rt4(4)
+ rt9(4)
+10.0.255.9/32 IP TE 140 rt3 - rt9(4)
+10.0.255.6/32 IP TE 150 rt3 - rt6(4)
+10.0.255.7/32 IP TE 150 rt3 - rt7(4)
+10.0.255.8/32 IP TE 150 rt3 - rt8(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.2/32 130 - rt3 16030/18/16020
+ 10.0.255.4/32 120 - rt3 16030/18/16040
+ 10.0.255.5/32 130 - rt3 16030/18/16050
+ 10.0.255.6/32 150 - rt3 16030/18/16060
+ 10.0.255.7/32 150 - rt3 16030/18/16070
+ 10.0.255.8/32 150 - rt3 16030/18/16080
+ 10.0.255.9/32 140 - rt3 16030/18/16090
+
+P-space (self):
+ rt3
+
+P-space (rt3):
+ rt3
+
+Q-space:
+ rt2
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt4 TE-IS 110 rt3 - rt3(4)
+rt2 TE-IS 120 rt3 - rt4(4)
+rt5 TE-IS 120 rt3 - rt4(4)
+2001:db8::4/128 IP6 internal 120 rt3 - rt4(4)
+rt9 TE-IS 130 rt3 - rt5(4)
+2001:db8::2/128 IP6 internal 130 rt3 - rt2(4)
+2001:db8::5/128 IP6 internal 130 rt3 - rt5(4)
+rt6 TE-IS 140 rt3 - rt4(4)
+ rt9(4)
+rt7 TE-IS 140 rt3 - rt4(4)
+ rt9(4)
+rt8 TE-IS 140 rt3 - rt4(4)
+ rt9(4)
+2001:db8::9/128 IP6 internal 140 rt3 - rt9(4)
+2001:db8::6/128 IP6 internal 150 rt3 - rt6(4)
+2001:db8::7/128 IP6 internal 150 rt3 - rt7(4)
+2001:db8::8/128 IP6 internal 150 rt3 - rt8(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::2/128 130 - rt3 16031/19/16021
+ 2001:db8::4/128 120 - rt3 16031/19/16041
+ 2001:db8::5/128 130 - rt3 16031/19/16051
+ 2001:db8::6/128 150 - rt3 16031/19/16061
+ 2001:db8::7/128 150 - rt3 16031/19/16071
+ 2001:db8::8/128 150 - rt3 16031/19/16081
+ 2001:db8::9/128 140 - rt3 16031/19/16091
+
+test# test isis topology 9 root rt9 ti-lfa system-id rt5
+P-space (self):
+ rt6
+ rt7
+ rt8
+
+P-space (rt6):
+ rt6
+
+P-space (rt7):
+ rt7
+
+P-space (rt8):
+ rt8
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt9
+10.0.255.9/32 IP internal 0 rt9(4)
+rt6 TE-IS 10 rt6 - rt9(4)
+rt7 TE-IS 10 rt7 - rt9(4)
+rt8 TE-IS 10 rt8 - rt9(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+10.0.255.7/32 IP TE 20 rt7 - rt7(4)
+10.0.255.8/32 IP TE 20 rt8 - rt8(4)
+rt4 TE-IS 40 rt6 - rt6(4)
+ rt7 - rt7(4)
+ rt8 - rt8(4)
+rt2 TE-IS 50 rt6 - rt4(4)
+ rt7 -
+ rt8 -
+rt5 TE-IS 50 rt6 - rt4(4)
+ rt7 -
+ rt8 -
+10.0.255.4/32 IP TE 50 rt6 - rt4(4)
+ rt7 -
+ rt8 -
+rt1 TE-IS 60 rt6 - rt2(4)
+ rt7 -
+ rt8 -
+10.0.255.2/32 IP TE 60 rt6 - rt2(4)
+ rt7 -
+ rt8 -
+10.0.255.5/32 IP TE 60 rt6 - rt5(4)
+ rt7 -
+ rt8 -
+rt3 TE-IS 70 rt6 - rt1(4)
+ rt7 -
+ rt8 -
+10.0.255.1/32 IP TE 70 rt6 - rt1(4)
+ rt7 -
+ rt8 -
+10.0.255.3/32 IP TE 80 rt6 - rt3(4)
+ rt7 -
+ rt8 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 70 - rt6 16060/16/16010
+ - rt7 16070/16/16010
+ - rt8 16080/16/16010
+ 10.0.255.2/32 60 - rt6 16060/16/16020
+ - rt7 16070/16/16020
+ - rt8 16080/16/16020
+ 10.0.255.3/32 80 - rt6 16060/16/16030
+ - rt7 16070/16/16030
+ - rt8 16080/16/16030
+ 10.0.255.4/32 50 - rt6 16060/16/16040
+ - rt7 16070/16/16040
+ - rt8 16080/16/16040
+ 10.0.255.5/32 60 - rt6 16060/16/16050
+ - rt7 16070/16/16050
+ - rt8 16080/16/16050
+
+P-space (self):
+ rt6
+ rt7
+ rt8
+
+P-space (rt6):
+ rt6
+
+P-space (rt7):
+ rt7
+
+P-space (rt8):
+ rt8
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt9
+2001:db8::9/128 IP6 internal 0 rt9(4)
+rt6 TE-IS 10 rt6 - rt9(4)
+rt7 TE-IS 10 rt7 - rt9(4)
+rt8 TE-IS 10 rt8 - rt9(4)
+2001:db8::6/128 IP6 internal 20 rt6 - rt6(4)
+2001:db8::7/128 IP6 internal 20 rt7 - rt7(4)
+2001:db8::8/128 IP6 internal 20 rt8 - rt8(4)
+rt4 TE-IS 40 rt6 - rt6(4)
+ rt7 - rt7(4)
+ rt8 - rt8(4)
+rt2 TE-IS 50 rt6 - rt4(4)
+ rt7 -
+ rt8 -
+rt5 TE-IS 50 rt6 - rt4(4)
+ rt7 -
+ rt8 -
+2001:db8::4/128 IP6 internal 50 rt6 - rt4(4)
+ rt7 -
+ rt8 -
+rt1 TE-IS 60 rt6 - rt2(4)
+ rt7 -
+ rt8 -
+2001:db8::2/128 IP6 internal 60 rt6 - rt2(4)
+ rt7 -
+ rt8 -
+2001:db8::5/128 IP6 internal 60 rt6 - rt5(4)
+ rt7 -
+ rt8 -
+rt3 TE-IS 70 rt6 - rt1(4)
+ rt7 -
+ rt8 -
+2001:db8::1/128 IP6 internal 70 rt6 - rt1(4)
+ rt7 -
+ rt8 -
+2001:db8::3/128 IP6 internal 80 rt6 - rt3(4)
+ rt7 -
+ rt8 -
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::1/128 70 - rt6 16061/17/16011
+ - rt7 16071/17/16011
+ - rt8 16081/17/16011
+ 2001:db8::2/128 60 - rt6 16061/17/16021
+ - rt7 16071/17/16021
+ - rt8 16081/17/16021
+ 2001:db8::3/128 80 - rt6 16061/17/16031
+ - rt7 16071/17/16031
+ - rt8 16081/17/16031
+ 2001:db8::4/128 50 - rt6 16061/17/16041
+ - rt7 16071/17/16041
+ - rt8 16081/17/16041
+ 2001:db8::5/128 60 - rt6 16061/17/16051
+ - rt7 16071/17/16051
+ - rt8 16081/17/16051
+
+test# test isis topology 9 root rt9 ti-lfa system-id rt8
+P-space (self):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+ rt6
+ rt7
+
+P-space (rt5):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+
+P-space (rt6):
+ rt6
+
+P-space (rt7):
+ rt7
+
+Q-space:
+ rt8
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt9
+10.0.255.9/32 IP internal 0 rt9(4)
+rt5 TE-IS 10 rt5 - rt9(4)
+rt6 TE-IS 10 rt6 - rt9(4)
+rt7 TE-IS 10 rt7 - rt9(4)
+rt4 TE-IS 20 rt5 - rt5(4)
+10.0.255.5/32 IP TE 20 rt5 - rt5(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+10.0.255.7/32 IP TE 20 rt7 - rt7(4)
+rt2 TE-IS 30 rt5 - rt4(4)
+10.0.255.4/32 IP TE 30 rt5 - rt4(4)
+rt1 TE-IS 40 rt5 - rt2(4)
+10.0.255.2/32 IP TE 40 rt5 - rt2(4)
+rt8 TE-IS 50 rt5 - rt4(4)
+rt3 TE-IS 50 rt5 - rt1(4)
+10.0.255.1/32 IP TE 50 rt5 - rt1(4)
+10.0.255.8/32 IP TE 60 rt5 - rt8(4)
+10.0.255.3/32 IP TE 60 rt5 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.8/32 60 - rt5 16040/26/16080
+
+P-space (self):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+ rt6
+ rt7
+
+P-space (rt5):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+
+P-space (rt6):
+ rt6
+
+P-space (rt7):
+ rt7
+
+Q-space:
+ rt8
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt9
+2001:db8::9/128 IP6 internal 0 rt9(4)
+rt5 TE-IS 10 rt5 - rt9(4)
+rt6 TE-IS 10 rt6 - rt9(4)
+rt7 TE-IS 10 rt7 - rt9(4)
+rt4 TE-IS 20 rt5 - rt5(4)
+2001:db8::5/128 IP6 internal 20 rt5 - rt5(4)
+2001:db8::6/128 IP6 internal 20 rt6 - rt6(4)
+2001:db8::7/128 IP6 internal 20 rt7 - rt7(4)
+rt2 TE-IS 30 rt5 - rt4(4)
+2001:db8::4/128 IP6 internal 30 rt5 - rt4(4)
+rt1 TE-IS 40 rt5 - rt2(4)
+2001:db8::2/128 IP6 internal 40 rt5 - rt2(4)
+rt8 TE-IS 50 rt5 - rt4(4)
+rt3 TE-IS 50 rt5 - rt1(4)
+2001:db8::1/128 IP6 internal 50 rt5 - rt1(4)
+2001:db8::8/128 IP6 internal 60 rt5 - rt8(4)
+2001:db8::3/128 IP6 internal 60 rt5 - rt3(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::8/128 60 - rt5 16041/27/16081
+
+test# test isis topology 10 root rt1 ti-lfa system-id rt2
+P-space (self):
+ rt3
+ rt4
+ rt6
+ rt7
+
+P-space (rt3):
+ rt3
+ rt6
+
+P-space (rt4):
+ rt4
+ rt7
+
+Q-space:
+ rt2
+ rt5
+ rt8
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 20 rt3 - rt1(4)
+rt4 TE-IS 20 rt4 - rt1(4)
+rt6 TE-IS 30 rt3 - rt3(4)
+rt7 TE-IS 30 rt4 - rt4(4)
+10.0.255.3/32 IP TE 30 rt3 - rt3(4)
+10.0.255.4/32 IP TE 30 rt4 - rt4(4)
+10.0.255.6/32 IP TE 40 rt3 - rt6(4)
+10.0.255.7/32 IP TE 40 rt4 - rt7(4)
+rt8 TE-IS 80 rt3 - rt6(4)
+ rt4 - rt7(4)
+rt5 TE-IS 90 rt3 - rt8(4)
+ rt4 -
+10.0.255.8/32 IP TE 90 rt3 - rt8(4)
+ rt4 -
+rt2 TE-IS 100 rt3 - rt5(4)
+ rt4 -
+10.0.255.5/32 IP TE 100 rt3 - rt5(4)
+ rt4 -
+10.0.255.2/32 IP TE 110 rt3 - rt2(4)
+ rt4 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.2/32 110 - rt3 20060/18/16020
+ - rt4 16070/18/16020
+ 10.0.255.5/32 100 - rt3 20060/18/16050
+ - rt4 16070/18/16050
+ 10.0.255.8/32 90 - rt3 20060/18/16080
+ - rt4 16070/18/16080
+
+P-space (self):
+ rt3
+ rt4
+ rt6
+ rt7
+
+P-space (rt3):
+ rt3
+ rt6
+
+P-space (rt4):
+ rt4
+ rt7
+
+Q-space:
+ rt2
+ rt5
+ rt8
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt3 TE-IS 20 rt3 - rt1(4)
+rt4 TE-IS 20 rt4 - rt1(4)
+rt6 TE-IS 30 rt3 - rt3(4)
+rt7 TE-IS 30 rt4 - rt4(4)
+2001:db8::3/128 IP6 internal 30 rt3 - rt3(4)
+2001:db8::4/128 IP6 internal 30 rt4 - rt4(4)
+2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
+2001:db8::7/128 IP6 internal 40 rt4 - rt7(4)
+rt8 TE-IS 80 rt3 - rt6(4)
+ rt4 - rt7(4)
+rt5 TE-IS 90 rt3 - rt8(4)
+ rt4 -
+2001:db8::8/128 IP6 internal 90 rt3 - rt8(4)
+ rt4 -
+rt2 TE-IS 100 rt3 - rt5(4)
+ rt4 -
+2001:db8::5/128 IP6 internal 100 rt3 - rt5(4)
+ rt4 -
+2001:db8::2/128 IP6 internal 110 rt3 - rt2(4)
+ rt4 -
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::2/128 110 - rt3 20061/19/16021
+ - rt4 16071/19/16021
+ 2001:db8::5/128 100 - rt3 20061/19/16051
+ - rt4 16071/19/16051
+ 2001:db8::8/128 90 - rt3 20061/19/16081
+ - rt4 16071/19/16081
+
+test# test isis topology 10 root rt1 ti-lfa system-id rt4
+P-space (self):
+ rt2
+ rt3
+ rt5
+ rt6
+ rt8
+
+P-space (rt2):
+ rt2
+ rt5
+ rt8
+
+P-space (rt3):
+ rt3
+ rt6
+
+Q-space:
+ rt4
+ rt7
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 20 rt3 - rt1(4)
+rt5 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt6 TE-IS 30 rt3 - rt3(4)
+rt8 TE-IS 30 rt2 - rt5(4)
+10.0.255.3/32 IP TE 30 rt3 - rt3(4)
+10.0.255.5/32 IP TE 30 rt2 - rt5(4)
+10.0.255.6/32 IP TE 40 rt3 - rt6(4)
+10.0.255.8/32 IP TE 40 rt2 - rt8(4)
+rt7 TE-IS 80 rt2 - rt8(4)
+rt4 TE-IS 90 rt2 - rt7(4)
+10.0.255.7/32 IP TE 90 rt2 - rt7(4)
+10.0.255.4/32 IP TE 100 rt2 - rt4(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.4/32 100 - rt2 16080/20/16040
+ 10.0.255.7/32 90 - rt2 16080/20/16070
+
+P-space (self):
+ rt2
+ rt3
+ rt5
+ rt6
+ rt8
+
+P-space (rt2):
+ rt2
+ rt5
+ rt8
+
+P-space (rt3):
+ rt3
+ rt6
+
+Q-space:
+ rt4
+ rt7
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 20 rt3 - rt1(4)
+rt5 TE-IS 20 rt2 - rt2(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+rt6 TE-IS 30 rt3 - rt3(4)
+rt8 TE-IS 30 rt2 - rt5(4)
+2001:db8::3/128 IP6 internal 30 rt3 - rt3(4)
+2001:db8::5/128 IP6 internal 30 rt2 - rt5(4)
+2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
+2001:db8::8/128 IP6 internal 40 rt2 - rt8(4)
+rt7 TE-IS 80 rt2 - rt8(4)
+rt4 TE-IS 90 rt2 - rt7(4)
+2001:db8::7/128 IP6 internal 90 rt2 - rt7(4)
+2001:db8::4/128 IP6 internal 100 rt2 - rt4(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------------
+ 2001:db8::4/128 100 - rt2 16081/21/16041
+ 2001:db8::7/128 90 - rt2 16081/21/16071
+
+test# test isis topology 11 root rt2 ti-lfa system-id rt4
+P-space (self):
+
+P-space (rt1):
+ rt1
+ rt3
+ rt5
+
+P-space (rt3):
+ rt1
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt1
+ rt3
+ rt4
+ rt5
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt1 TE-IS 50 rt1 - rt2(4)
+rt3 TE-IS 50 rt3 - rt2(4)
+rt2
+rt5 TE-IS 60 rt3 - rt3(4)
+10.0.255.1/32 IP TE 60 rt1 - rt1(4)
+10.0.255.3/32 IP TE 60 rt3 - rt3(4)
+rt4 TE-IS 70 rt3 - rt5(4)
+rt6 TE-IS 70 rt3 - rt5(4)
+10.0.255.5/32 IP TE 70 rt3 - rt5(4)
+10.0.255.4/32 IP TE 80 rt3 - rt4(4)
+10.0.255.6/32 IP TE 80 rt3 - rt6(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 60 - rt1 implicit-null
+ 10.0.255.3/32 60 - rt3 implicit-null
+ 10.0.255.4/32 80 - rt3 16050/16040
+ 10.0.255.5/32 70 - rt3 16050
+ 10.0.255.6/32 80 - rt3 16060
+
+P-space (self):
+
+P-space (rt1):
+ rt1
+ rt3
+ rt5
+
+P-space (rt3):
+ rt1
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt1
+ rt3
+ rt4
+ rt5
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+2001:db8::2/128 IP6 internal 0 rt2(4)
+rt1 TE-IS 50 rt1 - rt2(4)
+rt3 TE-IS 50 rt3 - rt2(4)
+rt2
+rt5 TE-IS 60 rt3 - rt3(4)
+2001:db8::1/128 IP6 internal 60 rt1 - rt1(4)
+2001:db8::3/128 IP6 internal 60 rt3 - rt3(4)
+rt4 TE-IS 70 rt3 - rt5(4)
+rt6 TE-IS 70 rt3 - rt5(4)
+2001:db8::5/128 IP6 internal 70 rt3 - rt5(4)
+2001:db8::4/128 IP6 internal 80 rt3 - rt4(4)
+2001:db8::6/128 IP6 internal 80 rt3 - rt6(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 60 - rt1 implicit-null
+ 2001:db8::3/128 60 - rt3 implicit-null
+ 2001:db8::4/128 80 - rt3 16051/16041
+ 2001:db8::5/128 70 - rt3 16051
+ 2001:db8::6/128 80 - rt3 16061
+
+test# test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt2
+ rt4
+ rt6
+ rt8
+ rt10
+
+P-space (rt2):
+ rt2
+ rt4
+ rt6
+ rt8
+ rt10
+
+Q-space:
+ rt3
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+rt8 TE-IS 40 rt2 - rt6(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+rt10 TE-IS 50 rt2 - rt8(4)
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+10.0.255.10/32 IP TE 60 rt2 - rt10(4)
+rt7 TE-IS 140 rt2 - rt8(4)
+rt9 TE-IS 150 rt2 - rt7(4)
+10.0.255.7/32 IP TE 150 rt2 - rt7(4)
+10.0.255.9/32 IP TE 160 rt2 - rt9(4)
+rt5 TE-IS 340 rt2 - rt7(4)
+10.0.255.5/32 IP TE 350 rt2 - rt5(4)
+rt3 TE-IS 740 rt2 - rt5(4)
+10.0.255.3/32 IP TE 750 rt2 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------------
+ 10.0.255.3/32 750 - rt2 16080/17/16/16/16030
+ 10.0.255.5/32 350 - rt2 16080/17/16/16050
+ 10.0.255.7/32 150 - rt2 16080/17/16070
+ 10.0.255.9/32 160 - rt2 16080/17/18/16090
+
+test# test isis topology 13 root rt1 ti-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt2
+
+P-space (rt2):
+ rt2
+ rt4
+
+Q-space:
+ rt3
+ rt4
+ rt5
+ rt6
+ rt7
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt3 TE-IS 30 rt2 - rt4(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+rt5 TE-IS 40 rt2 - rt3(4)
+rt6 TE-IS 40 rt2 - rt3(4)
+10.0.255.3/32 IP TE 40 rt2 - rt3(4)
+rt7 TE-IS 50 rt2 - rt5(4)
+ rt6(4)
+10.0.255.5/32 IP TE 50 rt2 - rt5(4)
+10.0.255.6/32 IP TE 50 rt2 - rt6(4)
+10.0.255.7/32 IP TE 60 rt2 - rt7(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.3/32 40 - rt2 16040/16030
+ 10.0.255.5/32 50 - rt2 16040/16050
+ 10.0.255.6/32 50 - rt2 16040/16060
+ 10.0.255.7/32 60 - rt2 16040/16070
test# end. diff --git a/tests/isisd/test_isis_vertex_queue.py b/tests/isisd/test_isis_vertex_queue.py index 5974edecc9..b9d2fc5fa2 100644 --- a/tests/isisd/test_isis_vertex_queue.py +++ b/tests/isisd/test_isis_vertex_queue.py @@ -1,6 +1,8 @@ import frrtest + class TestIsisVertexQueue(frrtest.TestMultiOut): - program = './test_isis_vertex_queue' + program = "./test_isis_vertex_queue" + TestIsisVertexQueue.exit_cleanly() diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c index 8f062d8b5e..8dba1e29f0 100644 --- a/tests/lib/cli/test_cli.c +++ b/tests/lib/cli/test_cli.c @@ -47,12 +47,10 @@ DEFPY(magic_test, magic_test_cmd, "magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}", "1\n2\n3\n4\n5\n") { - char buf[256]; vty_out(vty, "def: %s\n", self->string); vty_out(vty, "num: %ld\n", magic); - vty_out(vty, "ipv4: %s\n", prefix2str(ipv4net, buf, sizeof(buf))); - vty_out(vty, "ipv6: %s\n", - inet_ntop(AF_INET6, &ipv6, buf, sizeof(buf))); + vty_out(vty, "ipv4: %pFX\n", ipv4net); + vty_out(vty, "ipv6: %pI6\n", &ipv6); return CMD_SUCCESS; } diff --git a/tests/lib/cli/test_cli.py b/tests/lib/cli/test_cli.py index 7371db283a..6fdd6faa65 100644 --- a/tests/lib/cli/test_cli.py +++ b/tests/lib/cli/test_cli.py @@ -1,5 +1,6 @@ import frrtest + class TestCli(frrtest.TestRefOut): - program = './test_cli' + program = "./test_cli" built_refout = True diff --git a/tests/lib/cli/test_commands.py b/tests/lib/cli/test_commands.py index d55345186a..cf99077c35 100644 --- a/tests/lib/cli/test_commands.py +++ b/tests/lib/cli/test_commands.py @@ -2,10 +2,12 @@ import frrtest import pytest import os + class TestCommands(frrtest.TestRefOut): - program = './test_commands' + program = "./test_commands" - @pytest.mark.skipif('QUAGGA_TEST_COMMANDS' not in os.environ, - reason='QUAGGA_TEST_COMMANDS not set') + @pytest.mark.skipif( + "QUAGGA_TEST_COMMANDS" not in os.environ, reason="QUAGGA_TEST_COMMANDS not set" + ) def test_refout(self): return super(TestCommands, self).test_refout() diff --git a/tests/lib/northbound/test_oper_data.py b/tests/lib/northbound/test_oper_data.py index 8f5fdd6fd0..a02bf05c1a 100644 --- a/tests/lib/northbound/test_oper_data.py +++ b/tests/lib/northbound/test_oper_data.py @@ -1,4 +1,5 @@ import frrtest + class TestNbOperData(frrtest.TestRefOut): - program = './test_oper_data' + program = "./test_oper_data" diff --git a/tests/lib/test_atomlist.py b/tests/lib/test_atomlist.py index 293d47f316..719a2e791d 100644 --- a/tests/lib/test_atomlist.py +++ b/tests/lib/test_atomlist.py @@ -1,6 +1,8 @@ import frrtest + class TestAtomlist(frrtest.TestMultiOut): - program = './test_atomlist' + program = "./test_atomlist" + TestAtomlist.exit_cleanly() diff --git a/tests/lib/test_graph.py b/tests/lib/test_graph.py index 697e56c149..b26986c83c 100644 --- a/tests/lib/test_graph.py +++ b/tests/lib/test_graph.py @@ -1,4 +1,5 @@ import frrtest + class TestGraph(frrtest.TestRefOut): - program = './test_graph' + program = "./test_graph" diff --git a/tests/lib/test_idalloc.py b/tests/lib/test_idalloc.py index 22de082be4..e2186dc521 100644 --- a/tests/lib/test_idalloc.py +++ b/tests/lib/test_idalloc.py @@ -1,6 +1,8 @@ import frrtest + class TestIDAlloc(frrtest.TestMultiOut): - program = './test_idalloc' + program = "./test_idalloc" + -TestIDAlloc.onesimple('ID Allocator test successful.') +TestIDAlloc.onesimple("ID Allocator test successful.") diff --git a/tests/lib/test_nexthop_iter.py b/tests/lib/test_nexthop_iter.py index bb330a1c75..0c39dce08e 100644 --- a/tests/lib/test_nexthop_iter.py +++ b/tests/lib/test_nexthop_iter.py @@ -1,7 +1,9 @@ import frrtest + class TestNexthopIter(frrtest.TestMultiOut): - program = './test_nexthop_iter' + program = "./test_nexthop_iter" + -TestNexthopIter.onesimple('Simple test passed.') -TestNexthopIter.onesimple('PRNG test passed.') +TestNexthopIter.onesimple("Simple test passed.") +TestNexthopIter.onesimple("PRNG test passed.") diff --git a/tests/lib/test_ntop.py b/tests/lib/test_ntop.py index 2526f53db5..69c4353620 100644 --- a/tests/lib/test_ntop.py +++ b/tests/lib/test_ntop.py @@ -1,6 +1,8 @@ import frrtest + class TestNtop(frrtest.TestMultiOut): - program = './test_ntop' + program = "./test_ntop" + TestNtop.exit_cleanly() diff --git a/tests/lib/test_prefix2str.py b/tests/lib/test_prefix2str.py index 6e26d1b409..fd883ed530 100644 --- a/tests/lib/test_prefix2str.py +++ b/tests/lib/test_prefix2str.py @@ -1,6 +1,8 @@ import frrtest + class TestPrefix2str(frrtest.TestMultiOut): - program = './test_prefix2str' + program = "./test_prefix2str" + TestPrefix2str.exit_cleanly() diff --git a/tests/lib/test_printfrr.py b/tests/lib/test_printfrr.py index 4fe238618e..b8ab89e337 100644 --- a/tests/lib/test_printfrr.py +++ b/tests/lib/test_printfrr.py @@ -1,6 +1,8 @@ import frrtest + class TestPrintfrr(frrtest.TestMultiOut): - program = './test_printfrr' + program = "./test_printfrr" + TestPrintfrr.exit_cleanly() diff --git a/tests/lib/test_ringbuf.py b/tests/lib/test_ringbuf.py index 5d994ddd7b..0cd9dee2b7 100644 --- a/tests/lib/test_ringbuf.py +++ b/tests/lib/test_ringbuf.py @@ -1,6 +1,8 @@ import frrtest + class TestRingbuf(frrtest.TestMultiOut): - program = './test_ringbuf' + program = "./test_ringbuf" + TestRingbuf.exit_cleanly() diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c index dbfe853365..097da113ab 100644 --- a/tests/lib/test_srcdest_table.c +++ b/tests/lib/test_srcdest_table.c @@ -271,7 +271,7 @@ static void test_state_verify(struct test_state *test) associated with rn */ expected_lock++; - if (rn->lock != expected_lock) + if (route_node_get_lock_count(rn) != expected_lock) test_failed( test, "Dest rnode lock count doesn't match expected count!", @@ -283,7 +283,7 @@ static void test_state_verify(struct test_state *test) != NULL) /* The route node is not internal */ expected_lock++; - if (rn->lock != expected_lock) { + if (route_node_get_lock_count(rn) != expected_lock) { srcdest_rnode_prefixes( rn, (const struct prefix **)&dst_p, (const struct prefix **)&src_p); diff --git a/tests/lib/test_srcdest_table.py b/tests/lib/test_srcdest_table.py index ee73121025..d0dde6a8e5 100644 --- a/tests/lib/test_srcdest_table.py +++ b/tests/lib/test_srcdest_table.py @@ -1,6 +1,8 @@ import frrtest + class TestSrcdestTable(frrtest.TestMultiOut): - program = './test_srcdest_table' + program = "./test_srcdest_table" + -TestSrcdestTable.onesimple('PRNG Test successful.') +TestSrcdestTable.onesimple("PRNG Test successful.") diff --git a/tests/lib/test_stream.py b/tests/lib/test_stream.py index 6f42db1839..11d902eb95 100644 --- a/tests/lib/test_stream.py +++ b/tests/lib/test_stream.py @@ -1,4 +1,5 @@ import frrtest + class TestStream(frrtest.TestRefOut): - program = './test_stream' + program = "./test_stream" diff --git a/tests/lib/test_table.c b/tests/lib/test_table.c index 90d6c76bf1..290657bd56 100644 --- a/tests/lib/test_table.c +++ b/tests/lib/test_table.c @@ -104,7 +104,6 @@ static void add_nodes(struct route_table *table, ...) static void print_subtree(struct route_node *rn, const char *legend, int indent_level) { - char buf[PREFIX2STR_BUFFER]; int i; /* @@ -114,8 +113,7 @@ static void print_subtree(struct route_node *rn, const char *legend, printf(" "); } - prefix2str(&rn->p, buf, sizeof(buf)); - printf("%s: %s", legend, buf); + printf("%s: %pFX", legend, &rn->p); if (!rn->info) { printf(" (internal)"); } diff --git a/tests/lib/test_table.py b/tests/lib/test_table.py index e724421273..ee1849fd86 100644 --- a/tests/lib/test_table.py +++ b/tests/lib/test_table.py @@ -1,10 +1,12 @@ import frrtest + class TestTable(frrtest.TestMultiOut): - program = './test_table' + program = "./test_table" + for i in range(6): - TestTable.onesimple('Verifying cmp') + TestTable.onesimple("Verifying cmp") for i in range(11): - TestTable.onesimple('Verifying successor') -TestTable.onesimple('Verified pausing') + TestTable.onesimple("Verifying successor") +TestTable.onesimple("Verified pausing") diff --git a/tests/lib/test_timer_correctness.c b/tests/lib/test_timer_correctness.c index cbf9b05546..416ea39772 100644 --- a/tests/lib/test_timer_correctness.c +++ b/tests/lib/test_timer_correctness.c @@ -153,7 +153,7 @@ int main(int argc, char **argv) continue; XFREE(MTYPE_TMP, timers[index]->arg); - thread_cancel(timers[index]); + thread_cancel(&timers[index]); timers[index] = NULL; timers_pending--; } diff --git a/tests/lib/test_timer_correctness.py b/tests/lib/test_timer_correctness.py index 8b4a765a81..71f45f980c 100644 --- a/tests/lib/test_timer_correctness.py +++ b/tests/lib/test_timer_correctness.py @@ -1,6 +1,8 @@ import frrtest + class TestTimerCorrectness(frrtest.TestMultiOut): - program = './test_timer_correctness' + program = "./test_timer_correctness" + -TestTimerCorrectness.onesimple('Expected output and actual output match.') +TestTimerCorrectness.onesimple("Expected output and actual output match.") diff --git a/tests/lib/test_timer_performance.c b/tests/lib/test_timer_performance.c index 2960e0d81e..45b29b92b1 100644 --- a/tests/lib/test_timer_performance.c +++ b/tests/lib/test_timer_performance.c @@ -59,7 +59,7 @@ int main(int argc, char **argv) thread_add_timer_msec(master, dummy_func, NULL, 0, &timers[i]); } for (i = 0; i < SCHEDULE_TIMERS; i++) - thread_cancel(timers[i]); + thread_cancel(&timers[i]); monotime(&tv_start); @@ -78,8 +78,7 @@ int main(int argc, char **argv) int index; index = prng_rand(prng) % SCHEDULE_TIMERS; - if (timers[index]) - thread_cancel(timers[index]); + thread_cancel(&timers[index]); timers[index] = NULL; } diff --git a/tests/lib/test_ttable.py b/tests/lib/test_ttable.py index 1d93932ad2..9151181a72 100644 --- a/tests/lib/test_ttable.py +++ b/tests/lib/test_ttable.py @@ -1,4 +1,5 @@ import frrtest + class TestTTable(frrtest.TestRefOut): - program = './test_ttable' + program = "./test_ttable" diff --git a/tests/lib/test_typelist.py b/tests/lib/test_typelist.py index 0b3c743971..fe3499cad8 100644 --- a/tests/lib/test_typelist.py +++ b/tests/lib/test_typelist.py @@ -1,19 +1,21 @@ import frrtest + class TestTypelist(frrtest.TestMultiOut): - program = './test_typelist' + program = "./test_typelist" + -TestTypelist.onesimple('LIST end') -TestTypelist.onesimple('DLIST end') -TestTypelist.onesimple('ATOMLIST end') -TestTypelist.onesimple('HEAP end') -TestTypelist.onesimple('SORTLIST_UNIQ end') -TestTypelist.onesimple('SORTLIST_NONUNIQ end') -TestTypelist.onesimple('HASH end') -TestTypelist.onesimple('HASH_collisions end') -TestTypelist.onesimple('SKIPLIST_UNIQ end') -TestTypelist.onesimple('SKIPLIST_NONUNIQ end') -TestTypelist.onesimple('RBTREE_UNIQ end') -TestTypelist.onesimple('RBTREE_NONUNIQ end') -TestTypelist.onesimple('ATOMSORT_UNIQ end') -TestTypelist.onesimple('ATOMSORT_NONUNIQ end') +TestTypelist.onesimple("LIST end") +TestTypelist.onesimple("DLIST end") +TestTypelist.onesimple("ATOMLIST end") +TestTypelist.onesimple("HEAP end") +TestTypelist.onesimple("SORTLIST_UNIQ end") +TestTypelist.onesimple("SORTLIST_NONUNIQ end") +TestTypelist.onesimple("HASH end") +TestTypelist.onesimple("HASH_collisions end") +TestTypelist.onesimple("SKIPLIST_UNIQ end") +TestTypelist.onesimple("SKIPLIST_NONUNIQ end") +TestTypelist.onesimple("RBTREE_UNIQ end") +TestTypelist.onesimple("RBTREE_NONUNIQ end") +TestTypelist.onesimple("ATOMSORT_UNIQ end") +TestTypelist.onesimple("ATOMSORT_NONUNIQ end") diff --git a/tests/lib/test_versioncmp.py b/tests/lib/test_versioncmp.py index 0990757000..8ded53bd58 100644 --- a/tests/lib/test_versioncmp.py +++ b/tests/lib/test_versioncmp.py @@ -1,6 +1,8 @@ import frrtest + class TestVersionCmp(frrtest.TestMultiOut): - program = './test_versioncmp' + program = "./test_versioncmp" + TestVersionCmp.exit_cleanly() diff --git a/tests/lib/test_zlog.py b/tests/lib/test_zlog.py index 2ca2585886..2a2d54e204 100644 --- a/tests/lib/test_zlog.py +++ b/tests/lib/test_zlog.py @@ -1,4 +1,5 @@ import frrtest + class TestZlog(frrtest.TestMultiOut): - program = './test_zlog' + program = "./test_zlog" diff --git a/tests/lib/test_zmq.py b/tests/lib/test_zmq.py index 1f8ee54169..5f6189d919 100644 --- a/tests/lib/test_zmq.py +++ b/tests/lib/test_zmq.py @@ -2,10 +2,13 @@ import frrtest import pytest import os + class TestZMQ(frrtest.TestRefOut): - program = './test_zmq' + program = "./test_zmq" - @pytest.mark.skipif('S["ZEROMQ_TRUE"]=""\n' not in open('../config.status').readlines(), - reason='ZEROMQ not enabled') + @pytest.mark.skipif( + 'S["ZEROMQ_TRUE"]=""\n' not in open("../config.status").readlines(), + reason="ZEROMQ not enabled", + ) def test_refout(self): return super(TestZMQ, self).test_refout() diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c index 24821febe6..c5bdcd3d13 100644 --- a/tests/ospf6d/test_lsdb.c +++ b/tests/ospf6d/test_lsdb.c @@ -134,9 +134,10 @@ DEFPY(lsdb_walk, lsdb_walk_cmd, "LSDB\n" "walk entries\n") { - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsanext; + unsigned cnt = 0; - for (ALL_LSDB(lsdb, lsa)) { + for (ALL_LSDB(lsdb, lsa, lsanext)) { lsa_show_oneline(vty, lsa); cnt++; } diff --git a/tests/ospf6d/test_lsdb.py b/tests/ospf6d/test_lsdb.py index 6a94395113..6ada617657 100644 --- a/tests/ospf6d/test_lsdb.py +++ b/tests/ospf6d/test_lsdb.py @@ -1,4 +1,5 @@ import frrtest + class TestLSDB(frrtest.TestRefOut): - program = './test_lsdb' + program = "./test_lsdb" diff --git a/tests/runtests.py b/tests/runtests.py index 533dc6b167..4677796152 100644 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -2,5 +2,5 @@ import pytest import sys import os -sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers','python')) +sys.path.append(os.path.join(os.path.dirname(__file__), "helpers", "python")) raise SystemExit(pytest.main(sys.argv[1:])) diff --git a/tests/subdir.am b/tests/subdir.am index d7318efc72..211814c1c3 100644 --- a/tests/subdir.am +++ b/tests/subdir.am @@ -168,6 +168,19 @@ tests_bgpd_test_peer_attr_CFLAGS = $(TESTS_CFLAGS) tests_bgpd_test_peer_attr_CPPFLAGS = $(TESTS_CPPFLAGS) tests_bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD) tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c +nodist_tests_bgpd_test_peer_attr_SOURCES = \ + yang/frr-bgp-types.yang.c \ + yang/frr-bgp.yang.c \ + yang/frr-bgp-common-structure.yang.c \ + yang/frr-bgp-common.yang.c \ + yang/frr-bgp-common-multiprotocol.yang.c \ + yang/frr-bgp-neighbor.yang.c \ + yang/frr-bgp-peer-group.yang.c \ + yang/frr-bgp-bmp.yang.c \ + yang/frr-bgp-rpki.yang.c \ + yang/frr-deviations-bgp-datacenter.yang.c \ + # end + tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd diff --git a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py index 4b57928366..0254ff6af6 100644 --- a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py +++ b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py @@ -55,6 +55,7 @@ fatal_error = "" ## ##################################################### + class NetworkTopo(Topo): "All Protocol Startup Test" @@ -64,15 +65,15 @@ class NetworkTopo(Topo): router = {} # # Setup Main Router - router[1] = topotest.addRouter(self, 'r1') + router[1] = topotest.addRouter(self, "r1") # # Setup Switches switch = {} # for i in range(0, 10): - switch[i] = self.addSwitch('sw%s' % i, cls=topotest.LegacySwitch) - self.addLink(switch[i], router[1], intfName2='r1-eth%s' % i ) + switch[i] = self.addSwitch("sw%s" % i, cls=topotest.LegacySwitch) + self.addLink(switch[i], router[1], intfName2="r1-eth%s" % i) ##################################################### @@ -81,6 +82,7 @@ class NetworkTopo(Topo): ## ##################################################### + def setup_module(module): global topo, net global fatal_error @@ -89,8 +91,8 @@ def setup_module(module): print("******************************************\n") print("Cleanup old Mininet runs") - os.system('sudo mn -c > /dev/null 2>&1') - os.system('sudo rm /tmp/r* > /dev/null 2>&1') + os.system("sudo mn -c > /dev/null 2>&1") + os.system("sudo rm /tmp/r* > /dev/null 2>&1") thisDir = os.path.dirname(os.path.realpath(__file__)) topo = NetworkTopo() @@ -98,33 +100,35 @@ def setup_module(module): net = Mininet(controller=None, topo=topo) net.start() - if net['r1'].get_routertype() != 'frr': + if net["r1"].get_routertype() != "frr": fatal_error = "Test is only implemented for FRR" - sys.stderr.write('\n\nTest is only implemented for FRR - Skipping\n\n') + sys.stderr.write("\n\nTest is only implemented for FRR - Skipping\n\n") pytest.skip(fatal_error) - + # Starting Routers # # Main router for i in range(1, 2): - net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i)) - net['r%s' % i].loadConf('ripd', '%s/r%s/ripd.conf' % (thisDir, i)) - net['r%s' % i].loadConf('ripngd', '%s/r%s/ripngd.conf' % (thisDir, i)) - net['r%s' % i].loadConf('ospfd', '%s/r%s/ospfd.conf' % (thisDir, i)) - if net['r1'].checkRouterVersion('<', '4.0'): - net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf-pre-v4' % (thisDir, i)) + net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i)) + net["r%s" % i].loadConf("ripd", "%s/r%s/ripd.conf" % (thisDir, i)) + net["r%s" % i].loadConf("ripngd", "%s/r%s/ripngd.conf" % (thisDir, i)) + net["r%s" % i].loadConf("ospfd", "%s/r%s/ospfd.conf" % (thisDir, i)) + if net["r1"].checkRouterVersion("<", "4.0"): + net["r%s" % i].loadConf( + "ospf6d", "%s/r%s/ospf6d.conf-pre-v4" % (thisDir, i) + ) else: - net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf' % (thisDir, i)) - net['r%s' % i].loadConf('isisd', '%s/r%s/isisd.conf' % (thisDir, i)) - net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i)) - if net['r%s' % i].daemon_available('ldpd'): + net["r%s" % i].loadConf("ospf6d", "%s/r%s/ospf6d.conf" % (thisDir, i)) + net["r%s" % i].loadConf("isisd", "%s/r%s/isisd.conf" % (thisDir, i)) + net["r%s" % i].loadConf("bgpd", "%s/r%s/bgpd.conf" % (thisDir, i)) + if net["r%s" % i].daemon_available("ldpd"): # Only test LDPd if it's installed and Kernel >= 4.5 - net['r%s' % i].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir, i)) - net['r%s' % i].loadConf('sharpd') - net['r%s' % i].loadConf('nhrpd', '%s/r%s/nhrpd.conf' % (thisDir, i)) - net['r%s' % i].loadConf('babeld', '%s/r%s/babeld.conf' % (thisDir, i)) - net['r%s' % i].loadConf('pbrd', '%s/r%s/pbrd.conf' % (thisDir, i)) - net['r%s' % i].startRouter() + net["r%s" % i].loadConf("ldpd", "%s/r%s/ldpd.conf" % (thisDir, i)) + net["r%s" % i].loadConf("sharpd") + net["r%s" % i].loadConf("nhrpd", "%s/r%s/nhrpd.conf" % (thisDir, i)) + net["r%s" % i].loadConf("babeld", "%s/r%s/babeld.conf" % (thisDir, i)) + net["r%s" % i].loadConf("pbrd", "%s/r%s/pbrd.conf" % (thisDir, i)) + net["r%s" % i].startRouter() # For debugging after starting FRR daemons, uncomment the next line # CLI(net) @@ -145,7 +149,7 @@ def test_router_running(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Check if FRR is running on each Router node") @@ -154,7 +158,7 @@ def test_router_running(): # Starting Routers for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -166,7 +170,7 @@ def test_error_messages_vtysh(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Check for error messages on VTYSH") @@ -179,38 +183,38 @@ def test_error_messages_vtysh(): # # VTYSH output from router - vtystdout = net['r%s' % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip() + vtystdout = net["r%s" % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip() # Fix newlines (make them all the same) - vtystdout = ('\n'.join(vtystdout.splitlines()) + '\n').rstrip() + vtystdout = ("\n".join(vtystdout.splitlines()) + "\n").rstrip() # Drop everything starting with "FRRouting X.xx" message vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL) - if (vtystdout == ''): + if vtystdout == "": print("r%s StdOut ok" % i) - assert vtystdout == '', "Vtysh StdOut Output check failed for router r%s" % i + assert vtystdout == "", "Vtysh StdOut Output check failed for router r%s" % i # # Second checking Standard Error # # VTYSH StdErr output from router - vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip() + vtystderr = net["r%s" % i].cmd('vtysh -c "show version" > /dev/null').rstrip() # Fix newlines (make them all the same) - vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip() + vtystderr = ("\n".join(vtystderr.splitlines()) + "\n").rstrip() # # Drop everything starting with "FRRouting X.xx" message - # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL) + # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL) - if (vtystderr == ''): + if vtystderr == "": print("r%s StdErr ok" % i) - assert vtystderr == '', "Vtysh StdErr Output check failed for router r%s" % i + assert vtystderr == "", "Vtysh StdErr Output check failed for router r%s" % i # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -222,7 +226,7 @@ def test_error_messages_daemons(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Check for error messages in daemons") @@ -231,67 +235,73 @@ def test_error_messages_daemons(): error_logs = "" for i in range(1, 2): - log = net['r%s' % i].getStdErr('ripd') + log = net["r%s" % i].getStdErr("ripd") if log: error_logs += "r%s RIPd StdErr Output:\n" % i error_logs += log - log = net['r%s' % i].getStdErr('ripngd') + log = net["r%s" % i].getStdErr("ripngd") if log: error_logs += "r%s RIPngd StdErr Output:\n" % i error_logs += log - log = net['r%s' % i].getStdErr('ospfd') + log = net["r%s" % i].getStdErr("ospfd") if log: error_logs += "r%s OSPFd StdErr Output:\n" % i error_logs += log - log = net['r%s' % i].getStdErr('ospf6d') + log = net["r%s" % i].getStdErr("ospf6d") if log: error_logs += "r%s OSPF6d StdErr Output:\n" % i error_logs += log - log = net['r%s' % i].getStdErr('isisd') + log = net["r%s" % i].getStdErr("isisd") # ISIS shows debugging enabled status on StdErr # Remove these messages log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip() if log: error_logs += "r%s ISISd StdErr Output:\n" % i error_logs += log - log = net['r%s' % i].getStdErr('bgpd') + log = net["r%s" % i].getStdErr("bgpd") if log: error_logs += "r%s BGPd StdErr Output:\n" % i error_logs += log - if (net['r%s' % i].daemon_available('ldpd')): - log = net['r%s' % i].getStdErr('ldpd') + if net["r%s" % i].daemon_available("ldpd"): + log = net["r%s" % i].getStdErr("ldpd") if log: error_logs += "r%s LDPd StdErr Output:\n" % i error_logs += log - log = net['r1'].getStdErr('nhrpd') + log = net["r1"].getStdErr("nhrpd") if log: error_logs += "r%s NHRPd StdErr Output:\n" % i error_logs += log - log = net['r1'].getStdErr('babeld') + log = net["r1"].getStdErr("babeld") if log: error_logs += "r%s BABELd StdErr Output:\n" % i error_logs += log - log = net['r1'].getStdErr('pbrd') + log = net["r1"].getStdErr("pbrd") if log: error_logs += "r%s PBRd StdErr Output:\n" % i error_logs += log - log = net['r%s' % i].getStdErr('zebra') + log = net["r%s" % i].getStdErr("zebra") if log: error_logs += "r%s Zebra StdErr Output:\n" error_logs += log if error_logs: - sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs) + sys.stderr.write( + "Failed check for StdErr Output on daemons:\n%s\n" % error_logs + ) # Ignoring the issue if told to ignore (ie not yet fixed) - if (error_logs != ""): - if (os.environ.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"): - sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n') - pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349') + if error_logs != "": + if os.environ.get("bamboo_TOPOTESTS_ISSUE_349") == "IGNORE": + sys.stderr.write( + "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n" + ) + pytest.skip( + "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349" + ) assert error_logs == "", "Daemons report errors to StdErr" @@ -304,7 +314,7 @@ def test_converge_protocols(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -318,62 +328,84 @@ def test_converge_protocols(): # Make sure that all daemons are running failures = 0 for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error - print("Show that v4 routes are right\n"); - v4_routesFile = '%s/r%s/ipv4_routes.ref' % (thisDir, i) + print("Show that v4 routes are right\n") + v4_routesFile = "%s/r%s/ipv4_routes.ref" % (thisDir, i) expected = open(v4_routesFile).read().rstrip() - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) - - actual = net['r%s' %i].cmd('vtysh -c "show ip route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip() + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) + + actual = ( + net["r%s" % i] + .cmd( + 'vtysh -c "show ip route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null' + ) + .rstrip() + ) # Drop time in last update actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) - diff = topotest.get_textdiff(actual, expected, - title1="Actual IP Routing Table", - title2="Expected IP RoutingTable") + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) + diff = topotest.get_textdiff( + actual, + expected, + title1="Actual IP Routing Table", + title2="Expected IP RoutingTable", + ) if diff: - sys.stderr.write('r%s failed IP Routing table check:\n%s\n' % (i, diff)) + sys.stderr.write("r%s failed IP Routing table check:\n%s\n" % (i, diff)) failures += 1 else: - print("r%s ok" %i) + print("r%s ok" % i) assert failures == 0, "IP Routing table failed for r%s\n%s" % (i, diff) failures = 0 print("Show that v6 routes are right\n") - v6_routesFile = '%s/r%s/ipv6_routes.ref' % (thisDir, i) + v6_routesFile = "%s/r%s/ipv6_routes.ref" % (thisDir, i) expected = open(v6_routesFile).read().rstrip() - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) - - actual = net['r%s' %i].cmd('vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip() + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) + + actual = ( + net["r%s" % i] + .cmd( + 'vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null' + ) + .rstrip() + ) # Drop time in last update actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) - diff = topotest.get_textdiff(actual, expected, - title1="Actual IPv6 Routing Table", - title2="Expected IPv6 RoutingTable") + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) + diff = topotest.get_textdiff( + actual, + expected, + title1="Actual IPv6 Routing Table", + title2="Expected IPv6 RoutingTable", + ) if diff: - sys.stderr.write('r%s failed IPv6 Routing table check:\n%s\n' % (i, diff)) + sys.stderr.write("r%s failed IPv6 Routing table check:\n%s\n" % (i, diff)) failures += 1 else: - print("r%s ok" %i) + print("r%s ok" % i) assert failures == 0, "IPv6 Routing table failed for r%s\n%s" % (i, diff) # For debugging after starting FRR daemons, uncomment the next line ## CLI(net) + def route_get_nhg_id(route_str): output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str) match = re.search(r"Nexthop Group ID: (\d+)", output) - assert match is not None, "Nexthop Group ID not found for sharpd route %s" % route_str + assert match is not None, ( + "Nexthop Group ID not found for sharpd route %s" % route_str + ) nhg_id = int(match.group(1)) return nhg_id + def verify_nexthop_group(nhg_id, recursive=False, ecmp=0): # Verify NHG is valid/installed output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id) @@ -389,10 +421,14 @@ def verify_nexthop_group(nhg_id, recursive=False, ecmp=0): depends = re.findall(r"\((\d+)\)", match.group(0)) if ecmp: - assert (len(depends) == ecmp), "Nexthop Group ID=%d doesn't match ecmp size" % nhg_id + assert len(depends) == ecmp, ( + "Nexthop Group ID=%d doesn't match ecmp size" % nhg_id + ) else: # If recursive, we need to look at its resolved group - assert (len(depends) == 1), "Nexthop Group ID=%d should only have one recursive depend" % nhg_id + assert len(depends) == 1, ( + "Nexthop Group ID=%d should only have one recursive depend" % nhg_id + ) resolved_id = int(depends[0]) verify_nexthop_group(resolved_id, False) @@ -400,17 +436,19 @@ def verify_nexthop_group(nhg_id, recursive=False, ecmp=0): match = re.search(r"Installed", output) assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id + def verify_route_nexthop_group(route_str, recursive=False, ecmp=0): # Verify route and that zebra created NHGs for and they are valid/installed nhg_id = route_get_nhg_id(route_str) verify_nexthop_group(nhg_id, recursive, ecmp) + def test_nexthop_groups(): global fatal_error global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Verifying Nexthop Groups") @@ -421,7 +459,9 @@ def test_nexthop_groups(): ## Basic test # Create a lib nexthop-group - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"' + ) # Create with sharpd using nexthop-group net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"') @@ -430,7 +470,9 @@ def test_nexthop_groups(): ## Connected - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"' + ) net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"') @@ -438,15 +480,21 @@ def test_nexthop_groups(): ## Recursive - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"' + ) - net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"') + net["r1"].cmd( + 'vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"' + ) verify_route_nexthop_group("3.3.3.1/32", True) ## Duplicate - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"' + ) net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"') @@ -454,15 +502,19 @@ def test_nexthop_groups(): ## Two 4-Way ECMP - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \ - -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \ + -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"' + ) net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"') verify_route_nexthop_group("4.4.4.1/32") - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \ - -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \ + -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"' + ) net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"') @@ -470,9 +522,13 @@ def test_nexthop_groups(): ## Recursive to 8-Way ECMP - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"' + ) - net["r1"].cmd('vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"') + net["r1"].cmd( + 'vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"' + ) verify_route_nexthop_group("5.5.5.1/32") @@ -488,12 +544,13 @@ def test_nexthop_groups(): net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"') net["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"') + def test_rip_status(): global fatal_error global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -502,30 +559,37 @@ def test_rip_status(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i) + refTableFile = "%s/r%s/rip_status.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip() - # Drop time in next due + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show ip rip status" 2> /dev/null') + .rstrip() + ) + # Drop time in next due actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual) # Drop time in last update actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual) # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual IP RIP status", - title2="expected IP RIP status") + title2="expected IP RIP status", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff)) + sys.stderr.write("r%s failed IP RIP status check:\n%s\n" % (i, diff)) failures += 1 else: print("r%s ok" % i) @@ -534,7 +598,7 @@ def test_rip_status(): # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -546,7 +610,7 @@ def test_ripng_status(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -555,41 +619,53 @@ def test_ripng_status(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i) + refTableFile = "%s/r%s/ripng_status.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null') + .rstrip() + ) # Mask out Link-Local mac address portion. They are random... actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual) - # Drop time in next due + # Drop time in next due actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual) # Drop time in last update actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual) # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual IPv6 RIPng status", - title2="expected IPv6 RIPng status") + title2="expected IPv6 RIPng status", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed IPv6 RIPng status check:\n%s\n" % (i, diff) + ) failures += 1 else: print("r%s ok" % i) - assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff) + assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % ( + i, + diff, + ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -601,7 +677,7 @@ def test_ospfv2_interfaces(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -610,50 +686,71 @@ def test_ospfv2_interfaces(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i) + refTableFile = "%s/r%s/show_ip_ospf_interface.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show ip ospf interface" 2> /dev/null') + .rstrip() + ) # Mask out Bandwidth portion. They may change.. actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual) actual = re.sub(r"ifindex [0-9]", "ifindex X", actual) - # Drop time in next due + # Drop time in next due actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual) - actual = re.sub(r"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual) + actual = re.sub( + r"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual + ) # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both - actual = re.sub(r"MTU mismatch detection:([a-z]+.*)", r"MTU mismatch detection: \1", actual) + actual = re.sub( + r"MTU mismatch detection:([a-z]+.*)", + r"MTU mismatch detection: \1", + actual, + ) # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual SHOW IP OSPF INTERFACE", - title2="expected SHOW IP OSPF INTERFACE") + title2="expected SHOW IP OSPF INTERFACE", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed SHOW IP OSPF INTERFACE check:\n%s\n" % (i, diff) + ) failures += 1 else: print("r%s ok" % i) # Ignoring the issue if told to ignore (ie not yet fixed) - if (failures != 0): - if (os.environ.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"): - sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n') - pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348') - - assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff) + if failures != 0: + if os.environ.get("bamboo_TOPOTESTS_ISSUE_348") == "IGNORE": + sys.stderr.write( + "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n" + ) + pytest.skip( + "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348" + ) + + assert ( + failures == 0 + ), "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -665,7 +762,7 @@ def test_isis_interfaces(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -674,42 +771,52 @@ def test_isis_interfaces(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i) + refTableFile = "%s/r%s/show_isis_interface_detail.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show isis interface detail" 2> /dev/null') + .rstrip() + ) # Mask out Link-Local mac address portion. They are random... actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual) # Mask out SNPA mac address portion. They are random... actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual) # Mask out Circuit ID number - actual = re.sub(r"Circuit Id: 0x[0-9a-f]+", "Circuit Id: 0xXX", - actual) + actual = re.sub(r"Circuit Id: 0x[0-9a-f]+", "Circuit Id: 0xXX", actual) # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual SHOW ISIS INTERFACE DETAIL", - title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL") + title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n" % (i, diff) + ) failures += 1 else: print("r%s ok" % i) - assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff) + assert ( + failures == 0 + ), "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -721,7 +828,7 @@ def test_bgp_summary(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -730,15 +837,19 @@ def test_bgp_summary(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/show_ip_bgp_summary.ref' % (thisDir, i) + refTableFile = "%s/r%s/show_ip_bgp_summary.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show ip bgp summary" 2> /dev/null') + .rstrip() + ) # Mask out "using XXiXX bytes" portion. They are random... actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual) # Mask out "using XiXXX KiB" portion. They are random... @@ -747,50 +858,60 @@ def test_bgp_summary(): # Remove extra summaries which exist with newer versions # # Remove summary lines (changed recently) - actual = re.sub(r'Total number.*', '', actual) - actual = re.sub(r'Displayed.*', '', actual) + actual = re.sub(r"Total number.*", "", actual) + actual = re.sub(r"Displayed.*", "", actual) # Remove IPv4 Unicast Summary (Title only) - actual = re.sub(r'IPv4 Unicast Summary:', '', actual) + actual = re.sub(r"IPv4 Unicast Summary:", "", actual) # Remove IPv4 Multicast Summary (all of it) - actual = re.sub(r'IPv4 Multicast Summary:', '', actual) - actual = re.sub(r'No IPv4 Multicast neighbor is configured', '', actual) + actual = re.sub(r"IPv4 Multicast Summary:", "", actual) + actual = re.sub(r"No IPv4 Multicast neighbor is configured", "", actual) # Remove IPv4 VPN Summary (all of it) - actual = re.sub(r'IPv4 VPN Summary:', '', actual) - actual = re.sub(r'No IPv4 VPN neighbor is configured', '', actual) + actual = re.sub(r"IPv4 VPN Summary:", "", actual) + actual = re.sub(r"No IPv4 VPN neighbor is configured", "", actual) # Remove IPv4 Encap Summary (all of it) - actual = re.sub(r'IPv4 Encap Summary:', '', actual) - actual = re.sub(r'No IPv4 Encap neighbor is configured', '', actual) + actual = re.sub(r"IPv4 Encap Summary:", "", actual) + actual = re.sub(r"No IPv4 Encap neighbor is configured", "", actual) # Remove Unknown Summary (all of it) - actual = re.sub(r'Unknown Summary:', '', actual) - actual = re.sub(r'No Unknown neighbor is configured', '', actual) + actual = re.sub(r"Unknown Summary:", "", actual) + actual = re.sub(r"No Unknown neighbor is configured", "", actual) - actual = re.sub(r'IPv4 labeled-unicast Summary:', '', actual) - actual = re.sub(r'No IPv4 labeled-unicast neighbor is configured', '', actual) + actual = re.sub(r"IPv4 labeled-unicast Summary:", "", actual) + actual = re.sub( + r"No IPv4 labeled-unicast neighbor is configured", "", actual + ) # Strip empty lines actual = actual.lstrip() actual = actual.rstrip() # # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual SHOW IP BGP SUMMARY", - title2="expected SHOW IP BGP SUMMARY") + title2="expected SHOW IP BGP SUMMARY", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed SHOW IP BGP SUMMARY check:\n%s\n" % (i, diff) + ) failures += 1 else: print("r%s ok" % i) - assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i, diff) + assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % ( + i, + diff, + ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -802,7 +923,7 @@ def test_bgp_ipv6_summary(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -811,15 +932,19 @@ def test_bgp_ipv6_summary(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i) + refTableFile = "%s/r%s/show_bgp_ipv6_summary.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null') + .rstrip() + ) # Mask out "using XXiXX bytes" portion. They are random... actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual) # Mask out "using XiXXX KiB" portion. They are random... @@ -828,51 +953,61 @@ def test_bgp_ipv6_summary(): # Remove extra summaries which exist with newer versions # # Remove summary lines (changed recently) - actual = re.sub(r'Total number.*', '', actual) - actual = re.sub(r'Displayed.*', '', actual) + actual = re.sub(r"Total number.*", "", actual) + actual = re.sub(r"Displayed.*", "", actual) # Remove IPv4 Unicast Summary (Title only) - actual = re.sub(r'IPv6 Unicast Summary:', '', actual) + actual = re.sub(r"IPv6 Unicast Summary:", "", actual) # Remove IPv4 Multicast Summary (all of it) - actual = re.sub(r'IPv6 Multicast Summary:', '', actual) - actual = re.sub(r'No IPv6 Multicast neighbor is configured', '', actual) + actual = re.sub(r"IPv6 Multicast Summary:", "", actual) + actual = re.sub(r"No IPv6 Multicast neighbor is configured", "", actual) # Remove IPv4 VPN Summary (all of it) - actual = re.sub(r'IPv6 VPN Summary:', '', actual) - actual = re.sub(r'No IPv6 VPN neighbor is configured', '', actual) + actual = re.sub(r"IPv6 VPN Summary:", "", actual) + actual = re.sub(r"No IPv6 VPN neighbor is configured", "", actual) # Remove IPv4 Encap Summary (all of it) - actual = re.sub(r'IPv6 Encap Summary:', '', actual) - actual = re.sub(r'No IPv6 Encap neighbor is configured', '', actual) + actual = re.sub(r"IPv6 Encap Summary:", "", actual) + actual = re.sub(r"No IPv6 Encap neighbor is configured", "", actual) # Remove Unknown Summary (all of it) - actual = re.sub(r'Unknown Summary:', '', actual) - actual = re.sub(r'No Unknown neighbor is configured', '', actual) + actual = re.sub(r"Unknown Summary:", "", actual) + actual = re.sub(r"No Unknown neighbor is configured", "", actual) # Remove Labeled Unicast Summary (all of it) - actual = re.sub(r'IPv6 labeled-unicast Summary:', '', actual) - actual = re.sub(r'No IPv6 labeled-unicast neighbor is configured', '', actual) + actual = re.sub(r"IPv6 labeled-unicast Summary:", "", actual) + actual = re.sub( + r"No IPv6 labeled-unicast neighbor is configured", "", actual + ) # Strip empty lines actual = actual.lstrip() actual = actual.rstrip() # # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual SHOW BGP IPv6 SUMMARY", - title2="expected SHOW BGP IPv6 SUMMARY") + title2="expected SHOW BGP IPv6 SUMMARY", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n" % (i, diff) + ) failures += 1 else: print("r%s ok" % i) - assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i, diff) + assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % ( + i, + diff, + ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -884,7 +1019,7 @@ def test_bgp_ipv4(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -894,27 +1029,31 @@ def test_bgp_ipv4(): diffresult = {} for i in range(1, 2): success = 0 - for refTableFile in (glob.glob( - '%s/r%s/show_bgp_ipv4*.ref' % (thisDir, i))): + for refTableFile in glob.glob("%s/r%s/show_bgp_ipv4*.ref" % (thisDir, i)): if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip() + ) # Remove summary line (changed recently) - actual = re.sub(r'Total number.*', '', actual) - actual = re.sub(r'Displayed.*', '', actual) + actual = re.sub(r"Total number.*", "", actual) + actual = re.sub(r"Displayed.*", "", actual) actual = actual.rstrip() # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual SHOW BGP IPv4", - title2="expected SHOW BGP IPv4") + title2="expected SHOW BGP IPv4", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: @@ -925,17 +1064,20 @@ def test_bgp_ipv4(): break if not success: - resultstr = 'No template matched.\n' + resultstr = "No template matched.\n" for f in diffresult.iterkeys(): - resultstr += ( - 'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n' - % (f, i, diffresult[f])) + resultstr += "template %s: r%s failed SHOW BGP IPv4 check:\n%s\n" % ( + f, + i, + diffresult[f], + ) raise AssertionError( - "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr)) + "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr) + ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -947,7 +1089,7 @@ def test_bgp_ipv6(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -957,27 +1099,31 @@ def test_bgp_ipv6(): diffresult = {} for i in range(1, 2): success = 0 - for refTableFile in (glob.glob( - '%s/r%s/show_bgp_ipv6*.ref' % (thisDir, i))): + for refTableFile in glob.glob("%s/r%s/show_bgp_ipv6*.ref" % (thisDir, i)): if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip() + ) # Remove summary line (changed recently) - actual = re.sub(r'Total number.*', '', actual) - actual = re.sub(r'Displayed.*', '', actual) + actual = re.sub(r"Total number.*", "", actual) + actual = re.sub(r"Displayed.*", "", actual) actual = actual.rstrip() # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual SHOW BGP IPv6", - title2="expected SHOW BGP IPv6") + title2="expected SHOW BGP IPv6", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: @@ -987,27 +1133,31 @@ def test_bgp_ipv6(): print("template %s matched: r%s ok" % (refTableFile, i)) if not success: - resultstr = 'No template matched.\n' + resultstr = "No template matched.\n" for f in diffresult.iterkeys(): - resultstr += ( - 'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n' - % (f, i, diffresult[f])) + resultstr += "template %s: r%s failed SHOW BGP IPv6 check:\n%s\n" % ( + f, + i, + diffresult[f], + ) raise AssertionError( - "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr)) + "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr) + ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line # CLI(net) + def test_route_map(): global fatal_error global net - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -1016,32 +1166,42 @@ def test_route_map(): print("*******************************************************\n") failures = 0 for i in range(1, 2): - refroutemap = '%s/r%s/show_route_map.ref' % (thisDir, i) + refroutemap = "%s/r%s/show_route_map.ref" % (thisDir, i) if os.path.isfile(refroutemap): expected = open(refroutemap).read().rstrip() - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) - actual = net['r%s' %i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip() - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ( + net["r%s" % i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip() + ) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) - diff = topotest.get_textdiff(actual, expected, - title1="actual show route-map", - title2="expected show route-map") + diff = topotest.get_textdiff( + actual, + expected, + title1="actual show route-map", + title2="expected show route-map", + ) if diff: - sys.stderr.write('r%s failed show route-map command Check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed show route-map command Check:\n%s\n" % (i, diff) + ) failures += 1 else: - print("r%s ok" %i) + print("r%s ok" % i) + + assert ( + failures == 0 + ), "Show route-map command failed for router r%s:\n%s" % (i, diff) - assert failures == 0, "Show route-map command failed for router r%s:\n%s" % (i, diff) def test_nexthop_groups_with_route_maps(): global fatal_error global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Verifying Nexthop Groups With Route-Maps") @@ -1050,14 +1210,18 @@ def test_nexthop_groups_with_route_maps(): ### Nexthop Group With Route-Map Tests # Create a lib nexthop-group - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"' + ) ## Route-Map Proto Source route_str = "2.2.2.1" src_str = "192.168.0.1" - net["r1"].cmd('vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str) + net["r1"].cmd( + 'vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str + ) net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"') net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str) @@ -1066,14 +1230,19 @@ def test_nexthop_groups_with_route_maps(): # Only a valid test on linux using nexthop objects if sys.platform.startswith("linux"): - output = net["r1"].cmd('ip route show %s/32' % route_str) + output = net["r1"].cmd("ip route show %s/32" % route_str) match = re.search(r"src %s" % src_str, output) - assert match is not None, "Route %s/32 not installed with src %s" % (route_str, src_str) + assert match is not None, "Route %s/32 not installed with src %s" % ( + route_str, + src_str, + ) # Remove NHG routes and route-map net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str) net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"') - net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str) + net["r1"].cmd( + 'vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str + ) net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"') ## Route-Map Deny/Permit with same nexthop group @@ -1081,18 +1250,26 @@ def test_nexthop_groups_with_route_maps(): permit_route_str = "3.3.3.1" deny_route_str = "3.3.3.2" - net["r1"].cmd('vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str) - net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"') + net["r1"].cmd( + 'vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str + ) + net["r1"].cmd( + 'vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"' + ) net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"') net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"') # This route should be permitted - net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str) + net["r1"].cmd( + 'vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str + ) verify_route_nexthop_group("%s/32" % permit_route_str) # This route should be denied - net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str) + net["r1"].cmd( + 'vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str + ) nhg_id = route_get_nhg_id(deny_route_str) output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id) @@ -1110,14 +1287,18 @@ def test_nexthop_groups_with_route_maps(): net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"') net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"') net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"') - net["r1"].cmd('vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str) + net["r1"].cmd( + 'vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' + % permit_route_str + ) + def test_nexthop_group_replace(): global fatal_error global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Verifying Nexthop Groups") @@ -1127,7 +1308,9 @@ def test_nexthop_group_replace(): ## 2-Way ECMP Directly Connected - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group replace" -c "nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.2 r1-eth2 onlink"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group replace" -c "nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.2 r1-eth2 onlink"' + ) # Create with sharpd using nexthop-group net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group replace 1"') @@ -1135,21 +1318,24 @@ def test_nexthop_group_replace(): verify_route_nexthop_group("3.3.3.1/32") # Change the nexthop group - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group replace" -c "no nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.3 r1-eth1 onlink" -c "nexthop 1.1.1.4 r1-eth4 onlink"') + net["r1"].cmd( + 'vtysh -c "c t" -c "nexthop-group replace" -c "no nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.3 r1-eth1 onlink" -c "nexthop 1.1.1.4 r1-eth4 onlink"' + ) # Verify it updated. We can just check install and ecmp count here. verify_route_nexthop_group("3.3.3.1/32", False, 3) + def test_mpls_interfaces(): global fatal_error global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) # Skip if no LDP installed or old kernel - if (net['r1'].daemon_available('ldpd') == False): + if net["r1"].daemon_available("ldpd") == False: pytest.skip("No MPLS or kernel < 4.5") thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -1158,40 +1344,51 @@ def test_mpls_interfaces(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i) + refTableFile = "%s/r%s/show_mpls_ldp_interface.ref" % (thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() # Fix newlines (make them all the same) - expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) # Actual output from router - actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip() + actual = ( + net["r%s" % i] + .cmd('vtysh -c "show mpls ldp interface" 2> /dev/null') + .rstrip() + ) # Mask out Timer in Uptime actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual) # Fix newlines (make them all the same) - actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) # Generate Diff - diff = topotest.get_textdiff(actual, expected, + diff = topotest.get_textdiff( + actual, + expected, title1="actual MPLS LDP interface status", - title2="expected MPLS LDP interface status") + title2="expected MPLS LDP interface status", + ) # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff)) + sys.stderr.write( + "r%s failed MPLS LDP Interface status Check:\n%s\n" % (i, diff) + ) failures += 1 else: print("r%s ok" % i) - if failures>0: + if failures > 0: fatal_error = "MPLS LDP Interface status failed" - assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff) + assert ( + failures == 0 + ), "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net['r%s' % i].checkRouterRunning() + fatal_error = net["r%s" % i].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -1203,58 +1400,60 @@ def test_shutdown_check_stderr(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) print("\n\n** Verifying unexpected STDERR output from daemons") print("******************************************\n") - if os.environ.get('TOPOTESTS_CHECK_STDERR') is None: - print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n") - pytest.skip('Skipping test for Stderr output') + if os.environ.get("TOPOTESTS_CHECK_STDERR") is None: + print( + "SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n" + ) + pytest.skip("Skipping test for Stderr output") thisDir = os.path.dirname(os.path.realpath(__file__)) print("thisDir=" + thisDir) - net['r1'].stopRouter() + net["r1"].stopRouter() - log = net['r1'].getStdErr('ripd') + log = net["r1"].getStdErr("ripd") if log: print("\nRIPd StdErr Log:\n" + log) - log = net['r1'].getStdErr('ripngd') + log = net["r1"].getStdErr("ripngd") if log: print("\nRIPngd StdErr Log:\n" + log) - log = net['r1'].getStdErr('ospfd') + log = net["r1"].getStdErr("ospfd") if log: print("\nOSPFd StdErr Log:\n" + log) - log = net['r1'].getStdErr('ospf6d') + log = net["r1"].getStdErr("ospf6d") if log: print("\nOSPF6d StdErr Log:\n" + log) - log = net['r1'].getStdErr('isisd') + log = net["r1"].getStdErr("isisd") if log: print("\nISISd StdErr Log:\n" + log) - log = net['r1'].getStdErr('bgpd') + log = net["r1"].getStdErr("bgpd") if log: print("\nBGPd StdErr Log:\n" + log) - log = net['r1'].getStdErr('nhrpd') + log = net["r1"].getStdErr("nhrpd") if log: print("\nNHRPd StdErr Log:\n" + log) - log = net['r1'].getStdErr('pbrd') + log = net["r1"].getStdErr("pbrd") if log: print("\nPBRd StdErr Log:\n" + log) - log = net['r1'].getStdErr('babeld') + log = net["r1"].getStdErr("babeld") if log: print("\nBABELd StdErr Log:\n" + log) - if (net['r1'].daemon_available('ldpd')): - log = net['r1'].getStdErr('ldpd') + if net["r1"].daemon_available("ldpd"): + log = net["r1"].getStdErr("ldpd") if log: print("\nLDPd StdErr Log:\n" + log) - log = net['r1'].getStdErr('zebra') + log = net["r1"].getStdErr("zebra") if log: print("\nZebra StdErr Log:\n" + log) @@ -1264,23 +1463,27 @@ def test_shutdown_check_memleak(): global net # Skip if previous fatal error condition is raised - if (fatal_error != ""): + if fatal_error != "": pytest.skip(fatal_error) - if os.environ.get('TOPOTESTS_CHECK_MEMLEAK') is None: - print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n") - pytest.skip('Skipping test for memory leaks') - + if os.environ.get("TOPOTESTS_CHECK_MEMLEAK") is None: + print( + "SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n" + ) + pytest.skip("Skipping test for memory leaks") + thisDir = os.path.dirname(os.path.realpath(__file__)) for i in range(1, 2): - net['r%s' % i].stopRouter() - net['r%s' % i].report_memory_leaks(os.environ.get('TOPOTESTS_CHECK_MEMLEAK'), os.path.basename(__file__)) + net["r%s" % i].stopRouter() + net["r%s" % i].report_memory_leaks( + os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__) + ) -if __name__ == '__main__': +if __name__ == "__main__": - setLogLevel('info') + setLogLevel("info") # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli # retval = pytest.main(["-s", "--tb=no"]) retval = pytest.main(["-s"]) diff --git a/tests/topotests/bfd-isis-topo1/rt1/isisd.conf b/tests/topotests/bfd-isis-topo1/rt1/isisd.conf index 3219371d2e..8026aad49d 100644 --- a/tests/topotests/bfd-isis-topo1/rt1/isisd.conf +++ b/tests/topotests/bfd-isis-topo1/rt1/isisd.conf @@ -30,6 +30,7 @@ interface eth-rt3 isis bfd ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0001.00 is-type level-1 ! diff --git a/tests/topotests/bfd-isis-topo1/rt2/isisd.conf b/tests/topotests/bfd-isis-topo1/rt2/isisd.conf index 63ccb640a4..b0fde64a5e 100644 --- a/tests/topotests/bfd-isis-topo1/rt2/isisd.conf +++ b/tests/topotests/bfd-isis-topo1/rt2/isisd.conf @@ -25,6 +25,7 @@ interface eth-rt5 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0002.00 is-type level-1 ! diff --git a/tests/topotests/bfd-isis-topo1/rt3/isisd.conf b/tests/topotests/bfd-isis-topo1/rt3/isisd.conf index 928f1e1a2b..5c36e96c0f 100644 --- a/tests/topotests/bfd-isis-topo1/rt3/isisd.conf +++ b/tests/topotests/bfd-isis-topo1/rt3/isisd.conf @@ -26,6 +26,7 @@ interface eth-rt4 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0003.00 is-type level-1 ! diff --git a/tests/topotests/bfd-isis-topo1/rt4/isisd.conf b/tests/topotests/bfd-isis-topo1/rt4/isisd.conf index fde97478a9..3eac407776 100644 --- a/tests/topotests/bfd-isis-topo1/rt4/isisd.conf +++ b/tests/topotests/bfd-isis-topo1/rt4/isisd.conf @@ -24,6 +24,7 @@ interface eth-rt5 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0004.00 is-type level-1 ! diff --git a/tests/topotests/bfd-isis-topo1/rt5/isisd.conf b/tests/topotests/bfd-isis-topo1/rt5/isisd.conf index fd00cb1ddb..5d449f6f93 100644 --- a/tests/topotests/bfd-isis-topo1/rt5/isisd.conf +++ b/tests/topotests/bfd-isis-topo1/rt5/isisd.conf @@ -24,6 +24,7 @@ interface eth-rt4 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0005.00 is-type level-1 ! diff --git a/tests/topotests/bfd-profiles-topo1/r3/isisd.conf b/tests/topotests/bfd-profiles-topo1/r3/isisd.conf index d27a783adf..ca965e3956 100644 --- a/tests/topotests/bfd-profiles-topo1/r3/isisd.conf +++ b/tests/topotests/bfd-profiles-topo1/r3/isisd.conf @@ -11,6 +11,7 @@ interface r3-eth1 isis bfd profile fasttx ! router isis lan + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00 redistribute ipv6 connected level-1 ! diff --git a/tests/topotests/bfd-profiles-topo1/r4/isisd.conf b/tests/topotests/bfd-profiles-topo1/r4/isisd.conf index 01e197bed5..d8ffc9bc2c 100644 --- a/tests/topotests/bfd-profiles-topo1/r4/isisd.conf +++ b/tests/topotests/bfd-profiles-topo1/r4/isisd.conf @@ -11,6 +11,7 @@ interface r4-eth0 isis bfd profile DOES_NOT_EXIST ! router isis lan + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00 redistribute ipv6 connected level-1 ! diff --git a/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py b/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py index 514933b891..bd3b876eeb 100644 --- a/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py +++ b/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py @@ -118,6 +118,7 @@ def teardown_module(_mod): tgen = get_topogen() tgen.stop_topology() + def test_wait_protocols_convergence(): "Wait for all protocols to converge" tgen = get_topogen() @@ -128,41 +129,40 @@ def test_wait_protocols_convergence(): def expect_loopback_route(router, iptype, route, proto): "Wait until route is present on RIB for protocol." - logger.info('waiting route {} in {}'.format(route, router)) + logger.info("waiting route {} in {}".format(route, router)) test_func = partial( topotest.router_json_cmp, tgen.gears[router], - 'show {} route json'.format(iptype), - { route: [{ 'protocol': proto }] } + "show {} route json".format(iptype), + {route: [{"protocol": proto}]}, ) _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) assertmsg = '"{}" OSPF convergence failure'.format(router) assert result is None, assertmsg - # Wait for R1 <-> R6 convergence. - expect_loopback_route('r1', 'ip', '10.254.254.6/32', 'ospf') + expect_loopback_route("r1", "ip", "10.254.254.6/32", "ospf") # Wait for R6 <-> R1 convergence. - expect_loopback_route('r6', 'ip', '10.254.254.1/32', 'ospf') + expect_loopback_route("r6", "ip", "10.254.254.1/32", "ospf") # Wait for R2 <-> R3 convergence. - expect_loopback_route('r2', 'ip', '10.254.254.3/32', 'bgp') + expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp") # Wait for R3 <-> R2 convergence. - expect_loopback_route('r3', 'ip', '10.254.254.2/32', 'bgp') + expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp") # Wait for R3 <-> R4 convergence. - expect_loopback_route('r3', 'ipv6', '2001:db8:3::/64', 'isis') + expect_loopback_route("r3", "ipv6", "2001:db8:3::/64", "isis") # Wait for R4 <-> R3 convergence. - expect_loopback_route('r4', 'ipv6', '2001:db8:1::/64', 'isis') + expect_loopback_route("r4", "ipv6", "2001:db8:1::/64", "isis") # Wait for R4 <-> R5 convergence. - expect_loopback_route('r4', 'ipv6', '2001:db8:3::/64', 'ospf6') + expect_loopback_route("r4", "ipv6", "2001:db8:3::/64", "ospf6") # Wait for R5 <-> R4 convergence. - expect_loopback_route('r5', 'ipv6', '2001:db8:2::/64', 'ospf6') + expect_loopback_route("r5", "ipv6", "2001:db8:2::/64", "ospf6") def test_bfd_profile_values(): diff --git a/tests/topotests/bfd-topo3/test_bfd_topo3.py b/tests/topotests/bfd-topo3/test_bfd_topo3.py index fa68ace59d..f473b67108 100644 --- a/tests/topotests/bfd-topo3/test_bfd_topo3.py +++ b/tests/topotests/bfd-topo3/test_bfd_topo3.py @@ -103,44 +103,44 @@ def test_wait_bgp_convergence(): def expect_loopback_route(router, iptype, route, proto): "Wait until route is present on RIB for protocol." - logger.info('waiting route {} in {}'.format(route, router)) + logger.info("waiting route {} in {}".format(route, router)) test_func = partial( topotest.router_json_cmp, tgen.gears[router], - 'show {} route json'.format(iptype), - { route: [{ 'protocol': proto }] } + "show {} route json".format(iptype), + {route: [{"protocol": proto}]}, ) _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) assertmsg = '"{}" OSPF convergence failure'.format(router) assert result is None, assertmsg # Wait for R1 <-> R2 convergence. - expect_loopback_route('r1', 'ip', '10.254.254.2/32', 'bgp') + expect_loopback_route("r1", "ip", "10.254.254.2/32", "bgp") # Wait for R1 <-> R3 convergence. - expect_loopback_route('r1', 'ip', '10.254.254.3/32', 'bgp') + expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp") # Wait for R1 <-> R4 convergence. - expect_loopback_route('r1', 'ip', '10.254.254.4/32', 'bgp') + expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp") # Wait for R2 <-> R1 convergence. - expect_loopback_route('r2', 'ip', '10.254.254.1/32', 'bgp') + expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp") # Wait for R2 <-> R3 convergence. - expect_loopback_route('r2', 'ip', '10.254.254.3/32', 'bgp') + expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp") # Wait for R2 <-> R4 convergence. - expect_loopback_route('r2', 'ip', '10.254.254.4/32', 'bgp') + expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp") # Wait for R3 <-> R1 convergence. - expect_loopback_route('r3', 'ip', '10.254.254.1/32', 'bgp') + expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp") # Wait for R3 <-> R2 convergence. - expect_loopback_route('r3', 'ip', '10.254.254.2/32', 'bgp') + expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp") # Wait for R3 <-> R4 convergence. - expect_loopback_route('r3', 'ip', '10.254.254.4/32', 'bgp') + expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp") # Wait for R4 <-> R1 convergence. - expect_loopback_route('r4', 'ip', '10.254.254.1/32', 'bgp') + expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp") # Wait for R4 <-> R2 convergence. - expect_loopback_route('r4', 'ip', '10.254.254.2/32', 'bgp') + expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp") # Wait for R4 <-> R3 convergence. - expect_loopback_route('r4', 'ip', '10.254.254.3/32', 'bgp') + expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp") def test_wait_bfd_convergence(): @@ -153,22 +153,22 @@ def test_wait_bfd_convergence(): def expect_bfd_configuration(router): "Load JSON file and compare with 'show bfd peer json'" - logger.info('waiting BFD configuration on router {}'.format(router)) - bfd_config = json.loads(open('{}/{}/bfd-peers.json'.format(CWD, router)).read()) + logger.info("waiting BFD configuration on router {}".format(router)) + bfd_config = json.loads(open("{}/{}/bfd-peers.json".format(CWD, router)).read()) test_func = partial( topotest.router_json_cmp, tgen.gears[router], - 'show bfd peers json', - bfd_config + "show bfd peers json", + bfd_config, ) _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) assertmsg = '"{}" BFD configuration failure'.format(router) assert result is None, assertmsg - expect_bfd_configuration('r1') - expect_bfd_configuration('r2') - expect_bfd_configuration('r3') - expect_bfd_configuration('r4') + expect_bfd_configuration("r1") + expect_bfd_configuration("r2") + expect_bfd_configuration("r3") + expect_bfd_configuration("r4") def teardown_module(_mod): diff --git a/tests/topotests/bgp-auth/test_bgp_auth.py b/tests/topotests/bgp-auth/test_bgp_auth.py index 286af3bf65..559cf4fb1b 100644 --- a/tests/topotests/bgp-auth/test_bgp_auth.py +++ b/tests/topotests/bgp-auth/test_bgp_auth.py @@ -270,7 +270,7 @@ def peer_name(rtr, prefix, vrf): def print_diag(vrf): "print failure disagnostics" - + tgen = get_topogen() router_list = tgen.routers() for rname, router in router_list.items(): @@ -330,7 +330,7 @@ def clear_ospf(vrf=""): def check_neigh_state(router, peer, state, vrf=""): "check BGP neighbor state on a router" - + count = 0 matched = False neigh_output = "" diff --git a/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py b/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py index 41fa7c0a09..b3b7256ac4 100644 --- a/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py +++ b/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py @@ -76,7 +76,7 @@ from lib.common_config import ( create_prefix_lists, create_route_maps, verify_bgp_community, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import ( @@ -139,7 +139,7 @@ def setup_module(mod): """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") @@ -567,7 +567,7 @@ def test_BGP_attributes_with_vrf_default_keyword_p0(request): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - #reset_config_on_routers(tgen) + # reset_config_on_routers(tgen) step("Configure static routes and redistribute in BGP on R3") for addr_type in ADDR_TYPES: diff --git a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py index eed118ebdc..12069a12dc 100644 --- a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py +++ b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py @@ -61,7 +61,7 @@ from lib.common_config import ( check_address_types, interface_status, reset_config_on_routers, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp @@ -110,7 +110,7 @@ def setup_module(mod): global ADDR_TYPES # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") @@ -144,9 +144,7 @@ def setup_module(mod): ) link_data = [ - val - for links, val in topo["routers"]["r2"]["links"].items() - if "r3" in links + val for links, val in topo["routers"]["r2"]["links"].items() if "r3" in links ] for adt in ADDR_TYPES: NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data] @@ -161,9 +159,7 @@ def setup_module(mod): INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1])) link_data = [ - val - for links, val in topo["routers"]["r3"]["links"].items() - if "r2" in links + val for links, val in topo["routers"]["r3"]["links"].items() if "r2" in links ] INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data] INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1])) diff --git a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py index 7357c33824..50aa281d34 100644 --- a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py +++ b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py @@ -61,7 +61,7 @@ from lib.common_config import ( check_address_types, interface_status, reset_config_on_routers, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp @@ -110,7 +110,7 @@ def setup_module(mod): global ADDR_TYPES # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") @@ -145,9 +145,7 @@ def setup_module(mod): ) link_data = [ - val - for links, val in topo["routers"]["r2"]["links"].items() - if "r3" in links + val for links, val in topo["routers"]["r2"]["links"].items() if "r3" in links ] for adt in ADDR_TYPES: NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data] @@ -162,9 +160,7 @@ def setup_module(mod): INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1])) link_data = [ - val - for links, val in topo["routers"]["r3"]["links"].items() - if "r2" in links + val for links, val in topo["routers"]["r3"]["links"].items() if "r2" in links ] INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data] INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1])) diff --git a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py index 9af22c06bd..4c56d1a02d 100644 --- a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py +++ b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py @@ -57,13 +57,13 @@ from mininet.topo import Topo class NetworkTopo(Topo): - ''' + """ EVPN Multihoming Topology - 1. Two level CLOS 2. Two spine switches - spine1, spine2 3. Two racks with Top-of-Rack switches per rack - tormx1, tormx2 4. Two dual attached hosts per-rack - hostdx1, hostdx2 - ''' + """ def build(self, **_opts): "Build function" @@ -84,7 +84,6 @@ class NetworkTopo(Topo): # On main router # First switch is for a dummy interface (for local network) - ##################### spine1 ######################## # spine1-eth0 is connected to torm11-eth0 switch = tgen.add_switch("sw1") @@ -178,38 +177,44 @@ class NetworkTopo(Topo): ## ##################################################### -tor_ips = {"torm11" : "192.168.100.15", \ - "torm12" : "192.168.100.16", \ - "torm21" : "192.168.100.17", \ - "torm22" : "192.168.100.18"} +tor_ips = { + "torm11": "192.168.100.15", + "torm12": "192.168.100.16", + "torm21": "192.168.100.17", + "torm22": "192.168.100.18", +} + +svi_ips = { + "torm11": "45.0.0.2", + "torm12": "45.0.0.3", + "torm21": "45.0.0.4", + "torm22": "45.0.0.5", +} -svi_ips = {"torm11" : "45.0.0.2", \ - "torm12" : "45.0.0.3", \ - "torm21" : "45.0.0.4", \ - "torm22" : "45.0.0.5"} +tor_ips_rack_1 = {"torm11": "192.168.100.15", "torm12": "192.168.100.16"} -tor_ips_rack_1 = {"torm11" : "192.168.100.15", \ - "torm12" : "192.168.100.16"} +tor_ips_rack_2 = {"torm21": "192.168.100.17", "torm22": "192.168.100.18"} -tor_ips_rack_2 = {"torm21" : "192.168.100.17", \ - "torm22" : "192.168.100.18"} +host_es_map = { + "hostd11": "03:44:38:39:ff:ff:01:00:00:01", + "hostd12": "03:44:38:39:ff:ff:01:00:00:02", + "hostd21": "03:44:38:39:ff:ff:02:00:00:01", + "hostd22": "03:44:38:39:ff:ff:02:00:00:02", +} -host_es_map = {"hostd11" : "03:44:38:39:ff:ff:01:00:00:01", - "hostd12" : "03:44:38:39:ff:ff:01:00:00:02", - "hostd21" : "03:44:38:39:ff:ff:02:00:00:01", - "hostd22" : "03:44:38:39:ff:ff:02:00:00:02"} def config_bond(node, bond_name, bond_members, bond_ad_sys_mac, br): - ''' + """ Used to setup bonds on the TORs and hosts for MH - ''' + """ node.run("ip link add dev %s type bond mode 802.3ad" % bond_name) node.run("ip link set dev %s type bond lacp_rate 1" % bond_name) node.run("ip link set dev %s type bond miimon 100" % bond_name) node.run("ip link set dev %s type bond xmit_hash_policy layer3+4" % bond_name) node.run("ip link set dev %s type bond min_links 1" % bond_name) - node.run("ip link set dev %s type bond ad_actor_system %s" %\ - (bond_name, bond_ad_sys_mac)) + node.run( + "ip link set dev %s type bond ad_actor_system %s" % (bond_name, bond_ad_sys_mac) + ) for bond_member in bond_members: node.run("ip link set dev %s down" % bond_member) @@ -225,15 +230,14 @@ def config_bond(node, bond_name, bond_members, bond_ad_sys_mac, br): node.run("/sbin/bridge vlan del vid 1 dev %s" % bond_name) node.run("/sbin/bridge vlan del vid 1 untagged pvid dev %s" % bond_name) node.run("/sbin/bridge vlan add vid 1000 dev %s" % bond_name) - node.run("/sbin/bridge vlan add vid 1000 untagged pvid dev %s"\ - % bond_name) + node.run("/sbin/bridge vlan add vid 1000 untagged pvid dev %s" % bond_name) def config_mcast_tunnel_termination_device(node): - ''' + """ The kernel requires a device to terminate VxLAN multicast tunnels when EVPN-PIM is used for flooded traffic - ''' + """ node.run("ip link add dev ipmr-lo type dummy") node.run("ip link set dev ipmr-lo mtu 16000") node.run("ip link set dev ipmr-lo mode dormant") @@ -241,9 +245,9 @@ def config_mcast_tunnel_termination_device(node): def config_bridge(node): - ''' + """ Create a VLAN aware bridge - ''' + """ node.run("ip link add dev bridge type bridge stp_state 0") node.run("ip link set dev bridge type bridge vlan_filtering 1") node.run("ip link set dev bridge mtu 9216") @@ -255,10 +259,10 @@ def config_bridge(node): def config_vxlan(node, node_ip): - ''' + """ Create a VxLAN device for VNI 1000 and add it to the bridge. VLAN-1000 is mapped to VNI-1000. - ''' + """ node.run("ip link add dev vx-1000 type vxlan id 1000 dstport 4789") node.run("ip link set dev vx-1000 type vxlan nolearning") node.run("ip link set dev vx-1000 type vxlan local %s" % node_ip) @@ -279,9 +283,9 @@ def config_vxlan(node, node_ip): def config_svi(node, svi_pip): - ''' + """ Create an SVI for VLAN 1000 - ''' + """ node.run("ip link add link bridge name vlan1000 type vlan id 1000 protocol 802.1q") node.run("ip addr add %s/24 dev vlan1000" % svi_pip) node.run("ip link set dev vlan1000 up") @@ -297,9 +301,9 @@ def config_svi(node, svi_pip): def config_tor(tor_name, tor, tor_ip, svi_pip): - ''' + """ Create the bond/vxlan-bridge on the TOR which acts as VTEP and EPN-PE - ''' + """ # create a device for terminating VxLAN multicast tunnels config_mcast_tunnel_termination_device(tor) @@ -329,17 +333,19 @@ def config_tors(tgen, tors): tor = tgen.gears[tor_name] config_tor(tor_name, tor, tor_ips.get(tor_name), svi_ips.get(tor_name)) + def compute_host_ip_mac(host_name): host_id = host_name.split("hostd")[1] - host_ip = "45.0.0."+ host_id + "/24" + host_ip = "45.0.0." + host_id + "/24" host_mac = "00:00:00:00:00:" + host_id return host_ip, host_mac + def config_host(host_name, host): - ''' + """ Create the dual-attached bond on host nodes for MH - ''' + """ bond_members = [] bond_members.append(host_name + "-eth0") bond_members.append(host_name + "-eth1") @@ -407,9 +413,9 @@ def teardown_module(_mod): def check_local_es(esi, vtep_ips, dut_name, down_vteps): - ''' + """ Check if ES peers are setup correctly on local ESs - ''' + """ peer_ips = [] if "torm1" in dut_name: tor_ips_rack = tor_ips_rack_1 @@ -432,9 +438,9 @@ def check_local_es(esi, vtep_ips, dut_name, down_vteps): def check_remote_es(esi, vtep_ips, dut_name, down_vteps): - ''' + """ Verify list of PEs associated with a remote ES - ''' + """ remote_ips = [] if "torm1" in dut_name: @@ -455,10 +461,11 @@ def check_remote_es(esi, vtep_ips, dut_name, down_vteps): return (esi, diff) if diff else None + def check_es(dut): - ''' + """ Verify list of PEs associated all ESs, local and remote - ''' + """ bgp_es = dut.vtysh_cmd("show bgp l2vp evpn es json") bgp_es_json = json.loads(bgp_es) @@ -490,10 +497,11 @@ def check_es(dut): return result if result else None + def check_one_es(dut, esi, down_vteps): - ''' + """ Verify list of PEs associated all ESs, local and remote - ''' + """ bgp_es = dut.vtysh_cmd("show bgp l2vp evpn es %s json" % esi) es = json.loads(bgp_es) @@ -513,12 +521,13 @@ def check_one_es(dut, esi, down_vteps): return result + def test_evpn_es(): - ''' + """ Two ES are setup on each rack. This test checks if - 1. ES peer has been added to the local ES (via Type-1/EAD route) 2. The remote ESs are setup with the right list of PEs (via Type-1) - ''' + """ tgen = get_topogen() @@ -534,11 +543,12 @@ def test_evpn_es(): assert result is None, assertmsg # tgen.mininet_cli() + def test_evpn_ead_update(): - ''' + """ Flap a host link one the remote rack and check if the EAD updates are sent/processed for the corresponding ESI - ''' + """ tgen = get_topogen() if tgen.routers_have_failure(): @@ -580,30 +590,32 @@ def test_evpn_ead_update(): # tgen.mininet_cli() + def check_mac(dut, vni, mac, m_type, esi, intf): - ''' + """ checks if mac is present and if desination matches the one provided - ''' + """ out = dut.vtysh_cmd("show evpn mac vni %d mac %s json" % (vni, mac)) mac_js = json.loads(out) for mac, info in mac_js.items(): tmp_esi = info.get("esi", "") - tmp_m_type = info.get("type", "") + tmp_m_type = info.get("type", "") tmp_intf = info.get("intf", "") if tmp_m_type == "local" else "" if tmp_esi == esi and tmp_m_type == m_type and intf == intf: return None return "invalid vni %d mac %s out %s" % (vni, mac, mac_js) + def test_evpn_mac(): - ''' + """ 1. Add a MAC on hostd11 and check if the MAC is synced between torm11 and torm12. And installed as a local MAC. 2. Add a MAC on hostd21 and check if the MAC is installed as a remote MAC on torm11 and torm12 - ''' + """ tgen = get_topogen() @@ -646,6 +658,126 @@ def test_evpn_mac(): assertmsg = '"{}" remote MAC content incorrect'.format(tor.name) assert result is None, assertmsg +def check_df_role(dut, esi, role): + ''' + Return error string if the df role on the dut is different + ''' + es_json = dut.vtysh_cmd("show evpn es %s json" % esi) + es = json.loads(es_json) + + if not es: + return "esi %s not found" % esi + + flags = es.get("flags", []) + curr_role = "nonDF" if "nonDF" in flags else "DF" + + if curr_role != role: + return "%s is %s for %s" % (dut.name, curr_role, esi) + + return None + +def test_evpn_df(): + ''' + 1. Check the DF role on all the PEs on rack-1. + 2. Increase the DF preference on the non-DF and check if it becomes + the DF winner. + ''' + + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # We will run the tests on just one ES + esi = host_es_map.get("hostd11") + intf = "hostbond1" + + tors = [] + tors.append(tgen.gears["torm11"]) + tors.append(tgen.gears["torm12"]) + df_node = "torm11" + + # check roles on rack-1 + for tor in tors: + role = "DF" if tor.name == df_node else "nonDF" + test_fn = partial(check_df_role, tor, esi, role) + _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3) + assertmsg = '"{}" DF role incorrect'.format(tor.name) + assert result is None, assertmsg + + # change df preference on the nonDF to make it the df + torm12 = tgen.gears["torm12"] + torm12.vtysh_cmd("conf\ninterface %s\nevpn mh es-df-pref %d" % (intf, 60000)) + df_node = "torm12" + + # re-check roles on rack-1; we should have a new winner + for tor in tors: + role = "DF" if tor.name == df_node else "nonDF" + test_fn = partial(check_df_role, tor, esi, role) + _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3) + assertmsg = '"{}" DF role incorrect'.format(tor.name) + assert result is None, assertmsg + + # tgen.mininet_cli() + +def check_protodown_rc(dut, protodown_rc): + ''' + check if specified protodown reason code is set + ''' + + out = dut.vtysh_cmd("show evpn json") + + evpn_js = json.loads(out) + tmp_rc = evpn_js.get("protodownReasons", []) + + if protodown_rc: + if protodown_rc not in tmp_rc: + return "protodown %s missing in %s" % (protodown_rc, tmp_rc) + else: + if tmp_rc: + return "unexpected protodown rc %s" % (tmp_rc) + + return None + +def test_evpn_uplink_tracking(): + ''' + 1. Wait for access ports to come out of startup-delay + 2. disable uplinks and check if access ports have been protodowned + 3. enable uplinks and check if access ports have been moved out + of protodown + ''' + + tgen = get_topogen() + + dut_name = "torm11" + dut = tgen.gears[dut_name] + + # wait for protodown rc to clear after startup + test_fn = partial(check_protodown_rc, dut, None) + _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3) + assertmsg = '"{}" protodown rc incorrect'.format(dut_name) + assert result is None, assertmsg + + # disable the uplinks + dut.run("ip link set %s-eth0 down" % dut_name) + dut.run("ip link set %s-eth1 down" % dut_name) + + # check if the access ports have been protodowned + test_fn = partial(check_protodown_rc, dut, "uplinkDown") + _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3) + assertmsg = '"{}" protodown rc incorrect'.format(dut_name) + assert result is None, assertmsg + + # enable the uplinks + dut.run("ip link set %s-eth0 up" % dut_name) + dut.run("ip link set %s-eth1 up" % dut_name) + + # check if the access ports have been moved out of protodown + test_fn = partial(check_protodown_rc, dut, None) + _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3) + assertmsg = '"{}" protodown rc incorrect'.format(dut_name) + assert result is None, assertmsg + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp-evpn-mh/torm11/zebra.conf b/tests/topotests/bgp-evpn-mh/torm11/zebra.conf index ee4e87e1c2..33e89c06ae 100644 --- a/tests/topotests/bgp-evpn-mh/torm11/zebra.conf +++ b/tests/topotests/bgp-evpn-mh/torm11/zebra.conf @@ -4,11 +4,15 @@ debug zebra evpn mh neigh debug zebra evpn mh nh debug zebra vxlan ! +evpn mh startup-delay 1 +! int torm11-eth0 ip addr 192.168.1.2/24 + evpn mh uplink ! int torm11-eth1 ip addr 192.168.5.2/24 + evpn mh uplink ! int lo ip addr 192.168.100.15/32 diff --git a/tests/topotests/bgp-evpn-mh/torm12/zebra.conf b/tests/topotests/bgp-evpn-mh/torm12/zebra.conf index 736af4159e..419f62b2ac 100644 --- a/tests/topotests/bgp-evpn-mh/torm12/zebra.conf +++ b/tests/topotests/bgp-evpn-mh/torm12/zebra.conf @@ -4,11 +4,16 @@ debug zebra evpn mh neigh debug zebra evpn mh nh debug zebra vxlan ! +evpn mh startup-delay 1 +! int torm12-eth0 ip addr 192.168.2.2/24 + evpn mh uplink ! int torm12-eth1 ip addr 192.168.6.2/24 + evpn mh uplink +! ! int lo ip addr 192.168.100.16/32 diff --git a/tests/topotests/bgp-evpn-mh/torm21/zebra.conf b/tests/topotests/bgp-evpn-mh/torm21/zebra.conf index 0ebe6f2d95..525f5eb099 100644 --- a/tests/topotests/bgp-evpn-mh/torm21/zebra.conf +++ b/tests/topotests/bgp-evpn-mh/torm21/zebra.conf @@ -4,11 +4,17 @@ debug zebra evpn mh neigh debug zebra evpn mh nh debug zebra vxlan ! +evpn mh startup-delay 1 +! int torm21-eth0 ip addr 192.168.3.2/24 + evpn mh uplink +! ! int torm21-eth1 ip addr 192.168.7.2/24 + evpn mh uplink +! ! int lo ip addr 192.168.100.17/32 diff --git a/tests/topotests/bgp-evpn-mh/torm22/evpn.conf b/tests/topotests/bgp-evpn-mh/torm22/evpn.conf index b4f4f1dc25..432135c94a 100644 --- a/tests/topotests/bgp-evpn-mh/torm22/evpn.conf +++ b/tests/topotests/bgp-evpn-mh/torm22/evpn.conf @@ -5,7 +5,6 @@ debug bgp evpn mh es debug bgp evpn mh route debug bgp zebra ! -! router bgp 65005 bgp router-id 192.168.100.18 no bgp ebgp-requires-policy diff --git a/tests/topotests/bgp-evpn-mh/torm22/zebra.conf b/tests/topotests/bgp-evpn-mh/torm22/zebra.conf index 356d8a43e7..398064df6c 100644 --- a/tests/topotests/bgp-evpn-mh/torm22/zebra.conf +++ b/tests/topotests/bgp-evpn-mh/torm22/zebra.conf @@ -4,11 +4,17 @@ debug zebra evpn mh neigh debug zebra evpn mh nh debug zebra vxlan ! +evpn mh startup-delay 1 +! int torm22-eth0 ip addr 192.168.4.2/24 + evpn mh uplink +! ! int torm22-eth1 ip addr 192.168.8.2/24 + evpn mh uplink +! ! int lo ip addr 192.168.100.18/32 diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py b/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py index 2a14105383..5098808d55 100644..100755 --- a/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py +++ b/tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py @@ -197,8 +197,12 @@ def mac_learn_test(host, local): host_output = host.vtysh_cmd("show interface {}-eth0".format(host.name)) int_lines = host_output.splitlines() - line_items = int_lines[7].split(": ") - mac = line_items[1] + for line in int_lines: + line_items = line.split(": ") + if "HWaddr" in line_items[0]: + mac = line_items[1] + break + mac_output = local.vtysh_cmd("show evpn mac vni 101 mac {} json".format(mac)) mac_output_json = json.loads(mac_output) assertmsg = "Local MAC output does not match interface mac {}".format(mac) @@ -287,8 +291,11 @@ def ip_learn_test(tgen, host, local, remote, ip_addr): "check the host IP gets learned by the VNI" host_output = host.vtysh_cmd("show interface {}-eth0".format(host.name)) int_lines = host_output.splitlines() - mac_line = int_lines[7].split(": ") - mac = mac_line[1] + for line in int_lines: + line_items = line.split(": ") + if "HWaddr" in line_items[0]: + mac = line_items[1] + break print(host_output) # check we have a local association between the MAC and IP diff --git a/tests/topotests/bgp-vrf-route-leak-basic/test_bgp-vrf-route-leak-basic.py b/tests/topotests/bgp-vrf-route-leak-basic/test_bgp-vrf-route-leak-basic.py index 5aa1bdf329..36f1d8cd56 100644 --- a/tests/topotests/bgp-vrf-route-leak-basic/test_bgp-vrf-route-leak-basic.py +++ b/tests/topotests/bgp-vrf-route-leak-basic/test_bgp-vrf-route-leak-basic.py @@ -90,84 +90,36 @@ def test_vrf_route_leak(): # Test DONNA VRF. expect = { - '10.0.0.0/24': [ - { - 'protocol': 'connected', - } + "10.0.0.0/24": [{"protocol": "connected",}], + "10.0.1.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} ], - '10.0.1.0/24': [ - { - 'protocol': 'bgp', - 'selected': True, - 'nexthops': [ - { - 'fib': True - } - ] - } + "10.0.2.0/24": [{"protocol": "connected"}], + "10.0.3.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} ], - '10.0.2.0/24': [ - { - 'protocol': 'connected' - } - ], - '10.0.3.0/24': [ - { - 'protocol': 'bgp', - 'selected': True, - 'nexthops': [ - { - 'fib': True - } - ] - } - ] } test_func = partial( - topotest.router_json_cmp, r1, 'show ip route vrf DONNA json', expect + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect ) result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result, "BGP VRF DONNA check failed:\n{}".format(diff) # Test EVA VRF. expect = { - '10.0.0.0/24': [ - { - 'protocol': 'bgp', - 'selected': True, - 'nexthops': [ - { - 'fib': True - } - ] - } - ], - '10.0.1.0/24': [ - { - 'protocol': 'connected', - } + "10.0.0.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} ], - '10.0.2.0/24': [ - { - 'protocol': 'bgp', - 'selected': True, - 'nexthops': [ - { - 'fib': True - } - ] - } + "10.0.1.0/24": [{"protocol": "connected",}], + "10.0.2.0/24": [ + {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} ], - '10.0.3.0/24': [ - { - 'protocol': 'connected', - } - ] + "10.0.3.0/24": [{"protocol": "connected",}], } test_func = partial( - topotest.router_json_cmp, r1, 'show ip route vrf EVA json', expect + topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect ) result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result, "BGP VRF EVA check failed:\n{}".format(diff) diff --git a/tests/topotests/bgp_default-route_route-map/__init__.py b/tests/topotests/bgp_aggregate_address_topo1/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/tests/topotests/bgp_default-route_route-map/__init__.py +++ b/tests/topotests/bgp_aggregate_address_topo1/__init__.py diff --git a/tests/topotests/bgp_aggregate_address_topo1/exabgp.env b/tests/topotests/bgp_aggregate_address_topo1/exabgp.env new file mode 100644 index 0000000000..28e642360a --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/exabgp.env @@ -0,0 +1,53 @@ +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' +##daemonize = false + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp_aggregate_address_topo1/peer1/exabgp.cfg b/tests/topotests/bgp_aggregate_address_topo1/peer1/exabgp.cfg new file mode 100644 index 0000000000..e0f6ab601f --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/peer1/exabgp.cfg @@ -0,0 +1,21 @@ +neighbor 10.0.0.1 { + router-id 10.254.254.3; + local-address 10.0.0.2; + local-as 65001; + peer-as 65000; + static { + route 10.254.254.3/32 next-hop 10.0.0.2; + + route 192.168.0.1/32 next-hop 10.0.0.2 med 10; + route 192.168.0.2/32 next-hop 10.0.0.2 med 10; + route 192.168.0.3/32 next-hop 10.0.0.2 med 10; + + route 192.168.1.1/32 next-hop 10.0.0.2 med 10; + route 192.168.1.2/32 next-hop 10.0.0.2 med 10; + route 192.168.1.3/32 next-hop 10.0.0.2 med 20; + + route 192.168.2.1/32 next-hop 10.0.0.2; + route 192.168.2.2/32 next-hop 10.0.0.2; + route 192.168.2.3/32 next-hop 10.0.0.2; + } +} diff --git a/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf b/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf new file mode 100644 index 0000000000..fa52150085 --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf @@ -0,0 +1,30 @@ +debug bgp updates +! +access-list acl-sup-one seq 5 permit 192.168.2.1/32 +access-list acl-sup-one seq 10 deny any +! +access-list acl-sup-two seq 5 permit 192.168.2.2/32 +access-list acl-sup-two seq 10 deny any +! +access-list acl-sup-three seq 5 permit 192.168.2.3/32 +access-list acl-sup-three seq 10 deny any +! +route-map rm-sup-one permit 10 + match ip address acl-sup-one +! +route-map rm-sup-two permit 10 + match ip address acl-sup-two +! +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 10.0.0.2 remote-as 65001 + neighbor 10.0.0.2 timers 3 10 + neighbor 10.0.1.2 remote-as internal + neighbor 10.0.1.2 timers 3 10 + address-family ipv4 unicast + redistribute connected + aggregate-address 192.168.0.0/24 matching-MED-only + aggregate-address 192.168.1.0/24 matching-MED-only + aggregate-address 192.168.2.0/24 suppress-map rm-sup-one + exit-address-family +! diff --git a/tests/topotests/bgp_aggregate_address_topo1/r1/zebra.conf b/tests/topotests/bgp_aggregate_address_topo1/r1/zebra.conf new file mode 100644 index 0000000000..931c73d8fa --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/r1/zebra.conf @@ -0,0 +1,13 @@ +! +interface lo + ip address 10.254.254.1/32 +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +interface r1-eth1 + ip address 10.0.1.1/24 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf b/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf new file mode 100644 index 0000000000..acacd86526 --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf @@ -0,0 +1,7 @@ +router bgp 65000 + neighbor 10.0.1.1 remote-as internal + neighbor 10.0.1.1 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_aggregate_address_topo1/r2/zebra.conf b/tests/topotests/bgp_aggregate_address_topo1/r2/zebra.conf new file mode 100644 index 0000000000..38e0c44299 --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/r2/zebra.conf @@ -0,0 +1,10 @@ +! +interface lo + ip address 10.254.254.2/32 +! +interface r2-eth0 + ip address 10.0.1.2/24 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py b/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py new file mode 100644 index 0000000000..3f3b71dea3 --- /dev/null +++ b/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python + +# +# test_bgp_aggregate_address_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2020 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test BGP aggregate address features. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class BgpAggregateAddressTopo1(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + peer1 = tgen.add_exabgp_peer( + "peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1" + ) + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(peer1) + + switch = tgen.add_switch("s2") + switch.add_link(r1) + switch.add_link(r2) + + +def setup_module(mod): + tgen = Topogen(BgpAggregateAddressTopo1, mod.__name__) + tgen.start_topology() + + router = tgen.gears["r1"] + router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf")) + router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf")) + router.start() + + router = tgen.gears["r2"] + router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r2/zebra.conf")) + router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r2/bgpd.conf")) + router.start() + + peer = tgen.gears["peer1"] + peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env")) + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def expect_route(router_name, routes_expected): + "Helper function to avoid repeated code." + tgen = get_topogen() + test_func = functools.partial( + topotest.router_json_cmp, + tgen.gears[router_name], + "show ip route json", + routes_expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=1) + assertmsg = '"{}" BGP convergence failure'.format(router_name) + assert result is None, assertmsg + + +def test_expect_convergence(): + "Test that BGP protocol converged." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for protocols to converge") + + def expect_loopback_route(router, iptype, route, proto): + "Wait until route is present on RIB for protocol." + logger.info("waiting route {} in {}".format(route, router)) + test_func = functools.partial( + topotest.router_json_cmp, + tgen.gears[router], + "show {} route json".format(iptype), + {route: [{"protocol": proto}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" BGP convergence failure'.format(router) + assert result is None, assertmsg + + expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp") + expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp") + + +def test_bgp_aggregate_address_matching_med_only(): + "Test that the command matching-MED-only works." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + routes_expected = { + # All MED matches, aggregation must exist. + "192.168.0.0/24": [{"protocol": "bgp", "metric": 0}], + "192.168.0.1/32": [{"protocol": "bgp", "metric": 10}], + "192.168.0.2/32": [{"protocol": "bgp", "metric": 10}], + "192.168.0.3/32": [{"protocol": "bgp", "metric": 10}], + # Non matching MED: aggregation must not exist. + "192.168.1.0/24": None, + "192.168.1.1/32": [{"protocol": "bgp", "metric": 10}], + "192.168.1.2/32": [{"protocol": "bgp", "metric": 10}], + "192.168.1.3/32": [{"protocol": "bgp", "metric": 20}], + } + + test_func = functools.partial( + topotest.router_json_cmp, + tgen.gears["r2"], + "show ip route json", + routes_expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assertmsg = '"r2" BGP convergence failure' + assert result is None, assertmsg + + +def test_bgp_aggregate_address_match_and_supress(): + "Test that the command matching-MED-only with suppression works." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r1"].vtysh_multicmd( + """ +configure terminal +router bgp 65000 +address-family ipv4 unicast +no aggregate-address 192.168.0.0/24 matching-MED-only +no aggregate-address 192.168.1.0/24 matching-MED-only +aggregate-address 192.168.0.0/24 matching-MED-only summary-only +aggregate-address 192.168.1.0/24 matching-MED-only summary-only +""" + ) + + routes_expected = { + # All MED matches, aggregation must exist. + "192.168.0.0/24": [{"protocol": "bgp", "metric": 0}], + "192.168.0.1/32": None, + "192.168.0.2/32": None, + "192.168.0.3/32": None, + # Non matching MED: aggregation must not exist. + "192.168.1.0/24": None, + "192.168.1.1/32": [{"protocol": "bgp", "metric": 10}], + "192.168.1.2/32": [{"protocol": "bgp", "metric": 10}], + "192.168.1.3/32": [{"protocol": "bgp", "metric": 20}], + } + + test_func = functools.partial( + topotest.router_json_cmp, + tgen.gears["r2"], + "show ip route json", + routes_expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=1) + assertmsg = '"r2" BGP convergence failure' + assert result is None, assertmsg + + +def test_bgp_aggregate_address_suppress_map(): + "Test that the command suppress-map works." + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + expect_route('r2', { + "192.168.2.0/24": [{"protocol": "bgp"}], + "192.168.2.1/32": None, + "192.168.2.2/32": [{"protocol": "bgp"}], + "192.168.2.3/32": [{"protocol": "bgp"}], + }) + + # Change route map and test again. + tgen.gears["r1"].vtysh_multicmd( + """ +configure terminal +router bgp 65000 +address-family ipv4 unicast +no aggregate-address 192.168.2.0/24 suppress-map rm-sup-one +aggregate-address 192.168.2.0/24 suppress-map rm-sup-two +""" + ) + + expect_route('r2', { + "192.168.2.0/24": [{"protocol": "bgp"}], + "192.168.2.1/32": [{"protocol": "bgp"}], + "192.168.2.2/32": None, + "192.168.2.3/32": [{"protocol": "bgp"}], + }) + + +def test_bgp_aggregate_address_suppress_map_update_route_map(): + "Test that the suppress-map late route map creation works." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r1"].vtysh_multicmd( + """ +configure terminal +router bgp 65000 +address-family ipv4 unicast +no aggregate-address 192.168.2.0/24 suppress-map rm-sup-two +aggregate-address 192.168.2.0/24 suppress-map rm-sup-three +""" + ) + + expect_route('r2', { + "192.168.2.0/24": [{"protocol": "bgp"}], + "192.168.2.1/32": [{"protocol": "bgp"}], + "192.168.2.2/32": [{"protocol": "bgp"}], + "192.168.2.3/32": [{"protocol": "bgp"}], + }) + + # Create missing route map and test again. + tgen.gears["r1"].vtysh_multicmd( + """ +configure terminal +route-map rm-sup-three permit 10 +match ip address acl-sup-three +""" + ) + + expect_route('r2', { + "192.168.2.0/24": [{"protocol": "bgp"}], + "192.168.2.1/32": [{"protocol": "bgp"}], + "192.168.2.2/32": [{"protocol": "bgp"}], + "192.168.2.3/32": None, + }) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py index f9d22a3a36..544bda145c 100644 --- a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py +++ b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py @@ -65,7 +65,7 @@ from lib.common_config import ( create_route_maps, check_address_types, step, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import ( @@ -114,7 +114,7 @@ def setup_module(mod): """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json b/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json new file mode 100644 index 0000000000..fa89f6b8f2 --- /dev/null +++ b/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json @@ -0,0 +1,191 @@ +{ + "address_types": [ + "ipv4", + "ipv6" + ], + "ipv4base": "10.0.0.0", + "ipv4mask": 24, + "ipv6base": "fd00::", + "ipv6mask": 64, + "link_ip_start": { + "ipv4": "10.0.0.0", + "v4mask": 24, + "ipv6": "fd00::", + "v6mask": 64 + }, + "lo_prefix": { + "ipv4": "1.0.", + "v4mask": 32, + "ipv6": "2001:db8:f::", + "v6mask": 128 + }, + "routers": { + "r1": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r2": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r3": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": {} + } + }, + "r3": { + "dest_link": { + "r1": { + } + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": { + } + } + }, + "r3": { + "dest_link": { + "r1": { + } + } + } + } + } + } + } + } + }, + "r2": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r1": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": { + "route_maps": [{ + "name": "rmap_global", + "direction": "in" + }] + } + } + } + } + } + } + } + }, + "route_maps": { + "rmap_global": [{ + "action": "permit", + "set": { + "ipv6": { + "nexthop": "prefer-global" + } + } + }] + } + }, + "r3": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r1": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "300", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r3": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r3": { + "route_maps": [{ + "name": "rmap_global", + "direction": "in" + }] + } + } + } + } + } + } + } + }, + "route_maps": { + "rmap_global": [{ + "action": "permit", + "set": { + "ipv6": { + "nexthop": "prefer-global" + } + } + }] + } + } + } +} diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py index 57e8e0d34a..f2e54b24d6 100644 --- a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py +++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py @@ -54,7 +54,7 @@ from lib.common_config import ( create_route_maps, create_prefix_lists, create_route_maps, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import ( @@ -104,7 +104,7 @@ def setup_module(mod): """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py new file mode 100644 index 0000000000..c0842148f1 --- /dev/null +++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py @@ -0,0 +1,422 @@ +#!/usr/bin/python + +# +# Copyright (c) 2020 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Following tests are covered to test bgp community functionality: +1. Verify that BGP well known communities work fine for + eBGP and iBGP peers. + Well known communities tested: no-export, local-AS, internet + +""" + +import os +import sys +import time +import json +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from mininet.topo import Topo +from lib.topogen import Topogen, get_topogen + +# Import topoJson from lib, to create topology and initial configuration +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + verify_rib, + create_static_routes, + check_address_types, + step, + create_route_maps, + create_prefix_lists, + create_route_maps, + required_linux_kernel_version, +) + +from lib.topolog import logger +from lib.bgp import ( + verify_bgp_convergence, + create_router_bgp, + clear_bgp_and_verify, + verify_bgp_rib, + verify_bgp_community, +) +from lib.topojson import build_topo_from_json, build_config_from_json +from copy import deepcopy + +# Reading the data from JSON File for topology creation +jsonFile = "{}/bgp_communities_topo2.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) + +# Global variables +BGP_CONVERGENCE = False +ADDR_TYPES = check_address_types() +NETWORK = { + "ipv4": ["192.0.2.1/32", "192.0.2.2/32"], + "ipv6": ["2001:DB8::1:1/128", "2001:DB8::1:2/128"], +} + + +class BGPCOMMUNITIES(Topo): + """ + Test BGPCOMMUNITIES - topology 1 + + * `Topo`: Topology object + """ + + def build(self, *_args, **_opts): + """Build function""" + tgen = get_topogen(self) + + # Building topology from json file + build_topo_from_json(tgen, topo) + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("4.14") + if result is not True: + pytest.skip("Kernel requirements are not met") + + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + tgen = Topogen(BGPCOMMUNITIES, mod.__name__) + # ... and here it calls Mininet initialization functions. + + # Starting topology, create tmp files which are loaded to routers + # to start deamons and then start routers + start_topology(tgen) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + # Checking BGP convergence + global BGP_CONVERGENCE + global ADDR_TYPES + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Api call verify whether BGP is converged + BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) + assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format( + BGP_CONVERGENCE + ) + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment + + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +##################################################### +# +# Tests starting +# +##################################################### + + +def test_bgp_no_export_local_as_and_internet_communities_p0(request): + """ + Verify that BGP well known communities work fine for + eBGP and iBGP peers. + Well known communities tested: no-export, local-AS, internet + """ + + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don"t run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Initial config: Configure BGP neighborship between R1 and R3.") + reset_config_on_routers(tgen) + + step("Configure static routes on R1 with next-hop as null0") + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r1": { + "static_routes": [{"network": NETWORK[addr_type], "next_hop": "null0"}] + } + } + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + for comm_type in ["no-export", "local-AS", "internet"]: + + step("Create a route-map on R1 to set community as {}".format(comm_type)) + + seq_id = 10 + input_rmap = { + "r1": { + "route_maps": { + "rmap_wkc": [ + { + "action": "permit", + "seq_id": seq_id, + "set": {"community": {"num": "{}".format(comm_type)}}, + } + ] + } + } + } + result = create_route_maps(tgen, input_rmap) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step("Apply route-map while redistributing static routes into BGP") + input_dict_2 = { + "r1": { + "bgp": { + "address_family": { + "ipv4": { + "unicast": { + "redistribute": [ + { + "redist_type": "static", + "attribute": {"route-map": "rmap_wkc"}, + } + ] + } + }, + "ipv6": { + "unicast": { + "redistribute": [ + { + "redist_type": "static", + "attribute": {"route-map": "rmap_wkc"}, + } + ] + } + }, + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + + step("Verify that BGP prefixes on R1 have community: {}".format(comm_type)) + input_dict_4 = {"community": "{}".format(comm_type)} + for addr_type in ADDR_TYPES: + result = verify_bgp_community( + tgen, addr_type, "r1", NETWORK[addr_type], input_dict_4 + ) + assert result is True, "Test case {} : Should fail \n Error: {}".format( + tc_name, result + ) + + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r1": { + "static_routes": [ + { + "network": NETWORK[addr_type], + "next_hop": topo["routers"]["r2"]["links"]["r1"][ + addr_type + ].split("/")[0], + } + ] + } + } + result = verify_bgp_rib( + tgen, + addr_type, + "r2", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + if comm_type == "internet": + step( + "Verify that these prefixes, originated on R1, are" + "received on both R2 and R3" + ) + + result = verify_rib( + tgen, + addr_type, + "r3", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[ + 0 + ], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + else: + step( + "Verify that these prefixes, originated on R1, are not" + "received on R3 but received on R2" + ) + + result = verify_rib( + tgen, + addr_type, + "r3", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[ + 0 + ], + expected=False, + ) + assert result is not True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + step("Remove route-map from redistribute static on R1") + input_dict_2 = { + "r1": { + "bgp": { + "address_family": { + "ipv4": { + "unicast": { + "redistribute": [ + {"redist_type": "static", "delete": True} + ] + } + }, + "ipv6": { + "unicast": { + "redistribute": [ + {"redist_type": "static", "delete": True} + ] + } + }, + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result) + + step("Configure redistribute static") + input_dict_2 = { + "r1": { + "bgp": { + "address_family": { + "ipv4": { + "unicast": {"redistribute": [{"redist_type": "static"}]} + }, + "ipv6": { + "unicast": {"redistribute": [{"redist_type": "static"}]} + }, + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that these prefixes, originated on R1, are now" + "received on both routers R2 and R3" + ) + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r1": { + "static_routes": [ + { + "network": NETWORK[addr_type], + "next_hop": topo["routers"]["r2"]["links"]["r1"][ + addr_type + ].split("/")[0], + } + ] + } + } + result = verify_bgp_rib( + tgen, + addr_type, + "r2", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + result = verify_bgp_rib( + tgen, + addr_type, + "r3", + input_dict_4, + next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0], + ) + assert result is True, "Testcase : Failed \n Error: {}".format( + tc_name, result + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_conditional_advertisement/__init__.py b/tests/topotests/bgp_conditional_advertisement/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/__init__.py diff --git a/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf new file mode 100644 index 0000000000..633d1832fd --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf @@ -0,0 +1,30 @@ +! +ip prefix-list CUST seq 5 permit 10.139.224.0/20 +ip prefix-list DEFAULT seq 5 permit 0.0.0.0/0 +ip prefix-list PL1 seq 5 permit 192.0.2.1/32 +! +route-map CUST permit 10 + match ip address prefix-list CUST + set community 64671:501 +! +route-map RM1 permit 10 + match ip address prefix-list PL1 + set community 64952:3008 +! +route-map DEF permit 10 + match ip address prefix-list DEFAULT + set community 64848:3011 65011:200 65013:200 +! +router bgp 1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.10.2 remote-as 2 + ! + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + network 192.0.2.1/32 route-map RM1 + network 192.0.2.5/32 + redistribute connected route-map CUST + neighbor 10.10.10.2 soft-reconfiguration inbound + exit-address-family +! diff --git a/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf new file mode 100644 index 0000000000..bb887e41ad --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf @@ -0,0 +1,19 @@ +! +hostname Router1 +! +ip route 0.0.0.0/0 blackhole +ip route 192.0.2.1/32 blackhole +ip route 192.0.2.2/32 blackhole +ip route 192.0.2.3/32 blackhole +ip route 192.0.2.4/32 blackhole +ip route 192.0.2.5/32 blackhole +! +interface r1-eth0 + ip address 10.10.10.1/24 +! +interface lo + ip address 10.139.224.1/20 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf new file mode 100644 index 0000000000..c6147fe658 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf @@ -0,0 +1,44 @@ +! +ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32 +ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32 +ip prefix-list EXIST seq 5 permit 10.10.10.10/32 +ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0 +ip prefix-list IP1 seq 5 permit 10.139.224.0/20 +ip prefix-list IP2 seq 5 permit 203.0.113.1/32 +! +bgp community-list standard DC-ROUTES seq 5 permit 64952:3008 +bgp community-list standard DC-ROUTES seq 10 permit 64671:501 +bgp community-list standard DC-ROUTES seq 15 permit 64950:3009 +bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200 +! +route-map ADV-MAP-1 permit 10 + match ip address prefix-list IP1 +! +route-map ADV-MAP-1 permit 20 + match community DC-ROUTES +! +route-map ADV-MAP-2 permit 10 + match ip address prefix-list IP2 +! +route-map EXIST-MAP permit 10 + match community DEFAULT-ROUTE + match ip address prefix-list DEFAULT-ROUTE +! +route-map RMAP-1 deny 10 + match ip address prefix-list IP1 +! +route-map RMAP-2 deny 10 + match ip address prefix-list IP2 +! +router bgp 2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.10.1 remote-as 1 + neighbor 10.10.20.3 remote-as 3 + ! + address-family ipv4 unicast + network 203.0.113.1/32 + neighbor 10.10.10.1 soft-reconfiguration inbound + neighbor 10.10.20.3 soft-reconfiguration inbound + exit-address-family +! diff --git a/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf new file mode 100644 index 0000000000..434ab68e3c --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf @@ -0,0 +1,15 @@ +! +hostname Router2 +! +interface r2-eth0 + ip address 10.10.10.2/24 +! +interface r2-eth1 + ip address 10.10.20.2/24 +! +interface lo + ip address 203.0.113.1/32 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf new file mode 100644 index 0000000000..2f4f5068d8 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf @@ -0,0 +1,11 @@ +! +router bgp 3 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 10.10.20.2 remote-as 2 + ! + address-family ipv4 unicast + neighbor 10.10.20.2 soft-reconfiguration inbound + exit-address-family +! + diff --git a/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf new file mode 100644 index 0000000000..0dadfdb3a9 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf @@ -0,0 +1,12 @@ +! +hostname Router3 +! +interface r3-eth0 + ip address 10.10.20.3/24 +! +interface lo + ip address 198.51.100.1/32 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py new file mode 100644 index 0000000000..0e31ab1995 --- /dev/null +++ b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py @@ -0,0 +1,961 @@ +#!/usr/bin/env python + +# +# test_bgp_conditional_advertisement.py +# +# Copyright (c) 2020 by +# Samsung R&D Institute India - Bangalore. +# Madhurilatha Kuruganti +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test BGP conditional advertisement functionality. + + +--------+ +--------+ +--------+ + | | | | | | + | R1 |------------| R2 |------------| R3 | + | | | | | | + +--------+ +--------+ +--------+ + +R2 is DUT and peers with R1 and R3 in default bgp instance. + +Following tests are covered under BGP conditional advertisement functionality. +Conditional advertisement +------------------------- +TC11: R3 BGP convergence, without advertise-map configuration. + All routes are advertised to R3. + +TC21: exist-map routes present in R2's BGP table. + advertise-map routes present in R2's BGP table are advertised to R3. +TC22: exist-map routes not present in R2's BGP table + advertise-map routes present in R2's BGP table are withdrawn from R3. +TC31: non-exist-map routes not present in R2's BGP table + advertise-map routes present in R2's BGP table are advertised to R3. +TC32: non-exist-map routes present in R2's BGP table + advertise-map routes present in R2's BGP table are withdrawn from R3. + +TC41: non-exist-map route-map configuration removed in R2. + advertise-map routes present in R2's BGP table are advertised to R3. +TC42: exist-map route-map configuration removed in R2 + advertise-map routes present in R2's BGP table are withdrawn from R3. + +Conditional advertisement(received routes) along with Route-map Filter +---------------------------------------------------------------------- +TC51: exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC52: exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. +TC53: non-exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC54: non-exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. + +TC61: exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC62: exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. +TC63: non-exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC64: non-exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. + +Conditional advertisement(attached routes) along with Route-map Filter +----------------------------------------------------------------- +TC71: exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC72: exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. +TC73: non-exist-map routes present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC74: non-exist-map routes present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. + +TC81: exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 including advertise-map routes. +TC82: exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 except advertise-map routes. +TC83: non-exist-map routes not present in R2's BGP table, with route-map filter. + All routes are withdrawn from R3 except advertise-map routes. +TC84: non-exist-map routes not present in R2's BGP table, without route-map filter. + All routes are advertised to R3 including advertise-map routes. + +TC91: exist-map routes present in R2's BGP table, with route-map filter and network. + All routes are advertised to R3 including advertise-map routes. +TC92: exist-map routes present in R2's BGP table, with route-map filter and no network. + All routes are advertised to R3 except advertise-map routes. +TC93: non-exist-map routes not present in R2's BGP table, with route-map filter and network. + All routes are advertised to R3 including advertise-map routes. +TC94: non-exist-map routes not present in R2's BGP table, with route-map filter and no network. + All routes are advertised to R3 except advertise-map routes. + +i.e. ++----------------+-------------------------+------------------------+ +| Routes in | exist-map status | advertise-map status | +| BGP table | | | ++----------------+-------------------------+------------------------+ +| Present | Condition matched | Advertise | ++----------------+-------------------------+------------------------+ +| Not Present | Condition not matched | Withdrawn | ++----------------+-------------------------+------------------------+ +| | non-exist-map status | advertise-map status | +| | | | ++----------------+-------------------------+------------------------+ +| Present | Condition matched | Withdrawn | ++----------------+-------------------------+------------------------+ +| Not Present | Condition not matched | Advertise | ++----------------+-------------------------+------------------------+ +Here in this topology, based on the default route presence in R2 and +the configured condition-map (exist-map/non-exist-map) 10.139.224.0/20 +will be either advertised/withdrawn to/from R3. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class BgpConditionalAdvertisementTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + r3 = tgen.add_router("r3") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(r2) + + switch = tgen.add_switch("s2") + switch.add_link(r2) + switch.add_link(r3) + + +def setup_module(mod): + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + tgen = Topogen(BgpConditionalAdvertisementTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +def test_bgp_conditional_advertisement(): + """ + Test BGP conditional advertisement functionality. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + router3 = tgen.gears["r3"] + + passed = "PASSED!!!" + failed = "FAILED!!!" + + def _all_routes_advertised(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": [{"protocol": "bgp"}], + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _all_routes_withdrawn(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": None, + "192.0.2.5/32": None, + "10.139.224.0/20": None, + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + # BGP conditional advertisement with route-maps + # EXIST-MAP, ADV-MAP-1 and RMAP-1 + def _exist_map_routes_present(router): + return _all_routes_advertised(router) + + def _exist_map_routes_not_present(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": None, + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": None, + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_present(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": [{"protocol": "bgp"}], + "192.0.2.1/32": None, + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": None, + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_not_present(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _exist_map_no_condition_route_map(router): + return _non_exist_map_routes_present(router) + + def _non_exist_map_no_condition_route_map(router): + return _all_routes_advertised(router) + + def _exist_map_routes_present_rmap_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": None, + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + def _exist_map_routes_present_no_rmap_filter(router): + return _all_routes_advertised(router) + + def _non_exist_map_routes_present_rmap_filter(router): + return _all_routes_withdrawn(router) + + def _non_exist_map_routes_present_no_rmap_filter(router): + return _non_exist_map_routes_present(router) + + def _exist_map_routes_not_present_rmap_filter(router): + return _all_routes_withdrawn(router) + + def _exist_map_routes_not_present_no_rmap_filter(router): + return _exist_map_routes_not_present(router) + + def _non_exist_map_routes_not_present_rmap_filter(router): + return _exist_map_routes_present_rmap_filter(router) + + def _non_exist_map_routes_not_present_no_rmap_filter(router): + return _non_exist_map_routes_not_present(router) + + # BGP conditional advertisement with route-maps + # EXIST-MAP, ADV-MAP-2 and RMAP-2 + def _exist_map_routes_not_present_rmap2_filter(router): + return _all_routes_withdrawn(router) + + def _exist_map_routes_not_present_no_rmap2_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_not_present_rmap2_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": None, + "192.0.2.1/32": None, + "192.0.2.5/32": None, + "10.139.224.0/20": None, + "203.0.113.1/32": [{"protocol": "bgp"}], + } + return topotest.json_cmp(output, expected) + + def _non_exist_map_routes_not_present_no_rmap2_filter(router): + return _non_exist_map_routes_not_present(router) + + def _exist_map_routes_present_rmap2_filter(router): + return _non_exist_map_routes_not_present_rmap2_filter(router) + + def _exist_map_routes_present_no_rmap2_filter(router): + return _all_routes_advertised(router) + + def _non_exist_map_routes_present_rmap2_filter(router): + return _all_routes_withdrawn(router) + + def _non_exist_map_routes_present_no_rmap2_filter(router): + output = json.loads(router.vtysh_cmd("show ip route json")) + expected = { + "0.0.0.0/0": [{"protocol": "bgp"}], + "192.0.2.1/32": [{"protocol": "bgp"}], + "192.0.2.5/32": [{"protocol": "bgp"}], + "10.139.224.0/20": [{"protocol": "bgp"}], + "203.0.113.1/32": None, + } + return topotest.json_cmp(output, expected) + + def _exist_map_routes_present_rmap2_network(router): + return _non_exist_map_routes_not_present_rmap2_filter(router) + + def _exist_map_routes_present_rmap2_no_network(router): + return _all_routes_withdrawn(router) + + def _non_exist_map_routes_not_present_rmap2_network(router): + return _non_exist_map_routes_not_present_rmap2_filter(router) + + def _non_exist_map_routes_not_present_rmap2_no_network(router): + return _all_routes_withdrawn(router) + + # TC11: R3 BGP convergence, without advertise-map configuration. + # All routes are advertised to R3. + test_func = functools.partial(_all_routes_advertised, router3) + success, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + + msg = 'TC11: "router3" BGP convergence - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC21: exist-map routes present in R2's BGP table. + # advertise-map routes present in R2's BGP table are advertised to R3. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC21: exist-map routes present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC22: exist-map routes not present in R2's BGP table + # advertise-map routes present in R2's BGP table are withdrawn from R3. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC22: exist-map routes not present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC31: non-exist-map routes not present in R2's BGP table + # advertise-map routes present in R2's BGP table are advertised to R3. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_non_exist_map_routes_not_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC31: non-exist-map routes not present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC32: non-exist-map routes present in R2's BGP table + # advertise-map routes present in R2's BGP table are withdrawn from R3. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC32: non-exist-map routes present in "router2" BGP table - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC41: non-exist-map route-map configuration removed in R2. + # advertise-map routes present in R2's BGP table are advertised to R3. + router2.vtysh_cmd( + """ + configure terminal + no route-map EXIST-MAP permit 10 + """ + ) + + test_func = functools.partial(_non_exist_map_no_condition_route_map, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC41: non-exist-map route-map removed in "router2" - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC42: exist-map route-map configuration removed in R2 + # advertise-map routes present in R2's BGP table are withdrawn from R3. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_no_condition_route_map, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = 'TC42: exist-map route-map removed in "router2" - ' + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC51: exist-map routes present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + route-map EXIST-MAP permit 10 + match community DEFAULT-ROUTE + match ip address prefix-list DEFAULT-ROUTE + ! + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC51: exist-map routes present with route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC52: exist-map routes present in R2's BGP table, no route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_exist_map_routes_present_no_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC52: exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC53: non-exist-map routes present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC53: non-exist-map routes present, with route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC54: non-exist-map routes present in R2's BGP table, no route-map filter. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present_no_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC54: non-exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC61: exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC61: exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC62: exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present_no_rmap_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC62: exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC63: non-exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-1 out + neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC63: non-exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC64: non-exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-1 out + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_no_rmap_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC64: non-exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC71: exist-map routes present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 except advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC71: exist-map routes present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC72: exist-map routes present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial(_exist_map_routes_present_no_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC72: exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC73: non-exist-map routes present in R2's BGP table, with route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_non_exist_map_routes_present_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC73: non-exist-map routes present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC74: non-exist-map routes present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_present_no_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC74: non-exist-map routes present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC81: exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are withdrawn from R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_not_present_rmap2_filter, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC81: exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC82: exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial( + _exist_map_routes_not_present_no_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC82: exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC83: non-exist-map routes not present in R2's BGP table, with route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC83: non-exist-map routes not present, route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC84: non-exist-map routes not present in R2's BGP table, without route-map filter. + # All routes are advertised to R3 including advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no neighbor 10.10.20.3 route-map RMAP-2 out + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_no_rmap2_filter, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC84: non-exist-map routes not present, no route-map filter - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC91: exist-map routes present in R2's BGP table, with route-map filter and network. + # All routes are advertised to R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + neighbor 10.10.20.3 route-map RMAP-2 out + neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap2_network, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC91: exist-map routes present, route-map filter and network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC92: exist-map routes present in R2's BGP table, with route-map filter and no network. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no network 203.0.113.1/32 + """ + ) + + test_func = functools.partial(_exist_map_routes_present_rmap2_no_network, router3) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC92: exist-map routes present, route-map filter and no network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC93: non-exist-map routes not present in R2's BGP table, with route-map filter and network. + # All routes are advertised to R3 including advertise-map routes. + router1.vtysh_cmd( + """ + configure terminal + router bgp 1 + address-family ipv4 unicast + no network 0.0.0.0/0 route-map DEF + """ + ) + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + network 203.0.113.1/32 + neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap2_network, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC93: non-exist-map routes not present, route-map filter and network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + # TC94: non-exist-map routes not present in R2's BGP table, with route-map filter and no network. + # All routes are advertised to R3 except advertise-map routes. + router2.vtysh_cmd( + """ + configure terminal + router bgp 2 + address-family ipv4 unicast + no network 203.0.113.1/32 + """ + ) + + test_func = functools.partial( + _non_exist_map_routes_not_present_rmap2_no_network, router3 + ) + success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + + msg = "TC94: non-exist-map routes not present, route-map filter and no network - " + assert result is None, msg + failed + + logger.info(msg + passed) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_default-route/__init__.py b/tests/topotests/bgp_default-route/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_default-route/__init__.py diff --git a/tests/topotests/bgp_default-route/r1/bgpd.conf b/tests/topotests/bgp_default-route/r1/bgpd.conf new file mode 100644 index 0000000000..8699d62ff2 --- /dev/null +++ b/tests/topotests/bgp_default-route/r1/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 192.168.255.2 remote-as 65001 + neighbor 192.168.255.2 timers 3 10 + address-family ipv4 unicast + neighbor 192.168.255.2 default-originate + exit-address-family +! diff --git a/tests/topotests/bgp_default-route_route-map/r1/zebra.conf b/tests/topotests/bgp_default-route/r1/zebra.conf index 0a283c06d5..0a283c06d5 100644 --- a/tests/topotests/bgp_default-route_route-map/r1/zebra.conf +++ b/tests/topotests/bgp_default-route/r1/zebra.conf diff --git a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf b/tests/topotests/bgp_default-route/r2/bgpd.conf index 00c96cc58b..00c96cc58b 100644 --- a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf +++ b/tests/topotests/bgp_default-route/r2/bgpd.conf diff --git a/tests/topotests/bgp_default-route_route-map/r2/zebra.conf b/tests/topotests/bgp_default-route/r2/zebra.conf index 606c17bec9..606c17bec9 100644 --- a/tests/topotests/bgp_default-route_route-map/r2/zebra.conf +++ b/tests/topotests/bgp_default-route/r2/zebra.conf diff --git a/tests/topotests/bgp_default-route/test_bgp_default-originate.py b/tests/topotests/bgp_default-route/test_bgp_default-originate.py new file mode 100644 index 0000000000..d8de0f0ac6 --- /dev/null +++ b/tests/topotests/bgp_default-route/test_bgp_default-originate.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +# Copyright (c) 2019-2020 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if default-originate works without route-map. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 3): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_default_originate_route_map(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r2"] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}}, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_default_route_is_valid(router): + output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json")) + expected = {"paths": [{"valid": True}]} + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, router) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) + + test_func = functools.partial(_bgp_default_route_is_valid, router) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert ( + result is None + ), 'Failed to see applied metric for default route in "{}"'.format(router) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_default-route_route-map_match/__init__.py b/tests/topotests/bgp_default-route_route-map_match/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match/__init__.py diff --git a/tests/topotests/bgp_default-route_route-map_match/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match/r1/bgpd.conf new file mode 100644 index 0000000000..97b440f5ce --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match/r1/bgpd.conf @@ -0,0 +1,17 @@ +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 192.168.255.2 remote-as 65001 + neighbor 192.168.255.2 timers 3 10 + address-family ipv4 unicast + network 192.168.13.0/24 route-map internal + neighbor 192.168.255.2 default-originate route-map default + exit-address-family +! +bgp community-list standard default seq 5 permit 65000:1 +! +route-map default permit 10 + match community default +! +route-map internal permit 10 + set community 65000:1 +! diff --git a/tests/topotests/bgp_default-route_route-map_match/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map_match/r1/zebra.conf new file mode 100644 index 0000000000..9e581a7be7 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match/r1/zebra.conf @@ -0,0 +1,11 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip route 192.168.13.0./24 Null0 +! +ip forwarding +! diff --git a/tests/topotests/bgp_default-route_route-map_match/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match/r2/bgpd.conf new file mode 100644 index 0000000000..00c96cc58b --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match/r2/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.255.1 remote-as 65000 + neighbor 192.168.255.1 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_default-route_route-map_match/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map_match/r2/zebra.conf new file mode 100644 index 0000000000..606c17bec9 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match/r2/zebra.conf @@ -0,0 +1,6 @@ +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_default-route_route-map_match/test_bgp_default-originate_route-map_match.py b/tests/topotests/bgp_default-route_route-map_match/test_bgp_default-originate_route-map_match.py new file mode 100644 index 0000000000..089c9a964e --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match/test_bgp_default-originate_route-map_match.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +# Copyright (c) 2019-2020 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if default-originate works with ONLY match operations. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 3): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_default_originate_route_map(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r2"] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}}, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_default_route_is_valid(router): + output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json")) + expected = {"paths": [{"valid": True}]} + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, router) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) + + test_func = functools.partial(_bgp_default_route_is_valid, router) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert ( + result is None + ), 'Failed to see applied metric for default route in "{}"'.format(router) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_default-route_route-map_match_set/__init__.py b/tests/topotests/bgp_default-route_route-map_match_set/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match_set/__init__.py diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match_set/r1/bgpd.conf new file mode 100644 index 0000000000..6ef8b1c0f4 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match_set/r1/bgpd.conf @@ -0,0 +1,18 @@ +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 192.168.255.2 remote-as 65001 + neighbor 192.168.255.2 timers 3 10 + address-family ipv4 unicast + network 192.168.13.0/24 route-map internal + neighbor 192.168.255.2 default-originate route-map default + exit-address-family +! +bgp community-list standard default seq 5 permit 65000:1 +! +route-map default permit 10 + match community default + set metric 123 +! +route-map internal permit 10 + set community 65000:1 +! diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map_match_set/r1/zebra.conf new file mode 100644 index 0000000000..9e581a7be7 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match_set/r1/zebra.conf @@ -0,0 +1,11 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip route 192.168.13.0./24 Null0 +! +ip forwarding +! diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match_set/r2/bgpd.conf new file mode 100644 index 0000000000..00c96cc58b --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match_set/r2/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.255.1 remote-as 65000 + neighbor 192.168.255.1 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map_match_set/r2/zebra.conf new file mode 100644 index 0000000000..606c17bec9 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_match_set/r2/zebra.conf @@ -0,0 +1,6 @@ +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_default-route_route-map/test_bgp_default-originate_route-map.py b/tests/topotests/bgp_default-route_route-map_match_set/test_bgp_default-originate_route-map_match_set.py index a72c3a4cbf..d9ea5db278 100644 --- a/tests/topotests/bgp_default-route_route-map/test_bgp_default-originate_route-map.py +++ b/tests/topotests/bgp_default-route_route-map_match_set/test_bgp_default-originate_route-map_match_set.py @@ -1,10 +1,6 @@ #!/usr/bin/env python -# -# bgp_default-originate_route-map.py -# Part of NetDEF Topology Tests -# -# Copyright (c) 2019 by +# Copyright (c) 2020 by # Donatas Abraitis <donatas.abraitis@gmail.com> # # Permission to use, copy, modify, and/or distribute this software @@ -23,15 +19,8 @@ # """ -bgp_default-originate_route-map.py: - -Test if works the following commands: -router bgp 65031 - address-family ipv4 unicast - neighbor 192.168.255.2 default-originate route-map default - -route-map default permit 10 - set metric 123 +Test if default-originate works with match operations. +And verify if set operations work as well. """ import os @@ -109,12 +98,12 @@ def test_bgp_default_originate_route_map(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) test_func = functools.partial(_bgp_default_route_has_metric, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert ( result is None diff --git a/tests/topotests/bgp_default-route_route-map_set/__init__.py b/tests/topotests/bgp_default-route_route-map_set/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_set/__init__.py diff --git a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map_set/r1/bgpd.conf index cb07ea9fdf..cb07ea9fdf 100644 --- a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf +++ b/tests/topotests/bgp_default-route_route-map_set/r1/bgpd.conf diff --git a/tests/topotests/bgp_default-route_route-map_set/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map_set/r1/zebra.conf new file mode 100644 index 0000000000..0a283c06d5 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_set/r1/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_default-route_route-map_set/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map_set/r2/bgpd.conf new file mode 100644 index 0000000000..00c96cc58b --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_set/r2/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.255.1 remote-as 65000 + neighbor 192.168.255.1 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_default-route_route-map_set/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map_set/r2/zebra.conf new file mode 100644 index 0000000000..606c17bec9 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_set/r2/zebra.conf @@ -0,0 +1,6 @@ +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_default-route_route-map_set/test_bgp_default-originate_route-map_set.py b/tests/topotests/bgp_default-route_route-map_set/test_bgp_default-originate_route-map_set.py new file mode 100644 index 0000000000..9a22c58b16 --- /dev/null +++ b/tests/topotests/bgp_default-route_route-map_set/test_bgp_default-originate_route-map_set.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +# Copyright (c) 2019-2020 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if default-originate works with ONLY set operations. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 3): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_default_originate_route_map(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r2"] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}}, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_default_route_has_metric(router): + output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json")) + expected = {"paths": [{"metric": 123}]} + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, router) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) + + test_func = functools.partial(_bgp_default_route_has_metric, router) + success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert ( + result is None + ), 'Failed to see applied metric for default route in "{}"'.format(router) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py index 2520763bda..003193f108 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py +++ b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py @@ -122,27 +122,39 @@ def test_ebgp_requires_policy(): test_func = functools.partial(_bgp_converge, "r2") success, result = topotest.run_and_expect(test_func, None, count=65, wait=2) - assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(tgen.gears["r2"]) + assert success is True, 'Failed bgp convergence (r2) in "{}"'.format( + tgen.gears["r2"] + ) test_func = functools.partial(_bgp_has_routes, "r2") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(tgen.gears["r2"]) + assert success is True, 'eBGP policy is not working (r2) in "{}"'.format( + tgen.gears["r2"] + ) test_func = functools.partial(_bgp_converge, "r4") success, result = topotest.run_and_expect(test_func, None, count=65, wait=2) - assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(tgen.gears["r4"]) + assert success is True, 'Failed bgp convergence (r4) in "{}"'.format( + tgen.gears["r4"] + ) test_func = functools.partial(_bgp_has_routes, "r4") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(tgen.gears["r4"]) + assert success is False, 'eBGP policy is not working (r4) in "{}"'.format( + tgen.gears["r4"] + ) test_func = functools.partial(_bgp_converge, "r6") success, result = topotest.run_and_expect(test_func, None, count=65, wait=2) - assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(tgen.gears["r6"]) + assert success is True, 'Failed bgp convergence (r6) in "{}"'.format( + tgen.gears["r6"] + ) test_func = functools.partial(_bgp_has_routes, "r6") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(tgen.gears["r6"]) + assert success is True, 'eBGP policy is not working (r6) in "{}"'.format( + tgen.gears["r6"] + ) if __name__ == "__main__": diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index 0d99f23ad9..222478f12d 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -35,7 +35,7 @@ import platform # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) +sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers @@ -47,27 +47,30 @@ from lib.topolog import logger from mininet.topo import Topo l3mdev_accept = 0 -krel = '' +krel = "" + class BGPEVPNTopo(Topo): "Test topology builder" + def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) - tgen.add_router('r1') - tgen.add_router('r2') + tgen.add_router("r1") + tgen.add_router("r2") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) - switch = tgen.add_switch('s1') - switch.add_link(tgen.gears['r1']) - switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r1"]) + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r2"]) - switch = tgen.add_switch('s2') - switch.add_link(tgen.gears['r1']) - switch = tgen.add_switch('s3') - switch.add_link(tgen.gears['r2']) - def setup_module(mod): "Sets up the pytest environment" global l3mdev_accept @@ -79,99 +82,109 @@ def setup_module(mod): router_list = tgen.routers() krel = platform.release() - if topotest.version_cmp(krel, '4.18') < 0: - logger.info('BGP EVPN RT5 NETNS tests will not run (have kernel "{}", but it requires 4.18)'.format(krel)) - return pytest.skip('Skipping BGP EVPN RT5 NETNS Test. Kernel not supported') + if topotest.version_cmp(krel, "4.18") < 0: + logger.info( + 'BGP EVPN RT5 NETNS tests will not run (have kernel "{}", but it requires 4.18)'.format( + krel + ) + ) + return pytest.skip("Skipping BGP EVPN RT5 NETNS Test. Kernel not supported") l3mdev_accept = 1 - logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept)) + logger.info("setting net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept)) # create VRF vrf-101 on R1 and R2 # create loop101 - cmds_vrflite = ['sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept), - 'ip link add {}-vrf-101 type vrf table 101', - 'ip ru add oif {}-vrf-101 table 101', - 'ip ru add iif {}-vrf-101 table 101', - 'ip link set dev {}-vrf-101 up', - 'sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept), - 'ip link add loop101 type dummy', - 'ip link set dev loop101 master {}-vrf-101', - 'ip link set dev loop101 up'] - cmds_netns = ['ip netns add {}-vrf-101', - 'ip link add loop101 type dummy', - 'ip link set dev loop101 netns {}-vrf-101', - 'ip netns exec {}-vrf-101 ip link set dev loop101 up'] - - cmds_r2 = [ # config routing 101 - 'ip link add name bridge-101 up type bridge stp_state 0', - 'ip link set bridge-101 master {}-vrf-101', - 'ip link set dev bridge-101 up', - 'ip link add name vxlan-101 type vxlan id 101 dstport 4789 dev r2-eth0 local 192.168.100.41', - 'ip link set dev vxlan-101 master bridge-101', - 'ip link set vxlan-101 up type bridge_slave learning off flood off mcast_flood off'] - - cmds_r1_netns_method3 = ['ip link add name vxlan-{1} type vxlan id {1} dstport 4789 dev {0}-eth0 local 192.168.100.21', - 'ip link set dev vxlan-{1} netns {0}-vrf-{1}', - 'ip netns exec {0}-vrf-{1} ip li set dev lo up', - 'ip netns exec {0}-vrf-{1} ip link add name bridge-{1} up type bridge stp_state 0', - 'ip netns exec {0}-vrf-{1} ip link set dev vxlan-{1} master bridge-{1}', - 'ip netns exec {0}-vrf-{1} ip link set bridge-{1} up', - 'ip netns exec {0}-vrf-{1} ip link set vxlan-{1} up'] - - router = tgen.gears['r1'] + cmds_vrflite = [ + "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept), + "ip link add {}-vrf-101 type vrf table 101", + "ip ru add oif {}-vrf-101 table 101", + "ip ru add iif {}-vrf-101 table 101", + "ip link set dev {}-vrf-101 up", + "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept), + "ip link add loop101 type dummy", + "ip link set dev loop101 master {}-vrf-101", + "ip link set dev loop101 up", + ] + cmds_netns = [ + "ip netns add {}-vrf-101", + "ip link add loop101 type dummy", + "ip link set dev loop101 netns {}-vrf-101", + "ip netns exec {}-vrf-101 ip link set dev loop101 up", + ] + + cmds_r2 = [ # config routing 101 + "ip link add name bridge-101 up type bridge stp_state 0", + "ip link set bridge-101 master {}-vrf-101", + "ip link set dev bridge-101 up", + "ip link add name vxlan-101 type vxlan id 101 dstport 4789 dev r2-eth0 local 192.168.100.41", + "ip link set dev vxlan-101 master bridge-101", + "ip link set vxlan-101 up type bridge_slave learning off flood off mcast_flood off", + ] + + cmds_r1_netns_method3 = [ + "ip link add name vxlan-{1} type vxlan id {1} dstport 4789 dev {0}-eth0 local 192.168.100.21", + "ip link set dev vxlan-{1} netns {0}-vrf-{1}", + "ip netns exec {0}-vrf-{1} ip li set dev lo up", + "ip netns exec {0}-vrf-{1} ip link add name bridge-{1} up type bridge stp_state 0", + "ip netns exec {0}-vrf-{1} ip link set dev vxlan-{1} master bridge-{1}", + "ip netns exec {0}-vrf-{1} ip link set bridge-{1} up", + "ip netns exec {0}-vrf-{1} ip link set vxlan-{1} up", + ] + + router = tgen.gears["r1"] for cmd in cmds_netns: - logger.info('cmd to r1: '+cmd); - output = router.run(cmd.format('r1')) - logger.info('result: '+output); + logger.info("cmd to r1: " + cmd) + output = router.run(cmd.format("r1")) + logger.info("result: " + output) - router = tgen.gears['r2'] + router = tgen.gears["r2"] for cmd in cmds_vrflite: - logger.info('cmd to r2: '+cmd.format('r2')); - output = router.run(cmd.format('r2')) - logger.info('result: '+output); + logger.info("cmd to r2: " + cmd.format("r2")) + output = router.run(cmd.format("r2")) + logger.info("result: " + output) for cmd in cmds_r2: - logger.info('cmd to r2: '+cmd.format('r2')); - output = router.run(cmd.format('r2')) - logger.info('result: '+output); + logger.info("cmd to r2: " + cmd.format("r2")) + output = router.run(cmd.format("r2")) + logger.info("result: " + output) - router = tgen.gears['r1'] - bridge_id = '101' + router = tgen.gears["r1"] + bridge_id = "101" for cmd in cmds_r1_netns_method3: - logger.info('cmd to r1: '+cmd.format('r1', bridge_id)); - output = router.run(cmd.format('r1', bridge_id)) - logger.info('result: '+output); - router = tgen.gears['r1'] + logger.info("cmd to r1: " + cmd.format("r1", bridge_id)) + output = router.run(cmd.format("r1", bridge_id)) + logger.info("result: " + output) + router = tgen.gears["r1"] for rname, router in router_list.items(): - if rname == 'r1': + if rname == "r1": router.load_config( TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)), - '--vrfwnetns -o vrf0' + os.path.join(CWD, "{}/zebra.conf".format(rname)), + "--vrfwnetns -o vrf0", ) else: router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_BGP, - os.path.join(CWD, '{}/bgpd.conf'.format(rname)) + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) ) # Initialize all routers. tgen.start_router() + def teardown_module(_mod): "Teardown the pytest environment" tgen = get_topogen() - cmds_rx_netns = ['ip netns del {}-vrf-101'] - - router = tgen.gears['r1'] + cmds_rx_netns = ["ip netns del {}-vrf-101"] + + router = tgen.gears["r1"] for cmd in cmds_rx_netns: - logger.info('cmd to r1: '+cmd.format('r1')); - output = router.run(cmd.format('r1')) + logger.info("cmd to r1: " + cmd.format("r1")) + output = router.run(cmd.format("r1")) tgen.stop_topology() @@ -183,52 +196,59 @@ def test_protocols_convergence(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) - topotest.sleep(4, 'waiting 4 seconds for bgp convergence') + topotest.sleep(4, "waiting 4 seconds for bgp convergence") # Check IPv4/IPv6 routing tables. - output = tgen.gears['r1'].vtysh_cmd('show bgp l2vpn evpn', isjson=False) - logger.info('==== result from show bgp l2vpn evpn') + output = tgen.gears["r1"].vtysh_cmd("show bgp l2vpn evpn", isjson=False) + logger.info("==== result from show bgp l2vpn evpn") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show bgp l2vpn evpn route detail', isjson=False) - logger.info('==== result from show bgp l2vpn evpn route detail') + output = tgen.gears["r1"].vtysh_cmd( + "show bgp l2vpn evpn route detail", isjson=False + ) + logger.info("==== result from show bgp l2vpn evpn route detail") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show bgp vrf r1-vrf-101 ipv4', isjson=False) - logger.info('==== result from show bgp vrf r1-vrf-101 ipv4') + output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101 ipv4", isjson=False) + logger.info("==== result from show bgp vrf r1-vrf-101 ipv4") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show bgp vrf r1-vrf-101', isjson=False) - logger.info('==== result from show bgp vrf r1-vrf-101 ') + output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101", isjson=False) + logger.info("==== result from show bgp vrf r1-vrf-101 ") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show ip route vrf r1-vrf-101', isjson=False) - logger.info('==== result from show ip route vrf r1-vrf-101') + output = tgen.gears["r1"].vtysh_cmd("show ip route vrf r1-vrf-101", isjson=False) + logger.info("==== result from show ip route vrf r1-vrf-101") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show evpn vni detail', isjson=False) - logger.info('==== result from show evpn vni detail') + output = tgen.gears["r1"].vtysh_cmd("show evpn vni detail", isjson=False) + logger.info("==== result from show evpn vni detail") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show evpn next-hops vni all', isjson=False) - logger.info('==== result from show evpn next-hops vni all') + output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False) + logger.info("==== result from show evpn next-hops vni all") logger.info(output) - output = tgen.gears['r1'].vtysh_cmd('show evpn rmac vni all', isjson=False) - logger.info('==== result from show evpn next-hops vni all') + output = tgen.gears["r1"].vtysh_cmd("show evpn rmac vni all", isjson=False) + logger.info("==== result from show evpn next-hops vni all") logger.info(output) # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn) - pingrouter = tgen.gears['r1'] - logger.info('Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)') - output = pingrouter.run('ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000') + pingrouter = tgen.gears["r1"] + logger.info( + "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)" + ) + output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000") logger.info(output) - if '1000 packets transmitted, 1000 received' not in output: - assertmsg = 'expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok' + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = ( + "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok" + ) assert 0, assertmsg else: - logger.info('Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK') + logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): - pytest.skip('Memory leak test/report is disabled') + pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() -if __name__ == '__main__': +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_features/test_bgp_features.py b/tests/topotests/bgp_features/test_bgp_features.py index 4ec060b642..bd092c4340 100644 --- a/tests/topotests/bgp_features/test_bgp_features.py +++ b/tests/topotests/bgp_features/test_bgp_features.py @@ -188,11 +188,15 @@ def test_bgp_shutdown(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65000\" -c \"bgp shutdown message ABCDabcd\"') + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "bgp shutdown message ABCDabcd"' + ) # Check BGP Summary on local and remote routers for rtrNum in [1, 2, 4]: - logger.info("Checking BGP Summary after shutdown of R1 BGP on router r{}".format(rtrNum)) + logger.info( + "Checking BGP Summary after shutdown of R1 BGP on router r{}".format(rtrNum) + ) router = tgen.gears["r{}".format(rtrNum)] reffile = os.path.join(CWD, "r{}/bgp_shutdown_summary.json".format(rtrNum)) @@ -202,7 +206,9 @@ def test_bgp_shutdown(): topotest.router_json_cmp, router, "show ip bgp summary json", expected ) _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) - assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(rtrNum) + assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format( + rtrNum + ) assert res is None, assertmsg @@ -218,18 +224,21 @@ def test_bgp_shutdown_message(): for rtrNum in [2, 4]: logger.info("Checking BGP shutdown received on router r{}".format(rtrNum)) - shut_message = tgen.net['r{}'.format(rtrNum)].cmd( - 'tail bgpd.log | grep "NOTIFICATION.*Cease/Administratively Shutdown"') + shut_message = tgen.net["r{}".format(rtrNum)].cmd( + 'tail bgpd.log | grep "NOTIFICATION.*Cease/Administratively Shutdown"' + ) assertmsg = "BGP shutdown message not received on router R{}".format(rtrNum) - assert shut_message != '', assertmsg + assert shut_message != "", assertmsg - m = re.search('.*([0-9]+ bytes[ 0-9a-fA-F]+)', shut_message) + m = re.search(".*([0-9]+ bytes[ 0-9a-fA-F]+)", shut_message) if m: found = m.group(1) else: - found = '' - assertmsg = "Incorrect BGP shutdown message received on router R{}".format(rtrNum) - assert found == '8 bytes 41 42 43 44 61 62 63 64', assertmsg + found = "" + assertmsg = "Incorrect BGP shutdown message received on router R{}".format( + rtrNum + ) + assert found == "8 bytes 41 42 43 44 61 62 63 64", assertmsg # tgen.mininet_cli() @@ -243,11 +252,15 @@ def test_bgp_no_shutdown(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65000\" -c \"no bgp shutdown\"') + tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no bgp shutdown"') # Check BGP Summary on local and remote routers for rtrNum in [1, 2, 4]: - logger.info("Checking BGP Summary after removing bgp shutdown on router r1 on router r{}".format(rtrNum)) + logger.info( + "Checking BGP Summary after removing bgp shutdown on router r1 on router r{}".format( + rtrNum + ) + ) router = tgen.gears["r{}".format(rtrNum)] reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum)) @@ -257,7 +270,9 @@ def test_bgp_no_shutdown(): topotest.router_json_cmp, router, "show ip bgp summary json", expected ) _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) - assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(rtrNum) + assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format( + rtrNum + ) assert res is None, assertmsg @@ -303,31 +318,43 @@ def test_bgp_metric_config(): # set metric +12 # ! - tgen.net['r1'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+ - '-c "address-family ipv4 unicast" '+ - '-c "neighbor 192.168.0.2 route-map addmetric-in in" '+ - '-c "neighbor 192.168.0.2 route-map addmetric-out out" '+ - '-c "neighbor 192.168.101.2 route-map setmetric-in in" '+ - '-c "neighbor 192.168.101.2 route-map setmetric-out out" ') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "ip prefix-list net1 seq 10 permit 192.168.101.0/24" '+ - '-c "ip prefix-list net2 seq 20 permit 192.168.1.0/24"') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "route-map setmetric-in permit 10" '+ - '-c "match ip address prefix-list net1" '+ - '-c "set metric 111" '+ - '-c "route-map setmetric-in permit 20"') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "route-map setmetric-out permit 10" '+ - '-c "match ip address prefix-list net2" '+ - '-c "set metric 1011" '+ - '-c "route-map setmetric-out permit 20"') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "route-map addmetric-in permit 10" '+ - '-c "set metric +11"') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "route-map addmetric-out permit 10" '+ - '-c "set metric +12"') + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" ' + + '-c "address-family ipv4 unicast" ' + + '-c "neighbor 192.168.0.2 route-map addmetric-in in" ' + + '-c "neighbor 192.168.0.2 route-map addmetric-out out" ' + + '-c "neighbor 192.168.101.2 route-map setmetric-in in" ' + + '-c "neighbor 192.168.101.2 route-map setmetric-out out" ' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" ' + + '-c "ip prefix-list net1 seq 10 permit 192.168.101.0/24" ' + + '-c "ip prefix-list net2 seq 20 permit 192.168.1.0/24"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map setmetric-in permit 10" ' + + '-c "match ip address prefix-list net1" ' + + '-c "set metric 111" ' + + '-c "route-map setmetric-in permit 20"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map setmetric-out permit 10" ' + + '-c "match ip address prefix-list net2" ' + + '-c "set metric 1011" ' + + '-c "route-map setmetric-out permit 20"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map addmetric-in permit 10" ' + + '-c "set metric +11"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map addmetric-out permit 10" ' + + '-c "set metric +12"' + ) # # Adding the following configuration to r2: # router bgp 65000 @@ -360,50 +387,72 @@ def test_bgp_metric_config(): # set metric -23 # ! - tgen.net['r2'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+ - '-c "address-family ipv4 unicast" '+ - '-c "neighbor 192.168.0.1 route-map subtractmetric-in in" '+ - '-c "neighbor 192.168.0.1 route-map subtractmetric-out out" '+ - '-c "neighbor 192.168.201.2 route-map setmetric-in in" ' + - '-c "neighbor 192.168.201.2 route-map setmetric-out out" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "ip prefix-list net1 seq 10 permit 192.168.201.0/24" '+ - '-c "ip prefix-list net2 seq 20 permit 192.168.2.0/24" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "route-map setmetric-in permit 10" '+ - '-c "match ip address prefix-list net1" '+ - '-c "set metric 222" '+ - '-c "route-map setmetric-in permit 20"') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "route-map setmetric-out permit 10" '+ - '-c "match ip address prefix-list net2" '+ - '-c "set metric 2022" '+ - '-c "route-map setmetric-out permit 20"') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "route-map subtractmetric-in permit 10" '+ - '-c "set metric -22"') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "route-map subtractmetric-out permit 10" '+ - '-c "set metric -23"') + tgen.net["r2"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" ' + + '-c "address-family ipv4 unicast" ' + + '-c "neighbor 192.168.0.1 route-map subtractmetric-in in" ' + + '-c "neighbor 192.168.0.1 route-map subtractmetric-out out" ' + + '-c "neighbor 192.168.201.2 route-map setmetric-in in" ' + + '-c "neighbor 192.168.201.2 route-map setmetric-out out" ' + ) + tgen.net["r2"].cmd( + 'vtysh -c "conf t" ' + + '-c "ip prefix-list net1 seq 10 permit 192.168.201.0/24" ' + + '-c "ip prefix-list net2 seq 20 permit 192.168.2.0/24" ' + ) + tgen.net["r2"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map setmetric-in permit 10" ' + + '-c "match ip address prefix-list net1" ' + + '-c "set metric 222" ' + + '-c "route-map setmetric-in permit 20"' + ) + tgen.net["r2"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map setmetric-out permit 10" ' + + '-c "match ip address prefix-list net2" ' + + '-c "set metric 2022" ' + + '-c "route-map setmetric-out permit 20"' + ) + tgen.net["r2"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map subtractmetric-in permit 10" ' + + '-c "set metric -22"' + ) + tgen.net["r2"].cmd( + 'vtysh -c "conf t" ' + + '-c "route-map subtractmetric-out permit 10" ' + + '-c "set metric -23"' + ) # Clear IN the bgp neighbors to make sure the route-maps are applied - tgen.net['r1'].cmd('vtysh -c "clear ip bgp 192.168.0.2 in" '+ - '-c "clear ip bgp 192.168.101.2 in"') - tgen.net['r2'].cmd('vtysh -c "clear ip bgp 192.168.0.1 in" '+ - '-c "clear ip bgp 192.168.201.2 in"') + tgen.net["r1"].cmd( + 'vtysh -c "clear ip bgp 192.168.0.2 in" ' + '-c "clear ip bgp 192.168.101.2 in"' + ) + tgen.net["r2"].cmd( + 'vtysh -c "clear ip bgp 192.168.0.1 in" ' + '-c "clear ip bgp 192.168.201.2 in"' + ) # tgen.mininet_cli() # Checking BGP config - should show the bgp metric settings in the route-maps logger.info("Checking BGP configuration for correct 'set metric' values") - setmetric111 = tgen.net['r1'].cmd('vtysh -c "show running" | grep "^ set metric 111"').rstrip() - assertmsg = "'set metric 111' configuration applied to R1, but not visible in configuration" - assert setmetric111 == ' set metric 111', assertmsg + setmetric111 = ( + tgen.net["r1"].cmd('vtysh -c "show running" | grep "^ set metric 111"').rstrip() + ) + assertmsg = ( + "'set metric 111' configuration applied to R1, but not visible in configuration" + ) + assert setmetric111 == " set metric 111", assertmsg - setmetric222 = tgen.net['r2'].cmd('vtysh -c "show running" | grep "^ set metric 222"').rstrip() - assertmsg = "'set metric 222' configuration applied to R2, but not visible in configuration" - assert setmetric222 == ' set metric 222', assertmsg + setmetric222 = ( + tgen.net["r2"].cmd('vtysh -c "show running" | grep "^ set metric 222"').rstrip() + ) + assertmsg = ( + "'set metric 222' configuration applied to R2, but not visible in configuration" + ) + assert setmetric222 == " set metric 222", assertmsg def test_bgp_metric_add_config(): @@ -417,9 +466,13 @@ def test_bgp_metric_add_config(): logger.info("Checking BGP configuration for correct 'set metric' ADD value") - setmetricP11 = tgen.net['r1'].cmd('vtysh -c "show running" | grep "^ set metric +11"').rstrip() - assertmsg = "'set metric +11' configuration applied to R1, but not visible in configuration" - assert setmetricP11 == ' set metric +11', assertmsg + setmetricP11 = ( + tgen.net["r1"].cmd('vtysh -c "show running" | grep "^ set metric +11"').rstrip() + ) + assertmsg = ( + "'set metric +11' configuration applied to R1, but not visible in configuration" + ) + assert setmetricP11 == " set metric +11", assertmsg def test_bgp_metric_subtract_config(): @@ -433,9 +486,13 @@ def test_bgp_metric_subtract_config(): logger.info("Checking BGP configuration for correct 'set metric' SUBTRACT value") - setmetricM22 = tgen.net['r2'].cmd('vtysh -c "show running" | grep "^ set metric -22"').rstrip() - assertmsg = "'set metric -22' configuration applied to R2, but not visible in configuration" - assert setmetricM22 == ' set metric -22', assertmsg + setmetricM22 = ( + tgen.net["r2"].cmd('vtysh -c "show running" | grep "^ set metric -22"').rstrip() + ) + assertmsg = ( + "'set metric -22' configuration applied to R2, but not visible in configuration" + ) + assert setmetricM22 == " set metric -22", assertmsg def test_bgp_set_metric(): @@ -478,47 +535,49 @@ def test_bgp_remove_metric_rmaps(): # Remove metric route-maps and relevant comfiguration - tgen.net['r1'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+ - '-c "address-family ipv4 unicast" '+ - '-c "no neighbor 192.168.0.2 route-map addmetric-in in" '+ - '-c "no neighbor 192.168.0.2 route-map addmetric-out out" '+ - '-c "no neighbor 192.168.101.2 route-map setmetric-in in" '+ - '-c "no neighbor 192.168.101.2 route-map setmetric-out out" ') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "no ip prefix-list net1" '+ - '-c "no ip prefix-list net2"') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "no route-map setmetric-in" ') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "no route-map setmetric-out" ') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "no route-map addmetric-in" ') - tgen.net['r1'].cmd('vtysh -c "conf t" '+ - '-c "no route-map addmetric-out" ') - - tgen.net['r2'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+ - '-c "address-family ipv4 unicast" '+ - '-c "no neighbor 192.168.0.1 route-map subtractmetric-in in" '+ - '-c "no neighbor 192.168.0.1 route-map subtractmetric-out out" '+ - '-c "no neighbor 192.168.201.2 route-map setmetric-in in" ' + - '-c "no neighbor 192.168.201.2 route-map setmetric-out out" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "no ip prefix-list net1" '+ - '-c "no ip prefix-list net2" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "no route-map setmetric-in" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "no route-map setmetric-out" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "no route-map addmetric-in" ') - tgen.net['r2'].cmd('vtysh -c "conf t" '+ - '-c "no route-map addmetric-out" ') + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" ' + + '-c "address-family ipv4 unicast" ' + + '-c "no neighbor 192.168.0.2 route-map addmetric-in in" ' + + '-c "no neighbor 192.168.0.2 route-map addmetric-out out" ' + + '-c "no neighbor 192.168.101.2 route-map setmetric-in in" ' + + '-c "no neighbor 192.168.101.2 route-map setmetric-out out" ' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" ' + + '-c "no ip prefix-list net1" ' + + '-c "no ip prefix-list net2"' + ) + tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-in" ') + tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-out" ') + tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-in" ') + tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-out" ') + + tgen.net["r2"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" ' + + '-c "address-family ipv4 unicast" ' + + '-c "no neighbor 192.168.0.1 route-map subtractmetric-in in" ' + + '-c "no neighbor 192.168.0.1 route-map subtractmetric-out out" ' + + '-c "no neighbor 192.168.201.2 route-map setmetric-in in" ' + + '-c "no neighbor 192.168.201.2 route-map setmetric-out out" ' + ) + tgen.net["r2"].cmd( + 'vtysh -c "conf t" ' + + '-c "no ip prefix-list net1" ' + + '-c "no ip prefix-list net2" ' + ) + tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-in" ') + tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-out" ') + tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-in" ') + tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-out" ') # Clear IN the bgp neighbors to make sure the route-maps are applied - tgen.net['r1'].cmd('vtysh -c "clear ip bgp 192.168.0.2 in" '+ - '-c "clear ip bgp 192.168.101.2 in"') - tgen.net['r2'].cmd('vtysh -c "clear ip bgp 192.168.0.1 in" '+ - '-c "clear ip bgp 192.168.201.2 in"') + tgen.net["r1"].cmd( + 'vtysh -c "clear ip bgp 192.168.0.2 in" ' + '-c "clear ip bgp 192.168.101.2 in"' + ) + tgen.net["r2"].cmd( + 'vtysh -c "clear ip bgp 192.168.0.1 in" ' + '-c "clear ip bgp 192.168.201.2 in"' + ) # tgen.mininet_cli() @@ -534,7 +593,9 @@ def test_bgp_remove_metric_rmaps(): topotest.router_json_cmp, router, "show ip bgp json", expected ) _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) - assertmsg = "BGP routes on router r{} are wrong after removing metric route-maps".format(rtrNum) + assertmsg = "BGP routes on router r{} are wrong after removing metric route-maps".format( + rtrNum + ) assert res is None, assertmsg @@ -549,15 +610,17 @@ def test_bgp_norib(): logger.info("Configuring 'bgp no-rib' on router r1") - tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"bgp no-rib\"') + tgen.net["r1"].cmd('vtysh -c "conf t" -c "bgp no-rib"') # Checking BGP config - should show the "bgp no-rib" under the router bgp section logger.info("Checking BGP configuration for 'bgp no-rib'") - norib_cfg = tgen.net['r1'].cmd('vtysh -c "show running bgpd" | grep "^bgp no-rib"').rstrip() + norib_cfg = ( + tgen.net["r1"].cmd('vtysh -c "show running bgpd" | grep "^bgp no-rib"').rstrip() + ) assertmsg = "'bgp no-rib' configuration applied, but not visible in configuration" - assert norib_cfg == 'bgp no-rib', assertmsg + assert norib_cfg == "bgp no-rib", assertmsg def test_bgp_norib_routes(): @@ -585,7 +648,11 @@ def test_bgp_norib_routes(): # Check BGP Summary on local and remote routers for rtrNum in [1, 2, 4]: - logger.info("Checking BGP Summary after 'bgp no-rib' on router r1 on router r{}".format(rtrNum)) + logger.info( + "Checking BGP Summary after 'bgp no-rib' on router r1 on router r{}".format( + rtrNum + ) + ) router = tgen.gears["r{}".format(rtrNum)] reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum)) @@ -595,7 +662,9 @@ def test_bgp_norib_routes(): topotest.router_json_cmp, router, "show ip bgp summary json", expected ) _, res = topotest.run_and_expect(test_func, None, count=30, wait=2) - assertmsg = "BGP sessions on router R{} has incorrect routes after adding 'bgp no-rib on r1'".format(rtrNum) + assertmsg = "BGP sessions on router R{} has incorrect routes after adding 'bgp no-rib on r1'".format( + rtrNum + ) assert res is None, assertmsg # tgen.mininet_cli() @@ -612,15 +681,21 @@ def test_bgp_disable_norib(): logger.info("Configuring 'no bgp no-rib' on router r1") - tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"no bgp no-rib\"') + tgen.net["r1"].cmd('vtysh -c "conf t" -c "no bgp no-rib"') # Checking BGP config - should show the "bgp no-rib" under the router bgp section logger.info("Checking BGP configuration for 'bgp no-rib'") - norib_cfg = tgen.net['r1'].cmd('vtysh -c "show running bgpd" | grep "^ bgp no-rib"').rstrip() + norib_cfg = ( + tgen.net["r1"] + .cmd('vtysh -c "show running bgpd" | grep "^ bgp no-rib"') + .rstrip() + ) - assertmsg = "'no bgp no-rib'configuration applied, but still visible in configuration" - assert norib_cfg == '', assertmsg + assertmsg = ( + "'no bgp no-rib'configuration applied, but still visible in configuration" + ) + assert norib_cfg == "", assertmsg def test_bgp_disable_norib_routes(): @@ -648,7 +723,11 @@ def test_bgp_disable_norib_routes(): # Check BGP Summary on local and remote routers for rtrNum in [1, 2, 4]: - logger.info("Checking BGP Summary after removing the 'bgp no-rib' on router r1 on router r{}".format(rtrNum)) + logger.info( + "Checking BGP Summary after removing the 'bgp no-rib' on router r1 on router r{}".format( + rtrNum + ) + ) router = tgen.gears["r{}".format(rtrNum)] reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum)) @@ -658,13 +737,14 @@ def test_bgp_disable_norib_routes(): topotest.router_json_cmp, router, "show ip bgp summary json", expected ) _, res = topotest.run_and_expect(test_func, None, count=30, wait=2) - assertmsg = "BGP sessions on router R{} has incorrect routes after removing 'bgp no-rib on r1'".format(rtrNum) + assertmsg = "BGP sessions on router R{} has incorrect routes after removing 'bgp no-rib on r1'".format( + rtrNum + ) assert res is None, assertmsg # tgen.mininet_cli() - if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py b/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py index 7e6bfc8b2b..a772a2aab1 100644 --- a/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py +++ b/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py @@ -200,6 +200,7 @@ def test_bgp_flowspec(): else: logger.info("Check BGP FS entry for 3::3 with redirect IP OK") + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py index fdbd317093..18d2ac59d2 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py @@ -135,7 +135,7 @@ from lib.common_config import ( kill_mininet_routers_process, get_frr_ipv6_linklocal, create_route_maps, - required_linux_kernel_version + required_linux_kernel_version, ) # Reading the data from JSON File for topology and configuration creation @@ -188,7 +188,7 @@ def setup_module(mod): global ADDR_TYPES # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py index e1ec0ea81b..da1a47cd29 100644 --- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py +++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py @@ -135,7 +135,7 @@ from lib.common_config import ( kill_mininet_routers_process, get_frr_ipv6_linklocal, create_route_maps, - required_linux_kernel_version + required_linux_kernel_version, ) # Reading the data from JSON File for topology and configuration creation @@ -185,7 +185,7 @@ def setup_module(mod): """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_gshut/test_bgp_gshut.py b/tests/topotests/bgp_gshut/test_bgp_gshut.py index 7f8cf17a5c..fe945a4565 100644 --- a/tests/topotests/bgp_gshut/test_bgp_gshut.py +++ b/tests/topotests/bgp_gshut/test_bgp_gshut.py @@ -99,12 +99,14 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r5"]) + def _run_cmd_and_check(router, cmd, results_file, retries=100, intvl=0.5): json_file = "{}/{}".format(CWD, results_file) expected = json.loads(open(json_file).read()) test_func = partial(topotest.router_json_cmp, router, cmd, expected) return topotest.run_and_expect(test_func, None, retries, intvl) + def setup_module(mod): tgen = Topogen(TemplateTopo, mod.__name__) tgen.start_topology() @@ -134,12 +136,14 @@ def setup_module(mod): tgen.start_router() # Basic peering test to see if things are ok - _, result = _run_cmd_and_check(r2, 'show ip bgp summary json', 'r2/bgp_sum_1.json') - assertmsg = 'R2: Basic sanity test after init failed -- global peerings not up' + _, result = _run_cmd_and_check(r2, "show ip bgp summary json", "r2/bgp_sum_1.json") + assertmsg = "R2: Basic sanity test after init failed -- global peerings not up" assert result is None, assertmsg - _, result = _run_cmd_and_check(r2, 'show ip bgp vrf vrf1 summary json', 'r2/bgp_sum_2.json') - assertmsg = 'R2: Basic sanity test after init failed -- VRF peerings not up' + _, result = _run_cmd_and_check( + r2, "show ip bgp vrf vrf1 summary json", "r2/bgp_sum_2.json" + ) + assertmsg = "R2: Basic sanity test after init failed -- VRF peerings not up" assert result is None, assertmsg @@ -160,80 +164,104 @@ def test_bgp_gshut(): r4 = tgen.gears["r4"] r5 = tgen.gears["r5"] - # Verify initial route states - logger.info('\nVerify initial route states') + logger.info("\nVerify initial route states") - _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json') - assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json" + ) + assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json') - assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json" + ) + assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_1.json') - assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json" + ) + assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - logger.info('\nInitial route states are as expected') - + logger.info("\nInitial route states are as expected") - #"Test #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers" - logger.info('\nTest #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers') + # "Test #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers" + logger.info( + "\nTest #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers" + ) r2.vtysh_cmd( """ configure terminal bgp graceful-shutdown """ - ) + ) # R1, R3 and R5 should see routes from R2 with GSHUT. In addition, # R1 should see LOCAL_PREF of 0 - _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_2.json') - assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_2.json" + ) + assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_2.json') - assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_2.json" + ) + assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_2.json') - assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_2.json" + ) + assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - logger.info('\nTest #1: Successful, routes have GSHUT and/or LPREF of 0 as expected') - + logger.info( + "\nTest #1: Successful, routes have GSHUT and/or LPREF of 0 as expected" + ) - #"Test #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers" - logger.info('\nTest #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers') + # "Test #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers" + logger.info( + "\nTest #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers" + ) r2.vtysh_cmd( """ configure terminal no bgp graceful-shutdown """ - ) + ) # R1, R3 and R5 should see routes from R2 with their original attributes - _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json') - assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json" + ) + assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json') - assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json" + ) + assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_1.json') - assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json" + ) + assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - logger.info('\nTest #2: Successful, routes have their original attributes with default LPREF and without GSHUT') + logger.info( + "\nTest #2: Successful, routes have their original attributes with default LPREF and without GSHUT" + ) - - #"Test #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers" - logger.info('\nTest #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers') + # "Test #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers" + logger.info( + "\nTest #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers" + ) r2.vtysh_cmd( """ @@ -241,44 +269,56 @@ def test_bgp_gshut(): router bgp 65001 vrf vrf1 bgp graceful-shutdown """ - ) + ) # R1 and R3 should see no change to their routes - _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json') - assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json" + ) + assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json') - assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json" + ) + assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg # R5 should see routes from R2 with GSHUT. - _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_2.json') - assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_2.json" + ) + assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - logger.info('\nTest #3: Successful, only VRF peers like R5 see routes with GSHUT') + logger.info("\nTest #3: Successful, only VRF peers like R5 see routes with GSHUT") - - #"Test #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1" - logger.info('\nTest #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1') + # "Test #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1" + logger.info( + "\nTest #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1" + ) ret = r2.vtysh_cmd( """ configure terminal bgp graceful-shutdown """ - ) + ) # This should fail - assertmsg = 'R2: BGP-wide graceful-shutdown config not rejected even though it is enabled in VRF1' - assert re.search("global graceful-shutdown not permitted", ret) is not None, assertmsg + assertmsg = "R2: BGP-wide graceful-shutdown config not rejected even though it is enabled in VRF1" + assert ( + re.search("global graceful-shutdown not permitted", ret) is not None + ), assertmsg - logger.info('\nTest #4: Successful, BGP-wide graceful-shutdown rejected as it is enabled in VRF') + logger.info( + "\nTest #4: Successful, BGP-wide graceful-shutdown rejected as it is enabled in VRF" + ) - - #"Test #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers" - logger.info('\nTest #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers') + # "Test #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers" + logger.info( + "\nTest #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers" + ) r2.vtysh_cmd( """ @@ -286,27 +326,34 @@ def test_bgp_gshut(): router bgp 65001 vrf vrf1 no bgp graceful-shutdown """ - ) + ) # R1 and R3 should see no change to their routes - _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json') - assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json" + ) + assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg - _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json') - assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json" + ) + assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg # R5 should see routes from R2 with original attributes. - _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_1.json') - assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params' + _, result = _run_cmd_and_check( + r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json" + ) + assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params" assert result is None, assertmsg + logger.info( + "\nTest #5: Successful, routes have their original attributes with default LPREF and without GSHUT" + ) - logger.info('\nTest #5: Successful, routes have their original attributes with default LPREF and without GSHUT') - + # tgen.mininet_cli() - #tgen.mininet_cli() if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf index 6e6b9edde2..ae574319b3 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf @@ -18,6 +18,8 @@ router bgp 5227 network 5.1.0.0/24 route-map rm-nh network 5.1.1.0/24 route-map rm-nh redistribute sharp route-map sharp-nh + network 6.0.1.0/24 route-map rm-nh + network 6.0.2.0/24 route-map rm-nh-same neighbor 192.168.1.1 activate exit-address-family ! @@ -41,5 +43,13 @@ route-map sharp-nh permit 10 set extcommunity rt 80:987 set community 0:65 ! - +route-map rm-nh-same permit 10 + match ip address al-any + set ip next-hop 99.0.0.1 + set local-preference 100 + set metric 100 + set large-community 12:34:11 + set extcommunity rt 89:123 + set community 0:67 +! end diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf index 618acabd9f..599e2ddc1e 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf @@ -18,6 +18,8 @@ router bgp 5227 network 5.1.0.0/24 route-map rm-nh network 5.1.1.0/24 route-map rm-nh redistribute sharp route-map sharp-nh + network 6.0.1.0/24 route-map rm-nh + network 6.0.2.0/24 route-map rm-nh-same neighbor 192.168.1.1 activate exit-address-family ! @@ -41,5 +43,13 @@ route-map sharp-nh permit 10 set extcommunity rt 70:456 set community 0:66 ! - +route-map rm-nh-same permit 10 + match ip address al-any + set ip next-hop 99.0.0.2 + set local-preference 100 + set metric 100 + set large-community 12:34:12 + set extcommunity rt 89:123 + set community 0:67 +! end diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf index 85c5973e6f..e316de5690 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf @@ -17,6 +17,8 @@ router bgp 5227 network 99.0.0.3/32 network 5.1.2.0/24 route-map rm-nh network 5.1.3.0/24 route-map rm-nh + network 6.0.1.0/24 route-map rm-nh + network 6.0.2.0/24 route-map rm-nh-same neighbor 192.168.1.1 activate exit-address-family ! @@ -31,5 +33,13 @@ route-map rm-nh permit 10 set extcommunity rt 89:123 set community 0:67 ! - +route-map rm-nh-same permit 10 + match ip address al-any + set ip next-hop 99.0.0.3 + set local-preference 100 + set metric 100 + set large-community 12:34:13 + set extcommunity rt 89:123 + set community 0:67 +! end diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf index 6a5075a000..60d9e93108 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf @@ -17,6 +17,8 @@ router bgp 5228 vrf ce4-cust2 network 99.0.0.4/32 network 5.4.2.0/24 route-map rm-nh network 5.4.3.0/24 route-map rm-nh + network 6.0.1.0/24 route-map rm-nh + network 6.0.2.0/24 route-map rm-nh-same neighbor 192.168.2.1 activate exit-address-family ! @@ -31,5 +33,13 @@ route-map rm-nh permit 10 set extcommunity rt 89:123 set community 0:67 ! - +route-map rm-nh-same permit 10 + match ip address al-any + set ip next-hop 99.0.0.4 + set local-preference 100 + set metric 100 + set large-community 12:34:14 + set extcommunity rt 89:123 + set community 0:67 +! end diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py index f5a29b95c9..98d2a3bafc 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py @@ -14,6 +14,8 @@ from bgprib import bgpribRequireVpnRoutes, bgpribRequireUnicastRoutes want = [ {"p": "5.1.0.0/24", "n": "99.0.0.1"}, {"p": "5.1.1.0/24", "n": "99.0.0.1"}, + {"p": "6.0.1.0/24", "n": "99.0.0.1"}, + {"p": "6.0.2.0/24", "n": "99.0.0.1"}, {"p": "99.0.0.1/32", "n": "0.0.0.0"}, ] bgpribRequireUnicastRoutes("ce1", "ipv4", "", "Cust 1 routes in ce1", want) @@ -21,6 +23,8 @@ bgpribRequireUnicastRoutes("ce1", "ipv4", "", "Cust 1 routes in ce1", want) want = [ {"p": "5.1.0.0/24", "n": "99.0.0.2"}, {"p": "5.1.1.0/24", "n": "99.0.0.2"}, + {"p": "6.0.1.0/24", "n": "99.0.0.2"}, + {"p": "6.0.2.0/24", "n": "99.0.0.2"}, {"p": "99.0.0.2/32", "n": "0.0.0.0"}, ] bgpribRequireUnicastRoutes("ce2", "ipv4", "", "Cust 2 routes in ce1", want) @@ -28,6 +32,8 @@ bgpribRequireUnicastRoutes("ce2", "ipv4", "", "Cust 2 routes in ce1", want) want = [ {"p": "5.1.2.0/24", "n": "99.0.0.3"}, {"p": "5.1.3.0/24", "n": "99.0.0.3"}, + {"p": "6.0.1.0/24", "n": "99.0.0.3"}, + {"p": "6.0.2.0/24", "n": "99.0.0.3"}, {"p": "99.0.0.3/32", "n": "0.0.0.0"}, ] bgpribRequireUnicastRoutes("ce3", "ipv4", "", "Cust 3 routes in ce1", want) @@ -35,6 +41,8 @@ bgpribRequireUnicastRoutes("ce3", "ipv4", "", "Cust 3 routes in ce1", want) want = [ {"p": "5.4.2.0/24", "n": "99.0.0.4"}, {"p": "5.4.3.0/24", "n": "99.0.0.4"}, + {"p": "6.0.1.0/24", "n": "99.0.0.4"}, + {"p": "6.0.2.0/24", "n": "99.0.0.4"}, {"p": "99.0.0.4/32", "n": "0.0.0.0"}, ] bgpribRequireUnicastRoutes("ce4", "ipv4", "ce4-cust2", "Cust 4 routes in ce1", want) @@ -49,6 +57,8 @@ bgpribRequireUnicastRoutes("ce4", "ipv4", "ce4-cust2", "Cust 4 routes in ce1", w want_r1_cust1_routes = [ {"p": "5.1.0.0/24", "n": "99.0.0.1"}, {"p": "5.1.1.0/24", "n": "99.0.0.1"}, + {"p": "6.0.1.0/24", "n": "99.0.0.1"}, + {"p": "6.0.2.0/24", "n": "99.0.0.1"}, {"p": "99.0.0.1/32", "n": "192.168.1.2"}, ] bgpribRequireUnicastRoutes( @@ -58,6 +68,8 @@ bgpribRequireUnicastRoutes( want_r3_cust1_routes = [ {"p": "5.1.0.0/24", "n": "99.0.0.2"}, {"p": "5.1.1.0/24", "n": "99.0.0.2"}, + {"p": "6.0.1.0/24", "n": "99.0.0.2"}, + {"p": "6.0.2.0/24", "n": "99.0.0.2"}, {"p": "99.0.0.2/32", "n": "192.168.1.2"}, ] bgpribRequireUnicastRoutes( @@ -67,6 +79,8 @@ bgpribRequireUnicastRoutes( want_r4_cust1_routes = [ {"p": "5.1.2.0/24", "n": "99.0.0.3"}, {"p": "5.1.3.0/24", "n": "99.0.0.3"}, + {"p": "6.0.1.0/24", "n": "99.0.0.3"}, + {"p": "6.0.2.0/24", "n": "99.0.0.3"}, {"p": "99.0.0.3/32", "n": "192.168.1.2"}, ] bgpribRequireUnicastRoutes( @@ -76,6 +90,8 @@ bgpribRequireUnicastRoutes( want_r4_cust2_routes = [ {"p": "5.4.2.0/24", "n": "99.0.0.4"}, {"p": "5.4.3.0/24", "n": "99.0.0.4"}, + {"p": "6.0.1.0/24", "n": "99.0.0.4"}, + {"p": "6.0.2.0/24", "n": "99.0.0.4"}, {"p": "99.0.0.4/32", "n": "192.168.2.2"}, ] bgpribRequireUnicastRoutes( @@ -152,23 +168,27 @@ else: luCommand( "r1", 'vtysh -c "show bgp ipv4 vpn"', - r"Distinguisher: *10:1.*5.1.0.0/24 *99.0.0.1\b.*5.1.1.0/24 *99.0.0.1\b.*99.0.0.1/32 *192.168.1.2\b", + r"Distinguisher: *10:1.*5.1.0.0/24 *99.0.0.1\b.*5.1.1.0/24 *99.0.0.1\b.*6.0.1.0/24 *99.0.0.1\b.*6.0.2.0/24 *99.0.0.1\b.*99.0.0.1/32 *192.168.1.2\b", "pass", "vrf->vpn routes", ) luCommand( "r3", 'vtysh -c "show bgp ipv4 vpn"', - r"Distinguisher: *10:3.*5.1.0.0/24 *99.0.0.2\b.*5.1.1.0/24 *99.0.0.2\b.*99.0.0.2/32 *192.168.1.2\b", + r"Distinguisher: *10:3.*5.1.0.0/24 *99.0.0.2\b.*5.1.1.0/24 *99.0.0.2\b.*6.0.1.0/24 *99.0.0.2\b.*6.0.2.0/24 *99.0.0.2\b.*99.0.0.2/32 *192.168.1.2\b", "pass", "vrf->vpn routes", ) want = [ {"rd": "10:41", "p": "5.1.2.0/24", "n": "99.0.0.3"}, {"rd": "10:41", "p": "5.1.3.0/24", "n": "99.0.0.3"}, + {"rd": "10:41", "p": "6.0.1.0/24", "n": "99.0.0.3"}, + {"rd": "10:41", "p": "6.0.2.0/24", "n": "99.0.0.3"}, {"rd": "10:41", "p": "99.0.0.3/32", "n": "192.168.1.2"}, {"rd": "10:42", "p": "5.4.2.0/24", "n": "99.0.0.4"}, {"rd": "10:42", "p": "5.4.3.0/24", "n": "99.0.0.4"}, + {"rd": "10:42", "p": "6.0.1.0/24", "n": "99.0.0.4"}, + {"rd": "10:42", "p": "6.0.2.0/24", "n": "99.0.0.4"}, {"rd": "10:42", "p": "99.0.0.4/32", "n": "192.168.2.2"}, ] bgpribRequireVpnRoutes("r4", "vrf->vpn routes", want) @@ -266,57 +286,114 @@ bgpribRequireVpnRoutes( # PE routers: VRFs contain routes from remote customer nets ######################################################################## want_r1_remote_cust1_routes = [ - {"p": "5.1.0.0/24", "n": "3.3.3.3"}, - {"p": "5.1.1.0/24", "n": "3.3.3.3"}, - {"p": "99.0.0.2/32", "n": "3.3.3.3"}, + {"p": "5.1.0.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "5.1.0.0/24", "n": "99.0.0.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "5.1.1.0/24", "n": "99.0.0.1", "bp": True}, {"p": "5.1.2.0/24", "n": "4.4.4.4"}, {"p": "5.1.3.0/24", "n": "4.4.4.4"}, - {"p": "99.0.0.3/32", "n": "4.4.4.4"}, {"p": "5.4.2.0/24", "n": "4.4.4.4"}, {"p": "5.4.3.0/24", "n": "4.4.4.4"}, + {"p": "6.0.1.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "4.4.4.4", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.1", "bp": True}, + {"p": "6.0.2.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.2.0/24", "n": "4.4.4.4", "bp": False}, + {"p": "6.0.2.0/24", "n": "99.0.0.1", "bp": True}, + {"p": "99.0.0.1/32", "n": "192.168.1.2", "bp": True}, + {"p": "99.0.0.2/32", "n": "3.3.3.3"}, {"p": "99.0.0.3/32", "n": "4.4.4.4"}, + {"p": "99.0.0.4/32", "n": "4.4.4.4"}, ] bgpribRequireUnicastRoutes( - "r1", "ipv4", "r1-cust1", "Customer 1 routes in r1 vrf", want_r1_remote_cust1_routes + "r1", + "ipv4", + "r1-cust1", + "Customer 1 routes in r1 vrf (2)", + want_r1_remote_cust1_routes, + debug=False, ) want_r3_remote_cust1_routes = [ - {"p": "5.1.0.0/24", "n": "1.1.1.1"}, - {"p": "5.1.1.0/24", "n": "1.1.1.1"}, - {"p": "99.0.0.1/32", "n": "1.1.1.1"}, - {"p": "5.1.2.0/24", "n": "4.4.4.4"}, - {"p": "5.1.3.0/24", "n": "4.4.4.4"}, - {"p": "99.0.0.3/32", "n": "4.4.4.4"}, - {"p": "5.4.2.0/24", "n": "4.4.4.4"}, - {"p": "5.4.3.0/24", "n": "4.4.4.4"}, - {"p": "99.0.0.3/32", "n": "4.4.4.4"}, + {"p": "5.1.0.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "5.1.0.0/24", "n": "99.0.0.2", "bp": False}, + {"p": "5.1.1.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "99.0.0.2", "bp": False}, + {"p": "5.1.2.0/24", "n": "4.4.4.4", "bp": True}, + {"p": "5.1.3.0/24", "n": "4.4.4.4", "bp": True}, + {"p": "5.4.2.0/24", "n": "4.4.4.4", "bp": True}, + {"p": "5.4.3.0/24", "n": "4.4.4.4", "bp": True}, + {"p": "6.0.1.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "4.4.4.4", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.2", "bp": False}, + {"p": "6.0.2.0/24", "n": "1.1.1.1", "bp": False}, + {"p": "6.0.2.0/24", "n": "4.4.4.4", "bp": False}, + {"p": "6.0.2.0/24", "n": "99.0.0.2", "bp": True}, + {"p": "99.0.0.1/32", "n": "1.1.1.1", "bp": True}, + {"p": "99.0.0.3/32", "n": "4.4.4.4", "bp": True}, + {"p": "99.0.0.4/32", "n": "4.4.4.4", "bp": True}, ] bgpribRequireUnicastRoutes( - "r3", "ipv4", "r3-cust1", "Customer 1 routes in r3 vrf", want_r3_remote_cust1_routes + "r3", + "ipv4", + "r3-cust1", + "Customer 1 routes in r3 vrf (2)", + want_r3_remote_cust1_routes, + debug=False, ) want_r4_remote_cust1_routes = [ - {"p": "5.1.0.0/24", "n": "1.1.1.1"}, - {"p": "5.1.1.0/24", "n": "1.1.1.1"}, - {"p": "5.1.0.0/24", "n": "3.3.3.3"}, - {"p": "5.1.1.0/24", "n": "3.3.3.3"}, - {"p": "99.0.0.1/32", "n": "1.1.1.1"}, - {"p": "99.0.0.2/32", "n": "3.3.3.3"}, + {"p": "5.1.0.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "5.1.0.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "5.1.1.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.4", "bp": False}, + {"p": "6.0.2.0/24", "n": "1.1.1.1", "bp": False}, + {"p": "6.0.2.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.2.0/24", "n": "99.0.0.3", "bp": False}, + {"p": "6.0.2.0/24", "n": "99.0.0.4", "bp": True}, + {"p": "99.0.0.1/32", "n": "1.1.1.1", "bp": True}, + {"p": "99.0.0.2/32", "n": "3.3.3.3", "bp": True}, + {"p": "99.0.0.3/32", "n": "192.168.1.2", "bp": True}, + {"p": "99.0.0.4/32", "n": "192.168.2.2", "bp": True}, ] bgpribRequireUnicastRoutes( - "r4", "ipv4", "r4-cust1", "Customer 1 routes in r4 vrf", want_r4_remote_cust1_routes + "r4", + "ipv4", + "r4-cust1", + "Customer 1 routes in r4 vrf (2)", + want_r4_remote_cust1_routes, + debug=False, ) want_r4_remote_cust2_routes = [ - {"p": "5.1.0.0/24", "n": "1.1.1.1"}, - {"p": "5.1.1.0/24", "n": "1.1.1.1"}, - {"p": "5.1.0.0/24", "n": "3.3.3.3"}, - {"p": "5.1.1.0/24", "n": "3.3.3.3"}, - {"p": "99.0.0.1/32", "n": "1.1.1.1"}, - {"p": "99.0.0.2/32", "n": "3.3.3.3"}, + {"p": "5.1.0.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "5.1.0.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "5.1.1.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "1.1.1.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.3", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.4", "bp": False}, + {"p": "6.0.2.0/24", "n": "1.1.1.1", "bp": False}, + {"p": "6.0.2.0/24", "n": "3.3.3.3", "bp": False}, + {"p": "6.0.2.0/24", "n": "99.0.0.3", "bp": True}, + {"p": "6.0.2.0/24", "n": "99.0.0.4", "bp": False}, + {"p": "99.0.0.1/32", "n": "1.1.1.1", "bp": True}, + {"p": "99.0.0.2/32", "n": "3.3.3.3", "bp": True}, + {"p": "99.0.0.3/32", "n": "192.168.1.2", "bp": True}, + {"p": "99.0.0.4/32", "n": "192.168.2.2", "bp": True}, ] bgpribRequireUnicastRoutes( - "r4", "ipv4", "r4-cust2", "Customer 2 routes in r4 vrf", want_r4_remote_cust2_routes + "r4", + "ipv4", + "r4-cust2", + "Customer 2 routes in r4 vrf (2)", + want_r4_remote_cust2_routes, + debug=False, ) @@ -330,36 +407,49 @@ bgpribRequireUnicastRoutes( luCommand( "ce1", 'vtysh -c "show bgp ipv4 uni"', - "10 routes and 10", + "12 routes and 12", "wait", "Local and remote routes", 10, ) want = [ - {"p": "5.1.2.0/24", "n": "192.168.1.1"}, - {"p": "5.1.3.0/24", "n": "192.168.1.1"}, - {"p": "5.4.2.0/24", "n": "192.168.1.1"}, - {"p": "5.4.3.0/24", "n": "192.168.1.1"}, + {"p": "5.1.0.0/24", "n": "99.0.0.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "99.0.0.1", "bp": True}, + {"p": "5.1.2.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.1.3.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.4.2.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.4.3.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "99.0.0.1", "bp": True}, + {"p": "6.0.2.0/24", "n": "99.0.0.1", "bp": True}, ] -bgpribRequireUnicastRoutes("ce1", "ipv4", "", "Cust 1 routes from remote", want) +bgpribRequireUnicastRoutes( + "ce1", "ipv4", "", "Cust 1 routes from remote", want, debug=False +) luCommand( "ce2", 'vtysh -c "show bgp ipv4 uni"', - "10 routes and 12", + "12 routes and 15", "wait", "Local and remote routes", 10, ) want = [ - {"p": "5.1.0.0/24", "n": "192.168.1.1"}, - {"p": "5.1.1.0/24", "n": "192.168.1.1"}, - {"p": "5.1.2.0/24", "n": "192.168.1.1"}, - {"p": "5.1.3.0/24", "n": "192.168.1.1"}, - {"p": "5.4.2.0/24", "n": "192.168.1.1"}, - {"p": "5.4.3.0/24", "n": "192.168.1.1"}, + {"p": "5.1.0.0/24", "n": "192.168.1.1", "bp": False}, + {"p": "5.1.0.0/24", "n": "99.0.0.2", "bp": True}, + {"p": "5.1.1.0/24", "n": "192.168.1.1", "bp": False}, + {"p": "5.1.1.0/24", "n": "99.0.0.2", "bp": True}, + {"p": "5.1.2.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.1.3.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.4.2.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.4.3.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "192.168.1.1", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.2", "bp": True}, + {"p": "6.0.2.0/24", "n": "99.0.0.2", "bp": True}, ] -bgpribRequireUnicastRoutes("ce2", "ipv4", "", "Cust 1 routes from remote", want) +bgpribRequireUnicastRoutes( + "ce2", "ipv4", "", "Cust 1 routes from remote", want, debug=False +) # human readable output for debugging luCommand("r4", 'vtysh -c "show bgp vrf r4-cust1 ipv4 uni"') @@ -371,34 +461,159 @@ luCommand("r4", 'vtysh -c "show ip route vrf r4-cust2"') luCommand( "ce3", 'vtysh -c "show bgp ipv4 uni"', - "10 routes and 10", + "12 routes and 14", "wait", "Local and remote routes", 10, ) # Requires bvl-bug-degenerate-no-label fix (FRR PR #2053) want = [ - {"p": "5.1.0.0/24", "n": "192.168.1.1"}, - {"p": "5.1.1.0/24", "n": "192.168.1.1"}, - {"p": "5.4.2.0/24", "n": "192.168.1.1"}, - {"p": "5.4.3.0/24", "n": "192.168.1.1"}, + {"p": "5.1.0.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.4.2.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "5.4.3.0/24", "n": "192.168.1.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "192.168.1.1", "bp": False}, + {"p": "6.0.2.0/24", "n": "192.168.1.1", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.3", "bp": True}, + {"p": "6.0.2.0/24", "n": "99.0.0.3", "bp": True}, ] -bgpribRequireUnicastRoutes("ce3", "ipv4", "", "Cust 1 routes from remote", want) +bgpribRequireUnicastRoutes( + "ce3", "ipv4", "", "Cust 1 routes from remote", want, debug=False +) luCommand( "ce4", 'vtysh -c "show bgp vrf ce4-cust2 ipv4 uni"', - "10 routes and 10", + "12 routes and 14", "wait", "Local and remote routes", 10, ) want = [ - {"p": "5.1.0.0/24", "n": "192.168.2.1"}, - {"p": "5.1.1.0/24", "n": "192.168.2.1"}, - {"p": "5.1.2.0/24", "n": "192.168.2.1"}, - {"p": "5.1.3.0/24", "n": "192.168.2.1"}, + {"p": "5.1.0.0/24", "n": "192.168.2.1", "bp": True}, + {"p": "5.1.1.0/24", "n": "192.168.2.1", "bp": True}, + {"p": "5.1.2.0/24", "n": "192.168.2.1", "bp": True}, + {"p": "5.1.3.0/24", "n": "192.168.2.1", "bp": True}, + {"p": "6.0.1.0/24", "n": "192.168.2.1", "bp": False}, + {"p": "6.0.2.0/24", "n": "192.168.2.1", "bp": False}, + {"p": "6.0.1.0/24", "n": "99.0.0.4", "bp": True}, + {"p": "6.0.2.0/24", "n": "99.0.0.4", "bp": True}, ] bgpribRequireUnicastRoutes( - "ce4", "ipv4", "ce4-cust2", "Cust 2 routes from remote", want + "ce4", "ipv4", "ce4-cust2", "Cust 2 routes from remote", want, debug=False +) + +# verify details of exported/imported routes +luCommand( + "ce1", + 'vtysh -c "show bgp ipv4 uni 6.0.1.0"', + "1 available.*192.168.1.1.*99.0.0.1.*Community: 0:67.*Extended Community: RT:89:123.*Large Community: 12:34:56", + "pass", + "Redundant route 1 details", +) +luCommand( + "ce2", + 'vtysh -c "show bgp ipv4 uni 6.0.1.0"', + "2 available, best .*192.168.1.1.* Local.* 192.168.1.1 from 192.168.1.1 .192.168.1.1" + + ".* Origin IGP, metric 98, localpref 123, valid, internal" + + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:56", + "pass", + "Redundant route 1 details", +) +luCommand( + "ce2", + 'vtysh -c "show bgp ipv4 uni 6.0.1.0"', + "2 available, best .*192.168.1.1.* Local.* 99.0.0.2 from 0.0.0.0 .99.0.0.2" + + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .Weight" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:56", + "pass", + "Redundant route 1 details", +) +luCommand( + "ce3", + 'vtysh -c "show bgp ipv4 uni 6.0.1.0"', + "2 available, best " + ".* Local.* 99.0.0.3 from 0.0.0.0 .99.0.0.3" + + ".* Origin IGP, metric 200, localpref 50, weight 32768, valid, sourced, local, best .Weight" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:56", + "pass", + "Redundant route 1 details", +) +luCommand( + "ce3", + 'vtysh -c "show bgp ipv4 uni 6.0.1.0"', + "2 available, best " + ".* Local.* 192.168.1.1 from 192.168.1.1 .192.168.1.1" + + ".* Origin IGP, metric 98, localpref 123, valid, internal" + + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:56", + "pass", + "Redundant route 1 details", +) +luCommand( + "ce4", + 'vtysh -c "show bgp vrf ce4-cust2 ipv4 6.0.1.0"', + "2 available, best .*192.168.2.1.* Local.* 192.168.2.1 from 192.168.2.1 .192.168.2.1" + + ".* Origin IGP, metric 98, localpref 123, valid, internal" + + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:56" + + ".* Local.* 99.0.0.4 from 0.0.0.0 .99.0.0.4" + + ".* Origin IGP, metric 200, localpref 50, weight 32768, valid, sourced, local, best .Weight" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:56", + "pass", + "Redundant route 1 details", +) + +luCommand( + "ce1", + 'vtysh -c "show bgp ipv4 uni 6.0.2.0"', + "1 available, best .*192.168.1.1.* Local.* 99.0.0.1 from 0.0.0.0 .99.0.0.1" + + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .First path received" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:11", + "pass", + "Redundant route 2 details", +) +luCommand( + "ce2", + 'vtysh -c "show bgp ipv4 uni 6.0.2.0"', + "1 available, best .*192.168.1.1.* Local.* 99.0.0.2 from 0.0.0.0 .99.0.0.2" + + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .First path received" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:12", + "pass", + "Redundant route 2 details", +) +luCommand( + "ce3", + 'vtysh -c "show bgp ipv4 uni 6.0.2.0"', + "2 available, best .*192.168.1.1.* Local.* 99.0.0.3 from 0.0.0.0 .99.0.0.3" + + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .Weight" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:13", + "pass", + "Redundant route 2 details", +) +luCommand( + "ce3", + 'vtysh -c "show bgp ipv4 uni 6.0.2.0"', + "2 available, best .*192.168.1.1.* Local.* 192.168.1.1 from 192.168.1.1 .192.168.1.1" + + ".* Origin IGP, metric 100, localpref 100, valid, internal" + + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:14", + "pass", + "Redundant route 2 details", +) +luCommand( + "ce4", + 'vtysh -c "show bgp vrf ce4-cust2 ipv4 6.0.2.0"', + "2 available, best .*192.168.2.1.* Local.* 192.168.2.1 from 192.168.2.1 .192.168.2.1" + + ".* Origin IGP, metric 100, localpref 100, valid, internal" + + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:13", + "pass", + "Redundant route 2 details", +) +luCommand( + "ce4", + 'vtysh -c "show bgp vrf ce4-cust2 ipv4 6.0.2.0"', + "2 available, best .*192.168.2.1.* Local.* 99.0.0.4 from 0.0.0.0 .99.0.0.4" + + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .Weight" + + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:14", + "pass", + "Redundant route 2 details", ) +# done diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py index b4fa240495..7990533f3a 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py @@ -49,7 +49,7 @@ if ret != False and found != None: luCommand( rtr, 'vtysh -c "show bgp ipv4 uni" | grep Display', - " 10 route", + " 12 route", "wait", "BGP routes removed", wait, diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py index dc06b7131a..40489f438f 100644 --- a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py +++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py @@ -67,7 +67,7 @@ from lib.common_config import ( verify_bgp_community, step, check_address_types, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify @@ -144,7 +144,7 @@ def setup_module(mod): * `mod`: module name """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py index bb88e47415..9c0355a3e9 100644 --- a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py +++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py @@ -91,7 +91,7 @@ from lib.common_config import ( verify_route_maps, create_static_routes, check_address_types, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify @@ -135,7 +135,7 @@ def setup_module(mod): """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_link_bw_ip/test_bgp_linkbw_ip.py b/tests/topotests/bgp_link_bw_ip/test_bgp_linkbw_ip.py index dff69e3a27..f09ff20651 100644 --- a/tests/topotests/bgp_link_bw_ip/test_bgp_linkbw_ip.py +++ b/tests/topotests/bgp_link_bw_ip/test_bgp_linkbw_ip.py @@ -35,7 +35,7 @@ import json # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) +sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers @@ -63,8 +63,10 @@ this scenario, the servers are also routers as they have to announce anycast IP (VIP) addresses via BGP. """ + class BgpLinkBwTopo(Topo): "Test topology builder" + def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) @@ -73,45 +75,46 @@ class BgpLinkBwTopo(Topo): # and 4 servers routers = {} for i in range(1, 11): - routers[i] = tgen.add_router('r{}'.format(i)) + routers[i] = tgen.add_router("r{}".format(i)) # Create 13 "switches" - to interconnect the above routers switches = {} for i in range(1, 14): - switches[i] = tgen.add_switch('s{}'.format(i)) + switches[i] = tgen.add_switch("s{}".format(i)) # Interconnect R1 (super-spine) to R2 and R3 (the two spines) - switches[1].add_link(tgen.gears['r1']) - switches[1].add_link(tgen.gears['r2']) - switches[2].add_link(tgen.gears['r1']) - switches[2].add_link(tgen.gears['r3']) + switches[1].add_link(tgen.gears["r1"]) + switches[1].add_link(tgen.gears["r2"]) + switches[2].add_link(tgen.gears["r1"]) + switches[2].add_link(tgen.gears["r3"]) # Interconnect R2 (spine in pod-1) to R4 and R5 (the associated # leaf switches) - switches[3].add_link(tgen.gears['r2']) - switches[3].add_link(tgen.gears['r4']) - switches[4].add_link(tgen.gears['r2']) - switches[4].add_link(tgen.gears['r5']) + switches[3].add_link(tgen.gears["r2"]) + switches[3].add_link(tgen.gears["r4"]) + switches[4].add_link(tgen.gears["r2"]) + switches[4].add_link(tgen.gears["r5"]) # Interconnect R3 (spine in pod-2) to R6 (associated leaf) - switches[5].add_link(tgen.gears['r3']) - switches[5].add_link(tgen.gears['r6']) + switches[5].add_link(tgen.gears["r3"]) + switches[5].add_link(tgen.gears["r6"]) # Interconnect leaf switches to servers - switches[6].add_link(tgen.gears['r4']) - switches[6].add_link(tgen.gears['r7']) - switches[7].add_link(tgen.gears['r4']) - switches[7].add_link(tgen.gears['r8']) - switches[8].add_link(tgen.gears['r5']) - switches[8].add_link(tgen.gears['r9']) - switches[9].add_link(tgen.gears['r6']) - switches[9].add_link(tgen.gears['r10']) + switches[6].add_link(tgen.gears["r4"]) + switches[6].add_link(tgen.gears["r7"]) + switches[7].add_link(tgen.gears["r4"]) + switches[7].add_link(tgen.gears["r8"]) + switches[8].add_link(tgen.gears["r5"]) + switches[8].add_link(tgen.gears["r9"]) + switches[9].add_link(tgen.gears["r6"]) + switches[9].add_link(tgen.gears["r10"]) # Create empty networks for the servers - switches[10].add_link(tgen.gears['r7']) - switches[11].add_link(tgen.gears['r8']) - switches[12].add_link(tgen.gears['r9']) - switches[13].add_link(tgen.gears['r10']) + switches[10].add_link(tgen.gears["r7"]) + switches[11].add_link(tgen.gears["r8"]) + switches[12].add_link(tgen.gears["r9"]) + switches[13].add_link(tgen.gears["r10"]) + def setup_module(mod): "Sets up the pytest environment" @@ -121,395 +124,454 @@ def setup_module(mod): router_list = tgen.routers() for rname, router in router_list.items(): router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_BGP, - os.path.join(CWD, '{}/bgpd.conf'.format(rname)) + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) ) # Initialize all routers. tgen.start_router() - #tgen.mininet_cli() + # tgen.mininet_cli() + def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() + def test_bgp_linkbw_adv(): "Test #1: Test BGP link-bandwidth advertisement based on number of multipaths" - logger.info('\nTest #1: Test BGP link-bandwidth advertisement based on number of multipaths') + logger.info( + "\nTest #1: Test BGP link-bandwidth advertisement based on number of multipaths" + ) tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] - r2 = tgen.gears['r2'] + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] # Configure anycast IP on server r7 - logger.info('Configure anycast IP on server r7') + logger.info("Configure anycast IP on server r7") - tgen.net['r7'].cmd('ip addr add 198.10.1.1/32 dev r7-eth1') + tgen.net["r7"].cmd("ip addr add 198.10.1.1/32 dev r7-eth1") # Check on spine router r2 for link-bw advertisement by leaf router r4 - logger.info('Check on spine router r2 for link-bw advertisement by leaf router r4') + logger.info("Check on spine router r2 for link-bw advertisement by leaf router r4") - json_file = '{}/r2/bgp-route-1.json'.format(CWD) + json_file = "{}/r2/bgp-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r2, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r2, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on spine router r2' + assertmsg = "JSON output mismatch on spine router r2" assert result is None, assertmsg # Check on spine router r2 that default weight is used as there is no multipath - logger.info('Check on spine router r2 that default weight is used as there is no multipath') + logger.info( + "Check on spine router r2 that default weight is used as there is no multipath" + ) - json_file = '{}/r2/ip-route-1.json'.format(CWD) + json_file = "{}/r2/ip-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r2, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r2, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on spine router r2' + assertmsg = "JSON output mismatch on spine router r2" assert result is None, assertmsg # Check on super-spine router r1 that link-bw has been propagated by spine router r2 - logger.info('Check on super-spine router r1 that link-bw has been propagated by spine router r2') + logger.info( + "Check on super-spine router r1 that link-bw has been propagated by spine router r2" + ) - json_file = '{}/r1/bgp-route-1.json'.format(CWD) + json_file = "{}/r1/bgp-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg + def test_bgp_cumul_linkbw(): "Test #2: Test cumulative link-bandwidth propagation" - logger.info('\nTest #2: Test cumulative link-bandwidth propagation') + logger.info("\nTest #2: Test cumulative link-bandwidth propagation") tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] - r2 = tgen.gears['r2'] - r4 = tgen.gears['r4'] + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + r4 = tgen.gears["r4"] # Configure anycast IP on additional server r8 - logger.info('Configure anycast IP on server r8') + logger.info("Configure anycast IP on server r8") - tgen.net['r8'].cmd('ip addr add 198.10.1.1/32 dev r8-eth1') + tgen.net["r8"].cmd("ip addr add 198.10.1.1/32 dev r8-eth1") # Check multipath on leaf router r4 - logger.info('Check multipath on leaf router r4') + logger.info("Check multipath on leaf router r4") - json_file = '{}/r4/bgp-route-1.json'.format(CWD) + json_file = "{}/r4/bgp-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r4, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r4, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on leaf router r4' + assertmsg = "JSON output mismatch on leaf router r4" assert result is None, assertmsg # Check regular ECMP is in effect on leaf router r4 - logger.info('Check regular ECMP is in effect on leaf router r4') + logger.info("Check regular ECMP is in effect on leaf router r4") - json_file = '{}/r4/ip-route-1.json'.format(CWD) + json_file = "{}/r4/ip-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r4, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r4, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on leaf router r4' + assertmsg = "JSON output mismatch on leaf router r4" assert result is None, assertmsg # Check on spine router r2 that leaf has propagated the cumulative link-bw based on num-multipaths - logger.info('Check on spine router r2 that leaf has propagated the cumulative link-bw based on num-multipaths') + logger.info( + "Check on spine router r2 that leaf has propagated the cumulative link-bw based on num-multipaths" + ) - json_file = '{}/r2/bgp-route-2.json'.format(CWD) + json_file = "{}/r2/bgp-route-2.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r2, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r2, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on spine router r2' + assertmsg = "JSON output mismatch on spine router r2" assert result is None, assertmsg + def test_weighted_ecmp(): "Test #3: Test weighted ECMP - multipath with next hop weights" - logger.info('\nTest #3: Test weighted ECMP - multipath with next hop weights') + logger.info("\nTest #3: Test weighted ECMP - multipath with next hop weights") tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] - r2 = tgen.gears['r2'] + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] # Configure anycast IP on additional server r9 - logger.info('Configure anycast IP on server r9') + logger.info("Configure anycast IP on server r9") - tgen.net['r9'].cmd('ip addr add 198.10.1.1/32 dev r9-eth1') + tgen.net["r9"].cmd("ip addr add 198.10.1.1/32 dev r9-eth1") # Check multipath on spine router r2 - logger.info('Check multipath on spine router r2') - json_file = '{}/r2/bgp-route-3.json'.format(CWD) + logger.info("Check multipath on spine router r2") + json_file = "{}/r2/bgp-route-3.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r2, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r2, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on spine router r2' + assertmsg = "JSON output mismatch on spine router r2" assert result is None, assertmsg # Check weighted ECMP is in effect on the spine router r2 - logger.info('Check weighted ECMP is in effect on the spine router r2') + logger.info("Check weighted ECMP is in effect on the spine router r2") - json_file = '{}/r2/ip-route-2.json'.format(CWD) + json_file = "{}/r2/ip-route-2.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r2, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r2, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on spine router r2' + assertmsg = "JSON output mismatch on spine router r2" assert result is None, assertmsg # Configure anycast IP on additional server r10 - logger.info('Configure anycast IP on server r10') + logger.info("Configure anycast IP on server r10") - tgen.net['r10'].cmd('ip addr add 198.10.1.1/32 dev r10-eth1') + tgen.net["r10"].cmd("ip addr add 198.10.1.1/32 dev r10-eth1") # Check multipath on super-spine router r1 - logger.info('Check multipath on super-spine router r1') - json_file = '{}/r1/bgp-route-2.json'.format(CWD) + logger.info("Check multipath on super-spine router r1") + json_file = "{}/r1/bgp-route-2.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg # Check weighted ECMP is in effect on the super-spine router r1 - logger.info('Check weighted ECMP is in effect on the super-spine router r1') - json_file = '{}/r1/ip-route-1.json'.format(CWD) + logger.info("Check weighted ECMP is in effect on the super-spine router r1") + json_file = "{}/r1/ip-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg + def test_weighted_ecmp_link_flap(): "Test #4: Test weighted ECMP rebalancing upon change (link flap)" - logger.info('\nTest #4: Test weighted ECMP rebalancing upon change (link flap)') + logger.info("\nTest #4: Test weighted ECMP rebalancing upon change (link flap)") tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] - r2 = tgen.gears['r2'] + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] # Bring down link on server r9 - logger.info('Bring down link on server r9') + logger.info("Bring down link on server r9") - tgen.net['r9'].cmd('ip link set dev r9-eth1 down') + tgen.net["r9"].cmd("ip link set dev r9-eth1 down") # Check spine router r2 has only one path - logger.info('Check spine router r2 has only one path') + logger.info("Check spine router r2 has only one path") - json_file = '{}/r2/ip-route-3.json'.format(CWD) + json_file = "{}/r2/ip-route-3.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r2, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r2, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on spine router r2' + assertmsg = "JSON output mismatch on spine router r2" assert result is None, assertmsg # Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1 - logger.info('Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1') + logger.info( + "Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1" + ) - json_file = '{}/r1/bgp-route-3.json'.format(CWD) + json_file = "{}/r1/bgp-route-3.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg - json_file = '{}/r1/ip-route-2.json'.format(CWD) + json_file = "{}/r1/ip-route-2.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg # Bring up link on server r9 - logger.info('Bring up link on server r9') + logger.info("Bring up link on server r9") - tgen.net['r9'].cmd('ip link set dev r9-eth1 up') + tgen.net["r9"].cmd("ip link set dev r9-eth1 up") # Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1 - logger.info('Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1') + logger.info( + "Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1" + ) - json_file = '{}/r1/bgp-route-2.json'.format(CWD) + json_file = "{}/r1/bgp-route-2.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg - json_file = '{}/r1/ip-route-1.json'.format(CWD) + json_file = "{}/r1/ip-route-1.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg + def test_weighted_ecmp_second_anycast_ip(): "Test #5: Test weighted ECMP for a second anycast IP" - logger.info('\nTest #5: Test weighted ECMP for a second anycast IP') + logger.info("\nTest #5: Test weighted ECMP for a second anycast IP") tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] - r2 = tgen.gears['r2'] + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] # Configure anycast IP on additional server r7, r9 and r10 - logger.info('Configure anycast IP on server r7, r9 and r10') + logger.info("Configure anycast IP on server r7, r9 and r10") - tgen.net['r7'].cmd('ip addr add 198.10.1.11/32 dev r7-eth1') - tgen.net['r9'].cmd('ip addr add 198.10.1.11/32 dev r9-eth1') - tgen.net['r10'].cmd('ip addr add 198.10.1.11/32 dev r10-eth1') + tgen.net["r7"].cmd("ip addr add 198.10.1.11/32 dev r7-eth1") + tgen.net["r9"].cmd("ip addr add 198.10.1.11/32 dev r9-eth1") + tgen.net["r10"].cmd("ip addr add 198.10.1.11/32 dev r10-eth1") # Check link-bandwidth and weighted ECMP on super-spine router r1 - logger.info('Check link-bandwidth and weighted ECMP on super-spine router r1') + logger.info("Check link-bandwidth and weighted ECMP on super-spine router r1") - json_file = '{}/r1/bgp-route-4.json'.format(CWD) + json_file = "{}/r1/bgp-route-4.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show bgp ipv4 uni 198.10.1.11/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.11/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg - json_file = '{}/r1/ip-route-3.json'.format(CWD) + json_file = "{}/r1/ip-route-3.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.11/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg + def test_paths_with_and_without_linkbw(): "Test #6: Test paths with and without link-bandwidth - receiver should resort to regular ECMP" - logger.info('\nTest #6: Test paths with and without link-bandwidth - receiver should resort to regular ECMP') + logger.info( + "\nTest #6: Test paths with and without link-bandwidth - receiver should resort to regular ECMP" + ) tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] + r1 = tgen.gears["r1"] # Configure leaf router r6 to not advertise any link-bandwidth - logger.info('Configure leaf router r6 to not advertise any link-bandwidth') + logger.info("Configure leaf router r6 to not advertise any link-bandwidth") - tgen.net['r6'].cmd('vtysh -c \"conf t\" -c \"router bgp 65303\" -c \"address-family ipv4 unicast\" -c \"no neighbor 11.1.3.1 route-map anycast_ip out\"') + tgen.net["r6"].cmd( + 'vtysh -c "conf t" -c "router bgp 65303" -c "address-family ipv4 unicast" -c "no neighbor 11.1.3.1 route-map anycast_ip out"' + ) # Check link-bandwidth change on super-spine router r1 - logger.info('Check link-bandwidth change on super-spine router r1') + logger.info("Check link-bandwidth change on super-spine router r1") - json_file = '{}/r1/bgp-route-5.json'.format(CWD) + json_file = "{}/r1/bgp-route-5.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg # Check super-spine router r1 resorts to regular ECMP - logger.info('Check super-spine router r1 resorts to regular ECMP') + logger.info("Check super-spine router r1 resorts to regular ECMP") - json_file = '{}/r1/ip-route-4.json'.format(CWD) + json_file = "{}/r1/ip-route-4.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg - json_file = '{}/r1/ip-route-5.json'.format(CWD) + json_file = "{}/r1/ip-route-5.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.11/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg + def test_linkbw_handling_options(): "Test #7: Test different options for processing link-bandwidth on the receiver" - logger.info('\nTest #7: Test different options for processing link-bandwidth on the receiver') + logger.info( + "\nTest #7: Test different options for processing link-bandwidth on the receiver" + ) tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") - r1 = tgen.gears['r1'] + r1 = tgen.gears["r1"] # Configure super-spine r1 to skip multipaths without link-bandwidth - logger.info('Configure super-spine r1 to skip multipaths without link-bandwidth') + logger.info("Configure super-spine r1 to skip multipaths without link-bandwidth") - tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65101\" -c \"bgp bestpath bandwidth skip-missing\"') + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65101" -c "bgp bestpath bandwidth skip-missing"' + ) # Check super-spine router r1 resorts to only one path as other path is skipped - logger.info('Check super-spine router r1 resorts to only one path as other path is skipped') + logger.info( + "Check super-spine router r1 resorts to only one path as other path is skipped" + ) - json_file = '{}/r1/ip-route-6.json'.format(CWD) + json_file = "{}/r1/ip-route-6.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg - json_file = '{}/r1/ip-route-7.json'.format(CWD) + json_file = "{}/r1/ip-route-7.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.11/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg # Configure super-spine r1 to use default-weight for multipaths without link-bandwidth - logger.info('Configure super-spine r1 to use default-weight for multipaths without link-bandwidth') + logger.info( + "Configure super-spine r1 to use default-weight for multipaths without link-bandwidth" + ) - tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65101\" -c \"bgp bestpath bandwidth default-weight-for-missing\"') + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65101" -c "bgp bestpath bandwidth default-weight-for-missing"' + ) # Check super-spine router r1 uses ECMP with weight 1 for path without link-bandwidth - logger.info('Check super-spine router r1 uses ECMP with weight 1 for path without link-bandwidth') + logger.info( + "Check super-spine router r1 uses ECMP with weight 1 for path without link-bandwidth" + ) - json_file = '{}/r1/ip-route-8.json'.format(CWD) + json_file = "{}/r1/ip-route-8.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.1/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg - json_file = '{}/r1/ip-route-9.json'.format(CWD) + json_file = "{}/r1/ip-route-9.json".format(CWD) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - r1, 'show ip route 198.10.1.11/32 json', expected) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5) - assertmsg = 'JSON output mismatch on super-spine router r1' + assertmsg = "JSON output mismatch on super-spine router r1" assert result is None, assertmsg -if __name__ == '__main__': + +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py index c15b88d371..cf6b7cc53f 100644 --- a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py +++ b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py @@ -132,7 +132,7 @@ from lib.common_config import ( create_bgp_community_lists, check_router_status, apply_raw_config, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger @@ -211,7 +211,7 @@ def setup_module(mod): * `mod`: module name """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") @@ -693,10 +693,12 @@ def test_static_routes_associated_to_specific_vrfs_p0(request): ) step( - "Verify that static routes 1.x.x.x/32 and 1::x/128 appear " "in VRF BLUE_A table" + "Verify that static routes 1.x.x.x/32 and 1::x/128 appear " + "in VRF BLUE_A table" ) step( - "Verify that static routes 2.x.x.x/32 and 2::x/128 appear " "in VRF BLUE_B table" + "Verify that static routes 2.x.x.x/32 and 2::x/128 appear " + "in VRF BLUE_B table" ) for addr_type in ADDR_TYPES: diff --git a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py index bb13d54019..cafe758209 100644 --- a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py +++ b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py @@ -78,7 +78,7 @@ from lib.common_config import ( get_frr_ipv6_linklocal, check_router_status, apply_raw_config, - required_linux_kernel_version + required_linux_kernel_version, ) from lib.topolog import logger @@ -143,7 +143,7 @@ def setup_module(mod): * `mod`: module name """ # Required linux kernel version for this suite to run. - result = required_linux_kernel_version('4.15') + result = required_linux_kernel_version("4.15") if result is not True: pytest.skip("Kernel requirements are not met") diff --git a/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py b/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py index fef6eb71dc..3af944473d 100644 --- a/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py +++ b/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py @@ -91,7 +91,7 @@ jsonFile = "{}/bgp_recursive_route_ebgp_multi_hop.json".format(CWD) try: with open(jsonFile, "r") as topoJson: topo = json.load(topoJson) -except IOError : +except IOError: logger.info("Could not read file:", jsonFile) # Global variables @@ -284,7 +284,9 @@ def test_recursive_routes_iBGP_peer_p1(request): input_dict_4, next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0], ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step( "Configure a static routes for next hop IP on R2 via multiple" @@ -317,7 +319,9 @@ def test_recursive_routes_iBGP_peer_p1(request): } } result = create_static_routes(tgen, input_dict_3) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("verify if redistributed routes are now installed in FIB of R2") result = verify_rib( @@ -328,7 +332,9 @@ def test_recursive_routes_iBGP_peer_p1(request): next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0], protocol="bgp", ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("Delete 1 route from static recursive for the next-hop IP") dut = "r2" @@ -345,7 +351,9 @@ def test_recursive_routes_iBGP_peer_p1(request): } } result = create_static_routes(tgen, input_dict_3) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("Verify that redistributed routes are withdrawn from FIB of R2") result = verify_rib( @@ -355,7 +363,7 @@ def test_recursive_routes_iBGP_peer_p1(request): input_dict_4, next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0], protocol="bgp", - expected=False + expected=False, ) assert result is not True, "Testcase : Failed \n Error : {}".format( tc_name, result @@ -375,7 +383,9 @@ def test_recursive_routes_iBGP_peer_p1(request): } } result = create_static_routes(tgen, input_dict_3) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("Verify that redistributed routes are again installed" "in FIB of R2") result = verify_rib( @@ -386,7 +396,9 @@ def test_recursive_routes_iBGP_peer_p1(request): next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0], protocol="bgp", ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("Configure static route with changed next-hop from same subnet") for addr_type in ADDR_TYPES: @@ -410,7 +422,9 @@ def test_recursive_routes_iBGP_peer_p1(request): } } result = create_static_routes(tgen, input_dict_4) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) result = verify_rib(tgen, addr_type, "r1", input_dict_4, protocol="static") assert result is True, "Testcase {} : Failed \n Error : {}".format( @@ -455,7 +469,9 @@ def test_recursive_routes_iBGP_peer_p1(request): } } result = create_static_routes(tgen, input_dict_4) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) result = verify_rib(tgen, addr_type, "r1", input_dict_4, protocol="static") assert result is True, "Testcase {} : Failed \n Error : {}".format( @@ -578,7 +594,7 @@ def test_next_hop_as_self_ip_p1(request): "r2", input_dict_4, next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], - expected=False + expected=False, ) assert result is not True, "Testcase : Failed \n Error : {}".format( tc_name, result @@ -614,7 +630,9 @@ def test_next_hop_as_self_ip_p1(request): input_dict_4, next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("No shutdown interface on R2 which was shut in previous step") intf_r2_r4 = topo["routers"]["r2"]["links"]["r4"]["interface"] @@ -644,14 +662,16 @@ def test_next_hop_as_self_ip_p1(request): input_dict_4, next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) result = verify_rib( tgen, addr_type, "r2", input_dict_4, next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], - expected=False + expected=False, ) assert result is not True, "Testcase : Failed \n Error : {}".format( tc_name, result @@ -907,7 +927,9 @@ def test_next_hop_with_recursive_lookup_p1(request): result = verify_bgp_convergence_from_running_config(tgen, expected=False) assert ( result is not True - ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(tc_name, result) + ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format( + tc_name, result + ) logger.info("Expected behaviour: {}".format(result)) for addr_type in ADDR_TYPES: @@ -1018,7 +1040,7 @@ def test_next_hop_with_recursive_lookup_p1(request): input_dict, protocol="bgp", next_hop=next_hop, - expected=False + expected=False, ) assert result is not True, ( "Testcase {} : Failed \n " @@ -1083,7 +1105,9 @@ def test_next_hop_with_recursive_lookup_p1(request): result = verify_bgp_convergence_from_running_config(tgen, expected=False) assert ( result is not True - ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(tc_name, result) + ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format( + tc_name, result + ) logger.info("Expected behaviour: {}".format(result)) for addr_type in ADDR_TYPES: @@ -1099,7 +1123,7 @@ def test_next_hop_with_recursive_lookup_p1(request): input_dict, protocol="bgp", next_hop=next_hop, - expected=False + expected=False, ) assert result is not True, ( "Testcase {} : Failed \n " @@ -1138,7 +1162,9 @@ def test_next_hop_with_recursive_lookup_p1(request): result = verify_bgp_convergence_from_running_config(tgen, expected=False) assert ( result is not True - ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(tc_name, result) + ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format( + tc_name, result + ) logger.info("Expected behaviour: {}".format(result)) for addr_type in ADDR_TYPES: @@ -1154,7 +1180,7 @@ def test_next_hop_with_recursive_lookup_p1(request): input_dict, protocol="bgp", next_hop=next_hop, - expected=False + expected=False, ) assert result is not True, ( "Testcase {} : Failed \n " @@ -1237,7 +1263,9 @@ def test_BGP_path_attributes_default_values_p1(request): topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0], ], ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: input_dict_4 = { @@ -1256,7 +1284,9 @@ def test_BGP_path_attributes_default_values_p1(request): rmap_name="rmap_pf", input_dict=input_dict_4, ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step( "Configure a route-map to set below attribute value as 500" @@ -1358,7 +1388,9 @@ def test_BGP_path_attributes_default_values_p1(request): rmap_name="rmap_pf", input_dict=input_dict_4, ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step("Remove the route-map from R4") input_dict_5 = { @@ -1432,7 +1464,9 @@ def test_BGP_path_attributes_default_values_p1(request): input_dict=input_dict_4, nexthop=None, ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) write_test_footer(tc_name) @@ -1670,7 +1704,7 @@ def test_BGP_peering_bw_loopback_and_physical_p1(request): input_dict_1, protocol="static", next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0], - expected=False + expected=False, ) assert result is not True, "Testcase {} : Failed \n Error : {}".format( tc_name, result @@ -1801,7 +1835,9 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request): topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0], ], ) - assert result is True, "Testcase : Failed \n Error : {}".format(tc_name, result) + assert result is True, "Testcase : Failed \n Error : {}".format( + tc_name, result + ) step( "Configure a route-map to set as-path attribute and" @@ -2037,7 +2073,7 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request): topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0], ], - expected=False + expected=False, ) assert result is not True, "Testcase {} : Failed \n Error : {}".format( tc_name, result @@ -2084,7 +2120,7 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request): topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0], ], - expected=False + expected=False, ) assert result is not True, "Testcase {} : Failed \n Error : {}".format( tc_name, result diff --git a/tests/topotests/bgp_update_delay/test_bgp_update_delay.py b/tests/topotests/bgp_update_delay/test_bgp_update_delay.py index 4de7184c8e..71bd58bf73 100644 --- a/tests/topotests/bgp_update_delay/test_bgp_update_delay.py +++ b/tests/topotests/bgp_update_delay/test_bgp_update_delay.py @@ -149,22 +149,21 @@ def test_bgp_update_delay(): def _bgp_check_update_delay_in_progress(router): output = json.loads(router.vtysh_cmd("show ip bgp sum json")) - expected = {"ipv4Unicast": {"updateDelayInProgress":True}} + expected = {"ipv4Unicast": {"updateDelayInProgress": True}} return topotest.json_cmp(output, expected) def _bgp_check_route_install(router): output = json.loads(router.vtysh_cmd("show ip route 172.16.253.254/32 json")) - expected = {"172.16.253.254/32": [ {"protocol": "bgp"}]} + expected = {"172.16.253.254/32": [{"protocol": "bgp"}]} return topotest.json_cmp(output, expected) def _bgp_check_update_delay_and_wait(router): output = json.loads(router.vtysh_cmd("show ip bgp sum json")) expected = { - "ipv4Unicast": { - "updateDelayLimit": 20, - "updateDelayEstablishWait": 10}} + "ipv4Unicast": {"updateDelayLimit": 20, "updateDelayEstablishWait": 10} + } return topotest.json_cmp(output, expected) @@ -177,14 +176,11 @@ def test_bgp_update_delay(): def _bgp_check_vrf_update_delay_and_wait(router): output = json.loads(router.vtysh_cmd("show ip bgp vrf vrf1 sum json")) expected = { - "ipv4Unicast": { - "updateDelayLimit": 20, - "updateDelayEstablishWait": 10}} - + "ipv4Unicast": {"updateDelayLimit": 20, "updateDelayEstablishWait": 10} + } return topotest.json_cmp(output, expected) - # Check r2 initial convergence in default table test_func = functools.partial(_bgp_converge, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) @@ -198,7 +194,7 @@ def test_bgp_update_delay(): router bgp 65002 update-delay 20 """ - ) + ) # Shutdown peering on r1 toward r2 so that delay timers can be exercised router1.vtysh_cmd( @@ -207,7 +203,7 @@ def test_bgp_update_delay(): router bgp 65001 neighbor 192.168.255.1 shut """ - ) + ) # Clear bgp neighbors on r2 and then check for the 'in progress' indicator router2.vtysh_cmd("""clear ip bgp *""") @@ -215,13 +211,17 @@ def test_bgp_update_delay(): test_func = functools.partial(_bgp_check_update_delay_in_progress, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format(router2) + assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format( + router2 + ) # Check that r2 only installs route learned from r4 after the max-delay timer expires test_func = functools.partial(_bgp_check_route_install, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to install route after update-delay "{}"'.format(router2) + assert result is None, 'Failed to install route after update-delay "{}"'.format( + router2 + ) # Define update-delay with max-delay and estabish-wait and check json output showing set router2.vtysh_cmd( @@ -230,12 +230,14 @@ def test_bgp_update_delay(): router bgp 65002 update-delay 20 10 """ - ) + ) test_func = functools.partial(_bgp_check_update_delay_and_wait, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to set max-delay and establish-weight timers in "{}"'.format(router2) + assert ( + result is None + ), 'Failed to set max-delay and establish-weight timers in "{}"'.format(router2) # Define update-delay with max-delay and estabish-wait and check json output showing set router2.vtysh_cmd("""clear ip bgp *""") @@ -243,7 +245,11 @@ def test_bgp_update_delay(): test_func = functools.partial(_bgp_check_route_install, router3) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2) + assert ( + result is None + ), 'Failed to installed advertised route after establish-wait timer espired "{}"'.format( + router2 + ) # Remove update-delay timer on r2 to verify that it goes back to normal behavior router2.vtysh_cmd( @@ -252,7 +258,7 @@ def test_bgp_update_delay(): router bgp 65002 no update-delay """ - ) + ) # Clear neighbors on r2 and check that route install time on r2 does not delay router2.vtysh_cmd("""clear ip bgp *""") @@ -260,7 +266,9 @@ def test_bgp_update_delay(): test_func = functools.partial(_bgp_check_route_install, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to remove update-delay delay timing "{}"'.format(router2) + assert result is None, 'Failed to remove update-delay delay timing "{}"'.format( + router2 + ) # Define global bgp update-delay with max-delay and establish-wait on r2 router2.vtysh_cmd( @@ -268,13 +276,15 @@ def test_bgp_update_delay(): configure terminal bgp update-delay 20 10 """ - ) + ) # Check that r2 default instance and vrf1 have the max-delay and establish set test_func = functools.partial(_bgp_check_update_delay_and_wait, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to set update-delay in default instance "{}"'.format(router2) + assert result is None, 'Failed to set update-delay in default instance "{}"'.format( + router2 + ) test_func = functools.partial(_bgp_check_vrf_update_delay_and_wait, router2) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) @@ -287,7 +297,11 @@ def test_bgp_update_delay(): test_func = functools.partial(_bgp_check_route_install, router3) success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2) + assert ( + result is None + ), 'Failed to installed advertised route after establish-wait timer espired "{}"'.format( + router2 + ) if __name__ == "__main__": diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py index 1947548b3e..63db393178 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py @@ -40,8 +40,8 @@ import platform # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) -sys.path.append(os.path.join(CWD, '../lib/')) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) # Required to instantiate the topology builder class. @@ -52,20 +52,32 @@ from lib.topotest import version_cmp from mininet.topo import Topo from lib.common_config import ( - start_topology, write_test_header, check_address_types, - write_test_footer, reset_config_on_routers, - verify_rib, step, create_route_maps, - shutdown_bringup_interface, create_static_routes, - create_prefix_lists, create_bgp_community_lists, + start_topology, + write_test_header, + check_address_types, + write_test_footer, + reset_config_on_routers, + verify_rib, + step, + create_route_maps, + shutdown_bringup_interface, + create_static_routes, + create_prefix_lists, + create_bgp_community_lists, create_interface_in_kernel, - check_router_status, verify_cli_json, - get_frr_ipv6_linklocal, verify_fib_routes + check_router_status, + verify_cli_json, + get_frr_ipv6_linklocal, + verify_fib_routes, ) from lib.topolog import logger from lib.bgp import ( - verify_bgp_convergence, create_router_bgp, - clear_bgp, verify_bgp_community, verify_bgp_rib + verify_bgp_convergence, + create_router_bgp, + clear_bgp, + verify_bgp_community, + verify_bgp_rib, ) from lib.topojson import build_topo_from_json, build_config_from_json @@ -99,10 +111,18 @@ NETWORK4_3 = {"ipv4": "50.50.50.5/32", "ipv6": "50:50::5/128"} NETWORK4_4 = {"ipv4": "50.50.50.50/32", "ipv6": "50:50::50/128"} NEXT_HOP_IP = {"ipv4": "Null0", "ipv6": "Null0"} -LOOPBACK_1 = {"ipv4": "10.0.0.7/24", "ipv6": "fd00:0:0:1::7/64", - "ipv4_mask": "255.255.255.0", "ipv6_mask": None} -LOOPBACK_2 = {"ipv4": "10.0.0.16/24", "ipv6": "fd00:0:0:3::5/64", - "ipv4_mask": "255.255.255.0", "ipv6_mask": None} +LOOPBACK_1 = { + "ipv4": "10.0.0.7/24", + "ipv6": "fd00:0:0:1::7/64", + "ipv4_mask": "255.255.255.0", + "ipv6_mask": None, +} +LOOPBACK_2 = { + "ipv4": "10.0.0.16/24", + "ipv6": "fd00:0:0:3::5/64", + "ipv4_mask": "255.255.255.0", + "ipv6_mask": None, +} PREFERRED_NEXT_HOP = "global" @@ -144,10 +164,11 @@ def setup_module(mod): start_topology(tgen) # Run these tests for kernel version 4.19 or above - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('BGP vrf dynamic route leak tests will not run ' - '(have kernel "{}", but it requires >= 4.19)'.\ - format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + "BGP vrf dynamic route leak tests will not run " + '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) + ) pytest.skip(error_msg) # Creating configuration from JSON @@ -158,8 +179,9 @@ def setup_module(mod): ADDR_TYPES = check_address_types() BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) - assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}". \ - format(BGP_CONVERGENCE) + assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( + BGP_CONVERGENCE + ) logger.info("Running setup_module() done") @@ -174,16 +196,19 @@ def teardown_module(): # Stop toplogy and Remove tmp files tgen.stop_topology() - logger.info("Testsuite end time: {}". - format(time.asctime(time.localtime(time.time())))) + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) logger.info("=" * 40) + ##################################################### # # Local APIs # ##################################################### + def disable_route_map_to_prefer_global_next_hop(tgen, topo): """ This API is to remove prefer global route-map applied on neighbors @@ -202,8 +227,7 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): logger.info("Remove prefer-global rmap applied on neighbors") input_dict = { "r1": { - "bgp": - [ + "bgp": [ { "local_as": "100", "vrf": "ISR", @@ -214,18 +238,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r2": { "dest_link": { "r1-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } + }, }, { "local_as": "100", @@ -236,18 +262,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r3": { "dest_link": { "r1-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } + }, }, { "local_as": "100", @@ -258,24 +286,25 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r4": { "dest_link": { "r1-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } - } + }, + }, ] }, "r2": { - "bgp": - [ + "bgp": [ { "local_as": "100", "vrf": "ISR", @@ -286,18 +315,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r1": { "dest_link": { "r2-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } + }, }, { "local_as": "100", @@ -308,18 +339,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r3": { "dest_link": { "r2-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } + }, }, { "local_as": "100", @@ -330,24 +363,25 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r4": { "dest_link": { "r2-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } - } + }, + }, ] }, "r3": { - "bgp": - [ + "bgp": [ { "local_as": "300", "address_family": { @@ -357,18 +391,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r1": { "dest_link": { "r3-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } + }, }, { "local_as": "300", @@ -379,24 +415,25 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r2": { "dest_link": { "r3-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } - } + }, + }, ] }, "r4": { - "bgp": - [ + "bgp": [ { "local_as": "400", "address_family": { @@ -406,18 +443,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r1": { "dest_link": { "r4-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } + }, }, { "local_as": "400", @@ -428,26 +467,27 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): "r2": { "dest_link": { "r4-link1": { - "route_maps": [{ - "name": "rmap_global", - "direction": "in", - "delete": True - }] + "route_maps": [ + { + "name": "rmap_global", + "direction": "in", + "delete": True, + } + ] } } } } } } - } - } + }, + }, ] - } + }, } result = create_router_bgp(tgen, topo, input_dict) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) return True @@ -458,6 +498,7 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): # ##################################################### + def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): """ TC5_FUNC_5: @@ -475,10 +516,11 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): for addr_type in ADDR_TYPES: - step("Redistribute configured static routes into BGP process" - " on R1 and R3/R4") + step( + "Redistribute configured static routes into BGP process" " on R1 and R3/R4" + ) - input_dict_1={} + input_dict_1 = {} DUT = ["r1", "r3", "r4"] VRFS = ["default", "default", "default"] AS_NUM = [100, 300, 400] @@ -493,47 +535,48 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): "vrf": vrf, "address_family": { addr_type: { - "unicast": { - "redistribute": [{ - "redist_type": "static" - }] - } + "unicast": {"redistribute": [{"redist_type": "static"}]} } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that R1 receives BGP routes from R3 and R4 in " - "vrf default.") + step("Verify that R1 receives BGP routes from R3 and R4 in " "vrf default.") input_routes_r3 = { "r3": { - "static_routes": [{ - "network": [ - NETWORK3_1[addr_type], \ - NETWORK3_2[addr_type], \ - NETWORK3_3[addr_type], \ - NETWORK3_4[addr_type] - ] - }] + "static_routes": [ + { + "network": [ + NETWORK3_1[addr_type], + NETWORK3_2[addr_type], + NETWORK3_3[addr_type], + NETWORK3_4[addr_type], + ] + } + ] } } input_routes_r4 = { "r4": { - "static_routes": [{ - "network": [ - NETWORK4_1[addr_type], \ - NETWORK4_2[addr_type], \ - NETWORK4_3[addr_type], \ - NETWORK4_4[addr_type] - ] - }] + "static_routes": [ + { + "network": [ + NETWORK4_1[addr_type], + NETWORK4_2[addr_type], + NETWORK4_3[addr_type], + NETWORK4_4[addr_type], + ] + } + ] } } @@ -542,20 +585,20 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): for dut, routes in zip(DUT, INPUT_DICT): result = verify_bgp_rib(tgen, addr_type, dut, routes) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) result = verify_fib_routes(tgen, addr_type, dut, routes) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: step("Import from default vrf into vrf ISR on R1") - input_dict_isr={} + input_dict_isr = {} DUT = ["r1", "r2"] VRFS = ["ISR", "ISR"] AS_NUM = [100, 100] @@ -569,50 +612,52 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "default" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "default"}}} + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that default vrf's imported routes are installed " - "in RIB/FIB of vrf ISR on R1:") + step( + "Verify that default vrf's imported routes are installed " + "in RIB/FIB of vrf ISR on R1:" + ) input_routes_r3 = { "r3": { - "static_routes": [{ - "network": [ - NETWORK3_1[addr_type], \ - NETWORK3_2[addr_type], \ - NETWORK3_3[addr_type], \ - NETWORK3_4[addr_type] - ], - "vrf": "ISR" - }] + "static_routes": [ + { + "network": [ + NETWORK3_1[addr_type], + NETWORK3_2[addr_type], + NETWORK3_3[addr_type], + NETWORK3_4[addr_type], + ], + "vrf": "ISR", + } + ] } } input_routes_r4 = { "r4": { - "static_routes": [{ - "network": [ - NETWORK4_1[addr_type], \ - NETWORK4_2[addr_type], \ - NETWORK4_3[addr_type], \ - NETWORK4_4[addr_type] - ], - "vrf": "ISR" - }] + "static_routes": [ + { + "network": [ + NETWORK4_1[addr_type], + NETWORK4_2[addr_type], + NETWORK4_3[addr_type], + NETWORK4_4[addr_type], + ], + "vrf": "ISR", + } + ] } } @@ -620,87 +665,101 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): for routes in INPUT_DICT_VRF: result = verify_bgp_rib(tgen, addr_type, "r1", routes) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) - result = verify_fib_routes(tgen, addr_type, "r1", routes) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + result = verify_fib_routes(tgen, addr_type, "r1", routes) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) intf_r2_r1 = topo["routers"]["r2"]["links"]["r1-link1"] for addr_type in ADDR_TYPES: - step("Create a loopback10 interface on R1 with below IP address and " - "associate with vrf ISR:") + step( + "Create a loopback10 interface on R1 with below IP address and " + "associate with vrf ISR:" + ) - create_interface_in_kernel(tgen, "r1", "loopback2", - LOOPBACK_2[addr_type], - "ISR", - LOOPBACK_2["{}_mask".\ - format(addr_type)]) + create_interface_in_kernel( + tgen, + "r1", + "loopback2", + LOOPBACK_2[addr_type], + "ISR", + LOOPBACK_2["{}_mask".format(addr_type)], + ) for addr_type in ADDR_TYPES: - step("On router R1 Change the next-hop of static routes in vrf " - "ISR to LOOPBACK_1") + step( + "On router R1 Change the next-hop of static routes in vrf " + "ISR to LOOPBACK_1" + ) - input_routes_r1= { + input_routes_r1 = { "r1": { - "static_routes":[ + "static_routes": [ { "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]], - "next_hop":"Null0", - "delete": True + "next_hop": "Null0", + "delete": True, } ] } } result = create_static_routes(tgen, input_routes_r1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) - input_routes_r1= { + input_routes_r1 = { "r1": { - "static_routes":[ + "static_routes": [ { "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]], - "next_hop": (intf_r2_r1[addr_type]).split("/")[0] + "next_hop": (intf_r2_r1[addr_type]).split("/")[0], } ] } } result = create_static_routes(tgen, input_routes_r1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that, though R1 originating BGP routes with next-hop" + step( + "Verify that, though R1 originating BGP routes with next-hop" " 24.1.1.2/24::1:2, which is local to R2(but in default vrf)" - ", R2 must receives and install all routes from R1 in vrf ISR.") - step("Verify on R2, that it now rejects 10.10.10.x routes originated " - "from R1. As next-hop IP is local to R2's vrf ISR.") + ", R2 must receives and install all routes from R1 in vrf ISR." + ) + step( + "Verify on R2, that it now rejects 10.10.10.x routes originated " + "from R1. As next-hop IP is local to R2's vrf ISR." + ) - input_routes_r1= { + input_routes_r1 = { "r1": { - "static_routes":[ + "static_routes": [ { "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]], - "vrf": "ISR" + "vrf": "ISR", } ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Routes are still present \n Error {}". \ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( + tc_name, result + ) write_test_footer(tc_name) @@ -722,71 +781,77 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): for addr_type in ADDR_TYPES: - step("Configure route-map to set community attribute for a specific" - "prefix on R1 in vrf ISR") + step( + "Configure route-map to set community attribute for a specific" + "prefix on R1 in vrf ISR" + ) input_dict_pf = { "r1": { "prefix_lists": { addr_type: { - "pflist_ABC_{}".format(addr_type): [{ - "seqid": 10, - "network": NETWORK1_1[addr_type], - "action": "permit" - }] + "pflist_ABC_{}".format(addr_type): [ + { + "seqid": 10, + "network": NETWORK1_1[addr_type], + "action": "permit", + } + ] } } } } result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) input_dict_cl = { "r1": { "bgp_community_lists": [ - { - "community_type": "expanded", - "action": "permit", - "name": "COMM", - "value": "100:100" + { + "community_type": "expanded", + "action": "permit", + "name": "COMM", + "value": "100:100", } ] } } result = create_bgp_community_lists(tgen, input_dict_cl) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: input_dict_rm = { "r1": { "route_maps": { - "rmap_XYZ_{}".format(addr_type): [{ - "action": "permit", - "match": { - addr_type: { - "prefix_lists": - "pflist_ABC_{}".format(addr_type) - } - }, - "set": { - "community": {"num": "100:100"} + "rmap_XYZ_{}".format(addr_type): [ + { + "action": "permit", + "match": { + addr_type: { + "prefix_lists": "pflist_ABC_{}".format(addr_type) + } + }, + "set": {"community": {"num": "100:100"}}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Apply this route-map on R1 to vrf ISR while redistributing the" - " prefixes into BGP") + step( + "Apply this route-map on R1 to vrf ISR while redistributing the" + " prefixes into BGP" + ) - input_dict_1={} + input_dict_1 = {} DUT = ["r1"] VRFS = ["ISR"] AS_NUM = [100] @@ -802,53 +867,58 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "address_family": { addr_type: { "unicast": { - "redistribute": [{ - "redist_type": "static", + "redistribute": [ + { + "redist_type": "static", "attribute": { - "route-map" : "rmap_XYZ_{}".\ - format(addr_type) - } + "route-map": "rmap_XYZ_{}".format(addr_type) + }, } ] } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Configure another route-map for filtering the prefixes based on" - " community attribute while importing into default vrf") + step( + "Configure another route-map for filtering the prefixes based on" + " community attribute while importing into default vrf" + ) input_dict_rm = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [{ - "action": "permit", - "match": { - "community_list": {"id": "COMM"} - }, - "set": { - "community": {"num": "none"} + "rmap_IMP_{}".format(addr_type): [ + { + "action": "permit", + "match": {"community_list": {"id": "COMM"}}, + "set": {"community": {"num": "none"}}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Apply the route-map while Importing vrf ISR's prefixes into " - "default vrf on router R1:") + step( + "Apply the route-map while Importing vrf ISR's prefixes into " + "default vrf on router R1:" + ) - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -862,15 +932,10 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) temp[dut]["bgp"].append( { @@ -884,50 +949,57 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify on R1 that only prefixes with community value 100:100" + step( + "Verify on R1 that only prefixes with community value 100:100" "in vrf ISR are imported to vrf default. While importing, the" - " community value has been stripped off:") + " community value has been stripped off:" + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) - - input_dict_comm = { - "community": "100:100" - } - - result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]], - input_dict_comm, expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error: Commnunity is not stipped off, {}".format( - tc_name, result)) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) + + input_dict_comm = {"community": "100:100"} + + result = verify_bgp_community( + tgen, + addr_type, + dut, + [NETWORK1_1[addr_type]], + input_dict_comm, + expected=False, + ) + assert ( + result is not True + ), "Testcase {} : Failed \n Error: Commnunity is not stipped off, {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: step("Remove/re-add route-map XYZ from redistribution.") - input_dict_1={} + input_dict_1 = {} DUT = ["r1"] VRFS = ["ISR"] AS_NUM = [100] @@ -943,49 +1015,52 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "address_family": { addr_type: { "unicast": { - "redistribute": [{ - "redist_type": "static", - "attribute": { - "route-map" : "rmap_XYZ_{}".\ - format(addr_type) - }, - "delete": True - }] + "redistribute": [ + { + "redist_type": "static", + "attribute": { + "route-map": "rmap_XYZ_{}".format(addr_type) + }, + "delete": True, + } + ] } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that all the routes disappear from vrf default when " + step( + "Verify that all the routes disappear from vrf default when " "route-map is removed from redistribution, and appear again " - "when route-map is re-added to redistribution in vrf ISR.") + "when route-map is re-added to redistribution in vrf ISR." + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error : Routes are still present \n {}".\ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - input_dict_1={} + input_dict_1 = {} DUT = ["r1"] VRFS = ["ISR"] AS_NUM = [100] @@ -1001,45 +1076,45 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "address_family": { addr_type: { "unicast": { - "redistribute": [{ - "redist_type": "static", - "attribute": { - "route-map" : "rmap_XYZ_{}".\ - format(addr_type) + "redistribute": [ + { + "redist_type": "static", + "attribute": { + "route-map": "rmap_XYZ_{}".format(addr_type) + }, } - }] + ] } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: step("Remove/re-add route-map IMP form import statement.") - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -1053,15 +1128,10 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) temp[dut]["bgp"].append( { @@ -1072,43 +1142,44 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "unicast": { "import": { "vrf": "route-map rmap_IMP_{}".format(addr_type), - "delete": True + "delete": True, } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that when route-map IMP is removed all the prefixes of" + step( + "Verify that when route-map IMP is removed all the prefixes of" " vrf ISR are imported to vrf default. However when route-map " "IMP is re-added only 11.11.11.1 and 11:11::1 (with community " - "value) are imported.") + "value) are imported." + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -1122,15 +1193,10 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) temp[dut]["bgp"].append( { @@ -1144,30 +1210,29 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: @@ -1177,165 +1242,178 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request): "r1": { "prefix_lists": { addr_type: { - "pflist_ABC_{}".format(addr_type): [{ - "seqid": 10, - "network": NETWORK1_1[addr_type], - "action": "permit", - "delete": True - }] + "pflist_ABC_{}".format(addr_type): [ + { + "seqid": 10, + "network": NETWORK1_1[addr_type], + "action": "permit", + "delete": True, + } + ] } } } } result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error : Routes are still present \n {}".\ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format( + tc_name, result + ) - input_dict_pf["r1"]["prefix_lists"][addr_type]["pflist_ABC_{}".\ - format(addr_type)][0]["delete"]=False + input_dict_pf["r1"]["prefix_lists"][addr_type][ + "pflist_ABC_{}".format(addr_type) + ][0]["delete"] = False result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) step("Delete/Re-add community-list COMM.") input_dict_cl = { "r1": { "bgp_community_lists": [ - { - "community_type": "expanded", - "action": "permit", - "name": "COMM", - "value": "100:100", - "delete": True + { + "community_type": "expanded", + "action": "permit", + "name": "COMM", + "value": "100:100", + "delete": True, } ] } } result = create_bgp_community_lists(tgen, input_dict_cl) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error : Routes are still present \n {}".\ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format( + tc_name, result + ) - input_dict_cl["r1"]["bgp_community_lists"][0]["delete"]=False + input_dict_cl["r1"]["bgp_community_lists"][0]["delete"] = False result = create_bgp_community_lists(tgen, input_dict_cl) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) step("Delete/Re-add route-map XYZ.") input_dict_rm = { "r1": { "route_maps": { - "rmap_XYZ_{}".format(addr_type): [{ - "action": "permit", - "match": { - addr_type: { - "prefix_lists": - "pflist_ABC_{}".format(addr_type) - } - }, - "set": { - "community": {"num": "100:100"} - }, - "delete": True - }] + "rmap_XYZ_{}".format(addr_type): [ + { + "action": "permit", + "match": { + addr_type: { + "prefix_lists": "pflist_ABC_{}".format(addr_type) + } + }, + "set": {"community": {"num": "100:100"}}, + "delete": True, + } + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error : Routes are still present \n {}".\ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format( + tc_name, result + ) - input_dict_rm["r1"]["route_maps"]["rmap_XYZ_{}".format(addr_type)][0]["delete"]=False + input_dict_rm["r1"]["route_maps"]["rmap_XYZ_{}".format(addr_type)][0][ + "delete" + ] = False result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) step("Delete/Re-add route-map IMP.") input_dict_rm2 = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [{ - "action": "permit", - "match": { - "community_list": {"id": "COMM"} - }, - "set": { - "community": {"num": "none"} - }, - "delete": True - }] + "rmap_IMP_{}".format(addr_type): [ + { + "action": "permit", + "match": {"community_list": {"id": "COMM"}}, + "set": {"community": {"num": "none"}}, + "delete": True, + } + ] } } } result = create_route_maps(tgen, input_dict_rm2) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error : Routes are still present \n {}".\ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format( + tc_name, result + ) - input_dict_rm2["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0]["delete"]=False + input_dict_rm2["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0][ + "delete" + ] = False result = create_route_maps(tgen, input_dict_rm2) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) write_test_footer(tc_name) @@ -1356,71 +1434,77 @@ def test_routemap_operatons_with_dynamic_import_p0(request): for addr_type in ADDR_TYPES: - step("Configure route-map to set community attribute for a specific" - "prefix on R1 in vrf ISR") + step( + "Configure route-map to set community attribute for a specific" + "prefix on R1 in vrf ISR" + ) input_dict_pf = { "r1": { "prefix_lists": { addr_type: { - "pflist_ABC_{}".format(addr_type): [{ - "seqid": 10, - "network": NETWORK1_1[addr_type], - "action": "permit" - }] + "pflist_ABC_{}".format(addr_type): [ + { + "seqid": 10, + "network": NETWORK1_1[addr_type], + "action": "permit", + } + ] } } } } result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) input_dict_cl = { "r1": { "bgp_community_lists": [ - { - "community_type": "expanded", - "action": "permit", - "name": "COMM", - "value": "100:100" + { + "community_type": "expanded", + "action": "permit", + "name": "COMM", + "value": "100:100", } ] } } result = create_bgp_community_lists(tgen, input_dict_cl) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: input_dict_rm = { "r1": { "route_maps": { - "rmap_XYZ_{}".format(addr_type): [{ - "action": "permit", - "match": { - addr_type: { - "prefix_lists": - "pflist_ABC_{}".format(addr_type) - } - }, - "set": { - "community": {"num": "100:100"} + "rmap_XYZ_{}".format(addr_type): [ + { + "action": "permit", + "match": { + addr_type: { + "prefix_lists": "pflist_ABC_{}".format(addr_type) + } + }, + "set": {"community": {"num": "100:100"}}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Apply this route-map on R1 to vrf ISR while redistributing the" - " prefixes into BGP") + step( + "Apply this route-map on R1 to vrf ISR while redistributing the" + " prefixes into BGP" + ) - input_dict_1={} + input_dict_1 = {} DUT = ["r1"] VRFS = ["ISR"] AS_NUM = [100] @@ -1436,53 +1520,58 @@ def test_routemap_operatons_with_dynamic_import_p0(request): "address_family": { addr_type: { "unicast": { - "redistribute": [{ - "redist_type": "static", + "redistribute": [ + { + "redist_type": "static", "attribute": { - "route-map" : "rmap_XYZ_{}".\ - format(addr_type) - } + "route-map": "rmap_XYZ_{}".format(addr_type) + }, } ] } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Configure another route-map for filtering the prefixes based on" - " community attribute while importing into default vrf") + step( + "Configure another route-map for filtering the prefixes based on" + " community attribute while importing into default vrf" + ) input_dict_rm = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [{ - "action": "permit", - "match": { - "community_list": {"id": "COMM"} - }, - "set": { - "community": {"num": "500:500"} + "rmap_IMP_{}".format(addr_type): [ + { + "action": "permit", + "match": {"community_list": {"id": "COMM"}}, + "set": {"community": {"num": "500:500"}}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Apply the route-map while Importing vrf ISR's prefixes into " - "default vrf on router R1:") + step( + "Apply the route-map while Importing vrf ISR's prefixes into " + "default vrf on router R1:" + ) - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -1496,15 +1585,10 @@ def test_routemap_operatons_with_dynamic_import_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) temp[dut]["bgp"].append( { @@ -1518,42 +1602,45 @@ def test_routemap_operatons_with_dynamic_import_p0(request): } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify on R1 that only prefixes with community value 100:100" + step( + "Verify on R1 that only prefixes with community value 100:100" "in vrf ISR are imported to vrf default. While importing, the" - " community value has been stripped off:") + " community value has been stripped off:" + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: step("Applying route-map first followed by import VRF command.") - step("Apply the route-map while Importing vrf ISR's prefixes into " - "default vrf on router R1:") + step( + "Apply the route-map while Importing vrf ISR's prefixes into " + "default vrf on router R1:" + ) - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -1568,15 +1655,11 @@ def test_routemap_operatons_with_dynamic_import_p0(request): "vrf": vrf, "address_family": { addr_type: { - "unicast": { - "import": { - "vrf": "ISR", - "delete": True - } - } + "unicast": {"import": {"vrf": "ISR", "delete": True}} } - } - }) + }, + } + ) temp[dut]["bgp"].append( { @@ -1590,39 +1673,41 @@ def test_routemap_operatons_with_dynamic_import_p0(request): } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that until 'import VRF command' is not configured, " + step( + "Verify that until 'import VRF command' is not configured, " "routes are not imported. After configuring 'import VRF command'" - " repeat step-4 for verification") + " repeat step-4 for verification" + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Error : Routes are still present \n {}".\ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -1636,15 +1721,10 @@ def test_routemap_operatons_with_dynamic_import_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) temp[dut]["bgp"].append( { @@ -1658,37 +1738,35 @@ def test_routemap_operatons_with_dynamic_import_p0(request): } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Delete/re-add import vrf ISR command multiple times in default" - "vrf.") + step("Delete/re-add import vrf ISR command multiple times in default" "vrf.") - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -1703,112 +1781,111 @@ def test_routemap_operatons_with_dynamic_import_p0(request): "vrf": vrf, "address_family": { addr_type: { - "unicast": { - "import": { - "vrf": "ISR", - "delete": True - } - } + "unicast": {"import": {"vrf": "ISR", "delete": True}} } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - step("Verify that when import vrf ISR command is deleted, " - "all routes of vrf ISR disappear from default vrf and " - "when it's re-configured, repeat step-4 for verification.") + step( + "Verify that when import vrf ISR command is deleted, " + "all routes of vrf ISR disappear from default vrf and " + "when it's re-configured, repeat step-4 for verification." + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Routes are still present, Error {}". \ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Routes are still present, Error {}".format( + tc_name, result + ) input_dict_isr["r1"]["bgp"][0]["address_family"][addr_type]["unicast"][ - "import"]["delete"]=False + "import" + ]["delete"] = False result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, ( - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result)) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Delete and re-configure route-map IMP from global config when " - "import and route-maps are applied in a ISR vrf.") + step( + "Delete and re-configure route-map IMP from global config when " + "import and route-maps are applied in a ISR vrf." + ) input_dict_rm = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [{ - "action": "permit", - "match": { - "community_list": {"id": "COMM"} - }, - "set": { - "community": {"num": "500:500"} - }, - "delete": True - }] + "rmap_IMP_{}".format(addr_type): [ + { + "action": "permit", + "match": {"community_list": {"id": "COMM"}}, + "set": {"community": {"num": "500:500"}}, + "delete": True, + } + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) - assert result is not True, ( - "Testcase {} : Failed \n Routes are still present, Error {}". \ - format(tc_name, result)) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) + assert ( + result is not True + ), "Testcase {} : Failed \n Routes are still present, Error {}".format( + tc_name, result + ) - input_dict_rm["r1"]["route_maps"]["rmap_IMP_{}".\ - format(addr_type)][0]["delete"]=False + input_dict_rm["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0][ + "delete" + ] = False result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - input_dict_comm = { - "community": "500:500" - } + input_dict_comm = {"community": "500:500"} - result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]], - input_dict_comm) - assert result is True, ( - "Testcase {} : Failed \n Error: {}".format( - tc_name, result)) + result = verify_bgp_community( + tgen, addr_type, dut, [NETWORK1_1[addr_type]], input_dict_comm + ) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) write_test_footer(tc_name) @@ -1828,21 +1905,21 @@ def test_verify_cli_json_p1(request): check_router_status(tgen) input_dict = { - "r1":{ - "cli": ["show bgp vrf default ipv4 summary", - "show bgp vrf all ipv6 summary", - "show bgp neighbors" + "r1": { + "cli": [ + "show bgp vrf default ipv4 summary", + "show bgp vrf all ipv6 summary", + "show bgp neighbors", ] } } result = verify_cli_json(tgen, input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) write_test_footer(tc_name) -if __name__ == '__main__': +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py index 6c106060b8..9106c163cd 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py @@ -38,8 +38,8 @@ import platform # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) -sys.path.append(os.path.join(CWD, '../lib/')) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) # Required to instantiate the topology builder class. @@ -50,22 +50,31 @@ from lib.topotest import version_cmp from mininet.topo import Topo from lib.common_config import ( - start_topology, write_test_header, check_address_types, + start_topology, + write_test_header, + check_address_types, write_test_footer, - verify_rib, step, create_route_maps, - create_static_routes, stop_router, start_router, + verify_rib, + step, + create_route_maps, + create_static_routes, + stop_router, + start_router, create_prefix_lists, create_bgp_community_lists, check_router_status, get_frr_ipv6_linklocal, - shutdown_bringup_interface + shutdown_bringup_interface, ) from lib.topolog import logger from lib.bgp import ( - verify_bgp_convergence, create_router_bgp, - verify_bgp_community, verify_bgp_attributes, - verify_best_path_as_per_bgp_attribute, verify_bgp_rib + verify_bgp_convergence, + create_router_bgp, + verify_bgp_community, + verify_bgp_attributes, + verify_best_path_as_per_bgp_attribute, + verify_bgp_rib, ) from lib.topojson import build_topo_from_json, build_config_from_json @@ -123,10 +132,11 @@ def setup_module(mod): start_topology(tgen) # Run these tests for kernel version 4.19 or above - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('BGP vrf dynamic route leak tests will not run ' - '(have kernel "{}", but it requires >= 4.19)'.\ - format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + "BGP vrf dynamic route leak tests will not run " + '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) + ) pytest.skip(error_msg) # Creating configuration from JSON @@ -137,8 +147,9 @@ def setup_module(mod): ADDR_TYPES = check_address_types() BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) - assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}". \ - format(BGP_CONVERGENCE) + assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( + BGP_CONVERGENCE + ) logger.info("Running setup_module() done") @@ -153,8 +164,9 @@ def teardown_module(): # Stop toplogy and Remove tmp files tgen.stop_topology() - logger.info("Testsuite end time: {}". - format(time.asctime(time.localtime(time.time())))) + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) logger.info("=" * 40) @@ -164,6 +176,7 @@ def teardown_module(): # ##################################################### + def test_bgp_best_path_with_dynamic_import_p0(request): """ TC6_FUNC_6: @@ -181,10 +194,11 @@ def test_bgp_best_path_with_dynamic_import_p0(request): for addr_type in ADDR_TYPES: - step("Redistribute configured static routes into BGP process" - " on R1/R2 and R3") + step( + "Redistribute configured static routes into BGP process" " on R1/R2 and R3" + ) - input_dict_1={} + input_dict_1 = {} DUT = ["r1", "r2", "r3", "r4"] VRFS = ["ISR", "ISR", "default", "default"] AS_NUM = [100, 100, 300, 400] @@ -199,24 +213,22 @@ def test_bgp_best_path_with_dynamic_import_p0(request): "vrf": vrf, "address_family": { addr_type: { - "unicast": { - "redistribute": [{ - "redist_type": "static" - }] - } + "unicast": {"redistribute": [{"redist_type": "static"}]} } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: step("Import from default vrf into vrf ISR on R1 and R2 as below") - input_dict_vrf={} + input_dict_vrf = {} DUT = ["r1", "r2"] VRFS = ["ISR", "ISR"] AS_NUM = [100, 100] @@ -230,21 +242,17 @@ def test_bgp_best_path_with_dynamic_import_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "default" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "default"}}} + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_vrf) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - input_dict_default={} + input_dict_default = {} DUT = ["r1", "r2"] VRFS = ["default", "default"] AS_NUM = [100, 100] @@ -258,36 +266,28 @@ def test_bgp_best_path_with_dynamic_import_p0(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_default) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - step("Verify ECMP/Next-hop/Imported routes Vs Locally originated " - "routes/eBGP routes vs iBGP routes --already covered in almost" - " all tests") + step( + "Verify ECMP/Next-hop/Imported routes Vs Locally originated " + "routes/eBGP routes vs iBGP routes --already covered in almost" + " all tests" + ) for addr_type in ADDR_TYPES: step("Verify Pre-emption") input_routes_r3 = { - "r3": { - "static_routes": [{ - "network": [ - NETWORK3_3[addr_type] - ] - }] - } + "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]} } intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] @@ -297,30 +297,27 @@ def test_bgp_best_path_with_dynamic_import_p0(request): nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) else: - nh_r3_r1 = topo["routers"]["r3"]["links"]\ - ["r1-link1"][addr_type].split("/")[0] - nh_r4_r1 = topo["routers"]["r4"]["links"]\ - ["r1-link1"][addr_type].split("/")[0] + nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[ + 0 + ] + nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[ + 0 + ] - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3, - next_hop=[nh_r4_r1]) - assert result is True, ( - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result)) + result = verify_bgp_rib( + tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r4_r1] + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) step("Shutdown interface connected to r1 from r4:") - shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, False) + shutdown_bringup_interface(tgen, "r4", intf_r4_r1, False) for addr_type in ADDR_TYPES: input_routes_r3 = { - "r3": { - "static_routes": [{ - "network": [ - NETWORK3_3[addr_type] - ] - }] - } + "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]} } intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] @@ -330,31 +327,28 @@ def test_bgp_best_path_with_dynamic_import_p0(request): nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) else: - nh_r3_r1 = topo["routers"]["r3"]["links"]\ - ["r1-link1"][addr_type].split("/")[0] - nh_r4_r1 = topo["routers"]["r4"]["links"]\ - ["r1-link1"][addr_type].split("/")[0] + nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[ + 0 + ] + nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[ + 0 + ] step("Verify next-hop is changed") - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3, - next_hop=[nh_r3_r1]) - assert result is True, ( - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result)) + result = verify_bgp_rib( + tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1] + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) step("Bringup interface connected to r1 from r4:") - shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, True) + shutdown_bringup_interface(tgen, "r4", intf_r4_r1, True) for addr_type in ADDR_TYPES: input_routes_r3 = { - "r3": { - "static_routes": [{ - "network": [ - NETWORK3_3[addr_type] - ] - }] - } + "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]} } intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] @@ -364,17 +358,20 @@ def test_bgp_best_path_with_dynamic_import_p0(request): nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) else: - nh_r3_r1 = topo["routers"]["r3"]["links"]\ - ["r1-link1"][addr_type].split("/")[0] - nh_r4_r1 = topo["routers"]["r4"]["links"]\ - ["r1-link1"][addr_type].split("/")[0] + nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[ + 0 + ] + nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[ + 0 + ] step("Verify next-hop is not chnaged aftr shutdown:") - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3, - next_hop=[nh_r3_r1]) - assert result is True, ( - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result)) + result = verify_bgp_rib( + tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1] + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) step("Active-Standby scenario(as-path prepend and Local pref)") @@ -386,18 +383,21 @@ def test_bgp_best_path_with_dynamic_import_p0(request): "r1": { "prefix_lists": { addr_type: { - "pf_ls_{}".format(addr_type): [{ - "seqid": 10, - "network": NETWORK3_4[addr_type], - "action": "permit" - }] + "pf_ls_{}".format(addr_type): [ + { + "seqid": 10, + "network": NETWORK3_4[addr_type], + "action": "permit", + } + ] } } } } result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) for addr_type in ADDR_TYPES: @@ -406,57 +406,56 @@ def test_bgp_best_path_with_dynamic_import_p0(request): input_dict_rm = { "r1": { "route_maps": { - "rmap_PATH1_{}".format(addr_type): [{ - "action": "permit", - "seq_id": 10, - "match": { - addr_type: { - "prefix_lists": - "pf_ls_{}".format(addr_type) - } - }, - "set": { - "locPrf": 500 + "rmap_PATH1_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 10, + "match": { + addr_type: { + "prefix_lists": "pf_ls_{}".format(addr_type) + } + }, + "set": {"locPrf": 500}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) step("Create route-map to match prefix-list and set localpref 600") input_dict_rm = { "r1": { "route_maps": { - "rmap_PATH2_{}".format(addr_type): [{ - "action": "permit", - "seq_id": 20, - "match": { - addr_type: { - "prefix_lists": - "pf_ls_{}".format(addr_type) - } - }, - "set": { - "locPrf": 600 + "rmap_PATH2_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 20, + "match": { + addr_type: { + "prefix_lists": "pf_ls_{}".format(addr_type) + } + }, + "set": {"locPrf": 600}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) - input_dict_rma={ + input_dict_rma = { "r1": { - "bgp": - [ + "bgp": [ { "local_as": "100", "address_family": { @@ -466,36 +465,44 @@ def test_bgp_best_path_with_dynamic_import_p0(request): "r3": { "dest_link": { "r1-link1": { - "route_maps": [{ - "name": "rmap_PATH1_{}".\ - format(addr_type), - "direction": "in" - }] + "route_maps": [ + { + "name": "rmap_PATH1_{}".format( + addr_type + ), + "direction": "in", + } + ] } } }, "r4": { "dest_link": { "r1-link1": { - "route_maps": [{ - "name": "rmap_PATH2_{}".\ - format(addr_type), - "direction": "in" - }] + "route_maps": [ + { + "name": "rmap_PATH2_{}".format( + addr_type + ), + "direction": "in", + } + ] } } - } + }, } } } - } + }, } - ]} + ] } + } result = create_router_bgp(tgen, topo, input_dict_rma) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) dut = "r1" attribute = "locPrf" @@ -506,20 +513,18 @@ def test_bgp_best_path_with_dynamic_import_p0(request): input_routes_r3 = { "r3": { - "static_routes": [{ - "network": [ - NETWORK3_3[addr_type], \ - NETWORK3_4[addr_type] - ] - }] + "static_routes": [ + {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]} + ] } } - result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut, - input_routes_r3, - attribute) + result = verify_best_path_as_per_bgp_attribute( + tgen, addr_type, dut, input_routes_r3, attribute + ) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) for addr_type in ADDR_TYPES: @@ -528,26 +533,26 @@ def test_bgp_best_path_with_dynamic_import_p0(request): input_dict_rm = { "r1": { "route_maps": { - "rmap_PATH1_{}".format(addr_type): [{ - "action": "permit", - "seq_id": 10, - "match": { - addr_type: { - "prefix_lists": - "pf_ls_{}".format(addr_type) - } - }, - "set": { - "locPrf": 700 + "rmap_PATH1_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 10, + "match": { + addr_type: { + "prefix_lists": "pf_ls_{}".format(addr_type) + } + }, + "set": {"locPrf": 700}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: @@ -555,20 +560,18 @@ def test_bgp_best_path_with_dynamic_import_p0(request): input_routes_r3 = { "r3": { - "static_routes": [{ - "network": [ - NETWORK3_3[addr_type], \ - NETWORK3_4[addr_type] - ] - }] + "static_routes": [ + {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]} + ] } } - result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut, - input_routes_r3, - attribute) + result = verify_best_path_as_per_bgp_attribute( + tgen, addr_type, dut, input_routes_r3, attribute + ) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) for addr_type in ADDR_TYPES: @@ -577,30 +580,29 @@ def test_bgp_best_path_with_dynamic_import_p0(request): input_dict_rm = { "r1": { "route_maps": { - "rmap_PATH2_{}".format(addr_type): [{ - "action": "permit", - "seq_id": 20, - "match": { - addr_type: { - "prefix_lists": - "pf_ls_{}".format(addr_type) - } - }, - "set": { - "localpref": 700, - "path": { - "as_num": "111", - "as_action": "prepend" - } + "rmap_PATH2_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 20, + "match": { + addr_type: { + "prefix_lists": "pf_ls_{}".format(addr_type) + } + }, + "set": { + "localpref": 700, + "path": {"as_num": "111", "as_action": "prepend"}, + }, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) attribute = "path" @@ -610,20 +612,18 @@ def test_bgp_best_path_with_dynamic_import_p0(request): input_routes_r3 = { "r3": { - "static_routes": [{ - "network": [ - NETWORK3_3[addr_type], \ - NETWORK3_4[addr_type] - ] - }] + "static_routes": [ + {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]} + ] } } - result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut, - input_routes_r3, - attribute) + result = verify_best_path_as_per_bgp_attribute( + tgen, addr_type, dut, input_routes_r3, attribute + ) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) write_test_footer(tc_name) @@ -645,71 +645,77 @@ def test_modify_route_map_match_set_clauses_p1(request): for addr_type in ADDR_TYPES: - step("Configure route-map to set community attribute for a specific" - "prefix on R1 in vrf ISR") + step( + "Configure route-map to set community attribute for a specific" + "prefix on R1 in vrf ISR" + ) input_dict_pf = { "r1": { "prefix_lists": { addr_type: { - "pflist_ABC_{}".format(addr_type): [{ - "seqid": 10, - "network": NETWORK1_1[addr_type], - "action": "permit" - }] + "pflist_ABC_{}".format(addr_type): [ + { + "seqid": 10, + "network": NETWORK1_1[addr_type], + "action": "permit", + } + ] } } } } result = create_prefix_lists(tgen, input_dict_pf) assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result) + tc_name, result + ) input_dict_cl = { "r1": { "bgp_community_lists": [ - { - "community_type": "expanded", - "action": "permit", - "name": "COMM", - "value": "100:100" + { + "community_type": "expanded", + "action": "permit", + "name": "COMM", + "value": "100:100", } ] } } result = create_bgp_community_lists(tgen, input_dict_cl) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: input_dict_rm = { "r1": { "route_maps": { - "rmap_XYZ_{}".format(addr_type): [{ - "action": "permit", - "match": { - addr_type: { - "prefix_lists": - "pflist_ABC_{}".format(addr_type) - } - }, - "set": { - "community": {"num": "100:100"} + "rmap_XYZ_{}".format(addr_type): [ + { + "action": "permit", + "match": { + addr_type: { + "prefix_lists": "pflist_ABC_{}".format(addr_type) + } + }, + "set": {"community": {"num": "100:100"}}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Apply this route-map on R1 to vrf ISR while redistributing the" - " prefixes into BGP") + step( + "Apply this route-map on R1 to vrf ISR while redistributing the" + " prefixes into BGP" + ) - input_dict_1={} + input_dict_1 = {} DUT = ["r1"] VRFS = ["ISR"] AS_NUM = [100] @@ -725,54 +731,59 @@ def test_modify_route_map_match_set_clauses_p1(request): "address_family": { addr_type: { "unicast": { - "redistribute": [{ - "redist_type": "static", + "redistribute": [ + { + "redist_type": "static", "attribute": { - "route-map" : "rmap_XYZ_{}".\ - format(addr_type) - } + "route-map": "rmap_XYZ_{}".format(addr_type) + }, } ] } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_1) - assert result is True, "Testcase {} :Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Configure another route-map for filtering the prefixes based on" - " community attribute while importing into default vrf") + step( + "Configure another route-map for filtering the prefixes based on" + " community attribute while importing into default vrf" + ) input_dict_rm = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [{ - "action": "permit", - "seq_id": 10, - "match": { - "community_list": {"id": "COMM"} - }, - "set": { - "community": {"num": "none"} + "rmap_IMP_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 10, + "match": {"community_list": {"id": "COMM"}}, + "set": {"community": {"num": "none"}}, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Apply the route-map while Importing vrf ISR's prefixes into " - "default vrf on router R1:") + step( + "Apply the route-map while Importing vrf ISR's prefixes into " + "default vrf on router R1:" + ) - input_dict_isr={} + input_dict_isr = {} DUT = ["r1"] VRFS = ["default"] AS_NUM = [100] @@ -786,15 +797,10 @@ def test_modify_route_map_match_set_clauses_p1(request): "local_as": as_num, "vrf": vrf, "address_family": { - addr_type: { - "unicast": { - "import": { - "vrf": "ISR" - } - } - } - } - }) + addr_type: {"unicast": {"import": {"vrf": "ISR"}}} + }, + } + ) temp[dut]["bgp"].append( { @@ -808,34 +814,35 @@ def test_modify_route_map_match_set_clauses_p1(request): } } } - } - }) + }, + } + ) result = create_router_bgp(tgen, topo, input_dict_isr) - assert result is True, "Testcase {} : Failed \n Error: {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify on R1 that only prefixes with community value 100:100" + step( + "Verify on R1 that only prefixes with community value 100:100" "in vrf ISR are imported to vrf default. While importing, the" - " community value has been stripped off:") + " community value has been stripped off:" + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) - assert result is True, \ - "Testcase {} : Failed \n Error {}". \ - format(tc_name, result) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: @@ -844,119 +851,106 @@ def test_modify_route_map_match_set_clauses_p1(request): input_dict_rm = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [{ - "action": "permit", - "seq_id": 10, - "match": { - "community_list": {"id": "COMM"} - }, - "set": { - "large_community": {"num": "100:100:100"}, - "locPrf": 500, - "path": { - "as_num": "100 100", - "as_action": "prepend" - } + "rmap_IMP_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 10, + "match": {"community_list": {"id": "COMM"}}, + "set": { + "large_community": {"num": "100:100:100"}, + "locPrf": 500, + "path": {"as_num": "100 100", "as_action": "prepend"}, + }, } - }] + ] } } } result = create_route_maps(tgen, input_dict_rm) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) for addr_type in ADDR_TYPES: - step("Verify that as we continue adding different attributes " + step( + "Verify that as we continue adding different attributes " "step-by-step in route-map IMP those attributes gets " - "attached to prefixes:") + "attached to prefixes:" + ) input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - input_dict_comm = { - "largeCommunity": "100:100:100" - } + input_dict_comm = {"largeCommunity": "100:100:100"} - result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]], - input_dict_comm) - assert result is True, ( - "Testcase {} : Failed \n Error {}".format( - tc_name, result)) + result = verify_bgp_community( + tgen, addr_type, dut, [NETWORK1_1[addr_type]], input_dict_comm + ) + assert result is True, "Testcase {} : Failed \n Error {}".format( + tc_name, result + ) input_rmap = { "r1": { "route_maps": { - "rmap_IMP_{}".format(addr_type): [ - { - "set": { - "locPrf": 500 - } - } - ] + "rmap_IMP_{}".format(addr_type): [{"set": {"locPrf": 500}}] } } } - result = verify_bgp_attributes(tgen, addr_type, "r1",\ - [NETWORK1_1[addr_type]], - rmap_name="rmap_IMP_{}".format(addr_type),\ - input_dict=input_rmap) - assert result is True, "Testcase : Failed \n Error: {}".format( - tc_name, result) + result = verify_bgp_attributes( + tgen, + addr_type, + "r1", + [NETWORK1_1[addr_type]], + rmap_name="rmap_IMP_{}".format(addr_type), + input_dict=input_rmap, + ) + assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result) - step("Change community-list to match a different value then " - "100:100.") + step("Change community-list to match a different value then " "100:100.") input_dict_cl = { "r1": { "bgp_community_lists": [ - { - "community_type": "expanded", - "action": "permit", - "name": "COMM", - "value": "100:100", - "delete": True + { + "community_type": "expanded", + "action": "permit", + "name": "COMM", + "value": "100:100", + "delete": True, } ] } } result = create_bgp_community_lists(tgen, input_dict_cl) - assert result is True, 'Testcase {} : Failed \n Error: {}'.format( - tc_name, result) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: input_routes_r1 = { "r1": { - "static_routes": [{ - "network": [ - NETWORK1_1[addr_type] - ], - "vrf": "default" - }] + "static_routes": [ + {"network": [NETWORK1_1[addr_type]], "vrf": "default"} + ] } } - result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, - expected=False) + result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) assert result is not True, ( "Testcase {} : Failed \n Error : Routes are still " - "present {}".\ - format(tc_name, result)) + "present {}".format(tc_name, result) + ) write_test_footer(tc_name) -if __name__ == '__main__': +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py index e913105e43..46e21857c8 100644 --- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py +++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py @@ -71,7 +71,7 @@ from lib.common_config import ( configure_brctl, apply_raw_config, verify_vrf_vni, - verify_cli_json + verify_cli_json, ) from lib.topolog import logger @@ -81,7 +81,7 @@ from lib.bgp import ( clear_bgp, verify_best_path_as_per_bgp_attribute, verify_attributes_for_evpn_routes, - verify_evpn_routes + verify_evpn_routes, ) from lib.topojson import build_topo_from_json, build_config_from_json @@ -177,9 +177,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('EVPN tests will not run (have kernel "{}", ' - 'but it requires >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'EVPN tests will not run (have kernel "{}", ' + "but it requires >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) global BGP_CONVERGENCE @@ -389,9 +391,9 @@ def test_verify_overlay_index_p1(request): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -463,7 +465,7 @@ def test_evpn_cli_json_available_p1(request): "cli": [ "show evpn vni detail", "show bgp l2vpn evpn all overlay", - "show bgp l2vpn evpn vni" + "show bgp l2vpn evpn vni", ] } } @@ -516,9 +518,9 @@ def test_RT_verification_auto_p0(request): "network": NETWORK4_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py index c1eb7d68bb..87f391ae49 100644 --- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py +++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py @@ -77,7 +77,7 @@ from lib.common_config import ( configure_vxlan, configure_brctl, verify_vrf_vni, - create_interface_in_kernel + create_interface_in_kernel, ) from lib.topolog import logger @@ -87,7 +87,7 @@ from lib.bgp import ( clear_bgp, verify_best_path_as_per_bgp_attribute, verify_attributes_for_evpn_routes, - verify_evpn_routes + verify_evpn_routes, ) from lib.topojson import build_topo_from_json, build_config_from_json @@ -179,9 +179,11 @@ def setup_module(mod): # Creating configuration from JSON build_config_from_json(tgen, topo) - if version_cmp(platform.release(), '4.19') < 0: - error_msg = ('EVPN tests will not run (have kernel "{}", ' - 'but it requires >= 4.19)'.format(platform.release())) + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'EVPN tests will not run (have kernel "{}", ' + "but it requires >= 4.19)".format(platform.release()) + ) pytest.skip(error_msg) global BGP_CONVERGENCE @@ -387,9 +389,9 @@ def test_RD_verification_manual_and_auto_p0(request): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -453,7 +455,7 @@ def test_RD_verification_manual_and_auto_p0(request): "vrf": "RED", "address_family": { "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}} - } + }, } ] } @@ -620,9 +622,9 @@ def test_RT_verification_manual_p0(request): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -652,7 +654,7 @@ def test_RT_verification_manual_p0(request): "l2vpn": { "evpn": {"route-target": {"export": [{"value": "100:100"}]}} }, - } + }, } ] } @@ -995,9 +997,9 @@ def test_active_standby_evpn_implementation_p1(request): "network": NETWORK1_4[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -1249,9 +1251,9 @@ def test_evpn_routes_from_VNFs_p1(request): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -1382,9 +1384,9 @@ def test_evpn_routes_from_VNFs_p1(request): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -1617,9 +1619,9 @@ def test_route_map_operations_for_evpn_address_family_p1(request, attribute): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) @@ -1811,9 +1813,9 @@ def test_bgp_attributes_for_evpn_address_family_p1(request, attribute): "network": NETWORK3_1[addr_type], "next_hop": NEXT_HOP_IP[addr_type], "vrf": "GREEN", - } + }, ] - } + }, } result = create_static_routes(tgen, input_dict_1) diff --git a/tests/topotests/isis-sr-topo1/rt1/isisd.conf b/tests/topotests/isis-sr-topo1/rt1/isisd.conf index 26ec4eb261..f441527597 100644 --- a/tests/topotests/isis-sr-topo1/rt1/isisd.conf +++ b/tests/topotests/isis-sr-topo1/rt1/isisd.conf @@ -19,9 +19,9 @@ interface eth-sw1 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0001.00 is-type level-1 - lsp-gen-interval 2 topology ipv6-unicast segment-routing on segment-routing global-block 16000 23999 diff --git a/tests/topotests/isis-sr-topo1/rt1/step1/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step1/show_ip_route.ref index 6b4a59011a..53bf8cb445 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step1/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step1/show_ip_route.ref @@ -290,5 +290,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step1/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step1/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step1/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step1/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step1/show_mpls_table.ref index 773f5e3d43..5b1950d8cb 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step1/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step1/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref index 69dcc91b1d..26f0dffa7a 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 2, "hold-timer": 9, "neighbor-priority": 64, "state": "up" @@ -19,7 +18,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 2, "hold-timer": 9, "neighbor-priority": 64, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt1/step10/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step10/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step10/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step10/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step10/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step10/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step10/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step10/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step10/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step10/show_mpls_table.ref index 25a48c2bfc..7e6c72627a 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step10/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step10/show_mpls_table.ref @@ -152,5 +152,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step2/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step2/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step2/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step2/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step2/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step2/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step2/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step2/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step2/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step2/show_mpls_table.ref index 773f5e3d43..5b1950d8cb 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step2/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step2/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step3/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step3/show_ip_route.ref index 05a8498693..71f9ebddfb 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step3/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step3/show_ip_route.ref @@ -250,5 +250,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step3/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step3/show_ipv6_route.ref index d50952c6c4..304c0a475b 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step3/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step3/show_ipv6_route.ref @@ -86,5 +86,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step3/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step3/show_mpls_table.ref index 73f517a6e5..94b3cb6d1a 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step3/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step3/show_mpls_table.ref @@ -94,5 +94,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step4/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step4/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step4/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step4/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step4/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step4/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step4/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step4/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step4/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step4/show_mpls_table.ref index ac39920ee5..6500a47fbf 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step4/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step4/show_mpls_table.ref @@ -101,15 +101,15 @@ "nexthops":[ { "type":"SR (IS-IS)", - "outLabel":16060, + "outLabel":17060, "installed":true, - "nexthop":"10.0.1.2" + "nexthop":"10.0.1.3" }, { "type":"SR (IS-IS)", - "outLabel":17060, + "outLabel":16060, "installed":true, - "nexthop":"10.0.1.3" + "nexthop":"10.0.1.2" } ] }, @@ -130,5 +130,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step5/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step5/show_ip_route.ref index 59213686f2..16d9358468 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step5/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step5/show_ip_route.ref @@ -277,5 +277,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step5/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step5/show_ipv6_route.ref index cdfae284ba..f2093a3fc0 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step5/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step5/show_ipv6_route.ref @@ -111,5 +111,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step5/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step5/show_mpls_table.ref index 73f517a6e5..94b3cb6d1a 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step5/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step5/show_mpls_table.ref @@ -94,5 +94,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step6/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step6/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step6/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step6/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step6/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step6/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step6/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step6/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step6/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step6/show_mpls_table.ref index 773f5e3d43..5b1950d8cb 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step6/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step6/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step7/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step7/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step7/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step7/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step7/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step7/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step7/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step7/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step7/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step7/show_mpls_table.ref index 773f5e3d43..5b1950d8cb 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step7/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step7/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step8/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step8/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step8/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step8/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step8/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step8/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step8/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step8/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step8/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step8/show_mpls_table.ref index 773f5e3d43..5b1950d8cb 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step8/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step8/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt1/step9/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt1/step9/show_ip_route.ref index 6b34d5e4ff..c712538c00 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step9/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step9/show_ip_route.ref @@ -283,5 +283,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step9/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt1/step9/show_ipv6_route.ref index c507688f5b..0b39584717 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step9/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step9/show_ipv6_route.ref @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 17101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt1/step9/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt1/step9/show_mpls_table.ref index 25a48c2bfc..7e6c72627a 100644 --- a/tests/topotests/isis-sr-topo1/rt1/step9/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt1/step9/show_mpls_table.ref @@ -152,5 +152,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":17101, + "installed":true, + "interface":"eth-sw1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt2/isisd.conf b/tests/topotests/isis-sr-topo1/rt2/isisd.conf index 8704a28b6c..796b6ed32c 100644 --- a/tests/topotests/isis-sr-topo1/rt2/isisd.conf +++ b/tests/topotests/isis-sr-topo1/rt2/isisd.conf @@ -30,9 +30,9 @@ interface eth-rt4-2 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0002.00 is-type level-1 - lsp-gen-interval 2 topology ipv6-unicast segment-routing on segment-routing global-block 16000 23999 diff --git a/tests/topotests/isis-sr-topo1/rt2/step1/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step1/show_ip_route.ref index be037aba8b..109b94f7a1 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step1/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step1/show_ip_route.ref @@ -343,5 +343,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step1/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step1/show_ipv6_route.ref index a888198ac8..eae700ee47 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step1/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step1/show_ipv6_route.ref @@ -144,5 +144,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step1/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step1/show_mpls_table.ref index 42fde2d77f..a32cd1d1bf 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step1/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step1/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -111,9 +111,9 @@ "nexthops":[ { "type":"SR (IS-IS)", - "outLabel":17050, + "outLabel":16050, "installed":true, - "nexthop":"10.0.1.3" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", @@ -123,9 +123,9 @@ }, { "type":"SR (IS-IS)", - "outLabel":16050, + "outLabel":17050, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.1.3" } ] }, @@ -135,9 +135,9 @@ "nexthops":[ { "type":"SR (IS-IS)", - "outLabel":17051, + "outLabel":16051, "installed":true, - "interface":"eth-sw1" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", @@ -147,9 +147,9 @@ }, { "type":"SR (IS-IS)", - "outLabel":16051, + "outLabel":17051, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-sw1" } ] }, @@ -161,13 +161,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -179,13 +179,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref index be018fd59f..07f43e5999 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0004", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0004", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 2, "hold-timer": 9, "neighbor-priority": 64, "state": "up" @@ -59,7 +56,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0001", - "neighbor-extended-circuit-id": 2, "hold-timer": 9, "neighbor-priority": 64, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt2/step10/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step10/show_ip_route.ref index 33fbdba28f..387d3b43d7 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step10/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step10/show_ip_route.ref @@ -134,6 +134,27 @@ ] } ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1" + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], "10.0.3.0\/24":[ { "prefix":"10.0.3.0\/24", @@ -255,5 +276,28 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step10/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step10/show_ipv6_route.ref index 19837bc700..355436cbfc 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step10/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step10/show_ipv6_route.ref @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step10/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step10/show_mpls_table.ref index 29ec55a589..4cbdb9fda9 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step10/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step10/show_mpls_table.ref @@ -89,13 +89,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -143,13 +143,43 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step2/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step2/show_ip_route.ref index a110c51077..159392f7f7 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step2/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step2/show_ip_route.ref @@ -316,5 +316,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step2/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step2/show_ipv6_route.ref index cb426897ce..e9f63849d8 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step2/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step2/show_ipv6_route.ref @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step2/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step2/show_mpls_table.ref index 118ec89b5c..0692553808 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step2/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step2/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -137,13 +137,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -155,13 +155,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step3/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step3/show_ip_route.ref index d31affeb59..16f49ffe46 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step3/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step3/show_ip_route.ref @@ -269,5 +269,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step3/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step3/show_ipv6_route.ref index d92df1918c..bde83c30d0 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step3/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step3/show_ipv6_route.ref @@ -95,5 +95,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step3/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step3/show_mpls_table.ref index f1e18be26b..cbb0d5c695 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step3/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step3/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -128,5 +128,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt2/step4/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step4/show_ip_route.ref index a110c51077..159392f7f7 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step4/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step4/show_ip_route.ref @@ -316,5 +316,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step4/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step4/show_ipv6_route.ref index cb426897ce..e9f63849d8 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step4/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step4/show_ipv6_route.ref @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step4/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step4/show_mpls_table.ref index 118ec89b5c..0692553808 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step4/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step4/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -137,13 +137,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -155,13 +155,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step5/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step5/show_ip_route.ref index f378e41d8d..fbfcce10aa 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step5/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step5/show_ip_route.ref @@ -310,5 +310,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step5/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step5/show_ipv6_route.ref index d63e7ceba5..f747a96518 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step5/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step5/show_ipv6_route.ref @@ -120,5 +120,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step5/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step5/show_mpls_table.ref index f1e18be26b..cbb0d5c695 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step5/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step5/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -128,5 +128,41 @@ "interface":"eth-sw1" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt2/step6/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step6/show_ip_route.ref index a110c51077..159392f7f7 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step6/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step6/show_ip_route.ref @@ -316,5 +316,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step6/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step6/show_ipv6_route.ref index cb426897ce..e9f63849d8 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step6/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step6/show_ipv6_route.ref @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step6/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step6/show_mpls_table.ref index 118ec89b5c..0692553808 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step6/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step6/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -137,13 +137,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -155,13 +155,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step7/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step7/show_ip_route.ref index a9b086a248..09ab6d4f8a 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step7/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step7/show_ip_route.ref @@ -313,5 +313,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step7/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step7/show_ipv6_route.ref index 1c61f91451..851275fbf7 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step7/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step7/show_ipv6_route.ref @@ -123,5 +123,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step7/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step7/show_mpls_table.ref index 0f0d24bbfb..87946aa7b9 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step7/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step7/show_mpls_table.ref @@ -53,13 +53,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -71,13 +71,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -113,13 +113,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -131,13 +131,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step8/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step8/show_ip_route.ref index a110c51077..159392f7f7 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step8/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step8/show_ip_route.ref @@ -316,5 +316,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step8/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step8/show_ipv6_route.ref index cb426897ce..e9f63849d8 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step8/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step8/show_ipv6_route.ref @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step8/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step8/show_mpls_table.ref index 118ec89b5c..0692553808 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step8/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step8/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -137,13 +137,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -155,13 +155,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step9/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt2/step9/show_ip_route.ref index 2e4c20257f..fc82ada7e3 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step9/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step9/show_ip_route.ref @@ -316,5 +316,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step9/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt2/step9/show_ipv6_route.ref index 19837bc700..355436cbfc 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step9/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step9/show_ipv6_route.ref @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt2/step9/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt2/step9/show_mpls_table.ref index 7c910fc6f6..05201724f4 100644 --- a/tests/topotests/isis-sr-topo1/rt2/step9/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt2/step9/show_mpls_table.ref @@ -77,13 +77,13 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -95,13 +95,13 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" } ] }, @@ -137,13 +137,13 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.2.4" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4" } ] }, @@ -155,13 +155,49 @@ "type":"SR (IS-IS)", "outLabel":16061, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16061, "installed":true, + "interface":"eth-rt4-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4-2" } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/isisd.conf b/tests/topotests/isis-sr-topo1/rt3/isisd.conf index 5a0add22a9..cc2aa1782b 100644 --- a/tests/topotests/isis-sr-topo1/rt3/isisd.conf +++ b/tests/topotests/isis-sr-topo1/rt3/isisd.conf @@ -30,9 +30,9 @@ interface eth-rt5-2 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0003.00 is-type level-1 - lsp-gen-interval 2 topology ipv6-unicast segment-routing on segment-routing global-block 17000 24999 diff --git a/tests/topotests/isis-sr-topo1/rt3/step1/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step1/show_ip_route.ref index 8d4fbec4b5..241f768859 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step1/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step1/show_ip_route.ref @@ -343,5 +343,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step1/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step1/show_ipv6_route.ref index 4e4961eaf0..dd78c7d318 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step1/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step1/show_ipv6_route.ref @@ -56,7 +56,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-sw1", "active":true, "labels":[ 16041 @@ -65,7 +65,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-sw1", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16041 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16041 @@ -96,7 +96,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -105,7 +105,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -127,7 +127,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -136,7 +136,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -144,5 +144,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step1/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step1/show_mpls_table.ref index b7bdc3e4af..8c6fca7b57 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step1/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step1/show_mpls_table.ref @@ -77,19 +77,19 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.1.2" + "nexthop":"10.0.5.5" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.5.5" + "nexthop":"10.0.4.5" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.4.5" + "nexthop":"10.0.1.2" } ] }, @@ -101,19 +101,19 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-sw1" + "interface":"eth-rt5-2" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt5-2" + "interface":"eth-rt5-1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt5-1" + "interface":"eth-sw1" } ] }, @@ -188,5 +188,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref index 82069cec48..7fa6f5cf47 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0005", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0005", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0001", - "neighbor-extended-circuit-id": 2, "hold-timer": 9, "neighbor-priority": 64, "state": "up" @@ -59,7 +56,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 2, "hold-timer": 9, "neighbor-priority": 64, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt3/step10/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step10/show_ip_route.ref index 9522b141b0..40a98ab7c6 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step10/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step10/show_ip_route.ref @@ -323,5 +323,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step10/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step10/show_ipv6_route.ref index fb630bc68f..1fb50407bd 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step10/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step10/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,7 +109,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -118,7 +118,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step10/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step10/show_mpls_table.ref index 4aec3b6904..44ddc4bc14 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step10/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step10/show_mpls_table.ref @@ -164,5 +164,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step2/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step2/show_ip_route.ref index 46ebeb8ab9..55d8213c4e 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step2/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step2/show_ip_route.ref @@ -323,5 +323,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step2/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step2/show_ipv6_route.ref index b2c774d493..4f6441e7b9 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step2/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step2/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,7 +109,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -118,7 +118,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step2/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step2/show_mpls_table.ref index a1e64afd67..db8253f83d 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step2/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step2/show_mpls_table.ref @@ -164,5 +164,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step3/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step3/show_ip_route.ref index 738aa17406..ed5cef8a5b 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step3/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step3/show_ip_route.ref @@ -276,5 +276,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step3/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step3/show_ipv6_route.ref index b6423cd2b8..b33058c3bd 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step3/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step3/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -95,5 +95,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step3/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step3/show_mpls_table.ref index 1a2b8728e6..70cccc0f0b 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step3/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step3/show_mpls_table.ref @@ -128,5 +128,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step4/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step4/show_ip_route.ref index 46ebeb8ab9..55d8213c4e 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step4/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step4/show_ip_route.ref @@ -323,5 +323,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step4/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step4/show_ipv6_route.ref index b2c774d493..4f6441e7b9 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step4/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step4/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,7 +109,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -118,7 +118,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step4/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step4/show_mpls_table.ref index a1e64afd67..db8253f83d 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step4/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step4/show_mpls_table.ref @@ -164,5 +164,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step5/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step5/show_ip_route.ref index 489b495bb1..3adcdce58c 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step5/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step5/show_ip_route.ref @@ -317,5 +317,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step5/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step5/show_ipv6_route.ref index 46ee7ba28e..863e26c30e 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step5/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step5/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,16 +109,47 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true }, { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step5/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step5/show_mpls_table.ref index 1a2b8728e6..70cccc0f0b 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step5/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step5/show_mpls_table.ref @@ -128,5 +128,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step6/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step6/show_ip_route.ref index 46ebeb8ab9..55d8213c4e 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step6/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step6/show_ip_route.ref @@ -323,5 +323,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step6/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step6/show_ipv6_route.ref index b2c774d493..4f6441e7b9 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step6/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step6/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,7 +109,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -118,7 +118,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step6/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step6/show_mpls_table.ref index a1e64afd67..db8253f83d 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step6/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step6/show_mpls_table.ref @@ -164,5 +164,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step7/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step7/show_ip_route.ref index 1e8c27c01f..7f6e05f08b 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step7/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step7/show_ip_route.ref @@ -320,5 +320,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step7/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step7/show_ipv6_route.ref index d21700d407..f4770e2ac9 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step7/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step7/show_ipv6_route.ref @@ -75,7 +75,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -84,7 +84,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -106,7 +106,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -115,7 +115,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -123,5 +123,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step7/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step7/show_mpls_table.ref index e97e0d017b..cb49505f55 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step7/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step7/show_mpls_table.ref @@ -140,5 +140,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step8/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step8/show_ip_route.ref index 46ebeb8ab9..55d8213c4e 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step8/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step8/show_ip_route.ref @@ -323,5 +323,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step8/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step8/show_ipv6_route.ref index b2c774d493..4f6441e7b9 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step8/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step8/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,7 +109,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -118,7 +118,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step8/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step8/show_mpls_table.ref index a1e64afd67..db8253f83d 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step8/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step8/show_mpls_table.ref @@ -164,5 +164,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt3/step9/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt3/step9/show_ip_route.ref index 9522b141b0..40a98ab7c6 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step9/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step9/show_ip_route.ref @@ -323,5 +323,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step9/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt3/step9/show_ipv6_route.ref index fb630bc68f..1fb50407bd 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step9/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step9/show_ipv6_route.ref @@ -78,7 +78,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16051 @@ -87,7 +87,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16051 @@ -109,7 +109,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16061 @@ -118,7 +118,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16061 @@ -126,5 +126,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt3/step9/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt3/step9/show_mpls_table.ref index 4aec3b6904..44ddc4bc14 100644 --- a/tests/topotests/isis-sr-topo1/rt3/step9/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt3/step9/show_mpls_table.ref @@ -164,5 +164,41 @@ "interface":"eth-rt5-1" } ] + }, + "17100":{ + "inLabel":17100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.4.5" + } + ] + }, + "17101":{ + "inLabel":17101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5-1" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/isisd.conf b/tests/topotests/isis-sr-topo1/rt4/isisd.conf index 39003b9d7b..3852b1962b 100644 --- a/tests/topotests/isis-sr-topo1/rt4/isisd.conf +++ b/tests/topotests/isis-sr-topo1/rt4/isisd.conf @@ -37,13 +37,15 @@ interface eth-rt6 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0004.00 is-type level-1 - lsp-gen-interval 2 topology ipv6-unicast segment-routing on segment-routing global-block 16000 23999 segment-routing node-msd 8 segment-routing prefix 4.4.4.4/32 index 40 no-php-flag + segment-routing prefix 10.10.10.10/32 index 100 no-php-flag n-flag-clear segment-routing prefix 2001:db8:1000::4/128 index 41 no-php-flag + segment-routing prefix 2001:db8:1000::10/128 index 101 no-php-flag n-flag-clear ! diff --git a/tests/topotests/isis-sr-topo1/rt4/step1/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step1/show_ip_route.ref index f06182b088..493f3ab60d 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step1/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step1/show_ip_route.ref @@ -319,5 +319,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step1/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step1/show_ipv6_route.ref index f5772f2726..217a4a5379 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step1/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step1/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 @@ -92,7 +92,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step1/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step1/show_mpls_table.ref index b7fb69dcde..307403964a 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step1/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step1/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" }, { "type":"SR (IS-IS)", @@ -103,13 +103,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" }, { "type":"SR (IS-IS)", @@ -188,5 +188,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.6.5" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref index 9d7a19e868..2eb64b6fc9 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0005", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -71,7 +68,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0006", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt4/step10/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step10/show_ip_route.ref index d7d42120a0..11bc948319 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step10/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step10/show_ip_route.ref @@ -231,6 +231,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -273,5 +274,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step10/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step10/show_ipv6_route.ref index 235c1facc6..844f6becf9 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step10/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step10/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step10/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step10/show_mpls_table.ref index 86ceaf4883..f275056070 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step10/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step10/show_mpls_table.ref @@ -19,13 +19,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -49,13 +49,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -158,5 +158,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step2/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step2/show_ip_route.ref index 4789f7268f..c2fbdeb30e 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step2/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step2/show_ip_route.ref @@ -289,6 +289,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -331,5 +332,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step2/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step2/show_ipv6_route.ref index 871b303cab..7f823b6896 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step2/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step2/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step2/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step2/show_mpls_table.ref index ff83c374f0..8dd37880d0 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step2/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step2/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step2/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt4/step2/show_yang_interface_isis_adjacencies.ref index 5fb8a361ac..be1e00b8a2 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step2/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step2/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0006", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt4/step3/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step3/show_ip_route.ref index d86562deb9..4dc0dd7cac 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step3/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step3/show_ip_route.ref @@ -262,12 +262,14 @@ "metric":40, "nexthops":[ { + "fib":true, "ip":"10.0.2.2", "afi":"ipv4", "interfaceName":"eth-rt2-1", "active":true }, { + "fib":true, "ip":"10.0.3.2", "afi":"ipv4", "interfaceName":"eth-rt2-2", @@ -276,6 +278,21 @@ ] } ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6" + } + ] + } + ], "10.0.8.0\/24":[ { "prefix":"10.0.8.0\/24", @@ -302,5 +319,33 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":40, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16100 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step3/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step3/show_ipv6_route.ref index c09f584641..34afda1966 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step3/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step3/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 @@ -105,7 +105,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16051 @@ -114,7 +114,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16051 diff --git a/tests/topotests/isis-sr-topo1/rt4/step3/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step3/show_mpls_table.ref index 85c6c055c9..65336d88d1 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step3/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step3/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -137,13 +137,13 @@ "type":"SR (IS-IS)", "outLabel":16050, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16050, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -155,13 +155,42 @@ "type":"SR (IS-IS)", "outLabel":16051, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16051, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" + } + ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.2.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.3.2" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step3/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt4/step3/show_yang_interface_isis_adjacencies.ref index 2a56f54e16..bcade1ca90 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step3/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step3/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0002", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt4/step4/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step4/show_ip_route.ref index 3c7dfda0a3..e930657f8d 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step4/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step4/show_ip_route.ref @@ -289,6 +289,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -331,5 +332,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step4/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step4/show_ipv6_route.ref index 38b51822dd..ca61c6e81f 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step4/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step4/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step4/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step4/show_mpls_table.ref index 4e5638f34f..eb95fa94c9 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step4/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step4/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step5/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step5/show_ip_route.ref index 90f69c06b8..8b0ddd4ee5 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step5/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step5/show_ip_route.ref @@ -283,6 +283,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -325,5 +326,22 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step5/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step5/show_ipv6_route.ref index 04056ed873..94e1fac450 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step5/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step5/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step5/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step5/show_mpls_table.ref index 4df722be4f..cd47cfa3a7 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step5/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step5/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -128,5 +128,16 @@ "installed":true } ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step6/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step6/show_ip_route.ref index 3c7dfda0a3..e930657f8d 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step6/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step6/show_ip_route.ref @@ -289,6 +289,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -331,5 +332,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step6/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step6/show_ipv6_route.ref index 38b51822dd..ca61c6e81f 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step6/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step6/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step6/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step6/show_mpls_table.ref index 4e5638f34f..eb95fa94c9 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step6/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step6/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step7/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step7/show_ip_route.ref index a3ac4ac109..f5ac45504e 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step7/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step7/show_ip_route.ref @@ -283,6 +283,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -325,5 +326,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step7/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step7/show_ipv6_route.ref index c59abbd2f5..1599c88122 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step7/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step7/show_ipv6_route.ref @@ -12,13 +12,13 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true }, { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true } ] @@ -37,7 +37,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -46,7 +46,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -68,7 +68,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -77,7 +77,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step7/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step7/show_mpls_table.ref index 512c057b31..19b0beb164 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step7/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step7/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -140,5 +140,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step8/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step8/show_ip_route.ref index 3c7dfda0a3..e930657f8d 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step8/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step8/show_ip_route.ref @@ -289,6 +289,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -331,5 +332,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step8/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step8/show_ipv6_route.ref index 38b51822dd..ca61c6e81f 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step8/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step8/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step8/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step8/show_mpls_table.ref index 4e5638f34f..eb95fa94c9 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step8/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step8/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/step9/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt4/step9/show_ip_route.ref index 73598e4605..a2b939a418 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step9/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step9/show_ip_route.ref @@ -289,6 +289,7 @@ "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.7.6", "afi":"ipv4", "interfaceName":"eth-rt6", @@ -331,5 +332,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt4/step9/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt4/step9/show_ipv6_route.ref index 235c1facc6..844f6becf9 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step9/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step9/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16011 @@ -43,7 +43,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16021 @@ -52,7 +52,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16021 @@ -74,7 +74,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -83,7 +83,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis-sr-topo1/rt4/step9/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt4/step9/show_mpls_table.ref index 5cdd99e425..5805bf3556 100644 --- a/tests/topotests/isis-sr-topo1/rt4/step9/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt4/step9/show_mpls_table.ref @@ -7,13 +7,13 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -25,13 +25,13 @@ "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16011, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -43,13 +43,13 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -61,13 +61,13 @@ "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16021, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -79,13 +79,13 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.2.2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.3.2" } ] }, @@ -97,13 +97,13 @@ "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-2" + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16031, "installed":true, - "interface":"eth-rt2-1" + "interface":"eth-rt2-2" } ] }, @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.7.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt4/zebra.conf b/tests/topotests/isis-sr-topo1/rt4/zebra.conf index 4945897e9d..5889901c56 100644 --- a/tests/topotests/isis-sr-topo1/rt4/zebra.conf +++ b/tests/topotests/isis-sr-topo1/rt4/zebra.conf @@ -8,7 +8,9 @@ debug zebra mpls ! interface lo ip address 4.4.4.4/32 + ip address 10.10.10.10/32 ipv6 address 2001:db8:1000::4/128 + ipv6 address 2001:db8:1000::10/128 ! interface eth-rt2-1 ip address 10.0.2.4/24 diff --git a/tests/topotests/isis-sr-topo1/rt5/isisd.conf b/tests/topotests/isis-sr-topo1/rt5/isisd.conf index e693ca156c..f7beea796c 100644 --- a/tests/topotests/isis-sr-topo1/rt5/isisd.conf +++ b/tests/topotests/isis-sr-topo1/rt5/isisd.conf @@ -37,13 +37,15 @@ interface eth-rt6 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0005.00 is-type level-1 - lsp-gen-interval 2 topology ipv6-unicast segment-routing on segment-routing global-block 16000 23999 segment-routing node-msd 8 segment-routing prefix 5.5.5.5/32 index 50 no-php-flag + segment-routing prefix 10.10.10.10/32 index 100 no-php-flag n-flag-clear segment-routing prefix 2001:db8:1000::5/128 index 51 no-php-flag + segment-routing prefix 2001:db8:1000::10/128 index 101 no-php-flag n-flag-clear ! diff --git a/tests/topotests/isis-sr-topo1/rt5/step1/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step1/show_ip_route.ref index 8eaf40f236..0497bd8399 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step1/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step1/show_ip_route.ref @@ -319,5 +319,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step1/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step1/show_mpls_table.ref index 9054c9c4af..99d1f773b7 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step1/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step1/show_mpls_table.ref @@ -188,5 +188,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.6.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref index 4a3e626123..1ff8c2cd4e 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0004", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -71,7 +68,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0006", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt5/step10/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step10/show_ip_route.ref index a5a0bacaad..620f5eac67 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step10/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step10/show_ip_route.ref @@ -274,6 +274,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -308,5 +323,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step10/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step10/show_mpls_table.ref index e43ef6671d..7cfea2a329 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step10/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step10/show_mpls_table.ref @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step2/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step2/show_ip_route.ref index 101b811d3b..19cdf9d896 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step2/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step2/show_ip_route.ref @@ -281,6 +281,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -315,5 +330,24 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step2/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step2/show_mpls_table.ref index 660e319a50..08f1635a39 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step2/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step2/show_mpls_table.ref @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step2/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt5/step2/show_yang_interface_isis_adjacencies.ref index ae26b5be99..d9ac0a8d00 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step2/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step2/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0006", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt5/step3/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step3/show_ip_route.ref index dff6c5f7eb..48b5e6491e 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step3/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step3/show_ip_route.ref @@ -254,6 +254,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -280,5 +295,33 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "distance":115, + "metric":40, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 17100 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 17100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step3/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step3/show_mpls_table.ref index 9df3fc9ef6..9980058b12 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step3/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step3/show_mpls_table.ref @@ -164,5 +164,34 @@ "installed":true } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.5.3" + }, + { + "type":"SR (IS-IS)", + "outLabel":17100, + "installed":true, + "nexthop":"10.0.4.3" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step3/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt5/step3/show_yang_interface_isis_adjacencies.ref index 7e62a65ea1..0b8e6ba5b9 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step3/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step3/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt5/step4/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step4/show_ip_route.ref index 6b29ff2d44..156beef0f1 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step4/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step4/show_ip_route.ref @@ -281,6 +281,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -301,17 +316,21 @@ ] } ], - "10.0.8.0\/24":[ + "10.10.10.10\/32":[ { - "prefix":"10.0.8.0\/24", + "prefix":"10.10.10.10\/32", "protocol":"isis", "distance":115, - "metric":20, + "metric":30, "nexthops":[ { "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6" + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step4/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step4/show_mpls_table.ref index 4d13108d7d..a84ed90b25 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step4/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step4/show_mpls_table.ref @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step4/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt5/step4/show_yang_interface_isis_adjacencies.ref index ae26b5be99..d9ac0a8d00 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step4/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step4/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0003", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -51,7 +49,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0006", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt5/step5/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step5/show_ip_route.ref index cadb674ba3..dba5e8d8a2 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step5/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step5/show_ip_route.ref @@ -275,6 +275,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -295,17 +310,19 @@ ] } ], - "10.0.8.0\/24":[ + "10.10.10.10\/32":[ { - "prefix":"10.0.8.0\/24", + "prefix":"10.10.10.10\/32", "protocol":"isis", "distance":115, - "metric":20, + "metric":30, "nexthops":[ { + "fib":true, "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6" + "interfaceName":"eth-rt6", + "active":true } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step5/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step5/show_mpls_table.ref index c60383093f..36c21b041f 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step5/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step5/show_mpls_table.ref @@ -128,5 +128,16 @@ "installed":true } ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step6/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step6/show_ip_route.ref index 6b29ff2d44..156beef0f1 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step6/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step6/show_ip_route.ref @@ -281,6 +281,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -301,17 +316,21 @@ ] } ], - "10.0.8.0\/24":[ + "10.10.10.10\/32":[ { - "prefix":"10.0.8.0\/24", + "prefix":"10.10.10.10\/32", "protocol":"isis", "distance":115, - "metric":20, + "metric":30, "nexthops":[ { "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6" + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step6/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step6/show_mpls_table.ref index 4d13108d7d..a84ed90b25 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step6/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step6/show_mpls_table.ref @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step7/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step7/show_ip_route.ref index 72b89ccf69..ece747bdac 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step7/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step7/show_ip_route.ref @@ -275,6 +275,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -295,17 +310,21 @@ ] } ], - "10.0.8.0\/24":[ + "10.10.10.10\/32":[ { - "prefix":"10.0.8.0\/24", + "prefix":"10.10.10.10\/32", "protocol":"isis", "distance":115, - "metric":20, + "metric":30, "nexthops":[ { "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6" + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step7/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step7/show_mpls_table.ref index 2b1e67ea71..c98da7effd 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step7/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step7/show_mpls_table.ref @@ -140,5 +140,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step8/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step8/show_ip_route.ref index 6b29ff2d44..156beef0f1 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step8/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step8/show_ip_route.ref @@ -281,6 +281,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -301,17 +316,21 @@ ] } ], - "10.0.8.0\/24":[ + "10.10.10.10\/32":[ { - "prefix":"10.0.8.0\/24", + "prefix":"10.10.10.10\/32", "protocol":"isis", "distance":115, - "metric":20, + "metric":30, "nexthops":[ { "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6" + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step8/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step8/show_mpls_table.ref index 4d13108d7d..a84ed90b25 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step8/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step8/show_mpls_table.ref @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/step9/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt5/step9/show_ip_route.ref index cc37894d67..90588c6708 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step9/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step9/show_ip_route.ref @@ -281,6 +281,21 @@ ] } ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], "10.0.7.0\/24":[ { "prefix":"10.0.7.0\/24", @@ -301,17 +316,21 @@ ] } ], - "10.0.8.0\/24":[ + "10.10.10.10\/32":[ { - "prefix":"10.0.8.0\/24", + "prefix":"10.10.10.10\/32", "protocol":"isis", "distance":115, - "metric":20, + "metric":30, "nexthops":[ { "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6" + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 18100 + ] } ] } diff --git a/tests/topotests/isis-sr-topo1/rt5/step9/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt5/step9/show_mpls_table.ref index e43ef6671d..7cfea2a329 100644 --- a/tests/topotests/isis-sr-topo1/rt5/step9/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt5/step9/show_mpls_table.ref @@ -176,5 +176,28 @@ "interface":"eth-rt6" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":18100, + "installed":true, + "nexthop":"10.0.8.6" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt5/zebra.conf b/tests/topotests/isis-sr-topo1/rt5/zebra.conf index 4cfea1a59f..a0c8f2cd7e 100644 --- a/tests/topotests/isis-sr-topo1/rt5/zebra.conf +++ b/tests/topotests/isis-sr-topo1/rt5/zebra.conf @@ -8,7 +8,9 @@ debug zebra mpls ! interface lo ip address 5.5.5.5/32 + ip address 10.10.10.10/32 ipv6 address 2001:db8:1000::5/128 + ipv6 address 2001:db8:1000::10/128 ! interface eth-rt3-1 ip address 10.0.4.5/24 diff --git a/tests/topotests/isis-sr-topo1/rt6/isisd.conf b/tests/topotests/isis-sr-topo1/rt6/isisd.conf index 3b85dbae4e..a29b78f0a4 100644 --- a/tests/topotests/isis-sr-topo1/rt6/isisd.conf +++ b/tests/topotests/isis-sr-topo1/rt6/isisd.conf @@ -25,9 +25,9 @@ interface eth-rt5 isis hello-multiplier 3 ! router isis 1 + lsp-gen-interval 2 net 49.0000.0000.0000.0006.00 is-type level-1 - lsp-gen-interval 2 topology ipv6-unicast segment-routing on segment-routing global-block 16000 23999 diff --git a/tests/topotests/isis-sr-topo1/rt6/step1/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step1/show_ip_route.ref index 324b71f7b8..7b62b0a9c6 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step1/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step1/show_ip_route.ref @@ -287,5 +287,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step1/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step1/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step1/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step1/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step1/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step1/show_mpls_table.ref index 970251fe8a..2c526e74f0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step1/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step1/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-sr-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref index 49c40a471c..734832358f 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref @@ -11,7 +11,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0004", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" @@ -31,7 +30,6 @@ { "neighbor-sys-type": "level-1", "neighbor-sysid": "0000.0000.0005", - "neighbor-extended-circuit-id": 0, "hold-timer": 9, "neighbor-priority": 0, "state": "up" diff --git a/tests/topotests/isis-sr-topo1/rt6/step10/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step10/show_ip_route.ref index 9d0c331ff2..d430ef5a33 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step10/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step10/show_ip_route.ref @@ -280,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step10/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step10/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step10/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step10/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step10/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step10/show_mpls_table.ref index a79406b300..be87ed90a0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step10/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step10/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step2/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step2/show_ip_route.ref index e4df0d846e..4b204dbc4c 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step2/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step2/show_ip_route.ref @@ -280,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step2/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step2/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step2/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step2/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step2/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step2/show_mpls_table.ref index 970251fe8a..2c526e74f0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step2/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step2/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "16100":{ + "inLabel":16100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "16101":{ + "inLabel":16101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step4/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step4/show_ip_route.ref index e4df0d846e..4b204dbc4c 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step4/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step4/show_ip_route.ref @@ -280,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step4/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step4/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step4/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step4/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step4/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step4/show_mpls_table.ref index a79406b300..be87ed90a0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step4/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step4/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step5/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step5/show_ip_route.ref index c200a9f476..4b204dbc4c 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step5/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step5/show_ip_route.ref @@ -14,14 +14,20 @@ "ip":"10.0.7.4", "afi":"ipv4", "interfaceName":"eth-rt4", - "active":true + "active":true, + "labels":[ + 16010 + ] }, { "fib":true, "ip":"10.0.8.5", "afi":"ipv4", "interfaceName":"eth-rt5", - "active":true + "active":true, + "labels":[ + 16010 + ] } ] } @@ -41,7 +47,10 @@ "ip":"10.0.7.4", "afi":"ipv4", "interfaceName":"eth-rt4", - "active":true + "active":true, + "labels":[ + 16020 + ] } ] } @@ -61,7 +70,10 @@ "ip":"10.0.8.5", "afi":"ipv4", "interfaceName":"eth-rt5", - "active":true + "active":true, + "labels":[ + 16030 + ] } ] } @@ -81,7 +93,10 @@ "ip":"10.0.7.4", "afi":"ipv4", "interfaceName":"eth-rt4", - "active":true + "active":true, + "labels":[ + 16040 + ] } ] } @@ -101,7 +116,10 @@ "ip":"10.0.8.5", "afi":"ipv4", "interfaceName":"eth-rt5", - "active":true + "active":true, + "labels":[ + 16050 + ] } ] } @@ -262,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step5/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step5/show_ipv6_route.ref index 2bf4b70be8..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step5/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step5/show_ipv6_route.ref @@ -12,14 +12,20 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", - "active":true + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] }, { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] } ] } @@ -38,7 +44,10 @@ "fib":true, "afi":"ipv6", "interfaceName":"eth-rt4", - "active":true + "active":true, + "labels":[ + 16021 + ] } ] } @@ -57,7 +66,10 @@ "fib":true, "afi":"ipv6", "interfaceName":"eth-rt5", - "active":true + "active":true, + "labels":[ + 16031 + ] } ] } @@ -76,7 +88,10 @@ "fib":true, "afi":"ipv6", "interfaceName":"eth-rt4", - "active":true + "active":true, + "labels":[ + 16041 + ] } ] } @@ -95,7 +110,41 @@ "fib":true, "afi":"ipv6", "interfaceName":"eth-rt5", - "active":true + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step5/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step5/show_mpls_table.ref index 2c63c08510..be87ed90a0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step5/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step5/show_mpls_table.ref @@ -1,2 +1,170 @@ { + "18010":{ + "inLabel":18010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18011":{ + "inLabel":18011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "18020":{ + "inLabel":18020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18021":{ + "inLabel":18021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "18030":{ + "inLabel":18030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.8.5" + } + ] + }, + "18031":{ + "inLabel":18031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "18040":{ + "inLabel":18040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18041":{ + "inLabel":18041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "18050":{ + "inLabel":18050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.8.5" + } + ] + }, + "18051":{ + "inLabel":18051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] + } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step6/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step6/show_ip_route.ref index e4df0d846e..4b204dbc4c 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step6/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step6/show_ip_route.ref @@ -280,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step6/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step6/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step6/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step6/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step6/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step6/show_mpls_table.ref index a79406b300..be87ed90a0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step6/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step6/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step7/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step7/show_ip_route.ref index b21e5db928..1787988207 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step7/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step7/show_ip_route.ref @@ -274,5 +274,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step7/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step7/show_ipv6_route.ref index dfbb1954b8..367d0ed173 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step7/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step7/show_ipv6_route.ref @@ -12,13 +12,13 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true }, { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true } ] @@ -111,5 +111,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step7/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step7/show_mpls_table.ref index 43d771bcbd..b44dda298e 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step7/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step7/show_mpls_table.ref @@ -94,5 +94,41 @@ "interface":"eth-rt5" } ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step8/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step8/show_ip_route.ref index e4df0d846e..4b204dbc4c 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step8/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step8/show_ip_route.ref @@ -280,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step8/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step8/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step8/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step8/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step8/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step8/show_mpls_table.ref index a79406b300..be87ed90a0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step8/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step8/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/rt6/step9/show_ip_route.ref b/tests/topotests/isis-sr-topo1/rt6/step9/show_ip_route.ref index e4df0d846e..4b204dbc4c 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step9/show_ip_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step9/show_ip_route.ref @@ -280,5 +280,38 @@ } ] } + ], + "10.10.10.10\/32":[ + { + "prefix":"10.10.10.10\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16100 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16100 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step9/show_ipv6_route.ref b/tests/topotests/isis-sr-topo1/rt6/step9/show_ipv6_route.ref index eee9dea4d3..834cdfe6ca 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step9/show_ipv6_route.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step9/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -117,5 +117,36 @@ } ] } + ], + "2001:db8:1000::10\/128":[ + { + "prefix":"2001:db8:1000::10\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16101 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16101 + ] + } + ] + } ] } diff --git a/tests/topotests/isis-sr-topo1/rt6/step9/show_mpls_table.ref b/tests/topotests/isis-sr-topo1/rt6/step9/show_mpls_table.ref index a79406b300..be87ed90a0 100644 --- a/tests/topotests/isis-sr-topo1/rt6/step9/show_mpls_table.ref +++ b/tests/topotests/isis-sr-topo1/rt6/step9/show_mpls_table.ref @@ -130,5 +130,41 @@ "interface":"eth-rt5" } ] + }, + "18100":{ + "inLabel":18100, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.8.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16100, + "installed":true, + "nexthop":"10.0.7.4" + } + ] + }, + "18101":{ + "inLabel":18101, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16101, + "installed":true, + "interface":"eth-rt4" + } + ] } } diff --git a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py index d4ebe52bf6..34eb6d90f6 100644 --- a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py +++ b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py @@ -73,7 +73,7 @@ from functools import partial # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) +sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers @@ -84,8 +84,10 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo + class TemplateTopo(Topo): "Test topology builder" + def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) @@ -93,44 +95,45 @@ class TemplateTopo(Topo): # # Define FRR Routers # - for router in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: tgen.add_router(router) # # Define connections # - switch = tgen.add_switch('s1') - switch.add_link(tgen.gears['rt1'], nodeif="eth-sw1") - switch.add_link(tgen.gears['rt2'], nodeif="eth-sw1") - switch.add_link(tgen.gears['rt3'], nodeif="eth-sw1") + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1") + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-1") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-1") - switch = tgen.add_switch('s2') - switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-1") - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-1") + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-2") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-2") - switch = tgen.add_switch('s3') - switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-2") - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-2") + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-1") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-1") - switch = tgen.add_switch('s4') - switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-1") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-1") + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-2") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-2") - switch = tgen.add_switch('s5') - switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-2") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-2") + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4") - switch = tgen.add_switch('s6') - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt5") - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt4") + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4") - switch = tgen.add_switch('s7') - switch.add_link(tgen.gears['rt4'], nodeif="eth-rt6") - switch.add_link(tgen.gears['rt6'], nodeif="eth-rt4") + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5") - switch = tgen.add_switch('s8') - switch.add_link(tgen.gears['rt5'], nodeif="eth-rt6") - switch.add_link(tgen.gears['rt6'], nodeif="eth-rt5") def setup_module(mod): "Sets up the pytest environment" @@ -142,16 +145,15 @@ def setup_module(mod): # For all registered routers, load the zebra configuration file for rname, router in router_list.items(): router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_ISIS, - os.path.join(CWD, '{}/isisd.conf'.format(rname)) + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) tgen.start_router() + def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() @@ -159,22 +161,23 @@ def teardown_module(mod): # This function tears down the whole topology. tgen.stop_topology() + def router_compare_json_output(rname, command, reference): "Compare router JSON output" logger.info('Comparing router "%s" "%s" output', rname, command) tgen = get_topogen() - filename = '{}/{}/{}'.format(CWD, rname, reference) + filename = "{}/{}/{}".format(CWD, rname, reference) expected = json.loads(open(filename).read()) # Run test function until we get an result. Wait at most 60 seconds. - test_func = partial(topotest.router_json_cmp, - tgen.gears[rname], command, expected) + test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) assert diff is None, assertmsg + # # Step 1 # @@ -188,9 +191,13 @@ def test_isis_adjacencies_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step1/show_yang_interface_isis_adjacencies.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step1/show_yang_interface_isis_adjacencies.ref", + ) + def test_rib_ipv4_step1(): logger.info("Test (step 1): verify IPv4 RIB") @@ -200,9 +207,11 @@ def test_rib_ipv4_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step1/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step1/show_ip_route.ref" + ) + def test_rib_ipv6_step1(): logger.info("Test (step 1): verify IPv6 RIB") @@ -212,9 +221,11 @@ def test_rib_ipv6_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step1/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step1/show_ipv6_route.ref" + ) + def test_mpls_lib_step1(): logger.info("Test (step 1): verify MPLS LIB") @@ -224,9 +235,11 @@ def test_mpls_lib_step1(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step1/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step1/show_mpls_table.ref" + ) + # # Step 2 @@ -252,13 +265,21 @@ def test_isis_adjacencies_step2(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Disabling IS-IS on the eth-rt5 interface on rt4') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no ip router isis 1"') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no ipv6 router isis 1"') + logger.info("Disabling IS-IS on the eth-rt5 interface on rt4") + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt5" -c "no ip router isis 1"' + ) + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt5" -c "no ipv6 router isis 1"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step2/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step2/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step2(): logger.info("Test (step 2): verify IPv4 RIB") @@ -268,9 +289,11 @@ def test_rib_ipv4_step2(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step2/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step2/show_ip_route.ref" + ) + def test_rib_ipv6_step2(): logger.info("Test (step 2): verify IPv6 RIB") @@ -280,9 +303,11 @@ def test_rib_ipv6_step2(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step2/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step2/show_ipv6_route.ref" + ) + def test_mpls_lib_step2(): logger.info("Test (step 2): verify MPLS LIB") @@ -292,9 +317,11 @@ def test_mpls_lib_step2(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step2/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step2/show_mpls_table.ref" + ) + # # Step 3 @@ -318,14 +345,18 @@ def test_isis_adjacencies_step3(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Shutting down the eth-rt4 interface on rt6') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "shutdown"') - logger.info('Shutting down the eth-rt5 interface on rt6') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "shutdown"') + logger.info("Shutting down the eth-rt4 interface on rt6") + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "shutdown"') + logger.info("Shutting down the eth-rt5 interface on rt6") + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "shutdown"') + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step3/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step3/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step3(): logger.info("Test (step 3): verify IPv4 RIB") @@ -335,9 +366,11 @@ def test_rib_ipv4_step3(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step3/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step3/show_ip_route.ref" + ) + def test_rib_ipv6_step3(): logger.info("Test (step 3): verify IPv6 RIB") @@ -347,9 +380,11 @@ def test_rib_ipv6_step3(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step3/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step3/show_ipv6_route.ref" + ) + def test_mpls_lib_step3(): logger.info("Test (step 3): verify MPLS LIB") @@ -359,9 +394,11 @@ def test_mpls_lib_step3(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step3/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step3/show_mpls_table.ref" + ) + # # Step 4 @@ -386,16 +423,22 @@ def test_isis_adjacencies_step4(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Bringing up the eth-rt4 interface on rt6') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "no shutdown"') - logger.info('Bringing up the eth-rt5 interface on rt6') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no shutdown"') - logger.info('Changing rt6\'s SRGB') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 18000 25999"') + logger.info("Bringing up the eth-rt4 interface on rt6") + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "no shutdown"') + logger.info("Bringing up the eth-rt5 interface on rt6") + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no shutdown"') + logger.info("Changing rt6's SRGB") + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 18000 25999"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step4/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step4/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step4(): logger.info("Test (step 4): verify IPv4 RIB") @@ -405,9 +448,11 @@ def test_rib_ipv4_step4(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step4/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step4/show_ip_route.ref" + ) + def test_rib_ipv6_step4(): logger.info("Test (step 4): verify IPv6 RIB") @@ -417,9 +462,11 @@ def test_rib_ipv6_step4(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step4/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step4/show_ipv6_route.ref" + ) + def test_mpls_lib_step4(): logger.info("Test (step 4): verify MPLS LIB") @@ -429,9 +476,11 @@ def test_mpls_lib_step4(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step4/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step4/show_mpls_table.ref" + ) + # # Step 5 @@ -453,12 +502,18 @@ def test_isis_adjacencies_step5(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Disabling SR on rt6') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing on"') + logger.info("Disabling SR on rt6") + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no segment-routing on"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step5/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step5/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step5(): logger.info("Test (step 5): verify IPv4 RIB") @@ -468,9 +523,11 @@ def test_rib_ipv4_step5(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step5/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step5/show_ip_route.ref" + ) + def test_rib_ipv6_step5(): logger.info("Test (step 5): verify IPv6 RIB") @@ -480,9 +537,11 @@ def test_rib_ipv6_step5(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step5/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step5/show_ipv6_route.ref" + ) + def test_mpls_lib_step5(): logger.info("Test (step 5): verify MPLS LIB") @@ -492,9 +551,11 @@ def test_mpls_lib_step5(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step5/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step5/show_mpls_table.ref" + ) + # # Step 6 @@ -516,12 +577,16 @@ def test_isis_adjacencies_step6(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Enabling SR on rt6') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing on"') + logger.info("Enabling SR on rt6") + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing on"') + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step6/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step6/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step6(): logger.info("Test (step 6): verify IPv4 RIB") @@ -531,9 +596,11 @@ def test_rib_ipv4_step6(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step6/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step6/show_ip_route.ref" + ) + def test_rib_ipv6_step6(): logger.info("Test (step 6): verify IPv6 RIB") @@ -543,9 +610,11 @@ def test_rib_ipv6_step6(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step6/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step6/show_ipv6_route.ref" + ) + def test_mpls_lib_step6(): logger.info("Test (step 6): verify MPLS LIB") @@ -555,9 +624,11 @@ def test_mpls_lib_step6(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step6/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step6/show_mpls_table.ref" + ) + # # Step 7 @@ -576,13 +647,21 @@ def test_isis_adjacencies_step7(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Deleting rt1\'s Prefix-SIDs') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 1.1.1.1/32 index 10"') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 2001:db8:1000::1/128 index 11"') + logger.info("Deleting rt1's Prefix-SIDs") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 1.1.1.1/32 index 10"' + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 2001:db8:1000::1/128 index 11"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step7/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step7/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step7(): logger.info("Test (step 7): verify IPv4 RIB") @@ -592,9 +671,11 @@ def test_rib_ipv4_step7(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step7/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step7/show_ip_route.ref" + ) + def test_rib_ipv6_step7(): logger.info("Test (step 7): verify IPv6 RIB") @@ -604,9 +685,11 @@ def test_rib_ipv6_step7(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step7/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step7/show_ipv6_route.ref" + ) + def test_mpls_lib_step7(): logger.info("Test (step 7): verify MPLS LIB") @@ -616,9 +699,11 @@ def test_mpls_lib_step7(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step7/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step7/show_mpls_table.ref" + ) + # # Step 8 @@ -637,13 +722,21 @@ def test_isis_adjacencies_step8(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Re-adding rt1\'s Prefix-SIDs') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"') + logger.info("Re-adding rt1's Prefix-SIDs") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"' + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step8/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step8/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step8(): logger.info("Test (step 8): verify IPv4 RIB") @@ -653,9 +746,11 @@ def test_rib_ipv4_step8(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step8/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step8/show_ip_route.ref" + ) + def test_rib_ipv6_step8(): logger.info("Test (step 8): verify IPv6 RIB") @@ -665,9 +760,11 @@ def test_rib_ipv6_step8(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step8/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step8/show_ipv6_route.ref" + ) + def test_mpls_lib_step8(): logger.info("Test (step 8): verify MPLS LIB") @@ -677,9 +774,11 @@ def test_mpls_lib_step8(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step8/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step8/show_mpls_table.ref" + ) + # # Step 9 @@ -700,16 +799,28 @@ def test_isis_adjacencies_step9(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Changing rt1\'s Prefix-SIDs to use the no-php option') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10 no-php-flag"') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11 no-php-flag"') - logger.info('Change rt6\'s Prefix-SIDs to stop using the explicit-null option') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60"') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61"') + logger.info("Changing rt1's Prefix-SIDs to use the no-php option") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10 no-php-flag"' + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11 no-php-flag"' + ) + logger.info("Change rt6's Prefix-SIDs to stop using the explicit-null option") + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60"' + ) + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step9/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step9/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step9(): logger.info("Test (step 9): verify IPv4 RIB") @@ -719,9 +830,11 @@ def test_rib_ipv4_step9(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step9/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step9/show_ip_route.ref" + ) + def test_rib_ipv6_step9(): logger.info("Test (step 9): verify IPv6 RIB") @@ -731,9 +844,11 @@ def test_rib_ipv6_step9(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step9/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step9/show_ipv6_route.ref" + ) + def test_mpls_lib_step9(): logger.info("Test (step 9): verify MPLS LIB") @@ -743,9 +858,11 @@ def test_mpls_lib_step9(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step9/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step9/show_mpls_table.ref" + ) + # # Step 10 @@ -766,12 +883,18 @@ def test_isis_adjacencies_step10(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Removing the IPv4 address from rt4\'s eth-rt2-1 interface') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt2-1" -c "no ip address 10.0.2.4/24"') + logger.info("Removing the IPv4 address from rt4's eth-rt2-1 interface") + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt2-1" -c "no ip address 10.0.2.4/24"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step10/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step10/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step10(): logger.info("Test (step 10): verify IPv4 RIB") @@ -781,9 +904,11 @@ def test_rib_ipv4_step10(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step10/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step10/show_ip_route.ref" + ) + def test_rib_ipv6_step10(): logger.info("Test (step 10): verify IPv6 RIB") @@ -793,9 +918,11 @@ def test_rib_ipv6_step10(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step10/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step10/show_ipv6_route.ref" + ) + def test_mpls_lib_step10(): logger.info("Test (step 10): verify MPLS LIB") @@ -805,9 +932,11 @@ def test_mpls_lib_step10(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step10/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step10/show_mpls_table.ref" + ) + # # Step 11 @@ -826,13 +955,26 @@ def test_isis_invalid_config_step11(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Entering invalid Segment Routing configuration...') - ret = tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10000"') - assert re.search("Configuration failed", ret) is not None, "Invalid SR configuration wasn't rejected" - ret = tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 14999"') - assert re.search("Configuration failed", ret) is not None, "Invalid SR configuration wasn't rejected" - ret = tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 16001"') - assert re.search("Configuration failed", ret) is not None, "Invalid SR configuration wasn't rejected" + logger.info("Entering invalid Segment Routing configuration...") + ret = tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10000"' + ) + assert ( + re.search("Configuration failed", ret) is not None + ), "Invalid SR configuration wasn't rejected" + ret = tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 14999"' + ) + assert ( + re.search("Configuration failed", ret) is not None + ), "Invalid SR configuration wasn't rejected" + ret = tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 16001"' + ) + assert ( + re.search("Configuration failed", ret) is not None + ), "Invalid SR configuration wasn't rejected" + # # Step 12 @@ -851,19 +993,39 @@ def test_isis_adjacencies_step12(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info('Restoring the original network setup') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "ip router isis 1"') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "ipv6 router isis 1"') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 23999"') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"') - tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60 explicit-null"') - tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61 explicit-null"') - tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt2-1" -c "ip address 10.0.2.4/24"') + logger.info("Restoring the original network setup") + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt5" -c "ip router isis 1"' + ) + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt5" -c "ipv6 router isis 1"' + ) + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 23999"' + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"' + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"' + ) + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60 explicit-null"' + ) + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61 explicit-null"' + ) + tgen.net["rt4"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt2-1" -c "ip address 10.0.2.4/24"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "step1/show_yang_interface_isis_adjacencies.ref", + ) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", - "step1/show_yang_interface_isis_adjacencies.ref") def test_rib_ipv4_step12(): logger.info("Test (step 12): verify IPv4 RIB") @@ -873,9 +1035,11 @@ def test_rib_ipv4_step12(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ip route isis json", - "step1/show_ip_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "step1/show_ip_route.ref" + ) + def test_rib_ipv6_step12(): logger.info("Test (step 12): verify IPv6 RIB") @@ -885,9 +1049,11 @@ def test_rib_ipv6_step12(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show ipv6 route isis json", - "step1/show_ipv6_route.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route isis json", "step1/show_ipv6_route.ref" + ) + def test_mpls_lib_step12(): logger.info("Test (step 12): verify MPLS LIB") @@ -897,19 +1063,22 @@ def test_mpls_lib_step12(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: - router_compare_json_output(rname, "show mpls table json", - "step1/show_mpls_table.ref") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", "step1/show_mpls_table.ref" + ) + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): - pytest.skip('Memory leak test/report is disabled') + pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() -if __name__ == '__main__': + +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis-tilfa-topo1/__init__.py b/tests/topotests/isis-tilfa-topo1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/__init__.py diff --git a/tests/topotests/isis-tilfa-topo1/rt1/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt1/isisd.conf new file mode 100644 index 0000000000..a447a2aa5a --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/isisd.conf @@ -0,0 +1,33 @@ +password 1 +hostname rt1 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis sr-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis priority 100 + isis fast-reroute ti-lfa +! +router isis 1 + net 49.0000.0000.0000.0001.00 + is-type level-1 + lsp-gen-interval 2 + topology ipv6-unicast + segment-routing on + segment-routing global-block 16000 23999 + segment-routing node-msd 8 + segment-routing prefix 1.1.1.1/32 index 10 + segment-routing prefix 2001:db8:1000::1/128 index 11 +! diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ip_route.ref new file mode 100644 index 0000000000..92b7437324 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..3232121a0f --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_mpls_table.ref new file mode 100644 index 0000000000..e3ed7c20b2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_mpls_table.ref @@ -0,0 +1,134 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..26f0dffa7a --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,32 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-sw1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 9, + "neighbor-priority": 64, + "state": "up" + }, + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 9, + "neighbor-priority": 64, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..1a9307ddb9 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ip_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step3/show_ip_route.ref 2020-09-25 17:48:05.062911204 -0300 ++++ rt1/step4/show_ip_route.ref 2020-09-25 17:49:01.563647190 -0300 +@@ -60,10 +60,7 @@ + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..f5036aeda8 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step3/show_ipv6_route.ref 2020-09-25 17:48:06.358928078 -0300 ++++ rt1/step4/show_ipv6_route.ref 2020-09-25 17:49:02.791663194 -0300 +@@ -57,10 +57,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16041 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff new file mode 100644 index 0000000000..30c612b544 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff @@ -0,0 +1,33 @@ +--- rt1/step3/show_mpls_table.ref 2020-09-25 17:48:03.782894539 -0300 ++++ rt1/step4/show_mpls_table.ref 2020-09-25 17:49:00.343631290 -0300 +@@ -47,30 +47,6 @@ + } + ] + }, +- "16040":{ +- "inLabel":16040, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "installed":true, +- "nexthop":"10.0.1.2" +- } +- ] +- }, +- "16041":{ +- "inLabel":16041, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "installed":true, +- "interface":"eth-sw1" +- } +- ] +- }, + "16050":{ + "inLabel":16050, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..79a452ef69 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step4/show_ip_route.ref 2020-09-25 17:49:01.563647190 -0300 ++++ rt1/step5/show_ip_route.ref 2020-09-25 17:50:12.144567593 -0300 +@@ -60,7 +60,10 @@ + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..805266aaaa --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step4/show_ipv6_route.ref 2020-09-25 17:49:02.791663194 -0300 ++++ rt1/step5/show_ipv6_route.ref 2020-09-25 17:50:13.428584346 -0300 +@@ -57,7 +57,10 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16041 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff new file mode 100644 index 0000000000..d7ab66ee18 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff @@ -0,0 +1,33 @@ +--- rt1/step4/show_mpls_table.ref 2020-09-25 17:49:00.343631290 -0300 ++++ rt1/step5/show_mpls_table.ref 2020-09-25 17:50:10.868550944 -0300 +@@ -47,6 +47,30 @@ + } + ] + }, ++ "16040":{ ++ "inLabel":16040, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "installed":true, ++ "nexthop":"10.0.1.2" ++ } ++ ] ++ }, ++ "16041":{ ++ "inLabel":16041, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "installed":true, ++ "interface":"eth-sw1" ++ } ++ ] ++ }, + "16050":{ + "inLabel":16050, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..9aa0cd2e39 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step6/show_ip_route.ref 2020-09-25 17:51:15.105389461 -0300 ++++ rt1/step7/show_ip_route.ref 2020-09-25 17:52:02.014002243 -0300 +@@ -83,10 +83,7 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..52fd7caf91 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step6/show_ipv6_route.ref 2020-09-25 17:51:16.345405655 -0300 ++++ rt1/step7/show_ipv6_route.ref 2020-09-25 17:52:03.230018133 -0300 +@@ -79,10 +79,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16051 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff new file mode 100644 index 0000000000..53332be569 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff @@ -0,0 +1,33 @@ +--- rt1/step6/show_mpls_table.ref 2020-09-25 17:51:13.861373215 -0300 ++++ rt1/step7/show_mpls_table.ref 2020-09-25 17:52:00.769985988 -0300 +@@ -71,30 +71,6 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.1.3" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, +- "interface":"eth-sw1" +- } +- ] +- }, + "16060":{ + "inLabel":16060, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..af9f72e718 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step7/show_ip_route.ref 2020-09-25 17:52:02.014002243 -0300 ++++ rt1/step8/show_ip_route.ref 2020-09-25 17:53:20.003021800 -0300 +@@ -83,7 +83,10 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..b733b33ed9 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff @@ -0,0 +1,14 @@ +--- rt1/step7/show_ipv6_route.ref 2020-09-25 17:52:03.230018133 -0300 ++++ rt1/step8/show_ipv6_route.ref 2020-09-25 17:53:21.239037966 -0300 +@@ -79,7 +79,10 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16051 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b6f8c962f0 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff @@ -0,0 +1,33 @@ +--- rt1/step7/show_mpls_table.ref 2020-09-25 17:52:00.769985988 -0300 ++++ rt1/step8/show_mpls_table.ref 2020-09-25 17:53:18.671004379 -0300 +@@ -71,6 +71,30 @@ + } + ] + }, ++ "16050":{ ++ "inLabel":16050, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "installed":true, ++ "nexthop":"10.0.1.3" ++ } ++ ] ++ }, ++ "16051":{ ++ "inLabel":16051, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "installed":true, ++ "interface":"eth-sw1" ++ } ++ ] ++ }, + "16060":{ + "inLabel":16060, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..1d96341557 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff @@ -0,0 +1,11 @@ +--- rt1/step8/show_ip_route.ref 2020-09-25 17:53:20.003021800 -0300 ++++ rt1/step9/show_ip_route.ref 2020-09-25 17:54:37.700038367 -0300 +@@ -85,7 +85,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..232b823ac2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff @@ -0,0 +1,11 @@ +--- rt1/step8/show_ipv6_route.ref 2020-09-25 17:53:21.239037966 -0300 ++++ rt1/step9/show_ipv6_route.ref 2020-09-25 17:54:38.912054230 -0300 +@@ -81,7 +81,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16051 ++ 16501 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff new file mode 100644 index 0000000000..7f0d50f5f2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff @@ -0,0 +1,64 @@ +--- rt1/step8/show_mpls_table.ref 2020-09-25 17:53:18.671004379 -0300 ++++ rt1/step9/show_mpls_table.ref 2020-09-25 17:54:36.428021718 -0300 +@@ -71,30 +71,6 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.1.3" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, +- "interface":"eth-sw1" +- } +- ] +- }, + "16060":{ + "inLabel":16060, + "installed":true, +@@ -129,6 +105,30 @@ + "installed":true, + "interface":"eth-sw1" + } ++ ] ++ }, ++ "16500":{ ++ "inLabel":16500, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16500, ++ "installed":true, ++ "nexthop":"10.0.1.3" ++ } ++ ] ++ }, ++ "16501":{ ++ "inLabel":16501, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16501, ++ "installed":true, ++ "interface":"eth-sw1" ++ } + ] + } + } diff --git a/tests/topotests/isis-tilfa-topo1/rt1/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt1/zebra.conf new file mode 100644 index 0000000000..9d71d3005f --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt1/zebra.conf @@ -0,0 +1,19 @@ +log file zebra.log +! +hostname rt1 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 1.1.1.1/32 + ipv6 address 2001:db8:1000::1/128 +! +interface eth-sw1 + ip address 10.0.1.1/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-tilfa-topo1/rt2/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt2/isisd.conf new file mode 100644 index 0000000000..1a756e2c72 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/isisd.conf @@ -0,0 +1,45 @@ +hostname rt2 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis sr-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt4-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt4-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +router isis 1 + net 49.0000.0000.0000.0002.00 + is-type level-1 + lsp-gen-interval 2 + topology ipv6-unicast + segment-routing on + segment-routing global-block 16000 23999 + segment-routing node-msd 8 + segment-routing prefix 2.2.2.2/32 index 20 + segment-routing prefix 2001:db8:1000::2/128 index 21 +! diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref new file mode 100644 index 0000000000..23e07b7cda --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref @@ -0,0 +1,560 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16010 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16010 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16030 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..d9bd04ef30 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref @@ -0,0 +1,226 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16031 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref new file mode 100644 index 0000000000..cd2f879593 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref @@ -0,0 +1,286 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.1.3" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.3.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.1.3" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..1ea72a528b --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,70 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt4-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt4-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-sw1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0001", + "hold-timer": 9, + "neighbor-priority": 100, + "state": "up" + }, + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 9, + "neighbor-priority": 64, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..22b896f684 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff @@ -0,0 +1,169 @@ +--- rt2/step1/show_ip_route.ref 2020-09-25 17:46:27.537642781 -0300 ++++ rt2/step2/show_ip_route.ref 2020-09-25 17:46:57.306029668 -0300 +@@ -15,36 +15,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050, +- 16010 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050, +- 16010 +- ] +- } + ] + } + ], +@@ -64,36 +38,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050, +- 16030 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050, +- 16030 +- ] +- } + ] + } + ], +@@ -248,40 +196,12 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] ++ "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "interfaceName":"eth-sw1" + } + ] + } +@@ -377,24 +297,6 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true, +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", + "active":true + } + ] +@@ -415,24 +317,6 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true, +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", + "active":true + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..08c7d2b1fc --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff @@ -0,0 +1,72 @@ +--- rt2/step1/show_ipv6_route.ref 2020-09-25 17:46:28.865660035 -0300 ++++ rt2/step2/show_ipv6_route.ref 2020-09-25 17:46:58.514045373 -0300 +@@ -14,34 +14,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051, +- 16011 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051, +- 16011 +- ] +- } + ] + } + ], +@@ -60,34 +36,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051, +- 16031 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051, +- 16031 +- ] +- } + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff new file mode 100644 index 0000000000..4feb927156 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff @@ -0,0 +1,102 @@ +--- rt2/step1/show_mpls_table.ref 2020-09-25 17:46:26.261626203 -0300 ++++ rt2/step2/show_mpls_table.ref 2020-09-25 17:46:56.086013807 -0300 +@@ -7,23 +7,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.1.1" + } + ] + }, +@@ -35,23 +19,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-2" ++ "interface":"eth-sw1" + } + ] + }, +@@ -63,23 +31,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.3", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.1.3" + } + ] + }, +@@ -91,23 +43,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-2" ++ "interface":"eth-sw1" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..af1cebc76d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff @@ -0,0 +1,169 @@ +--- rt2/step2/show_ip_route.ref 2020-09-25 17:46:57.306029668 -0300 ++++ rt2/step3/show_ip_route.ref 2020-09-25 17:48:05.274913964 -0300 +@@ -15,10 +15,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16010 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16010 ++ ] ++ } + ] + } + ], +@@ -38,10 +64,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16030 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16030 ++ ] ++ } + ] + } + ], +@@ -196,12 +248,40 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } +@@ -297,6 +377,24 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", ++ "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", + "active":true + } + ] +@@ -317,6 +415,24 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", ++ "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", + "active":true + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..9809c316e8 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff @@ -0,0 +1,72 @@ +--- rt2/step2/show_ipv6_route.ref 2020-09-25 17:46:58.514045373 -0300 ++++ rt2/step3/show_ipv6_route.ref 2020-09-25 17:48:06.570930838 -0300 +@@ -14,10 +14,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16011 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16011 ++ ] ++ } + ] + } + ], +@@ -36,10 +60,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16031 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16031 ++ ] ++ } + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff new file mode 100644 index 0000000000..180323e4c8 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff @@ -0,0 +1,102 @@ +--- rt2/step2/show_mpls_table.ref 2020-09-25 17:46:56.086013807 -0300 ++++ rt2/step3/show_mpls_table.ref 2020-09-25 17:48:03.994897300 -0300 +@@ -7,7 +7,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1" ++ "nexthop":"10.0.1.1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.3.4" + } + ] + }, +@@ -19,7 +35,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1" ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-2" + } + ] + }, +@@ -31,7 +63,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.3" ++ "nexthop":"10.0.1.3", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.3.4" + } + ] + }, +@@ -43,7 +91,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1" ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-2" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..12d45bbe07 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff @@ -0,0 +1,192 @@ +--- rt2/step3/show_ip_route.ref 2020-09-25 17:48:05.274913964 -0300 ++++ rt2/step4/show_ip_route.ref 2020-09-25 17:49:01.763649797 -0300 +@@ -15,36 +15,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050, +- 16010 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050, +- 16010 +- ] +- } + ] + } + ], +@@ -64,36 +38,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050, +- 16030 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050, +- 16030 +- ] +- } + ] + } + ], +@@ -115,9 +63,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + }, + { +@@ -128,9 +73,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], +@@ -141,8 +83,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050, +- 16040 ++ 16050 + ] + } + ] +@@ -173,20 +114,14 @@ + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + } + ] + } +@@ -209,9 +144,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 16060 + ] + }, + { +@@ -222,9 +154,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 16060 + ] + } + ], +@@ -248,40 +177,12 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] ++ "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "interfaceName":"eth-sw1" + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..fdf658d59d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff @@ -0,0 +1,144 @@ +--- rt2/step3/show_ipv6_route.ref 2020-09-25 17:48:06.570930838 -0300 ++++ rt2/step4/show_ipv6_route.ref 2020-09-25 17:49:02.995665853 -0300 +@@ -14,34 +14,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051, +- 16011 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051, +- 16011 +- ] +- } + ] + } + ], +@@ -60,34 +36,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051, +- 16031 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051, +- 16031 +- ] +- } + ] + } + ], +@@ -108,9 +60,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + }, + { +@@ -120,9 +69,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], +@@ -132,8 +78,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16051, +- 16041 ++ 16051 + ] + } + ] +@@ -162,19 +107,13 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051 +- ] ++ "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051 +- ] ++ "active":true + } + ] + } +@@ -196,9 +135,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 16061 + ] + }, + { +@@ -208,9 +144,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 16061 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff new file mode 100644 index 0000000000..a78f79c576 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff @@ -0,0 +1,200 @@ +--- rt2/step3/show_mpls_table.ref 2020-09-25 17:48:03.994897300 -0300 ++++ rt2/step4/show_mpls_table.ref 2020-09-25 17:49:00.551634001 -0300 +@@ -7,23 +7,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.1.1" + } + ] + }, +@@ -35,23 +19,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-2" ++ "interface":"eth-sw1" + } + ] + }, +@@ -63,23 +31,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.3", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.1.3" + } + ] + }, +@@ -91,84 +43,6 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-2" +- } +- ] +- }, +- "16040":{ +- "inLabel":16040, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.3.4", +- "backupIndex":[ +- 0 +- ] +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.2.4", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.1.3" +- } +- ] +- }, +- "16041":{ +- "inLabel":16041, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt4-2", +- "backupIndex":[ +- 0 +- ] +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt4-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, + "interface":"eth-sw1" + } + ] +@@ -181,18 +55,6 @@ + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, +- "nexthop":"10.0.3.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, + "nexthop":"10.0.1.3" + } + ] +@@ -204,18 +66,6 @@ + { + "type":"SR (IS-IS)", + "outLabel":16051, +- "installed":true, +- "interface":"eth-rt4-2" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..7d20fad3f4 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff @@ -0,0 +1,192 @@ +--- rt2/step4/show_ip_route.ref 2020-09-25 17:49:01.763649797 -0300 ++++ rt2/step5/show_ip_route.ref 2020-09-25 17:50:12.360570411 -0300 +@@ -15,10 +15,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16010 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16010 ++ ] ++ } + ] + } + ], +@@ -38,10 +64,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16030 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16030 ++ ] ++ } + ] + } + ], +@@ -63,6 +115,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + }, + { +@@ -73,6 +128,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], +@@ -83,7 +141,8 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050 ++ 16050, ++ 16040 + ] + } + ] +@@ -114,14 +173,20 @@ + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } +@@ -144,6 +209,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 16060 + ] + }, + { +@@ -154,6 +222,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 16060 + ] + } + ], +@@ -177,12 +248,40 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..9330964338 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff @@ -0,0 +1,144 @@ +--- rt2/step4/show_ipv6_route.ref 2020-09-25 17:49:02.995665853 -0300 ++++ rt2/step5/show_ipv6_route.ref 2020-09-25 17:50:13.636587060 -0300 +@@ -14,10 +14,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16011 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16011 ++ ] ++ } + ] + } + ], +@@ -36,10 +60,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16031 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16031 ++ ] ++ } + ] + } + ], +@@ -60,6 +108,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + }, + { +@@ -69,6 +120,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], +@@ -78,7 +132,8 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16051 ++ 16051, ++ 16041 + ] + } + ] +@@ -107,13 +162,19 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", +- "active":true ++ "active":true, ++ "labels":[ ++ 16051 ++ ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16051 ++ ] + } + ] + } +@@ -135,6 +196,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 16061 + ] + }, + { +@@ -144,6 +208,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 16061 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b1e44a727f --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff @@ -0,0 +1,200 @@ +--- rt2/step4/show_mpls_table.ref 2020-09-25 17:49:00.551634001 -0300 ++++ rt2/step5/show_mpls_table.ref 2020-09-25 17:50:11.068553553 -0300 +@@ -7,7 +7,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1" ++ "nexthop":"10.0.1.1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.3.4" + } + ] + }, +@@ -19,7 +35,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1" ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-2" + } + ] + }, +@@ -31,7 +63,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.3" ++ "nexthop":"10.0.1.3", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.3.4" + } + ] + }, +@@ -43,6 +91,84 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-2" ++ } ++ ] ++ }, ++ "16040":{ ++ "inLabel":16040, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.3.4", ++ "backupIndex":[ ++ 0 ++ ] ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.2.4", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.1.3" ++ } ++ ] ++ }, ++ "16041":{ ++ "inLabel":16041, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt4-2", ++ "backupIndex":[ ++ 0 ++ ] ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt4-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, + "interface":"eth-sw1" + } + ] +@@ -55,6 +181,18 @@ + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, ++ "nexthop":"10.0.3.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "installed":true, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "installed":true, + "nexthop":"10.0.1.3" + } + ] +@@ -66,6 +204,18 @@ + { + "type":"SR (IS-IS)", + "outLabel":16051, ++ "installed":true, ++ "interface":"eth-rt4-2" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "installed":true, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..c92195d704 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff @@ -0,0 +1,288 @@ +--- rt2/step6/show_ip_route.ref 2020-09-25 17:51:15.313392177 -0300 ++++ rt2/step7/show_ip_route.ref 2020-09-25 17:52:02.210004805 -0300 +@@ -15,36 +15,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050, +- 16010 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050, +- 16010 +- ] +- } + ] + } + ], +@@ -64,36 +38,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050, +- 16030 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050, +- 16030 +- ] +- } + ] + } + ], +@@ -113,9 +61,6 @@ + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -126,25 +71,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.3", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16050, +- 16040 +- ] +- } + ] + } + ], +@@ -163,30 +93,21 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + } + ] + } +@@ -248,40 +169,12 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] ++ "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.2.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16050 +- ] +- }, +- { +- "ip":"10.0.3.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "interfaceName":"eth-sw1" + } + ] + } +@@ -296,30 +189,13 @@ + { + "ip":"10.0.2.4", + "afi":"ipv4", +- "interfaceName":"eth-rt4-1", +- "backupIndex":[ +- 0 +- ] ++ "interfaceName":"eth-rt4-1" + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.3", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + } + ] + } +@@ -335,29 +211,12 @@ + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", +- "interfaceName":"eth-rt4-2", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.3", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "interfaceName":"eth-rt4-2" + } + ] + } +@@ -494,31 +353,14 @@ + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.3", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16050 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..140c7b08bf --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff @@ -0,0 +1,139 @@ +--- rt2/step6/show_ipv6_route.ref 2020-09-25 17:51:16.549408319 -0300 ++++ rt2/step7/show_ipv6_route.ref 2020-09-25 17:52:03.438020851 -0300 +@@ -14,34 +14,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051, +- 16011 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051, +- 16011 +- ] +- } + ] + } + ], +@@ -60,34 +36,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051, +- 16031 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051, +- 16031 +- ] +- } + ] + } + ], +@@ -106,9 +58,6 @@ + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -118,24 +67,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16051, +- 16041 +- ] +- } + ] + } + ], +@@ -153,28 +88,19 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16051 +- ] ++ "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", +- "active":true, +- "labels":[ +- 16051 +- ] ++ "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", +- "active":true, +- "labels":[ +- 16051 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff new file mode 100644 index 0000000000..f8476cd0bb --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff @@ -0,0 +1,207 @@ +--- rt2/step6/show_mpls_table.ref 2020-09-25 17:51:14.073375985 -0300 ++++ rt2/step7/show_mpls_table.ref 2020-09-25 17:52:00.973988653 -0300 +@@ -7,23 +7,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.1.1" + } + ] + }, +@@ -35,23 +19,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-2" ++ "interface":"eth-sw1" + } + ] + }, +@@ -63,23 +31,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.3", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.1.3" + } + ] + }, +@@ -91,23 +43,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-rt4-2" ++ "interface":"eth-sw1" + } + ] + }, +@@ -119,26 +55,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.3.4", +- "backupIndex":[ +- 0 +- ] ++ "nexthop":"10.0.3.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.2.4", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "nexthop":"10.0.1.3" ++ "nexthop":"10.0.2.4" + } + ] + }, +@@ -150,74 +73,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt4-2", +- "backupIndex":[ +- 0 +- ] +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt4-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-sw1" +- } +- ] +- }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.3.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.1.3" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16051, ++ "outLabel":3, + "installed":true, + "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, +- "interface":"eth-sw1" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..7d5237e740 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff @@ -0,0 +1,288 @@ +--- rt2/step7/show_ip_route.ref 2020-09-25 17:52:02.210004805 -0300 ++++ rt2/step8/show_ip_route.ref 2020-09-25 17:53:20.207024469 -0300 +@@ -15,10 +15,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16010 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16010 ++ ] ++ } + ] + } + ], +@@ -38,10 +64,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16030 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16030 ++ ] ++ } + ] + } + ], +@@ -61,6 +113,9 @@ + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -71,10 +126,25 @@ + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16050, ++ 16040 ++ ] ++ } + ] + } + ], +@@ -93,21 +163,30 @@ + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } +@@ -169,12 +248,40 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.2.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] ++ }, ++ { ++ "ip":"10.0.3.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } +@@ -189,13 +296,30 @@ + { + "ip":"10.0.2.4", + "afi":"ipv4", +- "interfaceName":"eth-rt4-1" ++ "interfaceName":"eth-rt4-1", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } +@@ -211,12 +335,29 @@ + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", +- "interfaceName":"eth-rt4-2" ++ "interfaceName":"eth-rt4-2", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } +@@ -353,14 +494,31 @@ + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16050 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..45322214e6 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff @@ -0,0 +1,139 @@ +--- rt2/step7/show_ipv6_route.ref 2020-09-25 17:52:03.438020851 -0300 ++++ rt2/step8/show_ipv6_route.ref 2020-09-25 17:53:21.443040633 -0300 +@@ -14,10 +14,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16011 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16011 ++ ] ++ } + ] + } + ], +@@ -36,10 +60,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16031 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4-2", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16031 ++ ] ++ } + ] + } + ], +@@ -58,6 +106,9 @@ + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -67,10 +118,24 @@ + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16051, ++ 16041 ++ ] ++ } + ] + } + ], +@@ -88,19 +153,28 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16051 ++ ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", +- "active":true ++ "active":true, ++ "labels":[ ++ 16051 ++ ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16051 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff new file mode 100644 index 0000000000..083c647802 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff @@ -0,0 +1,207 @@ +--- rt2/step7/show_mpls_table.ref 2020-09-25 17:52:00.973988653 -0300 ++++ rt2/step8/show_mpls_table.ref 2020-09-25 17:53:18.923007676 -0300 +@@ -7,7 +7,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1" ++ "nexthop":"10.0.1.1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.3.4" + } + ] + }, +@@ -19,7 +35,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1" ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-2" + } + ] + }, +@@ -31,7 +63,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.3" ++ "nexthop":"10.0.1.3", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.3.4" + } + ] + }, +@@ -43,7 +91,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1" ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-rt4-2" + } + ] + }, +@@ -55,13 +119,26 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.3.4" ++ "nexthop":"10.0.3.4", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.2.4" ++ "nexthop":"10.0.2.4", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "nexthop":"10.0.1.3" + } + ] + }, +@@ -73,13 +150,74 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt4-2" ++ "interface":"eth-rt4-2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, ++ "interface":"eth-rt4-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "interface":"eth-sw1" ++ } ++ ] ++ }, ++ "16050":{ ++ "inLabel":16050, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "installed":true, ++ "nexthop":"10.0.3.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "installed":true, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16050, ++ "installed":true, ++ "nexthop":"10.0.1.3" ++ } ++ ] ++ }, ++ "16051":{ ++ "inLabel":16051, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "installed":true, ++ "interface":"eth-rt4-2" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "installed":true, + "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16051, ++ "installed":true, ++ "interface":"eth-sw1" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..15370a0a62 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff @@ -0,0 +1,119 @@ +--- rt2/step8/show_ip_route.ref 2020-09-25 17:53:20.207024469 -0300 ++++ rt2/step9/show_ip_route.ref 2020-09-25 17:54:37.908041089 -0300 +@@ -31,7 +31,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16050, ++ 16500, + 16010 + ] + }, +@@ -41,7 +41,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16050, ++ 16500, + 16010 + ] + } +@@ -80,7 +80,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16050, ++ 16500, + 16030 + ] + }, +@@ -90,7 +90,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16050, ++ 16500, + 16030 + ] + } +@@ -141,7 +141,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050, ++ 16500, + 16040 + ] + } +@@ -165,7 +165,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + }, + { +@@ -175,7 +175,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + }, + { +@@ -185,7 +185,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + } + ] +@@ -271,7 +271,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + }, + { +@@ -280,7 +280,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + } + ] +@@ -318,7 +318,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + } + ] +@@ -356,7 +356,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + } + ] +@@ -517,7 +517,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16050 ++ 16500 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..2585f32595 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff @@ -0,0 +1,74 @@ +--- rt2/step8/show_ipv6_route.ref 2020-09-25 17:53:21.443040633 -0300 ++++ rt2/step9/show_ipv6_route.ref 2020-09-25 17:54:39.112056848 -0300 +@@ -29,7 +29,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16051, ++ 16501, + 16011 + ] + }, +@@ -38,7 +38,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16051, ++ 16501, + 16011 + ] + } +@@ -75,7 +75,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16051, ++ 16501, + 16031 + ] + }, +@@ -84,7 +84,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16051, ++ 16501, + 16031 + ] + } +@@ -132,7 +132,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16051, ++ 16501, + 16041 + ] + } +@@ -155,7 +155,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16051 ++ 16501 + ] + }, + { +@@ -164,7 +164,7 @@ + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ +- 16051 ++ 16501 + ] + }, + { +@@ -173,7 +173,7 @@ + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ +- 16051 ++ 16501 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b90b889eba --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff @@ -0,0 +1,182 @@ +--- rt2/step8/show_mpls_table.ref 2020-09-25 17:53:18.923007676 -0300 ++++ rt2/step9/show_mpls_table.ref 2020-09-25 17:54:36.640024493 -0300 +@@ -17,12 +17,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16050, ++ "outLabel":16500, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16050, ++ "outLabel":16500, + "nexthop":"10.0.3.4" + } + ] +@@ -45,12 +45,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16051, ++ "outLabel":16501, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16051, ++ "outLabel":16501, + "interface":"eth-rt4-2" + } + ] +@@ -73,12 +73,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16050, ++ "outLabel":16500, + "nexthop":"10.0.2.4" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16050, ++ "outLabel":16500, + "nexthop":"10.0.3.4" + } + ] +@@ -101,12 +101,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16051, ++ "outLabel":16501, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16051, ++ "outLabel":16501, + "interface":"eth-rt4-2" + } + ] +@@ -137,7 +137,7 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16050, ++ "outLabel":16500, + "nexthop":"10.0.1.3" + } + ] +@@ -168,55 +168,7 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16051, +- "interface":"eth-sw1" +- } +- ] +- }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.3.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.2.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16050, +- "installed":true, +- "nexthop":"10.0.1.3" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, +- "interface":"eth-rt4-2" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, +- "interface":"eth-rt4-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16051, +- "installed":true, ++ "outLabel":16501, + "interface":"eth-sw1" + } + ] +@@ -282,5 +234,53 @@ + "interface":"eth-sw1" + } + ] ++ }, ++ "16500":{ ++ "inLabel":16500, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16500, ++ "installed":true, ++ "nexthop":"10.0.3.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16500, ++ "installed":true, ++ "nexthop":"10.0.2.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16500, ++ "installed":true, ++ "nexthop":"10.0.1.3" ++ } ++ ] ++ }, ++ "16501":{ ++ "inLabel":16501, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16501, ++ "installed":true, ++ "interface":"eth-rt4-2" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16501, ++ "installed":true, ++ "interface":"eth-rt4-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16501, ++ "installed":true, ++ "interface":"eth-sw1" ++ } ++ ] + } + } diff --git a/tests/topotests/isis-tilfa-topo1/rt2/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt2/zebra.conf new file mode 100644 index 0000000000..dcb0686dc2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt2/zebra.conf @@ -0,0 +1,25 @@ +log file zebra.log +! +hostname rt2 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 2.2.2.2/32 + ipv6 address 2001:db8:1000::2/128 +! +interface eth-sw1 + ip address 10.0.1.2/24 +! +interface eth-rt4-1 + ip address 10.0.2.2/24 +! +interface eth-rt4-2 + ip address 10.0.3.2/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-tilfa-topo1/rt3/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt3/isisd.conf new file mode 100644 index 0000000000..986bf2804a --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/isisd.conf @@ -0,0 +1,45 @@ +hostname rt3 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis sr-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt5-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt5-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +router isis 1 + net 49.0000.0000.0000.0003.00 + is-type level-1 + lsp-gen-interval 2 + topology ipv6-unicast + segment-routing on + segment-routing global-block 16000 23999 + segment-routing node-msd 8 + segment-routing prefix 3.3.3.3/32 index 30 + segment-routing prefix 2001:db8:1000::3/128 index 31 +! diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref new file mode 100644 index 0000000000..8c37180daf --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref @@ -0,0 +1,560 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..5ddb24af5a --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref @@ -0,0 +1,226 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref new file mode 100644 index 0000000000..f68d1f4244 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref @@ -0,0 +1,286 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.4.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.5.5", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.4.5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.1.2" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..d174b4a475 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,70 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt5-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt5-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-sw1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0001", + "hold-timer": 9, + "neighbor-priority": 100, + "state": "up" + }, + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 9, + "neighbor-priority": 64, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..707f95495d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff @@ -0,0 +1,288 @@ +--- rt3/step3/show_ip_route.ref 2020-09-25 17:48:05.506916984 -0300 ++++ rt3/step4/show_ip_route.ref 2020-09-25 17:49:01.963652403 -0300 +@@ -15,36 +15,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.4.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16040, +- 16010 +- ] +- }, +- { +- "ip":"10.0.5.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16040, +- 16010 +- ] +- } + ] + } + ], +@@ -64,36 +38,10 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.4.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16040, +- 16020 +- ] +- }, +- { +- "ip":"10.0.5.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16040, +- 16020 +- ] +- } + ] + } + ], +@@ -112,30 +60,21 @@ + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "active":true + } + ] + } +@@ -156,9 +95,6 @@ + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -169,25 +105,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.2", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16040, +- 16050 +- ] +- } + ] + } + ], +@@ -248,40 +169,12 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] ++ "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.4.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16040 +- ] +- }, +- { +- "ip":"10.0.5.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "interfaceName":"eth-sw1" + } + ] + } +@@ -372,30 +265,13 @@ + { + "ip":"10.0.4.5", + "afi":"ipv4", +- "interfaceName":"eth-rt5-1", +- "backupIndex":[ +- 0 +- ] ++ "interfaceName":"eth-rt5-1" + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.2", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "active":true + } + ] + } +@@ -411,29 +287,12 @@ + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", +- "interfaceName":"eth-rt5-2", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.2", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "interfaceName":"eth-rt5-2" + } + ] + } +@@ -528,31 +387,14 @@ + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.1.2", +- "afi":"ipv4", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16040 +- ] ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..76d0ebc913 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff @@ -0,0 +1,139 @@ +--- rt3/step3/show_ipv6_route.ref 2020-09-25 17:48:06.790933702 -0300 ++++ rt3/step4/show_ipv6_route.ref 2020-09-25 17:49:03.199668512 -0300 +@@ -14,34 +14,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16041, +- 16011 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16041, +- 16011 +- ] +- } + ] + } + ], +@@ -60,34 +36,10 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, +- "backupIndex":[ +- 0, +- 1 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16041, +- 16021 +- ] +- }, +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16041, +- 16021 +- ] +- } + ] + } + ], +@@ -105,28 +57,19 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16041 +- ] ++ "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", +- "active":true, +- "labels":[ +- 16041 +- ] ++ "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", +- "active":true, +- "labels":[ +- 16041 +- ] ++ "active":true + } + ] + } +@@ -146,9 +89,6 @@ + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -158,24 +98,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-sw1", +- "active":true, +- "labels":[ +- 16041, +- 16051 +- ] +- } + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b888c9d273 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff @@ -0,0 +1,206 @@ +--- rt3/step3/show_mpls_table.ref 2020-09-25 17:48:04.214900164 -0300 ++++ rt3/step4/show_mpls_table.ref 2020-09-25 17:49:00.759636711 -0300 +@@ -7,23 +7,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "nexthop":"10.0.4.5" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "nexthop":"10.0.5.5" ++ "nexthop":"10.0.1.1" + } + ] + }, +@@ -35,23 +19,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "interface":"eth-rt5-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "interface":"eth-rt5-2" ++ "interface":"eth-sw1" + } + ] + }, +@@ -63,23 +31,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.2", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "nexthop":"10.0.4.5" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "nexthop":"10.0.5.5" ++ "nexthop":"10.0.1.2" + } + ] + }, +@@ -91,70 +43,6 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1", +- "backupIndex":[ +- 0, +- 1 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "interface":"eth-rt5-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "interface":"eth-rt5-2" +- } +- ] +- }, +- "16040":{ +- "inLabel":16040, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "installed":true, +- "nexthop":"10.0.5.5" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "installed":true, +- "nexthop":"10.0.4.5" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "installed":true, +- "nexthop":"10.0.1.2" +- } +- ] +- }, +- "16041":{ +- "inLabel":16041, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "installed":true, +- "interface":"eth-rt5-2" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "installed":true, +- "interface":"eth-rt5-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "installed":true, + "interface":"eth-sw1" + } + ] +@@ -167,26 +55,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.5.5", +- "backupIndex":[ +- 0 +- ] ++ "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.4.5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "nexthop":"10.0.1.2" ++ "nexthop":"10.0.4.5" + } + ] + }, +@@ -198,26 +73,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5-2", +- "backupIndex":[ +- 0 +- ] ++ "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "interface":"eth-sw1" ++ "interface":"eth-rt5-1" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..8eac75bec7 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff @@ -0,0 +1,288 @@ +--- rt3/step4/show_ip_route.ref 2020-09-25 17:49:01.963652403 -0300 ++++ rt3/step5/show_ip_route.ref 2020-09-25 17:50:12.592573438 -0300 +@@ -15,10 +15,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.4.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5-1", ++ "active":true, ++ "labels":[ ++ 16040, ++ 16010 ++ ] ++ }, ++ { ++ "ip":"10.0.5.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5-2", ++ "active":true, ++ "labels":[ ++ 16040, ++ 16010 ++ ] ++ } + ] + } + ], +@@ -38,10 +64,36 @@ + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.4.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5-1", ++ "active":true, ++ "labels":[ ++ 16040, ++ 16020 ++ ] ++ }, ++ { ++ "ip":"10.0.5.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5-2", ++ "active":true, ++ "labels":[ ++ 16040, ++ 16020 ++ ] ++ } + ] + } + ], +@@ -60,21 +112,30 @@ + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", +- "active":true ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + } + ] + } +@@ -95,6 +156,9 @@ + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -105,10 +169,25 @@ + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16040, ++ 16050 ++ ] ++ } + ] + } + ], +@@ -169,12 +248,40 @@ + { + "ip":"10.0.1.1", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", +- "interfaceName":"eth-sw1" ++ "interfaceName":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.4.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5-1", ++ "active":true, ++ "labels":[ ++ 16040 ++ ] ++ }, ++ { ++ "ip":"10.0.5.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5-2", ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + } + ] + } +@@ -265,13 +372,30 @@ + { + "ip":"10.0.4.5", + "afi":"ipv4", +- "interfaceName":"eth-rt5-1" ++ "interfaceName":"eth-rt5-1", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + } + ] + } +@@ -287,12 +411,29 @@ + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", +- "interfaceName":"eth-rt5-2" ++ "interfaceName":"eth-rt5-2", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + } + ] + } +@@ -387,14 +528,31 @@ + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.1.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16040 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..fc55267ad1 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff @@ -0,0 +1,139 @@ +--- rt3/step4/show_ipv6_route.ref 2020-09-25 17:49:03.199668512 -0300 ++++ rt3/step5/show_ipv6_route.ref 2020-09-25 17:50:13.840589722 -0300 +@@ -14,10 +14,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5-1", ++ "active":true, ++ "labels":[ ++ 16041, ++ 16011 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5-2", ++ "active":true, ++ "labels":[ ++ 16041, ++ 16011 ++ ] ++ } + ] + } + ], +@@ -36,10 +60,34 @@ + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, ++ "backupIndex":[ ++ 0, ++ 1 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5-1", ++ "active":true, ++ "labels":[ ++ 16041, ++ 16021 ++ ] ++ }, ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5-2", ++ "active":true, ++ "labels":[ ++ 16041, ++ 16021 ++ ] ++ } + ] + } + ], +@@ -57,19 +105,28 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16041 ++ ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", +- "active":true ++ "active":true, ++ "labels":[ ++ 16041 ++ ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", +- "active":true ++ "active":true, ++ "labels":[ ++ 16041 ++ ] + } + ] + } +@@ -89,6 +146,9 @@ + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -98,10 +158,24 @@ + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-sw1", ++ "active":true, ++ "labels":[ ++ 16041, ++ 16051 ++ ] ++ } + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff new file mode 100644 index 0000000000..4ed491e241 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff @@ -0,0 +1,206 @@ +--- rt3/step4/show_mpls_table.ref 2020-09-25 17:49:00.759636711 -0300 ++++ rt3/step5/show_mpls_table.ref 2020-09-25 17:50:11.280556320 -0300 +@@ -7,7 +7,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.1" ++ "nexthop":"10.0.1.1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "nexthop":"10.0.4.5" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "nexthop":"10.0.5.5" + } + ] + }, +@@ -19,7 +35,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-sw1" ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "interface":"eth-rt5-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "interface":"eth-rt5-2" + } + ] + }, +@@ -31,7 +63,23 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.1.2" ++ "nexthop":"10.0.1.2", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "nexthop":"10.0.4.5" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "nexthop":"10.0.5.5" + } + ] + }, +@@ -43,6 +91,70 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, ++ "interface":"eth-sw1", ++ "backupIndex":[ ++ 0, ++ 1 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "interface":"eth-rt5-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "interface":"eth-rt5-2" ++ } ++ ] ++ }, ++ "16040":{ ++ "inLabel":16040, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "installed":true, ++ "nexthop":"10.0.5.5" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "installed":true, ++ "nexthop":"10.0.4.5" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "installed":true, ++ "nexthop":"10.0.1.2" ++ } ++ ] ++ }, ++ "16041":{ ++ "inLabel":16041, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "installed":true, ++ "interface":"eth-rt5-2" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "installed":true, ++ "interface":"eth-rt5-1" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "installed":true, + "interface":"eth-sw1" + } + ] +@@ -55,13 +167,26 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.5.5" ++ "nexthop":"10.0.5.5", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.4.5" ++ "nexthop":"10.0.4.5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "nexthop":"10.0.1.2" + } + ] + }, +@@ -73,13 +198,26 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5-2" ++ "interface":"eth-rt5-2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5-1" ++ "interface":"eth-rt5-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "interface":"eth-sw1" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..9273c75352 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff @@ -0,0 +1,101 @@ +--- rt3/step5/show_ip_route.ref 2020-09-25 17:50:12.592573438 -0300 ++++ rt3/step6/show_ip_route.ref 2020-09-25 17:51:15.521394894 -0300 +@@ -31,7 +31,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16040, ++ 30040, + 16010 + ] + }, +@@ -41,7 +41,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16040, ++ 30040, + 16010 + ] + } +@@ -80,7 +80,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16040, ++ 30040, + 16020 + ] + }, +@@ -90,7 +90,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16040, ++ 30040, + 16020 + ] + } +@@ -124,7 +124,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16040 ++ 30040 + ] + }, + { +@@ -134,7 +134,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16040 ++ 30040 + ] + } + ] +@@ -185,7 +185,7 @@ + "active":true, + "labels":[ + 16040, +- 16050 ++ 30050 + ] + } + ] +@@ -211,7 +211,7 @@ + 0 + ], + "labels":[ +- 16060 ++ 30060 + ] + }, + { +@@ -224,7 +224,7 @@ + 0 + ], + "labels":[ +- 16060 ++ 30060 + ] + } + ], +@@ -271,7 +271,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16040 ++ 30040 + ] + }, + { +@@ -280,7 +280,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16040 ++ 30040 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..f50be893e4 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff @@ -0,0 +1,83 @@ +--- rt3/step5/show_ipv6_route.ref 2020-09-25 17:50:13.840589722 -0300 ++++ rt3/step6/show_ipv6_route.ref 2020-09-25 17:51:16.757411035 -0300 +@@ -29,7 +29,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16041, ++ 30041, + 16011 + ] + }, +@@ -38,7 +38,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16041, ++ 30041, + 16011 + ] + } +@@ -75,7 +75,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16041, ++ 30041, + 16021 + ] + }, +@@ -84,7 +84,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16041, ++ 30041, + 16021 + ] + } +@@ -116,7 +116,7 @@ + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ +- 16041 ++ 30041 + ] + }, + { +@@ -125,7 +125,7 @@ + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ +- 16041 ++ 30041 + ] + } + ] +@@ -173,7 +173,7 @@ + "active":true, + "labels":[ + 16041, +- 16051 ++ 30051 + ] + } + ] +@@ -198,7 +198,7 @@ + 0 + ], + "labels":[ +- 16061 ++ 30061 + ] + }, + { +@@ -210,7 +210,7 @@ + 0 + ], + "labels":[ +- 16061 ++ 30061 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b63a728ef1 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff @@ -0,0 +1,130 @@ +--- rt3/step5/show_mpls_table.ref 2020-09-25 17:50:11.280556320 -0300 ++++ rt3/step6/show_mpls_table.ref 2020-09-25 17:51:14.281378700 -0300 +@@ -17,12 +17,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":30040, + "nexthop":"10.0.4.5" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":30040, + "nexthop":"10.0.5.5" + } + ] +@@ -45,12 +45,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":30041, + "interface":"eth-rt5-2" + } + ] +@@ -73,12 +73,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":30040, + "nexthop":"10.0.4.5" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":30040, + "nexthop":"10.0.5.5" + } + ] +@@ -101,12 +101,12 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":30041, + "interface":"eth-rt5-2" + } + ] +@@ -117,13 +117,13 @@ + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":30040, + "installed":true, + "nexthop":"10.0.5.5" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":30040, + "installed":true, + "nexthop":"10.0.4.5" + }, +@@ -141,13 +141,13 @@ + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":30041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":30041, + "installed":true, + "interface":"eth-rt5-1" + }, +@@ -227,7 +227,7 @@ + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16060, ++ "outLabel":30060, + "installed":true, + "nexthop":"10.0.5.5", + "backupIndex":[ +@@ -236,7 +236,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":16060, ++ "outLabel":30060, + "installed":true, + "nexthop":"10.0.4.5", + "backupIndex":[ +@@ -258,7 +258,7 @@ + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16061, ++ "outLabel":30061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ +@@ -267,7 +267,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":16061, ++ "outLabel":30061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..0ae87afa3b --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff @@ -0,0 +1,32 @@ +--- rt3/step6/show_ip_route.ref 2020-09-25 17:51:15.521394894 -0300 ++++ rt3/step7/show_ip_route.ref 2020-09-25 17:52:02.414007470 -0300 +@@ -158,9 +158,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + }, + { +@@ -171,9 +168,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], +@@ -184,8 +178,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16040, +- 30050 ++ 16040 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..f392f644c0 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff @@ -0,0 +1,32 @@ +--- rt3/step6/show_ipv6_route.ref 2020-09-25 17:51:16.757411035 -0300 ++++ rt3/step7/show_ipv6_route.ref 2020-09-25 17:52:03.650023622 -0300 +@@ -148,9 +148,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + }, + { +@@ -160,9 +157,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], +@@ -172,8 +166,7 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16041, +- 30051 ++ 16041 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b74eb9579c --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff @@ -0,0 +1,71 @@ +--- rt3/step6/show_mpls_table.ref 2020-09-25 17:51:14.281378700 -0300 ++++ rt3/step7/show_mpls_table.ref 2020-09-25 17:52:01.181991371 -0300 +@@ -159,68 +159,6 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.5.5", +- "backupIndex":[ +- 0 +- ] +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.4.5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16040, +- "nexthop":"10.0.1.2" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt5-2", +- "backupIndex":[ +- 0 +- ] +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt5-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16041, +- "interface":"eth-sw1" +- } +- ] +- }, + "16060":{ + "inLabel":16060, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..25b42f2825 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff @@ -0,0 +1,32 @@ +--- rt3/step7/show_ip_route.ref 2020-09-25 17:52:02.414007470 -0300 ++++ rt3/step8/show_ip_route.ref 2020-09-25 17:53:20.419027241 -0300 +@@ -158,6 +158,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + }, + { +@@ -168,6 +171,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], +@@ -178,7 +184,8 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16040 ++ 16040, ++ 30050 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..42d9356c8a --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff @@ -0,0 +1,32 @@ +--- rt3/step7/show_ipv6_route.ref 2020-09-25 17:52:03.650023622 -0300 ++++ rt3/step8/show_ipv6_route.ref 2020-09-25 17:53:21.643043250 -0300 +@@ -148,6 +148,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + }, + { +@@ -157,6 +160,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], +@@ -166,7 +172,8 @@ + "interfaceName":"eth-sw1", + "active":true, + "labels":[ +- 16041 ++ 16041, ++ 30051 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff new file mode 100644 index 0000000000..bd40f954eb --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff @@ -0,0 +1,71 @@ +--- rt3/step7/show_mpls_table.ref 2020-09-25 17:52:01.181991371 -0300 ++++ rt3/step8/show_mpls_table.ref 2020-09-25 17:53:19.135010448 -0300 +@@ -159,6 +159,68 @@ + } + ] + }, ++ "16050":{ ++ "inLabel":16050, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.5.5", ++ "backupIndex":[ ++ 0 ++ ] ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.4.5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16040, ++ "nexthop":"10.0.1.2" ++ } ++ ] ++ }, ++ "16051":{ ++ "inLabel":16051, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt5-2", ++ "backupIndex":[ ++ 0 ++ ] ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt5-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16041, ++ "interface":"eth-sw1" ++ } ++ ] ++ }, + "16060":{ + "inLabel":16060, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..687e84ad40 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff @@ -0,0 +1,11 @@ +--- rt3/step8/show_ip_route.ref 2020-09-25 17:53:20.419027241 -0300 ++++ rt3/step9/show_ip_route.ref 2020-09-25 17:54:38.112043759 -0300 +@@ -185,7 +185,7 @@ + "active":true, + "labels":[ + 16040, +- 30050 ++ 30500 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..4b76be66ac --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff @@ -0,0 +1,11 @@ +--- rt3/step8/show_ipv6_route.ref 2020-09-25 17:53:21.643043250 -0300 ++++ rt3/step9/show_ipv6_route.ref 2020-09-25 17:54:39.320059571 -0300 +@@ -173,7 +173,7 @@ + "active":true, + "labels":[ + 16041, +- 30051 ++ 30501 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff new file mode 100644 index 0000000000..6f6451e510 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff @@ -0,0 +1,133 @@ +--- rt3/step8/show_mpls_table.ref 2020-09-25 17:53:19.135010448 -0300 ++++ rt3/step9/show_mpls_table.ref 2020-09-25 17:54:36.852027268 -0300 +@@ -159,13 +159,13 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, ++ "16060":{ ++ "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":3, ++ "outLabel":30060, + "installed":true, + "nexthop":"10.0.5.5", + "backupIndex":[ +@@ -174,7 +174,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":3, ++ "outLabel":30060, + "installed":true, + "nexthop":"10.0.4.5", + "backupIndex":[ +@@ -185,18 +185,18 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16040, ++ "outLabel":3, + "nexthop":"10.0.1.2" + } + ] + }, +- "16051":{ +- "inLabel":16051, ++ "16061":{ ++ "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":3, ++ "outLabel":30061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ +@@ -205,7 +205,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":3, ++ "outLabel":30061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ +@@ -216,18 +216,18 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16041, ++ "outLabel":3, + "interface":"eth-sw1" + } + ] + }, +- "16060":{ +- "inLabel":16060, ++ "16500":{ ++ "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":30060, ++ "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "backupIndex":[ +@@ -236,7 +236,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":30060, ++ "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "backupIndex":[ +@@ -247,18 +247,18 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":3, ++ "outLabel":16040, + "nexthop":"10.0.1.2" + } + ] + }, +- "16061":{ +- "inLabel":16061, ++ "16501":{ ++ "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":30061, ++ "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ +@@ -267,7 +267,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":30061, ++ "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ +@@ -278,7 +278,7 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":3, ++ "outLabel":16041, + "interface":"eth-sw1" + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt3/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt3/zebra.conf new file mode 100644 index 0000000000..3254529386 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt3/zebra.conf @@ -0,0 +1,25 @@ +log file zebra.log +! +hostname rt3 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 3.3.3.3/32 + ipv6 address 2001:db8:1000::3/128 +! +interface eth-sw1 + ip address 10.0.1.3/24 +! +interface eth-rt5-1 + ip address 10.0.4.3/24 +! +interface eth-rt5-2 + ip address 10.0.5.3/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-tilfa-topo1/rt4/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt4/isisd.conf new file mode 100644 index 0000000000..7d411069d1 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/isisd.conf @@ -0,0 +1,53 @@ +hostname rt4 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis sr-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt2-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt2-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt5 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt6 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +router isis 1 + net 49.0000.0000.0000.0004.00 + is-type level-1 + lsp-gen-interval 2 + topology ipv6-unicast + segment-routing on + segment-routing global-block 16000 23999 + segment-routing node-msd 8 + segment-routing prefix 4.4.4.4/32 index 40 + segment-routing prefix 2001:db8:1000::4/128 index 41 +! diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref new file mode 100644 index 0000000000..168b90a3f6 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref @@ -0,0 +1,497 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..a4442ee089 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref @@ -0,0 +1,198 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref new file mode 100644 index 0000000000..18354e947d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref @@ -0,0 +1,262 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.6.5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.6.5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.6.5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.7.6" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.6.5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..2eb64b6fc9 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,82 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt2-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt2-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt5", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt6", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0006", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..7dcdb744ac --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff @@ -0,0 +1,312 @@ +--- rt4/step3/show_ip_route.ref 2020-09-25 17:48:05.722919797 -0300 ++++ rt4/step4/show_ip_route.ref 2020-09-25 17:49:02.163655010 -0300 +@@ -15,9 +15,6 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 16010 + ] +@@ -28,21 +25,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 16010 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "active":true +- } + ] + } + ], +@@ -62,9 +48,6 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -75,25 +58,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "active":true, +- "labels":[ +- 16030, +- 16020 +- ] +- } + ] + } + ], +@@ -156,21 +124,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.7.6", +- "afi":"ipv4", +- "interfaceName":"eth-rt6", +- "active":true +- } + ] + } + ], +@@ -190,21 +147,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "active":true +- } + ] + } + ], +@@ -223,27 +169,13 @@ + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", + "active":true + } + ] +@@ -259,30 +191,13 @@ + { + "ip":"10.0.2.2", + "afi":"ipv4", +- "interfaceName":"eth-rt2-1", +- "backupIndex":[ +- 0 +- ] ++ "interfaceName":"eth-rt2-1" + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "active":true, +- "labels":[ +- 16030 +- ] ++ "active":true + } + ] + } +@@ -298,29 +213,12 @@ + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", +- "interfaceName":"eth-rt2-2", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "active":true, +- "labels":[ +- 16030 +- ] ++ "interfaceName":"eth-rt2-2" + } + ] + } +@@ -340,31 +238,6 @@ + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", +- "active":true, +- "backupIndex":[ +- 0, +- 1, +- 2 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.7.6", +- "afi":"ipv4", +- "interfaceName":"eth-rt6", +- "active":true +- }, +- { +- "ip":"10.0.2.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2-1", +- "active":true +- }, +- { +- "ip":"10.0.3.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2-2", + "active":true + } + ] +@@ -385,31 +258,6 @@ + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", +- "active":true, +- "backupIndex":[ +- 0, +- 1, +- 2 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.7.6", +- "afi":"ipv4", +- "interfaceName":"eth-rt6", +- "active":true +- }, +- { +- "ip":"10.0.2.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2-1", +- "active":true +- }, +- { +- "ip":"10.0.3.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2-2", + "active":true + } + ] +@@ -425,18 +273,7 @@ + { + "ip":"10.0.6.5", + "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.7.6", +- "afi":"ipv4", +- "interfaceName":"eth-rt6", +- "active":true ++ "interfaceName":"eth-rt5" + } + ] + } +@@ -451,18 +288,7 @@ + { + "ip":"10.0.7.6", + "afi":"ipv4", +- "interfaceName":"eth-rt6", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.5", +- "afi":"ipv4", +- "interfaceName":"eth-rt5", +- "active":true ++ "interfaceName":"eth-rt6" + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..b84ceaff1a --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff @@ -0,0 +1,110 @@ +--- rt4/step3/show_ipv6_route.ref 2020-09-25 17:48:06.998936410 -0300 ++++ rt4/step4/show_ipv6_route.ref 2020-09-25 17:49:03.399671119 -0300 +@@ -14,9 +14,6 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 16011 + ] +@@ -26,20 +23,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 16011 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5", +- "active":true +- } + ] + } + ], +@@ -58,9 +45,6 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -70,24 +54,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5", +- "active":true, +- "labels":[ +- 16031, +- 16021 +- ] +- } + ] + } + ], +@@ -146,20 +116,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt6", +- "active":true +- } + ] + } + ], +@@ -178,20 +138,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt5", +- "active":true +- } + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff new file mode 100644 index 0000000000..70e0108b0d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff @@ -0,0 +1,194 @@ +--- rt4/step3/show_mpls_table.ref 2020-09-25 17:48:04.418902820 -0300 ++++ rt4/step4/show_mpls_table.ref 2020-09-25 17:49:00.959639319 -0300 +@@ -7,26 +7,13 @@ + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, +- "nexthop":"10.0.3.2", +- "backupIndex":[ +- 0 +- ] ++ "nexthop":"10.0.3.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, +- "nexthop":"10.0.2.2", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.6.5" ++ "nexthop":"10.0.2.2" + } + ] + }, +@@ -38,26 +25,13 @@ + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, +- "interface":"eth-rt2-2", +- "backupIndex":[ +- 0 +- ] ++ "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, +- "interface":"eth-rt2-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt5" ++ "interface":"eth-rt2-1" + } + ] + }, +@@ -69,26 +43,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.3.2", +- "backupIndex":[ +- 0 +- ] ++ "nexthop":"10.0.3.2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.2.2", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16030, +- "nexthop":"10.0.6.5" ++ "nexthop":"10.0.2.2" + } + ] + }, +@@ -100,26 +61,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt2-2", +- "backupIndex":[ +- 0 +- ] ++ "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt2-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16031, +- "interface":"eth-rt5" ++ "interface":"eth-rt2-1" + } + ] + }, +@@ -179,17 +127,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.6.5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.7.6" ++ "nexthop":"10.0.6.5" + } + ] + }, +@@ -201,17 +139,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt6" ++ "interface":"eth-rt5" + } + ] + }, +@@ -223,17 +151,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.7.6", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.6.5" ++ "nexthop":"10.0.7.6" + } + ] + }, +@@ -245,17 +163,7 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt6", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt5" ++ "interface":"eth-rt6" + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..aa319a3232 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff @@ -0,0 +1,312 @@ +--- rt4/step4/show_ip_route.ref 2020-09-25 17:49:02.163655010 -0300 ++++ rt4/step5/show_ip_route.ref 2020-09-25 17:50:12.800576153 -0300 +@@ -15,6 +15,9 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 16010 + ] +@@ -25,10 +28,21 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 16010 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", ++ "active":true ++ } + ] + } + ], +@@ -48,6 +62,9 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -58,10 +75,25 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", ++ "active":true, ++ "labels":[ ++ 16030, ++ 16020 ++ ] ++ } + ] + } + ], +@@ -124,10 +156,21 @@ + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.7.6", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt6", ++ "active":true ++ } + ] + } + ], +@@ -147,10 +190,21 @@ + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", ++ "active":true ++ } + ] + } + ], +@@ -169,13 +223,27 @@ + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", + "active":true + } + ] +@@ -191,13 +259,30 @@ + { + "ip":"10.0.2.2", + "afi":"ipv4", +- "interfaceName":"eth-rt2-1" ++ "interfaceName":"eth-rt2-1", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", ++ "active":true, ++ "labels":[ ++ 16030 ++ ] + } + ] + } +@@ -213,12 +298,29 @@ + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", +- "interfaceName":"eth-rt2-2" ++ "interfaceName":"eth-rt2-2", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", ++ "active":true, ++ "labels":[ ++ 16030 ++ ] + } + ] + } +@@ -238,6 +340,31 @@ + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", ++ "active":true, ++ "backupIndex":[ ++ 0, ++ 1, ++ 2 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.7.6", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt6", ++ "active":true ++ }, ++ { ++ "ip":"10.0.2.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2-1", ++ "active":true ++ }, ++ { ++ "ip":"10.0.3.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2-2", + "active":true + } + ] +@@ -258,6 +385,31 @@ + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", ++ "active":true, ++ "backupIndex":[ ++ 0, ++ 1, ++ 2 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.7.6", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt6", ++ "active":true ++ }, ++ { ++ "ip":"10.0.2.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2-1", ++ "active":true ++ }, ++ { ++ "ip":"10.0.3.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2-2", + "active":true + } + ] +@@ -273,7 +425,18 @@ + { + "ip":"10.0.6.5", + "afi":"ipv4", +- "interfaceName":"eth-rt5" ++ "interfaceName":"eth-rt5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.7.6", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt6", ++ "active":true + } + ] + } +@@ -288,7 +451,18 @@ + { + "ip":"10.0.7.6", + "afi":"ipv4", +- "interfaceName":"eth-rt6" ++ "interfaceName":"eth-rt6", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.5", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt5", ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..1bd207854c --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff @@ -0,0 +1,110 @@ +--- rt4/step4/show_ipv6_route.ref 2020-09-25 17:49:03.399671119 -0300 ++++ rt4/step5/show_ipv6_route.ref 2020-09-25 17:50:14.040592332 -0300 +@@ -14,6 +14,9 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 16011 + ] +@@ -23,10 +26,20 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 16011 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5", ++ "active":true ++ } + ] + } + ], +@@ -45,6 +58,9 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -54,10 +70,24 @@ + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5", ++ "active":true, ++ "labels":[ ++ 16031, ++ 16021 ++ ] ++ } + ] + } + ], +@@ -116,10 +146,20 @@ + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt6", ++ "active":true ++ } + ] + } + ], +@@ -138,10 +178,20 @@ + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt5", ++ "active":true ++ } + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff new file mode 100644 index 0000000000..664b129a1b --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff @@ -0,0 +1,194 @@ +--- rt4/step4/show_mpls_table.ref 2020-09-25 17:49:00.959639319 -0300 ++++ rt4/step5/show_mpls_table.ref 2020-09-25 17:50:11.488559034 -0300 +@@ -7,13 +7,26 @@ + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, +- "nexthop":"10.0.3.2" ++ "nexthop":"10.0.3.2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, +- "nexthop":"10.0.2.2" ++ "nexthop":"10.0.2.2", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.6.5" + } + ] + }, +@@ -25,13 +38,26 @@ + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, +- "interface":"eth-rt2-2" ++ "interface":"eth-rt2-2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, +- "interface":"eth-rt2-1" ++ "interface":"eth-rt2-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt5" + } + ] + }, +@@ -43,13 +69,26 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.3.2" ++ "nexthop":"10.0.3.2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.2.2" ++ "nexthop":"10.0.2.2", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16030, ++ "nexthop":"10.0.6.5" + } + ] + }, +@@ -61,13 +100,26 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt2-2" ++ "interface":"eth-rt2-2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt2-1" ++ "interface":"eth-rt2-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16031, ++ "interface":"eth-rt5" + } + ] + }, +@@ -127,7 +179,17 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.6.5" ++ "nexthop":"10.0.6.5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.7.6" + } + ] + }, +@@ -139,7 +201,17 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5" ++ "interface":"eth-rt5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt6" + } + ] + }, +@@ -151,7 +223,17 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.7.6" ++ "nexthop":"10.0.7.6", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.6.5" + } + ] + }, +@@ -163,7 +245,17 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt6" ++ "interface":"eth-rt6", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt5" + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..c758b89839 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff @@ -0,0 +1,38 @@ +--- rt4/step5/show_ip_route.ref 2020-09-25 17:50:12.800576153 -0300 ++++ rt4/step6/show_ip_route.ref 2020-09-25 17:51:15.725397558 -0300 +@@ -90,7 +90,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16030, ++ 30030, + 16020 + ] + } +@@ -134,7 +134,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16030 ++ 30030 + ] + } + ] +@@ -281,7 +281,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16030 ++ 30030 + ] + } + ] +@@ -319,7 +319,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16030 ++ 30030 + ] + } + ] diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..ca495216dd --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff @@ -0,0 +1,20 @@ +--- rt4/step5/show_ipv6_route.ref 2020-09-25 17:50:14.040592332 -0300 ++++ rt4/step6/show_ipv6_route.ref 2020-09-25 17:51:16.969413804 -0300 +@@ -84,7 +84,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16031, ++ 30031, + 16021 + ] + } +@@ -116,7 +116,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16031 ++ 30031 + ] + }, + { diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff new file mode 100644 index 0000000000..630e0419cf --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff @@ -0,0 +1,38 @@ +--- rt4/step5/show_mpls_table.ref 2020-09-25 17:50:11.488559034 -0300 ++++ rt4/step6/show_mpls_table.ref 2020-09-25 17:51:14.481381312 -0300 +@@ -87,7 +87,7 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16030, ++ "outLabel":30030, + "nexthop":"10.0.6.5" + } + ] +@@ -118,7 +118,7 @@ + "backupNexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16031, ++ "outLabel":30031, + "interface":"eth-rt5" + } + ] +@@ -141,7 +141,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":16030, ++ "outLabel":30030, + "installed":true, + "nexthop":"10.0.6.5" + } +@@ -165,7 +165,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":16031, ++ "outLabel":30031, + "installed":true, + "interface":"eth-rt5" + } diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..30e0dcf3c0 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff @@ -0,0 +1,12 @@ +--- rt4/step6/show_ip_route.ref 2020-09-25 17:51:15.725397558 -0300 ++++ rt4/step7/show_ip_route.ref 2020-09-25 17:52:02.614010084 -0300 +@@ -158,9 +158,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..2606027d75 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff @@ -0,0 +1,12 @@ +--- rt4/step6/show_ipv6_route.ref 2020-09-25 17:51:16.969413804 -0300 ++++ rt4/step7/show_ipv6_route.ref 2020-09-25 17:52:03.854026287 -0300 +@@ -148,9 +148,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff new file mode 100644 index 0000000000..5334cfd048 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff @@ -0,0 +1,53 @@ +--- rt4/step6/show_mpls_table.ref 2020-09-25 17:51:14.481381312 -0300 ++++ rt4/step7/show_mpls_table.ref 2020-09-25 17:52:01.385994037 -0300 +@@ -171,50 +171,6 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.6.5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.7.6" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt6" +- } +- ] +- }, + "16060":{ + "inLabel":16060, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..b393970e42 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff @@ -0,0 +1,12 @@ +--- rt4/step7/show_ip_route.ref 2020-09-25 17:52:02.614010084 -0300 ++++ rt4/step8/show_ip_route.ref 2020-09-25 17:53:20.623029909 -0300 +@@ -158,6 +158,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..8bad2edcf3 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff @@ -0,0 +1,12 @@ +--- rt4/step7/show_ipv6_route.ref 2020-09-25 17:52:03.854026287 -0300 ++++ rt4/step8/show_ipv6_route.ref 2020-09-25 17:53:21.843045865 -0300 +@@ -148,6 +148,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff new file mode 100644 index 0000000000..d296dbdcaf --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff @@ -0,0 +1,53 @@ +--- rt4/step7/show_mpls_table.ref 2020-09-25 17:52:01.385994037 -0300 ++++ rt4/step8/show_mpls_table.ref 2020-09-25 17:53:19.371013534 -0300 +@@ -171,6 +171,50 @@ + } + ] + }, ++ "16050":{ ++ "inLabel":16050, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.6.5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.7.6" ++ } ++ ] ++ }, ++ "16051":{ ++ "inLabel":16051, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt6" ++ } ++ ] ++ }, + "16060":{ + "inLabel":16060, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff new file mode 100644 index 0000000000..408cbfb0ba --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff @@ -0,0 +1,102 @@ +--- rt4/step8/show_mpls_table.ref 2020-09-25 17:53:19.371013534 -0300 ++++ rt4/step9/show_mpls_table.ref 2020-09-25 17:54:37.064030042 -0300 +@@ -171,15 +171,15 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, ++ "16060":{ ++ "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.6.5", ++ "nexthop":"10.0.7.6", + "backupIndex":[ + 0 + ] +@@ -189,19 +189,19 @@ + { + "type":"SR (IS-IS)", + "outLabel":3, +- "nexthop":"10.0.7.6" ++ "nexthop":"10.0.6.5" + } + ] + }, +- "16051":{ +- "inLabel":16051, ++ "16061":{ ++ "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt5", ++ "interface":"eth-rt6", + "backupIndex":[ + 0 + ] +@@ -211,19 +211,19 @@ + { + "type":"SR (IS-IS)", + "outLabel":3, +- "interface":"eth-rt6" ++ "interface":"eth-rt5" + } + ] + }, +- "16060":{ +- "inLabel":16060, ++ "16500":{ ++ "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.7.6", ++ "nexthop":"10.0.6.5", + "backupIndex":[ + 0 + ] +@@ -233,19 +233,19 @@ + { + "type":"SR (IS-IS)", + "outLabel":3, +- "nexthop":"10.0.6.5" ++ "nexthop":"10.0.7.6" + } + ] + }, +- "16061":{ +- "inLabel":16061, ++ "16501":{ ++ "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt6", ++ "interface":"eth-rt5", + "backupIndex":[ + 0 + ] +@@ -255,7 +255,7 @@ + { + "type":"SR (IS-IS)", + "outLabel":3, +- "interface":"eth-rt5" ++ "interface":"eth-rt6" + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt4/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt4/zebra.conf new file mode 100644 index 0000000000..4945897e9d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt4/zebra.conf @@ -0,0 +1,28 @@ +log file zebra.log +! +hostname rt4 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 4.4.4.4/32 + ipv6 address 2001:db8:1000::4/128 +! +interface eth-rt2-1 + ip address 10.0.2.4/24 +! +interface eth-rt2-2 + ip address 10.0.3.4/24 +! +interface eth-rt5 + ip address 10.0.6.4/24 +! +interface eth-rt6 + ip address 10.0.7.4/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-tilfa-topo1/rt5/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt5/isisd.conf new file mode 100644 index 0000000000..be52eb0322 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/isisd.conf @@ -0,0 +1,53 @@ +hostname rt5 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis sr-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt3-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt3-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt4 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt6 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +router isis 1 + net 49.0000.0000.0000.0005.00 + is-type level-1 + lsp-gen-interval 2 + topology ipv6-unicast + segment-routing on + segment-routing global-block 16000 23999 + segment-routing node-msd 8 + segment-routing prefix 5.5.5.5/32 index 50 + segment-routing prefix 2001:db8:1000::5/128 index 51 +! diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref new file mode 100644 index 0000000000..f747065f9c --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref @@ -0,0 +1,497 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..6c0a5e0b9b --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref @@ -0,0 +1,198 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref new file mode 100644 index 0000000000..2b70392adc --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref @@ -0,0 +1,262 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.6.4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.8.6" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.6.4" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..1ff8c2cd4e --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,82 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt3-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt3-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt4", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt6", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0006", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..6402b51893 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff @@ -0,0 +1,125 @@ +--- rt5/step3/show_ip_route.ref 2020-09-25 17:48:05.950922766 -0300 ++++ rt5/step4/show_ip_route.ref 2020-09-25 17:49:02.363657616 -0300 +@@ -81,10 +81,7 @@ + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16020 +- ] ++ "active":true + } + ] + } +@@ -105,9 +102,6 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -118,25 +112,10 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16020, +- 16030 +- ] +- } + ] + } + ], +@@ -158,9 +137,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], +@@ -349,30 +325,13 @@ + { + "ip":"10.0.4.3", + "afi":"ipv4", +- "interfaceName":"eth-rt3-1", +- "backupIndex":[ +- 0 +- ] ++ "interfaceName":"eth-rt3-1" + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16020 +- ] ++ "active":true + } + ] + } +@@ -388,29 +347,12 @@ + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", +- "active":true, +- "backupIndex":[ +- 0 +- ] ++ "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", +- "interfaceName":"eth-rt3-2", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.6.4", +- "afi":"ipv4", +- "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16020 +- ] ++ "interfaceName":"eth-rt3-2" + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..7a0135bf04 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff @@ -0,0 +1,59 @@ +--- rt5/step3/show_ipv6_route.ref 2020-09-25 17:48:07.218939274 -0300 ++++ rt5/step4/show_ipv6_route.ref 2020-09-25 17:49:03.599673726 -0300 +@@ -57,10 +57,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16021 +- ] ++ "active":true + }, + { + "fib":true, +@@ -98,9 +95,6 @@ + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] +@@ -110,24 +104,10 @@ + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, +- "backupIndex":[ +- 0 +- ], + "labels":[ + 3 + ] + } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16021, +- 16031 +- ] +- } + ] + } + ], +@@ -148,9 +128,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff new file mode 100644 index 0000000000..299dac7640 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff @@ -0,0 +1,130 @@ +--- rt5/step3/show_mpls_table.ref 2020-09-25 17:48:04.626905528 -0300 ++++ rt5/step4/show_mpls_table.ref 2020-09-25 17:49:01.159641924 -0300 +@@ -76,12 +76,6 @@ + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16020, +- "installed":true, +- "nexthop":"10.0.6.4" + } + ] + }, +@@ -100,12 +94,6 @@ + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16021, +- "installed":true, +- "interface":"eth-rt4" + } + ] + }, +@@ -117,26 +105,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.5.3", +- "backupIndex":[ +- 0 +- ] ++ "nexthop":"10.0.5.3" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.4.3", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16020, +- "nexthop":"10.0.6.4" ++ "nexthop":"10.0.4.3" + } + ] + }, +@@ -148,70 +123,13 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt3-2", +- "backupIndex":[ +- 0 +- ] ++ "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt3-1", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":16021, +- "interface":"eth-rt4" +- } +- ] +- }, +- "16040":{ +- "inLabel":16040, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.6.4", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.8.6" +- } +- ] +- }, +- "16041":{ +- "inLabel":16041, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt4", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt6" ++ "interface":"eth-rt3-1" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..31f70b17a3 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff @@ -0,0 +1,125 @@ +--- rt5/step4/show_ip_route.ref 2020-09-25 17:49:02.363657616 -0300 ++++ rt5/step5/show_ip_route.ref 2020-09-25 17:50:13.012578918 -0300 +@@ -81,7 +81,10 @@ + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", +- "active":true ++ "active":true, ++ "labels":[ ++ 16020 ++ ] + } + ] + } +@@ -102,6 +105,9 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -112,10 +118,25 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4", ++ "active":true, ++ "labels":[ ++ 16020, ++ 16030 ++ ] ++ } + ] + } + ], +@@ -137,6 +158,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], +@@ -325,13 +349,30 @@ + { + "ip":"10.0.4.3", + "afi":"ipv4", +- "interfaceName":"eth-rt3-1" ++ "interfaceName":"eth-rt3-1", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4", ++ "active":true, ++ "labels":[ ++ 16020 ++ ] + } + ] + } +@@ -347,12 +388,29 @@ + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", +- "interfaceName":"eth-rt3-2" ++ "interfaceName":"eth-rt3-2", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.6.4", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt4", ++ "active":true, ++ "labels":[ ++ 16020 ++ ] + } + ] + } diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..59d9755e18 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff @@ -0,0 +1,59 @@ +--- rt5/step4/show_ipv6_route.ref 2020-09-25 17:49:03.599673726 -0300 ++++ rt5/step5/show_ipv6_route.ref 2020-09-25 17:50:14.248595046 -0300 +@@ -57,7 +57,10 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", +- "active":true ++ "active":true, ++ "labels":[ ++ 16021 ++ ] + }, + { + "fib":true, +@@ -95,6 +98,9 @@ + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] +@@ -104,10 +110,24 @@ + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, ++ "backupIndex":[ ++ 0 ++ ], + "labels":[ + 3 + ] + } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt4", ++ "active":true, ++ "labels":[ ++ 16021, ++ 16031 ++ ] ++ } + ] + } + ], +@@ -128,6 +148,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff new file mode 100644 index 0000000000..669c07e344 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff @@ -0,0 +1,130 @@ +--- rt5/step4/show_mpls_table.ref 2020-09-25 17:49:01.159641924 -0300 ++++ rt5/step5/show_mpls_table.ref 2020-09-25 17:50:11.696561748 -0300 +@@ -69,6 +69,12 @@ + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, ++ "nexthop":"10.0.6.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16020, ++ "installed":true, + "nexthop":"10.0.5.3" + }, + { +@@ -87,6 +93,12 @@ + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, ++ "interface":"eth-rt4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16021, ++ "installed":true, + "interface":"eth-rt3-2" + }, + { +@@ -105,13 +117,26 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.5.3" ++ "nexthop":"10.0.5.3", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "nexthop":"10.0.4.3" ++ "nexthop":"10.0.4.3", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16020, ++ "nexthop":"10.0.6.4" + } + ] + }, +@@ -123,13 +148,70 @@ + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt3-2" ++ "interface":"eth-rt3-2", ++ "backupIndex":[ ++ 0 ++ ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, +- "interface":"eth-rt3-1" ++ "interface":"eth-rt3-1", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16021, ++ "interface":"eth-rt4" ++ } ++ ] ++ }, ++ "16040":{ ++ "inLabel":16040, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.6.4", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.8.6" ++ } ++ ] ++ }, ++ "16041":{ ++ "inLabel":16041, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt4", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt6" + } + ] + }, diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff new file mode 100644 index 0000000000..a4f82cbf10 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff @@ -0,0 +1,146 @@ +--- rt5/step5/show_mpls_table.ref 2020-09-25 17:50:11.696561748 -0300 ++++ rt5/step6/show_mpls_table.ref 2020-09-25 17:51:14.685383977 -0300 +@@ -1,6 +1,6 @@ + { +- "16010":{ +- "inLabel":16010, ++ "30010":{ ++ "inLabel":30010, + "installed":true, + "nexthops":[ + { +@@ -30,8 +30,8 @@ + } + ] + }, +- "16011":{ +- "inLabel":16011, ++ "30011":{ ++ "inLabel":30011, + "installed":true, + "nexthops":[ + { +@@ -61,56 +61,56 @@ + } + ] + }, +- "16020":{ +- "inLabel":16020, ++ "30020":{ ++ "inLabel":30020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, +- "nexthop":"10.0.6.4" ++ "nexthop":"10.0.5.3" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, +- "nexthop":"10.0.5.3" ++ "nexthop":"10.0.4.3" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, +- "nexthop":"10.0.4.3" ++ "nexthop":"10.0.6.4" + } + ] + }, +- "16021":{ +- "inLabel":16021, ++ "30021":{ ++ "inLabel":30021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, +- "interface":"eth-rt4" ++ "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, +- "interface":"eth-rt3-2" ++ "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, +- "interface":"eth-rt3-1" ++ "interface":"eth-rt4" + } + ] + }, +- "16030":{ +- "inLabel":16030, ++ "30030":{ ++ "inLabel":30030, + "installed":true, + "nexthops":[ + { +@@ -140,8 +140,8 @@ + } + ] + }, +- "16031":{ +- "inLabel":16031, ++ "30031":{ ++ "inLabel":30031, + "installed":true, + "nexthops":[ + { +@@ -171,8 +171,8 @@ + } + ] + }, +- "16040":{ +- "inLabel":16040, ++ "30040":{ ++ "inLabel":30040, + "installed":true, + "nexthops":[ + { +@@ -193,8 +193,8 @@ + } + ] + }, +- "16041":{ +- "inLabel":16041, ++ "30041":{ ++ "inLabel":30041, + "installed":true, + "nexthops":[ + { +@@ -215,8 +215,8 @@ + } + ] + }, +- "16060":{ +- "inLabel":16060, ++ "30060":{ ++ "inLabel":30060, + "installed":true, + "nexthops":[ + { +@@ -237,8 +237,8 @@ + } + ] + }, +- "16061":{ +- "inLabel":16061, ++ "30061":{ ++ "inLabel":30061, + "installed":true, + "nexthops":[ + { diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt5/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt5/zebra.conf new file mode 100644 index 0000000000..4cfea1a59f --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt5/zebra.conf @@ -0,0 +1,28 @@ +log file zebra.log +! +hostname rt5 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 5.5.5.5/32 + ipv6 address 2001:db8:1000::5/128 +! +interface eth-rt3-1 + ip address 10.0.4.5/24 +! +interface eth-rt3-2 + ip address 10.0.5.5/24 +! +interface eth-rt4 + ip address 10.0.6.5/24 +! +interface eth-rt6 + ip address 10.0.8.5/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-tilfa-topo1/rt6/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt6/isisd.conf new file mode 100644 index 0000000000..db47622a10 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/isisd.conf @@ -0,0 +1,39 @@ +hostname rt6 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis sr-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt4 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +interface eth-rt5 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-multiplier 3 + isis fast-reroute ti-lfa +! +router isis 1 + net 49.0000.0000.0000.0006.00 + is-type level-1 + lsp-gen-interval 2 + topology ipv6-unicast + segment-routing on + segment-routing global-block 16000 23999 + segment-routing node-msd 8 + segment-routing prefix 6.6.6.6/32 index 60 + segment-routing prefix 2001:db8:1000::6/128 index 61 +! diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref new file mode 100644 index 0000000000..5bcef4c2f6 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref @@ -0,0 +1,401 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..8294b07136 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref @@ -0,0 +1,161 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref new file mode 100644 index 0000000000..33dbf59204 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref @@ -0,0 +1,214 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.8.5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.8.5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.8.5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.7.4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.8.5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.7.4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..734832358f --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,44 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt4", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt5", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_mpls_table.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_mpls_table.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..04adaefe78 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff @@ -0,0 +1,34 @@ +--- rt6/step3/show_ip_route.ref 2020-09-25 17:48:06.154925422 -0300 ++++ rt6/step4/show_ip_route.ref 2020-09-25 17:49:02.583660484 -0300 +@@ -14,10 +14,7 @@ + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16010 +- ] ++ "active":true + }, + { + "fib":true, +@@ -50,9 +47,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 16020 + ] + } + ], +@@ -118,9 +112,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..20aa1ec83b --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff @@ -0,0 +1,34 @@ +--- rt6/step3/show_ipv6_route.ref 2020-09-25 17:48:07.434942087 -0300 ++++ rt6/step4/show_ipv6_route.ref 2020-09-25 17:49:03.847676958 -0300 +@@ -22,10 +22,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", +- "active":true, +- "labels":[ +- 16011 +- ] ++ "active":true + } + ] + } +@@ -47,9 +44,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 16021 + ] + } + ], +@@ -111,9 +105,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff new file mode 100644 index 0000000000..3f24547f6d --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff @@ -0,0 +1,79 @@ +--- rt6/step3/show_mpls_table.ref 2020-09-25 17:48:04.842908340 -0300 ++++ rt6/step4/show_mpls_table.ref 2020-09-25 17:49:01.363644584 -0300 +@@ -7,12 +7,6 @@ + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, +- "nexthop":"10.0.7.4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16010, +- "installed":true, + "nexthop":"10.0.8.5" + } + ] +@@ -25,12 +19,6 @@ + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, +- "interface":"eth-rt4" +- }, +- { +- "type":"SR (IS-IS)", +- "outLabel":16011, +- "installed":true, + "interface":"eth-rt5" + } + ] +@@ -123,50 +111,6 @@ + } + ] + }, +- "16040":{ +- "inLabel":16040, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.7.4", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.8.5" +- } +- ] +- }, +- "16041":{ +- "inLabel":16041, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt4", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt5" +- } +- ] +- }, + "16050":{ + "inLabel":16050, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..9f73a2904e --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff @@ -0,0 +1,34 @@ +--- rt6/step4/show_ip_route.ref 2020-09-25 17:49:02.583660484 -0300 ++++ rt6/step5/show_ip_route.ref 2020-09-25 17:50:13.220581632 -0300 +@@ -14,7 +14,10 @@ + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", +- "active":true ++ "active":true, ++ "labels":[ ++ 16010 ++ ] + }, + { + "fib":true, +@@ -47,6 +50,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 16020 + ] + } + ], +@@ -112,6 +118,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..c9358d45b2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff @@ -0,0 +1,34 @@ +--- rt6/step4/show_ipv6_route.ref 2020-09-25 17:49:03.847676958 -0300 ++++ rt6/step5/show_ipv6_route.ref 2020-09-25 17:50:14.456597760 -0300 +@@ -22,7 +22,10 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", +- "active":true ++ "active":true, ++ "labels":[ ++ 16011 ++ ] + } + ] + } +@@ -44,6 +47,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 16021 + ] + } + ], +@@ -105,6 +111,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff new file mode 100644 index 0000000000..c9d67955ef --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff @@ -0,0 +1,79 @@ +--- rt6/step4/show_mpls_table.ref 2020-09-25 17:49:01.363644584 -0300 ++++ rt6/step5/show_mpls_table.ref 2020-09-25 17:50:11.904564461 -0300 +@@ -7,6 +7,12 @@ + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, ++ "nexthop":"10.0.7.4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16010, ++ "installed":true, + "nexthop":"10.0.8.5" + } + ] +@@ -19,6 +25,12 @@ + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, ++ "interface":"eth-rt4" ++ }, ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":16011, ++ "installed":true, + "interface":"eth-rt5" + } + ] +@@ -111,6 +123,50 @@ + } + ] + }, ++ "16040":{ ++ "inLabel":16040, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.7.4", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.8.5" ++ } ++ ] ++ }, ++ "16041":{ ++ "inLabel":16041, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt4", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt5" ++ } ++ ] ++ }, + "16050":{ + "inLabel":16050, + "installed":true, diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..527ec74958 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff @@ -0,0 +1,20 @@ +--- rt6/step5/show_ip_route.ref 2020-09-25 17:50:13.220581632 -0300 ++++ rt6/step6/show_ip_route.ref 2020-09-25 17:51:16.137402938 -0300 +@@ -26,7 +26,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16010 ++ 30010 + ] + } + ] +@@ -86,7 +86,7 @@ + 0 + ], + "labels":[ +- 16030 ++ 30030 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..7b8f8022f2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff @@ -0,0 +1,20 @@ +--- rt6/step5/show_ipv6_route.ref 2020-09-25 17:50:14.456597760 -0300 ++++ rt6/step6/show_ipv6_route.ref 2020-09-25 17:51:17.401419446 -0300 +@@ -15,7 +15,7 @@ + "interfaceName":"eth-rt5", + "active":true, + "labels":[ +- 16011 ++ 30011 + ] + }, + { +@@ -81,7 +81,7 @@ + 0 + ], + "labels":[ +- 16031 ++ 30031 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff new file mode 100644 index 0000000000..edd5afeeb8 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff @@ -0,0 +1,38 @@ +--- rt6/step5/show_mpls_table.ref 2020-09-25 17:50:11.904564461 -0300 ++++ rt6/step6/show_mpls_table.ref 2020-09-25 17:51:14.893386692 -0300 +@@ -11,7 +11,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":16010, ++ "outLabel":30010, + "installed":true, + "nexthop":"10.0.8.5" + } +@@ -29,7 +29,7 @@ + }, + { + "type":"SR (IS-IS)", +- "outLabel":16011, ++ "outLabel":30011, + "installed":true, + "interface":"eth-rt5" + } +@@ -85,7 +85,7 @@ + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16030, ++ "outLabel":30030, + "installed":true, + "nexthop":"10.0.8.5", + "backupIndex":[ +@@ -107,7 +107,7 @@ + "nexthops":[ + { + "type":"SR (IS-IS)", +- "outLabel":16031, ++ "outLabel":30031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..7553dd22e5 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff @@ -0,0 +1,12 @@ +--- rt6/step6/show_ip_route.ref 2020-09-25 17:51:16.137402938 -0300 ++++ rt6/step7/show_ip_route.ref 2020-09-25 17:52:03.018015363 -0300 +@@ -152,9 +152,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..b56890de0f --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff @@ -0,0 +1,12 @@ +--- rt6/step6/show_ipv6_route.ref 2020-09-25 17:51:17.401419446 -0300 ++++ rt6/step7/show_ipv6_route.ref 2020-09-25 17:52:04.270031723 -0300 +@@ -143,9 +143,6 @@ + "active":true, + "backupIndex":[ + 0 +- ], +- "labels":[ +- 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff new file mode 100644 index 0000000000..ff043fb0bf --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff @@ -0,0 +1,52 @@ +--- rt6/step6/show_mpls_table.ref 2020-09-25 17:51:14.893386692 -0300 ++++ rt6/step7/show_mpls_table.ref 2020-09-25 17:52:01.809999577 -0300 +@@ -166,49 +166,5 @@ + "interface":"eth-rt5" + } + ] +- }, +- "16050":{ +- "inLabel":16050, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "nexthop":"10.0.8.5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "nexthop":"10.0.7.4" +- } +- ] +- }, +- "16051":{ +- "inLabel":16051, +- "installed":true, +- "nexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "installed":true, +- "interface":"eth-rt5", +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "type":"SR (IS-IS)", +- "outLabel":3, +- "interface":"eth-rt4" +- } +- ] + } + } diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..d0b25bffa3 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff @@ -0,0 +1,12 @@ +--- rt6/step7/show_ip_route.ref 2020-09-25 17:52:03.018015363 -0300 ++++ rt6/step8/show_ip_route.ref 2020-09-25 17:53:21.035035298 -0300 +@@ -152,6 +152,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..203175510c --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff @@ -0,0 +1,12 @@ +--- rt6/step7/show_ipv6_route.ref 2020-09-25 17:52:04.270031723 -0300 ++++ rt6/step8/show_ipv6_route.ref 2020-09-25 17:53:22.239051045 -0300 +@@ -143,6 +143,9 @@ + "active":true, + "backupIndex":[ + 0 ++ ], ++ "labels":[ ++ 3 + ] + } + ], diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff new file mode 100644 index 0000000000..535f30bf35 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff @@ -0,0 +1,52 @@ +--- rt6/step7/show_mpls_table.ref 2020-09-25 17:52:01.809999577 -0300 ++++ rt6/step8/show_mpls_table.ref 2020-09-25 17:53:19.799019132 -0300 +@@ -166,5 +166,49 @@ + "interface":"eth-rt5" + } + ] ++ }, ++ "16050":{ ++ "inLabel":16050, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "nexthop":"10.0.8.5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "nexthop":"10.0.7.4" ++ } ++ ] ++ }, ++ "16051":{ ++ "inLabel":16051, ++ "installed":true, ++ "nexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "installed":true, ++ "interface":"eth-rt5", ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "type":"SR (IS-IS)", ++ "outLabel":3, ++ "interface":"eth-rt4" ++ } ++ ] + } + } diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ip_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff new file mode 100644 index 0000000000..b6e5396554 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff @@ -0,0 +1,24 @@ +--- rt6/step8/show_mpls_table.ref 2020-09-25 17:53:19.799019132 -0300 ++++ rt6/step9/show_mpls_table.ref 2020-09-25 17:54:37.492035644 -0300 +@@ -167,8 +167,8 @@ + } + ] + }, +- "16050":{ +- "inLabel":16050, ++ "16500":{ ++ "inLabel":16500, + "installed":true, + "nexthops":[ + { +@@ -189,8 +189,8 @@ + } + ] + }, +- "16051":{ +- "inLabel":16051, ++ "16501":{ ++ "inLabel":16501, + "installed":true, + "nexthops":[ + { diff --git a/tests/topotests/isis-tilfa-topo1/rt6/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt6/zebra.conf new file mode 100644 index 0000000000..6084010a93 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/rt6/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt6 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 6.6.6.6/32 + ipv6 address 2001:db8:1000::6/128 +! +interface eth-rt4 + ip address 10.0.7.6/24 +! +interface eth-rt5 + ip address 10.0.8.6/24 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py new file mode 100755 index 0000000000..6bc097b0e7 --- /dev/null +++ b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py @@ -0,0 +1,674 @@ +#!/usr/bin/env python + +# +# test_isis_tilfa_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2020 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_isis_tilfa_topo1.py: + + +---------+ + | | + | RT1 | + | 1.1.1.1 | + | | + +---------+ + |eth-sw1 + | + | + | + +---------+ | +---------+ + | | | | | + | RT2 |eth-sw1 | eth-sw1| RT3 | + | 2.2.2.2 +----------+----------+ 3.3.3.3 | + | | 10.0.1.0/24 | | + +---------+ +---------+ + eth-rt4-1| |eth-rt4-2 eth-rt5-1| |eth-rt5-2 + | | | | + 10.0.2.0/24| |10.0.3.0/24 10.0.4.0/24| |10.0.5.0/24 + | | | | + eth-rt2-1| |eth-rt2-2 eth-rt3-1| |eth-rt3-2 + +---------+ +---------+ + | | | | + | RT4 | 10.0.6.0/24 | RT5 | + | 4.4.4.4 +---------------------+ 5.5.5.5 | + | |eth-rt5 eth-rt4| | + +---------+ +---------+ + eth-rt6| |eth-rt6 + | | + 10.0.7.0/24| |10.0.8.0/24 + | +---------+ | + | | | | + | | RT6 | | + +----------+ 6.6.6.6 +-----------+ + eth-rt4| |eth-rt5 + +---------+ +""" + +import os +import sys +import pytest +import json +import re +import tempfile +from time import sleep +from functools import partial + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, '../')) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. +from mininet.topo import Topo + +# Global multi-dimensional dictionary containing all expected outputs +outputs = {} + +class TemplateTopo(Topo): + "Test topology builder" + def build(self, *_args, **_opts): + "Build function" + tgen = get_topogen(self) + + # + # Define FRR Routers + # + for router in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + tgen.add_router(router) + + # + # Define connections + # + switch = tgen.add_switch('s1') + switch.add_link(tgen.gears['rt1'], nodeif="eth-sw1") + switch.add_link(tgen.gears['rt2'], nodeif="eth-sw1") + switch.add_link(tgen.gears['rt3'], nodeif="eth-sw1") + + switch = tgen.add_switch('s2') + switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-1") + switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-1") + + switch = tgen.add_switch('s3') + switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-2") + switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-2") + + switch = tgen.add_switch('s4') + switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-1") + switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-1") + + switch = tgen.add_switch('s5') + switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-2") + switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-2") + + switch = tgen.add_switch('s6') + switch.add_link(tgen.gears['rt4'], nodeif="eth-rt5") + switch.add_link(tgen.gears['rt5'], nodeif="eth-rt4") + + switch = tgen.add_switch('s7') + switch.add_link(tgen.gears['rt4'], nodeif="eth-rt6") + switch.add_link(tgen.gears['rt6'], nodeif="eth-rt4") + + switch = tgen.add_switch('s8') + switch.add_link(tgen.gears['rt5'], nodeif="eth-rt6") + switch.add_link(tgen.gears['rt6'], nodeif="eth-rt5") + + # + # Populate multi-dimensional dictionary containing all expected outputs + # + files = ["show_ip_route.ref", + "show_ipv6_route.ref", + "show_mpls_table.ref", + "show_yang_interface_isis_adjacencies.ref"] + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + outputs[rname] = {} + for step in range(1, 9 + 1): + outputs[rname][step] = {} + for file in files: + if step == 1: + # Get snapshots relative to the expected initial network convergence + filename = '{}/{}/step{}/{}'.format(CWD, rname, step, file) + outputs[rname][step][file] = open(filename).read() + else: + if file == "show_yang_interface_isis_adjacencies.ref": + continue + + # Get diff relative to the previous step + filename = '{}/{}/step{}/{}.diff'.format(CWD, rname, step, file) + + # Create temporary files in order to apply the diff + f_in = tempfile.NamedTemporaryFile() + f_in.write(outputs[rname][step - 1][file]) + f_in.flush() + f_out = tempfile.NamedTemporaryFile() + os.system("patch -s -o %s %s %s" %(f_out.name, f_in.name, filename)) + + # Store the updated snapshot and remove the temporary files + outputs[rname][step][file] = open(f_out.name).read() + f_in.close() + f_out.close() + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + # For all registered routers, load the zebra configuration file + for rname, router in router_list.iteritems(): + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, '{}/zebra.conf'.format(rname)) + ) + router.load_config( + TopoRouter.RD_ISIS, + os.path.join(CWD, '{}/isisd.conf'.format(rname)) + ) + + tgen.start_router() + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + +def router_compare_json_output(rname, command, reference): + "Compare router JSON output" + + logger.info('Comparing router "%s" "%s" output', rname, command) + + tgen = get_topogen() + expected = json.loads(reference) + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(topotest.router_json_cmp, + tgen.gears[rname], command, expected) + _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) + assert diff is None, assertmsg + +# +# Step 1 +# +# Test initial network convergence +# +def test_isis_adjacencies_step1(): + logger.info("Test (step 1): check IS-IS adjacencies") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd", + outputs[rname][1]["show_yang_interface_isis_adjacencies.ref"]) + +def test_rib_ipv4_step1(): + logger.info("Test (step 1): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][1]["show_ip_route.ref"]) + +def test_rib_ipv6_step1(): + logger.info("Test (step 1): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][1]["show_ipv6_route.ref"]) + +def test_mpls_lib_step1(): + logger.info("Test (step 1): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][1]["show_mpls_table.ref"]) + +# +# Step 2 +# +# Action(s): +# -Disable TI-LFA link protection on rt2's eth-sw1 interface +# +# Expected changes: +# -rt2 should uninstall the backup nexthops from destinations reachable over eth-sw1. +# +def test_rib_ipv4_step2(): + logger.info("Test (step 2): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Disabling TI-LFA link protection on rt2\'s eth-sw1 interface') + tgen.net['rt2'].cmd('vtysh -c "conf t" -c "interface eth-sw1" -c "no isis fast-reroute ti-lfa"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][2]["show_ip_route.ref"]) + +def test_rib_ipv6_step2(): + logger.info("Test (step 2): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][2]["show_ipv6_route.ref"]) + +def test_mpls_lib_step2(): + logger.info("Test (step 2): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][2]["show_mpls_table.ref"]) + +# +# Step 3 +# +# Action(s): +# -Enable TI-LFA link protection on rt2's eth-sw1 interface +# +# Expected changes: +# -rt2 should install backup nexthops for destinations reachable over eth-sw1. +# +def test_rib_ipv4_step3(): + logger.info("Test (step 3): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Enabling TI-LFA link protection on rt2\'s eth-sw1 interface') + tgen.net['rt2'].cmd('vtysh -c "conf t" -c "interface eth-sw1" -c "isis fast-reroute ti-lfa"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][3]["show_ip_route.ref"]) + +def test_rib_ipv6_step3(): + logger.info("Test (step 3): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][3]["show_ipv6_route.ref"]) + +def test_mpls_lib_step3(): + logger.info("Test (step 3): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][3]["show_mpls_table.ref"]) + +# +# Step 4 +# +# Action(s): +# -Disable SR on rt4 +# +# Expected changes: +# -rt4 should uninstall all Prefix-SIDs from the network +# -rt4 should uninstall all TI-LFA backup nexthops +# -All routers should uninstall rt4's Prefix-SIDs +# -All routers should uninstall all SR labels for destinations whose nexthop is rt4 +# -All routers should uninstall all TI-LFA backup nexthops that point to rt4 +# -All routers should uninstall all TI-LFA backup nexthops that use rt4's Prefix-SIDs +# +def test_rib_ipv4_step4(): + logger.info("Test (step 4): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Disabling SR on rt4') + tgen.net['rt4'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing on"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][4]["show_ip_route.ref"]) + +def test_rib_ipv6_step4(): + logger.info("Test (step 4): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][4]["show_ipv6_route.ref"]) + +def test_mpls_lib_step4(): + logger.info("Test (step 4): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][4]["show_mpls_table.ref"]) + +# +# Step 5 +# +# Action(s): +# -Enable SR on rt4 +# +# Expected changes: +# -Reverse all changes done on the previous step +# +def test_rib_ipv4_step5(): + logger.info("Test (step 5): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Enabling SR on rt4') + tgen.net['rt4'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing on"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][5]["show_ip_route.ref"]) + +def test_rib_ipv6_step5(): + logger.info("Test (step 5): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][5]["show_ipv6_route.ref"]) + +def test_mpls_lib_step5(): + logger.info("Test (step 5): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][5]["show_mpls_table.ref"]) + +# +# Step 6 +# +# Action(s): +# -Change rt5's SRGB +# +# Expected changes: +# -All routers should update all SR labels for destinations whose primary or backup nexthop is rt5 +# +def test_rib_ipv4_step6(): + logger.info("Test (step 6): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Changing rt5\'s SRGB') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 30000 37999"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][6]["show_ip_route.ref"]) + +def test_rib_ipv6_step6(): + logger.info("Test (step 6): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][6]["show_ipv6_route.ref"]) + +def test_mpls_lib_step6(): + logger.info("Test (step 6): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][6]["show_mpls_table.ref"]) + +# +# Step 7 +# +# Action(s): +# -Delete rt5's Prefix-SIDs +# +# Expected changes: +# -All routers should uninstall rt5's Prefix-SIDs +# -All routers should uninstall all TI-LFA backup nexthops that use rt5's Prefix-SIDs +# +def test_rib_ipv4_step7(): + logger.info("Test (step 7): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Deleting rt5\'s Prefix-SIDs') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 5.5.5.5/32 index 50"') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 2001:db8:1000::5/128 index 51"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][7]["show_ip_route.ref"]) + +def test_rib_ipv6_step7(): + logger.info("Test (step 7): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][7]["show_ipv6_route.ref"]) + +def test_mpls_lib_step7(): + logger.info("Test (step 7): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][7]["show_mpls_table.ref"]) + +# +# Step 8 +# +# Action(s): +# -Re-add rt5's Prefix-SIDs +# +# Expected changes: +# -Reverse all changes done on the previous step +# +def test_rib_ipv4_step8(): + logger.info("Test (step 8): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Re-adding rt5\'s Prefix-SIDs') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 5.5.5.5/32 index 50"') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::5/128 index 51"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][8]["show_ip_route.ref"]) + +def test_rib_ipv6_step8(): + logger.info("Test (step 8): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][8]["show_ipv6_route.ref"]) + +def test_mpls_lib_step8(): + logger.info("Test (step 8): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][8]["show_mpls_table.ref"]) + +# +# Step 9 +# +# Action(s): +# -Change rt5's Prefix-SIDs +# +# Expected changes: +# -All routers should update rt5's Prefix-SIDs +# -All routers should update all TI-LFA backup nexthops that use rt5's Prefix-SIDs +# +def test_rib_ipv4_step9(): + logger.info("Test (step 9): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info('Re-adding rt5\'s Prefix-SIDs') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 5.5.5.5/32 index 500"') + tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::5/128 index 501"') + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ip route isis json", + outputs[rname][9]["show_ip_route.ref"]) + +def test_rib_ipv6_step9(): + logger.info("Test (step 9): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show ipv6 route isis json", + outputs[rname][9]["show_ipv6_route.ref"]) + +def test_mpls_lib_step9(): + logger.info("Test (step 9): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']: + router_compare_json_output(rname, "show mpls table json", + outputs[rname][9]["show_mpls_table.ref"]) + +# Memory leak test template +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip('Memory leak test/report is disabled') + + tgen.report_memory_leaks() + +if __name__ == '__main__': + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis-topo1-vrf/r1/isisd.conf b/tests/topotests/isis-topo1-vrf/r1/isisd.conf index 4ac4597015..5fb4c14d0b 100755 --- a/tests/topotests/isis-topo1-vrf/r1/isisd.conf +++ b/tests/topotests/isis-topo1-vrf/r1/isisd.conf @@ -8,6 +8,7 @@ interface r1-eth0 isis circuit-type level-2-only ! router isis 1 vrf r1-cust1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00 metric-style wide redistribute ipv4 connected level-2 diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route.json b/tests/topotests/isis-topo1-vrf/r1/r1_route.json index 77d2ad9c63..f0a3593a4c 100644 --- a/tests/topotests/isis-topo1-vrf/r1/r1_route.json +++ b/tests/topotests/isis-topo1-vrf/r1/r1_route.json @@ -20,20 +20,6 @@ ], "10.0.20.0/24": [ { - "distance": 115, - "metric": 20, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r1-eth0", - "ip": "10.0.20.1" - } - ], - "prefix": "10.0.20.0/24", - "protocol": "isis", - "vrfName": "r1-cust1" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1-vrf/r2/isisd.conf b/tests/topotests/isis-topo1-vrf/r2/isisd.conf index 4c68540265..0d2bc7ab72 100755 --- a/tests/topotests/isis-topo1-vrf/r2/isisd.conf +++ b/tests/topotests/isis-topo1-vrf/r2/isisd.conf @@ -8,6 +8,7 @@ interface r2-eth0 isis circuit-type level-2-only ! router isis 1 vrf r2-cust1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00 metric-style wide redistribute ipv4 connected level-2 diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route.json b/tests/topotests/isis-topo1-vrf/r2/r2_route.json index 98252c5939..a26cdfad8e 100644 --- a/tests/topotests/isis-topo1-vrf/r2/r2_route.json +++ b/tests/topotests/isis-topo1-vrf/r2/r2_route.json @@ -20,20 +20,6 @@ ], "10.0.21.0/24": [ { - "distance": 115, - "metric": 20, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r2-eth0", - "ip": "10.0.21.1" - } - ], - "prefix": "10.0.21.0/24", - "protocol": "isis", - "vrfName": "r2-cust1" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1-vrf/r3/isisd.conf b/tests/topotests/isis-topo1-vrf/r3/isisd.conf index ca01876690..66092407ab 100755 --- a/tests/topotests/isis-topo1-vrf/r3/isisd.conf +++ b/tests/topotests/isis-topo1-vrf/r3/isisd.conf @@ -13,6 +13,7 @@ interface r3-eth1 isis circuit-type level-1 ! router isis 1 vrf r3-cust1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route.json b/tests/topotests/isis-topo1-vrf/r3/r3_route.json index de158876f1..9717df5c1a 100644 --- a/tests/topotests/isis-topo1-vrf/r3/r3_route.json +++ b/tests/topotests/isis-topo1-vrf/r3/r3_route.json @@ -50,20 +50,6 @@ ], "10.0.20.0/24": [ { - "distance": 115, - "metric": 20, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r3-eth0", - "ip": "10.0.20.2" - } - ], - "prefix": "10.0.20.0/24", - "protocol": "isis", - "vrfName": "r3-cust1" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1-vrf/r4/isisd.conf b/tests/topotests/isis-topo1-vrf/r4/isisd.conf index 74b1603d85..05815e8418 100755 --- a/tests/topotests/isis-topo1-vrf/r4/isisd.conf +++ b/tests/topotests/isis-topo1-vrf/r4/isisd.conf @@ -16,6 +16,7 @@ interface r4-eth1 isis circuit-type level-1 ! router isis 1 vrf r4-cust1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0004.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route.json b/tests/topotests/isis-topo1-vrf/r4/r4_route.json index b3ed4f2cbe..6cb79b0301 100644 --- a/tests/topotests/isis-topo1-vrf/r4/r4_route.json +++ b/tests/topotests/isis-topo1-vrf/r4/r4_route.json @@ -66,18 +66,6 @@ { "nexthops": [ { - "afi": "ipv4", - "interfaceName": "r4-eth0", - "ip": "10.0.21.2" - } - ], - "prefix": "10.0.21.0/24", - "protocol": "isis", - "vrfName": "r4-cust1" - }, - { - "nexthops": [ - { "active": true, "directlyConnected": true, "fib": true, diff --git a/tests/topotests/isis-topo1-vrf/r5/isisd.conf b/tests/topotests/isis-topo1-vrf/r5/isisd.conf index 9e9b030455..f663c33fe9 100755 --- a/tests/topotests/isis-topo1-vrf/r5/isisd.conf +++ b/tests/topotests/isis-topo1-vrf/r5/isisd.conf @@ -13,6 +13,7 @@ interface r5-eth1 isis circuit-type level-1 ! router isis 1 vrf r5-cust1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0005.00 metric-style wide is-type level-1 diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py index 7943b94189..12121e4ddf 100644 --- a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py @@ -82,6 +82,7 @@ class ISISTopo1(Topo): sw.add_link(tgen.gears["r4"]) sw.add_link(tgen.gears["r5"]) + def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(ISISTopo1, mod.__name__) @@ -129,16 +130,14 @@ def setup_module(mod): for rname, router in tgen.routers().items(): router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, "{}/zebra.conf".format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_ISIS, - os.path.join(CWD, "{}/isisd.conf".format(rname)) + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) # After loading the configurations, this function loads configured daemons. tgen.start_router() - + has_version_20 = False for router in tgen.routers().values(): if router.has_version("<", "4"): @@ -148,6 +147,7 @@ def setup_module(mod): logger.info("Skipping ISIS vrf tests for FRR 2.0") tgen.set_error("ISIS has convergence problems with IPv6") + def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() @@ -155,6 +155,7 @@ def teardown_module(mod): # delete rx-vrf tgen.stop_topology() + def test_isis_convergence(): "Wait for the protocol to converge before starting to test" tgen = get_topogen() @@ -163,10 +164,11 @@ def test_isis_convergence(): pytest.skip(tgen.errors) logger.info("waiting for ISIS protocol to converge") - + for rname, router in tgen.routers().items(): filename = "{0}/{1}/{1}_topology.json".format(CWD, rname) expected = json.loads(open(filename).read()) + def compare_isis_topology(router, expected): "Helper function to test ISIS vrf topology convergence." actual = show_isis_topology(router) @@ -177,6 +179,7 @@ def test_isis_convergence(): (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=120) assert result, "ISIS did not converge on {}:\n{}".format(rname, diff) + def test_isis_route_installation(): "Check whether all expected routes are present" tgen = get_topogen() @@ -189,7 +192,9 @@ def test_isis_route_installation(): for rname, router in tgen.routers().items(): filename = "{0}/{1}/{1}_route.json".format(CWD, rname) expected = json.loads(open(filename, "r").read()) - actual = router.vtysh_cmd("show ip route vrf {0}-cust1 json".format(rname) , isjson=True) + actual = router.vtysh_cmd( + "show ip route vrf {0}-cust1 json".format(rname), isjson=True + ) # Older FRR versions don't list interfaces in some ISIS routes if router.has_version("<", "3.1"): for network, routes in expected.items(): @@ -209,7 +214,7 @@ def test_isis_linux_route_installation(): dist = platform.dist() - if (dist[1] == "16.04"): + if dist[1] == "16.04": pytest.skip("Kernel not supported for vrf") "Check whether all expected routes are present and installed in the OS" @@ -234,6 +239,7 @@ def test_isis_linux_route_installation(): assertmsg = "Router '{}' OS routes mismatch".format(rname) assert topotest.json_cmp(actual, expected) is None, assertmsg + def test_isis_route6_installation(): "Check whether all expected routes are present" tgen = get_topogen() @@ -246,7 +252,9 @@ def test_isis_route6_installation(): for rname, router in tgen.routers().items(): filename = "{0}/{1}/{1}_route6.json".format(CWD, rname) expected = json.loads(open(filename, "r").read()) - actual = router.vtysh_cmd("show ipv6 route vrf {}-cust1 json".format(rname) , isjson=True) + actual = router.vtysh_cmd( + "show ipv6 route vrf {}-cust1 json".format(rname), isjson=True + ) # Older FRR versions don't list interfaces in some ISIS routes if router.has_version("<", "3.1"): @@ -262,11 +270,12 @@ def test_isis_route6_installation(): assertmsg = "Router '{}' routes mismatch".format(rname) assert topotest.json_cmp(actual, expected) is None, assertmsg + def test_isis_linux_route6_installation(): dist = platform.dist() - if (dist[1] == "16.04"): + if dist[1] == "16.04": pytest.skip("Kernel not supported for vrf") "Check whether all expected routes are present and installed in the OS" @@ -291,6 +300,7 @@ def test_isis_linux_route6_installation(): assertmsg = "Router '{}' OS routes mismatch".format(rname) assert topotest.json_cmp(actual, expected) is None, assertmsg + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() @@ -452,4 +462,3 @@ def show_isis_topology(router): dict_merge(l1, l2) return l1 - diff --git a/tests/topotests/isis-topo1/r1/isisd.conf b/tests/topotests/isis-topo1/r1/isisd.conf index ee7dba3692..4e3761e5a1 100644 --- a/tests/topotests/isis-topo1/r1/isisd.conf +++ b/tests/topotests/isis-topo1/r1/isisd.conf @@ -4,10 +4,12 @@ debug isis events debug isis update-packets interface r1-eth0 ip router isis 1 + isis hello-interval 2 ipv6 router isis 1 isis circuit-type level-2-only ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00 metric-style wide redistribute ipv4 connected level-2 diff --git a/tests/topotests/isis-topo1/r1/r1_route.json b/tests/topotests/isis-topo1/r1/r1_route.json index 123b4dd163..f94233a80f 100644 --- a/tests/topotests/isis-topo1/r1/r1_route.json +++ b/tests/topotests/isis-topo1/r1/r1_route.json @@ -19,19 +19,6 @@ ], "10.0.20.0/24": [ { - "distance": 115, - "metric": 10, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r1-eth0", - "ip": "10.0.20.1" - } - ], - "prefix": "10.0.20.0/24", - "protocol": "isis" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1/r2/isisd.conf b/tests/topotests/isis-topo1/r2/isisd.conf index f6fee6c845..14db0940ec 100644 --- a/tests/topotests/isis-topo1/r2/isisd.conf +++ b/tests/topotests/isis-topo1/r2/isisd.conf @@ -4,10 +4,12 @@ debug isis events debug isis update-packets interface r2-eth0 ip router isis 1 + isis hello-interval 2 ipv6 router isis 1 isis circuit-type level-2-only ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00 metric-style wide redistribute ipv4 connected level-2 diff --git a/tests/topotests/isis-topo1/r2/r2_route.json b/tests/topotests/isis-topo1/r2/r2_route.json index fe2de05734..aab651eff0 100644 --- a/tests/topotests/isis-topo1/r2/r2_route.json +++ b/tests/topotests/isis-topo1/r2/r2_route.json @@ -19,19 +19,6 @@ ], "10.0.21.0/24": [ { - "distance": 115, - "metric": 10, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r2-eth0", - "ip": "10.0.21.1" - } - ], - "prefix": "10.0.21.0/24", - "protocol": "isis" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1/r3/isisd.conf b/tests/topotests/isis-topo1/r3/isisd.conf index 4ae56b4af4..6f36c0fa36 100644 --- a/tests/topotests/isis-topo1/r3/isisd.conf +++ b/tests/topotests/isis-topo1/r3/isisd.conf @@ -4,6 +4,7 @@ debug isis events debug isis update-packets interface r3-eth0 ip router isis 1 + isis hello-interval 2 ipv6 router isis 1 isis circuit-type level-2-only ! @@ -13,6 +14,7 @@ interface r3-eth1 isis circuit-type level-1 ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/isis-topo1/r3/r3_route.json b/tests/topotests/isis-topo1/r3/r3_route.json index 1f0fcdfcd6..61d05e80bb 100644 --- a/tests/topotests/isis-topo1/r3/r3_route.json +++ b/tests/topotests/isis-topo1/r3/r3_route.json @@ -47,19 +47,6 @@ ], "10.0.20.0/24": [ { - "distance": 115, - "metric": 10, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r3-eth0", - "ip": "10.0.20.2" - } - ], - "prefix": "10.0.20.0/24", - "protocol": "isis" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1/r4/isisd.conf b/tests/topotests/isis-topo1/r4/isisd.conf index bf9653387e..502e035f50 100644 --- a/tests/topotests/isis-topo1/r4/isisd.conf +++ b/tests/topotests/isis-topo1/r4/isisd.conf @@ -4,6 +4,7 @@ debug isis events debug isis update-packets interface r4-eth0 ip router isis 1 + isis hello-interval 2 ipv6 router isis 1 isis circuit-type level-2-only ! @@ -13,6 +14,7 @@ interface r4-eth1 isis circuit-type level-1 ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0004.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/isis-topo1/r4/r4_route.json b/tests/topotests/isis-topo1/r4/r4_route.json index 597e953c09..79361af4b5 100644 --- a/tests/topotests/isis-topo1/r4/r4_route.json +++ b/tests/topotests/isis-topo1/r4/r4_route.json @@ -16,19 +16,6 @@ ], "10.0.21.0/24": [ { - "distance": 115, - "metric": 10, - "nexthops": [ - { - "afi": "ipv4", - "interfaceName": "r4-eth0", - "ip": "10.0.21.2" - } - ], - "prefix": "10.0.21.0/24", - "protocol": "isis" - }, - { "nexthops": [ { "active": true, diff --git a/tests/topotests/isis-topo1/r5/isisd.conf b/tests/topotests/isis-topo1/r5/isisd.conf index 5a044988a9..42493a4991 100644 --- a/tests/topotests/isis-topo1/r5/isisd.conf +++ b/tests/topotests/isis-topo1/r5/isisd.conf @@ -4,6 +4,7 @@ debug isis events debug isis update-packets interface r5-eth0 ip router isis 1 + isis hello-interval 2 ipv6 router isis 1 isis circuit-type level-1 ! @@ -13,6 +14,7 @@ interface r5-eth1 isis circuit-type level-1 ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0005.00 metric-style wide is-type level-1 diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf b/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf index af8d117bc1..da2970d94e 100644 --- a/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf +++ b/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf @@ -6,6 +6,7 @@ debug isis update-packets debug isis ldp-sync ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf b/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf index e477bce827..b29a2b93ee 100644 --- a/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf +++ b/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf @@ -6,6 +6,7 @@ debug isis update-packets debug isis ldp-sync ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf b/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf index e50fb077ba..4c8499f23d 100644 --- a/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf +++ b/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf @@ -6,6 +6,7 @@ debug isis update-packets debug isis ldp-sync ! router isis 1 + lsp-gen-interval 2 net 10.0000.0000.0000.0000.0000.0000.0000.0000.0003.00 metric-style wide redistribute ipv4 connected level-1 diff --git a/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py b/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py index d339b7bd7b..331e6fafd4 100644 --- a/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py +++ b/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py @@ -182,7 +182,9 @@ def test_isis_convergence(): router_compare_json_output( rname, "show yang operational-data /frr-interface:lib isisd", - "show_yang_interface_isis_adjacencies.ref") + "show_yang_interface_isis_adjacencies.ref", + ) + def test_rib(): logger.info("Test: verify RIB") @@ -265,6 +267,7 @@ def test_ldp_pseudowires(): rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref" ) + def test_ldp_igp_sync(): logger.info("Test: verify LDP igp-sync") tgen = get_topogen() @@ -278,6 +281,7 @@ def test_ldp_igp_sync(): rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref" ) + def test_isis_ldp_sync(): logger.info("Test: verify ISIS igp-sync") tgen = get_topogen() @@ -287,9 +291,7 @@ def test_isis_ldp_sync(): pytest.skip(tgen.errors) for rname in ["r1", "r2", "r3"]: - (result, diff) = validate_show_isis_ldp_sync( - rname, "show_isis_ldp_sync.ref" - ) + (result, diff) = validate_show_isis_ldp_sync(rname, "show_isis_ldp_sync.ref") assert result, "ISIS did not converge on {}:\n{}".format(rname, diff) for rname in ["r1", "r2", "r3"]: @@ -320,7 +322,9 @@ def test_r1_eth1_shutdown(): for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref" + rname, + "show mpls ldp igp-sync json", + "show_ldp_igp_sync_r1_eth1_shutdown.ref", ) for rname in ["r1", "r2", "r3"]: @@ -355,9 +359,7 @@ def test_r1_eth1_no_shutdown(): ) for rname in ["r1", "r2", "r3"]: - (result, diff) = validate_show_isis_ldp_sync( - rname, "show_isis_ldp_sync.ref" - ) + (result, diff) = validate_show_isis_ldp_sync(rname, "show_isis_ldp_sync.ref") assert result, "ISIS did not converge on {}:\n{}".format(rname, diff) for rname in ["r1", "r2", "r3"]: @@ -382,7 +384,9 @@ def test_r2_eth1_shutdown(): for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref" + rname, + "show mpls ldp igp-sync json", + "show_ldp_igp_sync_r1_eth1_shutdown.ref", ) for rname in ["r1", "r2", "r3"]: @@ -417,9 +421,7 @@ def test_r2_eth1_no_shutdown(): ) for rname in ["r1", "r2", "r3"]: - (result, diff) = validate_show_isis_ldp_sync( - rname, "show_isis_ldp_sync.ref" - ) + (result, diff) = validate_show_isis_ldp_sync(rname, "show_isis_ldp_sync.ref") assert result, "ISIS did not converge on {}:\n{}".format(rname, diff) for rname in ["r1", "r2", "r3"]: @@ -448,6 +450,7 @@ if __name__ == "__main__": # Auxiliary functions # + def parse_show_isis_ldp_sync(lines, rname): """ Parse the output of 'show isis mpls ldp sync' into a Python dict. @@ -461,23 +464,23 @@ def parse_show_isis_ldp_sync(lines, rname): interface = {} interface_name = None - line = it.next(); + line = it.next() if line.startswith(rname + "-eth"): interface_name = line - line = it.next(); + line = it.next() if line.startswith(" LDP-IGP Synchronization enabled: "): interface["ldpIgpSyncEnabled"] = line.endswith("yes") - line = it.next(); + line = it.next() if line.startswith(" holddown timer in seconds: "): - interface["holdDownTimeInSec"] = int(line.split(": ")[-1]) - line = it.next(); + interface["holdDownTimeInSec"] = int(line.split(": ")[-1]) + line = it.next() if line.startswith(" State: "): - interface["ldpIgpSyncState"] = line.split(": ")[-1] + interface["ldpIgpSyncState"] = line.split(": ")[-1] elif line.startswith(" Interface "): interface["Interface"] = line.endswith("down") @@ -534,7 +537,7 @@ def parse_show_isis_interface_detail(lines, rname): while True: try: - line = it.next(); + line = it.next() area_match = re.match(r"Area (.+):", line) if not area_match: @@ -543,34 +546,36 @@ def parse_show_isis_interface_detail(lines, rname): area_id = area_match.group(1) area = {} - line = it.next(); + line = it.next() while line.startswith(" Interface: "): - interface_name = re.split(':|,', line)[1].lstrip() + interface_name = re.split(":|,", line)[1].lstrip() - area[interface_name]= [] + area[interface_name] = [] # Look for keyword: Level-1 or Level-2 while not line.startswith(" Level-"): - line = it.next(); + line = it.next() while line.startswith(" Level-"): level = {} level_name = line.split()[0] - level['level'] = level_name + level["level"] = level_name - line = it.next(); + line = it.next() if line.startswith(" Metric:"): - level['metric'] = re.split(':|,', line)[1].lstrip() + level["metric"] = re.split(":|,", line)[1].lstrip() area[interface_name].append(level) # Look for keyword: Level-1 or Level-2 or Interface: - while not line.startswith(" Level-") and not line.startswith(" Interface: "): - line = it.next(); + while not line.startswith(" Level-") and not line.startswith( + " Interface: " + ): + line = it.next() if line.startswith(" Level-"): continue @@ -623,4 +628,3 @@ def validate_show_isis_interface_detail(rname, fname): (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=160) return (result, diff) - diff --git a/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py index 9694fa982f..20d7f46d4c 100644 --- a/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py +++ b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py @@ -264,6 +264,7 @@ def test_ldp_pseudowires(): rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref" ) + def test_ldp_igp_sync(): logger.info("Test: verify LDP igp-sync") tgen = get_topogen() @@ -277,6 +278,7 @@ def test_ldp_igp_sync(): rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref" ) + def test_ospf_ldp_sync(): logger.info("Test: verify OSPF igp-sync") tgen = get_topogen() @@ -317,19 +319,26 @@ def test_r1_eth1_shutdown(): for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref" + rname, + "show mpls ldp igp-sync json", + "show_ldp_igp_sync_r1_eth1_shutdown.ref", ) for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync_r1_eth1_shutdown.ref" + rname, + "show ip ospf mpls ldp-sync json", + "show_ospf_ldp_sync_r1_eth1_shutdown.ref", ) for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show ip ospf interface json", "show_ip_ospf_interface_r1_eth1_shutdown.ref" + rname, + "show ip ospf interface json", + "show_ip_ospf_interface_r1_eth1_shutdown.ref", ) + def test_r1_eth1_no_shutdown(): logger.info("Test: verify behaviour after r1-eth1 is no shutdown") tgen = get_topogen() @@ -358,6 +367,7 @@ def test_r1_eth1_no_shutdown(): rname, "show ip ospf interface json", "show_ip_ospf_interface.ref" ) + def test_r2_eth1_shutdown(): logger.info("Test: verify behaviour after r2-eth1 is shutdown") tgen = get_topogen() @@ -373,19 +383,26 @@ def test_r2_eth1_shutdown(): for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref" + rname, + "show mpls ldp igp-sync json", + "show_ldp_igp_sync_r1_eth1_shutdown.ref", ) for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync_r2_eth1_shutdown.ref" + rname, + "show ip ospf mpls ldp-sync json", + "show_ospf_ldp_sync_r2_eth1_shutdown.ref", ) for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show ip ospf interface json", "show_ip_ospf_interface_r2_eth1_shutdown.ref" + rname, + "show ip ospf interface json", + "show_ip_ospf_interface_r2_eth1_shutdown.ref", ) + def test_r2_eth1_no_shutdown(): logger.info("Test: verify behaviour after r2-eth1 is no shutdown") tgen = get_topogen() @@ -414,6 +431,7 @@ def test_r2_eth1_no_shutdown(): rname, "show ip ospf interface json", "show_ip_ospf_interface.ref" ) + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." diff --git a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py index 0b8bf4de0e..ba94cd47d4 100644 --- a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py +++ b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py @@ -283,8 +283,7 @@ def test_ldp_pseudowires_after_link_down(): # for nexthop resolution). Give some extra wait time. for rname in ["r1", "r2", "r3"]: router_compare_json_output( - rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref", - count=160, wait=1 + rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref", count=160, wait=1 ) diff --git a/tests/topotests/lib/bgprib.py b/tests/topotests/lib/bgprib.py index 3d92718c78..a23092de83 100644 --- a/tests/topotests/lib/bgprib.py +++ b/tests/topotests/lib/bgprib.py @@ -18,8 +18,8 @@ # # want_rd_routes = [ -# {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1'}, -# {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1'}, +# {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1', 'bp': True}, +# {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1', 'bp': False}, # # {'rd':'10:3', 'p':'5.1.0.0/24', 'n':'3.3.3.3'}, # ] @@ -34,39 +34,46 @@ # ribRequireUnicastRoutes('r1','ipv4','','Customer routes in default',want_unicast_routes) # -from lutil import luCommand, luResult +from lutil import luCommand, luResult, LUtil import json import re # gpz: get rib in json form and compare against desired routes class BgpRib: + def log(self, str): + LUtil.log("BgpRib: " + str) + def routes_include_wanted(self, pfxtbl, want, debug): # helper function to RequireVpnRoutes for pfx in pfxtbl.iterkeys(): if debug: - print "trying pfx " + pfx + self.log("trying pfx %s" % pfx) if pfx != want["p"]: if debug: - print "want pfx=" + want["p"] + ", not " + pfx + self.log("want pfx=" + want["p"] + ", not " + pfx) continue if debug: - print "have pfx=" + pfx + self.log("have pfx=%s" % pfx) for r in pfxtbl[pfx]: + bp = r.get("bestpath", False) if debug: - print "trying route" + self.log("trying route %s bp=%s" % (r, bp)) nexthops = r["nexthops"] for nh in nexthops: if debug: - print "trying nh " + nh["ip"] + self.log("trying nh %s" % nh["ip"]) if nh["ip"] == want["n"]: if debug: - print "found " + want["n"] - return 1 + self.log("found %s" % want["n"]) + if bp == want.get("bp", bp): + return 1 + elif debug: + self.log("bestpath mismatch %s != %s" % (bp, want["bp"])) else: if debug: - print "want nh=" + want["n"] + ", not " + nh["ip"] + self.log("want nh=" + want["n"] + ", not " + nh["ip"]) if debug: - print "missing route: pfx=" + want["p"] + ", nh=" + want["n"] + self.log("missing route: pfx=" + want["p"] + ", nh=" + want["n"]) return 0 def RequireVpnRoutes(self, target, title, wantroutes, debug=0): @@ -99,12 +106,12 @@ class BgpRib: for want in wantroutes: found = 0 if debug: - print "want rd " + want["rd"] + self.log("want rd %s" % want["rd"]) for rd in rds.iterkeys(): if rd != want["rd"]: continue if debug: - print "found rd " + rd + self.log("found rd %s" % rd) table = rds[rd] if self.routes_include_wanted(table, want, debug): found = 1 @@ -115,13 +122,13 @@ class BgpRib: luResult(target, True, title, logstr) def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0): - logstr = "RequireVpnRoutes " + str(wantroutes) + logstr = "RequireVpnRoutes %s" % str(wantroutes) vrfstr = "" if vrf != "": vrfstr = "vrf %s" % (vrf) if (afi != "ipv4") and (afi != "ipv6"): - print "ERROR invalid afi" + self.log("ERROR invalid afi") cmdstr = "show bgp %s %s unicast" % (vrfstr, afi) # non json form for humans @@ -148,7 +155,11 @@ class BgpRib: errstr = "-script ERROR: check if vrf missing" luResult(target, False, title + errstr, logstr) return + # if debug: + # self.log("table=%s" % table) for want in wantroutes: + if debug: + self.log("want=%s" % want) if not self.routes_include_wanted(table, want, debug): luResult(target, False, title, logstr) return diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 1fa6d35101..d83f946c42 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -400,6 +400,7 @@ def check_router_status(tgen): logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) return True + def getStrIO(): """ Return a StringIO object appropriate for the current python version. @@ -409,6 +410,7 @@ def getStrIO(): else: return StringIO.StringIO() + def reset_config_on_routers(tgen, routerName=None): """ Resets configuration on routers to the snapshot created using input JSON @@ -702,14 +704,14 @@ def start_topology(tgen, daemon=None): ) TMPDIR = os.path.join(LOGDIR, tgen.modname) - linux_ver = '' + linux_ver = "" router_list = tgen.routers() for rname in ROUTER_LIST: router = router_list[rname] # It will help in debugging the failures, will give more details on which # specific kernel version tests are failing - if linux_ver == '': + if linux_ver == "": linux_ver = router.run("uname -a") logger.info("Logging platform related details: \n %s \n", linux_ver) @@ -741,11 +743,10 @@ def start_topology(tgen, daemon=None): # Loading empty bgpd.conf file to router, to start the bgp deamon router.load_config(TopoRouter.RD_BGP, "{}/{}/bgpd.conf".format(TMPDIR, rname)) - if daemon and 'ospfd' in daemon: + if daemon and "ospfd" in daemon: # Loading empty ospf.conf file to router, to start the bgp deamon router.load_config( - TopoRouter.RD_OSPF, - '{}/{}/ospfd.conf'.format(TMPDIR, rname) + TopoRouter.RD_OSPF, "{}/{}/ospfd.conf".format(TMPDIR, rname) ) # Starting routers logger.info("Starting all routers once topology is created") @@ -831,8 +832,8 @@ def topo_daemons(tgen, topo): ) for rtr in ROUTER_LIST: - if 'ospf' in topo['routers'][rtr] and 'ospfd' not in daemon_list: - daemon_list.append('ospfd') + if "ospf" in topo["routers"][rtr] and "ospfd" not in daemon_list: + daemon_list.append("ospfd") return daemon_list @@ -1266,8 +1267,7 @@ def interface_status(tgen, topo, input_dict): return True -def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, - return_is_dict=False): +def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict=False): """ Retries function execution, if return is an errormsg or exception @@ -1279,11 +1279,10 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, """ def _retry(func): - @wraps(func) def func_retry(*args, **kwargs): - _wait = kwargs.pop('wait', wait) - _attempts = kwargs.pop('attempts', attempts) + _wait = kwargs.pop("wait", wait) + _attempts = kwargs.pop("attempts", attempts) _attempts = int(_attempts) expected = True if _attempts < 0: @@ -1293,19 +1292,21 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, logger.info("Waiting for [%s]s as initial delay", initial_wait) sleep(initial_wait) - _return_is_str = kwargs.pop('return_is_str', return_is_str) - _return_is_dict = kwargs.pop('return_is_str', return_is_dict) + _return_is_str = kwargs.pop("return_is_str", return_is_str) + _return_is_dict = kwargs.pop("return_is_str", return_is_dict) for i in range(1, _attempts + 1): try: - _expected = kwargs.setdefault('expected', True) + _expected = kwargs.setdefault("expected", True) if _expected is False: expected = _expected - kwargs.pop('expected') + kwargs.pop("expected") ret = func(*args, **kwargs) logger.debug("Function returned %s", ret) if _return_is_str and isinstance(ret, bool) and _expected: return ret - if (isinstance(ret, str) or isinstance(ret, unicode)) and _expected is False: + if ( + isinstance(ret, str) or isinstance(ret, unicode) + ) and _expected is False: return ret if _return_is_dict and isinstance(ret, dict): return ret @@ -1316,17 +1317,17 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, except Exception as err: if _attempts == i and expected: generate_support_bundle() - logger.info("Max number of attempts (%r) reached", - _attempts) + logger.info("Max number of attempts (%r) reached", _attempts) raise else: logger.info("Function returned %s", err) if i < _attempts: - logger.info("Retry [#%r] after sleeping for %ss" - % (i, _wait)) + logger.info("Retry [#%r] after sleeping for %ss" % (i, _wait)) sleep(_wait) + func_retry._original = func return func_retry + return _retry @@ -1420,58 +1421,63 @@ def create_interfaces_cfg(tgen, topo, build=False): else: interface_data.append("ipv6 address {}\n".format(intf_addr)) - if 'ospf' in data: - ospf_data = data['ospf'] - if 'area' in ospf_data: - intf_ospf_area = c_data["links"][destRouterLink][ - "ospf"]["area"] + if "ospf" in data: + ospf_data = data["ospf"] + if "area" in ospf_data: + intf_ospf_area = c_data["links"][destRouterLink]["ospf"]["area"] if "delete" in data and data["delete"]: interface_data.append("no ip ospf area") else: - interface_data.append("ip ospf area {}".format( - intf_ospf_area - )) + interface_data.append( + "ip ospf area {}".format(intf_ospf_area) + ) - if "hello_interval" in ospf_data: - intf_ospf_hello = c_data["links"][destRouterLink][ - "ospf"]["hello_interval"] + if "hello_interval" in ospf_data: + intf_ospf_hello = c_data["links"][destRouterLink]["ospf"][ + "hello_interval" + ] if "delete" in data and data["delete"]: - interface_data.append("no ip ospf "\ - " hello-interval") + interface_data.append("no ip ospf " " hello-interval") else: - interface_data.append("ip ospf "\ - " hello-interval {}".format(intf_ospf_hello)) + interface_data.append( + "ip ospf " " hello-interval {}".format(intf_ospf_hello) + ) if "dead_interval" in ospf_data: - intf_ospf_dead = c_data["links"][destRouterLink][ - "ospf"]["dead_interval"] + intf_ospf_dead = c_data["links"][destRouterLink]["ospf"][ + "dead_interval" + ] if "delete" in data and data["delete"]: - interface_data.append("no ip ospf"\ - " dead-interval") + interface_data.append("no ip ospf" " dead-interval") else: - interface_data.append("ip ospf "\ - " dead-interval {}".format(intf_ospf_dead)) + interface_data.append( + "ip ospf " " dead-interval {}".format(intf_ospf_dead) + ) if "network" in ospf_data: - intf_ospf_nw = c_data["links"][destRouterLink][ - "ospf"]["network"] + intf_ospf_nw = c_data["links"][destRouterLink]["ospf"][ + "network" + ] if "delete" in data and data["delete"]: - interface_data.append("no ip ospf"\ - " network {}".format(intf_ospf_nw)) + interface_data.append( + "no ip ospf" " network {}".format(intf_ospf_nw) + ) else: - interface_data.append("ip ospf"\ - " network {}".format(intf_ospf_nw)) + interface_data.append( + "ip ospf" " network {}".format(intf_ospf_nw) + ) if "priority" in ospf_data: - intf_ospf_nw = c_data["links"][destRouterLink][ - "ospf"]["priority"] + intf_ospf_nw = c_data["links"][destRouterLink]["ospf"][ + "priority" + ] if "delete" in data and data["delete"]: - interface_data.append("no ip ospf"\ - " priority") + interface_data.append("no ip ospf" " priority") else: - interface_data.append("ip ospf"\ - " priority {}".format(intf_ospf_nw)) + interface_data.append( + "ip ospf" " priority {}".format(intf_ospf_nw) + ) result = create_common_configuration( tgen, c_router, interface_data, "interface_config", build=build ) @@ -3013,7 +3019,7 @@ def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None): for st_rt in ip_list: st_rt = str(ipaddress.ip_network(frr_unicode(st_rt))) - #st_rt = str(ipaddr.IPNetwork(unicode(st_rt))) + # st_rt = str(ipaddr.IPNetwork(unicode(st_rt))) _addr_type = validate_ip_address(st_rt) if _addr_type != addr_type: @@ -3118,7 +3124,7 @@ def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None): nh_found = False for st_rt in ip_list: - #st_rt = str(ipaddr.IPNetwork(unicode(st_rt))) + # st_rt = str(ipaddr.IPNetwork(unicode(st_rt))) st_rt = str(ipaddress.ip_network(frr_unicode(st_rt))) _addr_type = validate_ip_address(st_rt) @@ -4075,8 +4081,9 @@ def required_linux_kernel_version(required_version): """ system_kernel = platform.release() if version_cmp(system_kernel, required_version) < 0: - error_msg = ('These tests will not run on kernel "{}", ' - 'they require kernel >= {})'.format(system_kernel, - required_version )) + error_msg = ( + 'These tests will not run on kernel "{}", ' + "they require kernel >= {})".format(system_kernel, required_version) + ) return error_msg return True diff --git a/tests/topotests/lib/ltemplate.py b/tests/topotests/lib/ltemplate.py index 3c93e1ac5c..d211be8836 100644 --- a/tests/topotests/lib/ltemplate.py +++ b/tests/topotests/lib/ltemplate.py @@ -43,7 +43,8 @@ from mininet.topo import Topo customize = None -class LTemplate(): + +class LTemplate: test = None testdir = None scriptdir = None @@ -54,12 +55,12 @@ class LTemplate(): def __init__(self, test, testdir): global customize - customize = imp.load_source('customize', os.path.join(testdir, 'customize.py')) + customize = imp.load_source("customize", os.path.join(testdir, "customize.py")) self.test = test self.testdir = testdir self.scriptdir = testdir - self.logdir = '/tmp/topotests/{0}.test_{0}'.format(test) - logger.info('LTemplate: '+test) + self.logdir = "/tmp/topotests/{0}.test_{0}".format(test) + logger.info("LTemplate: " + test) def setup_module(self, mod): "Sets up the pytest environment" @@ -68,14 +69,14 @@ class LTemplate(): # ... and here it calls Mininet initialization functions. tgen.start_topology() - logger.info('Topology started') + logger.info("Topology started") try: self.prestarthooksuccess = customize.ltemplatePreRouterStartHook() except AttributeError: - #not defined + # not defined logger.debug("ltemplatePreRouterStartHook() not defined") if self.prestarthooksuccess != True: - logger.info('ltemplatePreRouterStartHook() failed, skipping test') + logger.info("ltemplatePreRouterStartHook() failed, skipping test") return # This is a sample of configuration loading. @@ -85,48 +86,57 @@ class LTemplate(): for rname, router in router_list.items(): logger.info("Setting up %s" % rname) for rd_val in TopoRouter.RD: - config = os.path.join(self.testdir, '{}/{}.conf'.format(rname,TopoRouter.RD[rd_val])) + config = os.path.join( + self.testdir, "{}/{}.conf".format(rname, TopoRouter.RD[rd_val]) + ) prog = os.path.join(tgen.net[rname].daemondir, TopoRouter.RD[rd_val]) if os.path.exists(config): if os.path.exists(prog): router.load_config(rd_val, config) else: - logger.warning("{} not found, but have {}.conf file".format(prog, TopoRouter.RD[rd_val])) + logger.warning( + "{} not found, but have {}.conf file".format( + prog, TopoRouter.RD[rd_val] + ) + ) # After loading the configurations, this function loads configured daemons. - logger.info('Starting routers') + logger.info("Starting routers") tgen.start_router() try: self.poststarthooksuccess = customize.ltemplatePostRouterStartHook() except AttributeError: - #not defined + # not defined logger.debug("ltemplatePostRouterStartHook() not defined") luStart(baseScriptDir=self.scriptdir, baseLogDir=self.logdir, net=tgen.net) -#initialized by ltemplate_start + +# initialized by ltemplate_start _lt = None + def setup_module(mod): global _lt root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - test = mod.__name__[:mod.__name__.rfind(".")] + test = mod.__name__[: mod.__name__.rfind(".")] testdir = os.path.join(root, test) - #don't do this for now as reload didn't work as expected - #fixup sys.path, want test dir there only once - #try: + # don't do this for now as reload didn't work as expected + # fixup sys.path, want test dir there only once + # try: # sys.path.remove(testdir) - #except ValueError: + # except ValueError: # logger.debug(testdir+" not found in original sys.path") - #add testdir - #sys.path.append(testdir) + # add testdir + # sys.path.append(testdir) - #init class + # init class _lt = LTemplate(test, testdir) _lt.setup_module(mod) - #drop testdir - #sys.path.remove(testdir) + # drop testdir + # sys.path.remove(testdir) + def teardown_module(mod): global _lt @@ -141,7 +151,10 @@ def teardown_module(mod): tgen.stop_topology() _lt = None -def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, KeepGoing=False): + +def ltemplateTest( + script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, KeepGoing=False +): global _lt if _lt == None or _lt.prestarthooksuccess != True: return @@ -149,8 +162,8 @@ def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, tgen = get_topogen() if not os.path.isfile(script): if not os.path.isfile(os.path.join(_lt.scriptdir, script)): - logger.error('Could not find script file: ' + script) - assert 'Could not find script file: ' + script + logger.error("Could not find script file: " + script) + assert "Could not find script file: " + script logger.info("Starting template test: " + script) numEntry = luNumFail() @@ -163,7 +176,7 @@ def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, if CheckFuncStr != None: check = eval(CheckFuncStr) if check != True: - pytest.skip("Check function '"+CheckFuncStr+"' returned: " + check) + pytest.skip("Check function '" + CheckFuncStr + "' returned: " + check) if CallOnFail != None: CallOnFail = eval(CallOnFail) @@ -173,22 +186,26 @@ def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, luShowFail() fatal_error = "%d tests failed" % numFail if not KeepGoing: - assert "scripts/cleanup_all.py failed" == "See summary output above", fatal_error + assert ( + "scripts/cleanup_all.py failed" == "See summary output above" + ), fatal_error + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): - pytest.skip('Memory leak test/report is disabled') + pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() -class ltemplateRtrCmd(): + +class ltemplateRtrCmd: def __init__(self): self.resetCounts() - def doCmd(self, tgen, rtr, cmd, checkstr = None): + def doCmd(self, tgen, rtr, cmd, checkstr=None): output = tgen.net[rtr].cmd(cmd).strip() if len(output): self.output += 1 @@ -199,8 +216,8 @@ class ltemplateRtrCmd(): else: self.match += 1 return ret - logger.info('command: {} {}'.format(rtr, cmd)) - logger.info('output: ' + output) + logger.info("command: {} {}".format(rtr, cmd)) + logger.info("output: " + output) self.none += 1 return None @@ -222,63 +239,69 @@ class ltemplateRtrCmd(): def getNone(self): return self.none -def ltemplateVersionCheck(vstr, rname='r1', compstr='<',cli=False, kernel='4.9', iproute2=None, mpls=True): + +def ltemplateVersionCheck( + vstr, rname="r1", compstr="<", cli=False, kernel="4.9", iproute2=None, mpls=True +): tgen = get_topogen() router = tgen.gears[rname] if cli: - logger.info('calling mininet CLI') + logger.info("calling mininet CLI") tgen.mininet_cli() - logger.info('exited mininet CLI') + logger.info("exited mininet CLI") if _lt == None: - ret = 'Template not initialized' + ret = "Template not initialized" return ret if _lt.prestarthooksuccess != True: - ret = 'ltemplatePreRouterStartHook failed' + ret = "ltemplatePreRouterStartHook failed" return ret if _lt.poststarthooksuccess != True: - ret = 'ltemplatePostRouterStartHook failed' + ret = "ltemplatePostRouterStartHook failed" return ret if mpls == True and tgen.hasmpls != True: - ret = 'MPLS not initialized' + ret = "MPLS not initialized" return ret if kernel != None: krel = platform.release() if topotest.version_cmp(krel, kernel) < 0: - ret = 'Skipping tests, old kernel ({} < {})'.format(krel, kernel) + ret = "Skipping tests, old kernel ({} < {})".format(krel, kernel) return ret if iproute2 != None: if _lt.iproute2Ver == None: - #collect/log info on iproute2 + # collect/log info on iproute2 cc = ltemplateRtrCmd() - found = cc.doCmd(tgen, rname, 'apt-cache policy iproute2', 'Installed: ([\d\.]*)') + found = cc.doCmd( + tgen, rname, "apt-cache policy iproute2", "Installed: ([\d\.]*)" + ) if found != None: iproute2Ver = found.group(1) else: - iproute2Ver = '0-unknown' - logger.info('Have iproute2 version=' + iproute2Ver) + iproute2Ver = "0-unknown" + logger.info("Have iproute2 version=" + iproute2Ver) if topotest.version_cmp(iproute2Ver, iproute2) < 0: - ret = 'Skipping tests, old iproute2 ({} < {})'.format(iproute2Ver, iproute2) + ret = "Skipping tests, old iproute2 ({} < {})".format(iproute2Ver, iproute2) return ret ret = True try: if router.has_version(compstr, vstr): - ret = 'Skipping tests, old FRR version {} {}'.format(compstr, vstr) + ret = "Skipping tests, old FRR version {} {}".format(compstr, vstr) return ret except: ret = True return ret -#for testing -if __name__ == '__main__': + +# for testing +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/lib/lutil.py b/tests/topotests/lib/lutil.py index 05ed9c007d..1fb4f48b0f 100644 --- a/tests/topotests/lib/lutil.py +++ b/tests/topotests/lib/lutil.py @@ -32,46 +32,53 @@ from mininet.net import Mininet # These functions are inteneted to provide support for CI testing within MiniNet # environments. + class lUtil: - #to be made configurable in the future - base_script_dir = '.' - base_log_dir = '.' - fout_name = 'output.log' - fsum_name = 'summary.txt' + # to be made configurable in the future + base_script_dir = "." + base_log_dir = "." + fout_name = "output.log" + fsum_name = "summary.txt" l_level = 6 CallOnFail = False l_total = 0 l_pass = 0 l_fail = 0 - l_filename = '' + l_filename = "" l_last = None l_line = 0 l_dotall_experiment = False l_last_nl = None - fout = '' - fsum = '' - net = '' + fout = "" + fsum = "" + net = "" def log(self, str, level=6): if self.l_level > 0: - if self.fout == '': - self.fout = open(self.fout_name, 'w', 0) - self.fout.write(str+'\n') + if self.fout == "": + self.fout = open(self.fout_name, "w", 0) + self.fout.write(str + "\n") if level <= self.l_level: print(str) def summary(self, str): - if self.fsum == '': - self.fsum = open(self.fsum_name, 'w', 0) - self.fsum.write('\ -******************************************************************************\n') - self.fsum.write('\ -Test Target Summary Pass Fail\n') - self.fsum.write('\ -******************************************************************************\n') - self.fsum.write(str+'\n') + if self.fsum == "": + self.fsum = open(self.fsum_name, "w", 0) + self.fsum.write( + "\ +******************************************************************************\n" + ) + self.fsum.write( + "\ +Test Target Summary Pass Fail\n" + ) + self.fsum.write( + "\ +******************************************************************************\n" + ) + self.fsum.write(str + "\n") def result(self, target, success, str, logstr=None): if success: @@ -88,32 +95,34 @@ Test Target Summary Pass Fail\n if logstr != None: self.log("R:%d %s: %s" % (self.l_total, sstr, logstr)) res = "%-4d %-6s %-56s %-4d %d" % (self.l_total, target, str, p, f) - self.log ('R:'+res) + self.log("R:" + res) self.summary(res) if f == 1 and self.CallOnFail != False: self.CallOnFail() def closeFiles(self): - ret = '\ + ret = ( + "\ ******************************************************************************\n\ Total %-4d %-4d %d\n\ -******************************************************************************'\ -% (self.l_total, self.l_pass, self.l_fail) - if self.fsum != '': - self.fsum.write(ret + '\n') +******************************************************************************" + % (self.l_total, self.l_pass, self.l_fail) + ) + if self.fsum != "": + self.fsum.write(ret + "\n") self.fsum.close() - self.fsum = '' - if self.fout != '': + self.fsum = "" + if self.fout != "": if os.path.isfile(self.fsum_name): - r = open(self.fsum_name, 'r') + r = open(self.fsum_name, "r") self.fout.write(r.read()) r.close() self.fout.close() - self.fout = '' + self.fout = "" return ret def setFilename(self, name): - str = 'FILE: ' + name + str = "FILE: " + name self.log(str) self.summary(str) self.l_filename = name @@ -128,19 +137,19 @@ Total %-4d %-4d %d\n\ def strToArray(self, string): a = [] c = 0 - end = '' + end = "" words = string.split() - if len(words) < 1 or words[0].startswith('#'): + if len(words) < 1 or words[0].startswith("#"): return a words = string.split() for word in words: if len(end) == 0: a.append(word) else: - a[c] += str(' '+word) - if end == '\\': - end = '' - if not word.endswith('\\'): + a[c] += str(" " + word) + if end == "\\": + end = "" + if not word.endswith("\\"): if end != '"': if word.startswith('"'): end = '"' @@ -148,14 +157,14 @@ Total %-4d %-4d %d\n\ c += 1 else: if word.endswith('"'): - end = '' + end = "" c += 1 else: c += 1 else: - end = '\\' - # if len(end) == 0: - # print('%d:%s:' % (c, a[c-1])) + end = "\\" + # if len(end) == 0: + # print('%d:%s:' % (c, a[c-1])) return a @@ -169,27 +178,37 @@ Total %-4d %-4d %d\n\ luCommand(a[1], a[2], a[3], a[4], a[5]) else: self.l_line += 1 - self.log('%s:%s %s' % (self.l_filename, self.l_line , line)) + self.log("%s:%s %s" % (self.l_filename, self.l_line, line)) if len(a) >= 2: - if a[0] == 'sleep': + if a[0] == "sleep": time.sleep(int(a[1])) - elif a[0] == 'include': + elif a[0] == "include": self.execTestFile(a[1]) f.close() else: - self.log('unable to read: ' + tstFile) + self.log("unable to read: " + tstFile) sys.exit(1) def command(self, target, command, regexp, op, result, returnJson): global net - if op != 'wait': - self.l_line += 1 - self.log('(#%d) %s:%s COMMAND:%s:%s:%s:%s:%s:' % \ - (self.l_total+1, - self.l_filename, self.l_line, target, command, regexp, op, result)) - if self.net == '': + if op != "wait": + self.l_line += 1 + self.log( + "(#%d) %s:%s COMMAND:%s:%s:%s:%s:%s:" + % ( + self.l_total + 1, + self.l_filename, + self.l_line, + target, + command, + regexp, + op, + result, + ) + ) + if self.net == "": return False - #self.log("Running %s %s" % (target, command)) + # self.log("Running %s %s" % (target, command)) js = None out = self.net[target].cmd(command).rstrip() if len(out) == 0: @@ -201,13 +220,15 @@ Total %-4d %-4d %d\n\ js = json.loads(out) except: js = None - self.log('WARNING: JSON load failed -- confirm command output is in JSON format.') - self.log('COMMAND OUTPUT:%s:' % report) + self.log( + "WARNING: JSON load failed -- confirm command output is in JSON format." + ) + self.log("COMMAND OUTPUT:%s:" % report) # Experiment: can we achieve the same match behavior via DOTALL # without converting newlines to spaces? out_nl = out - search_nl = re.search(regexp, out_nl, re.DOTALL); + search_nl = re.search(regexp, out_nl, re.DOTALL) self.l_last_nl = search_nl # Set up for comparison if search_nl != None: @@ -220,32 +241,50 @@ Total %-4d %-4d %d\n\ search = re.search(regexp, out) self.l_last = search if search == None: - if op == 'fail': + if op == "fail": success = True else: success = False ret = success else: ret = search.group() - if op != 'fail': + if op != "fail": success = True level = 7 else: success = False level = 5 - self.log('found:%s:' % ret, level) + self.log("found:%s:" % ret, level) # Experiment: compare matched strings obtained each way if self.l_dotall_experiment and (group_nl_converted != ret): - self.log('DOTALL experiment: strings differ dotall=[%s] orig=[%s]' % (group_nl_converted, ret), 9) - if op == 'pass' or op == 'fail': + self.log( + "DOTALL experiment: strings differ dotall=[%s] orig=[%s]" + % (group_nl_converted, ret), + 9, + ) + if op == "pass" or op == "fail": self.result(target, success, result) if js != None: return js return ret - def wait(self, target, command, regexp, op, result, wait, returnJson, wait_time=0.5): - self.log('%s:%s WAIT:%s:%s:%s:%s:%s:%s:%s:' % \ - (self.l_filename, self.l_line, target, command, regexp, op, result,wait,wait_time)) + def wait( + self, target, command, regexp, op, result, wait, returnJson, wait_time=0.5 + ): + self.log( + "%s:%s WAIT:%s:%s:%s:%s:%s:%s:%s:" + % ( + self.l_filename, + self.l_line, + target, + command, + regexp, + op, + result, + wait, + wait_time, + ) + ) found = False n = 0 startt = time.time() @@ -264,103 +303,137 @@ Total %-4d %-4d %d\n\ time.sleep(wait_time) delta = time.time() - startt - self.log('Done after %d loops, time=%s, Found=%s' % (n, delta, found)) - found = self.command(target, command, regexp, 'pass', '%s +%4.2f secs' % (result, delta), returnJson) + self.log("Done after %d loops, time=%s, Found=%s" % (n, delta, found)) + found = self.command( + target, + command, + regexp, + "pass", + "%s +%4.2f secs" % (result, delta), + returnJson, + ) return found -#initialized by luStart -LUtil=None -#entry calls -def luStart(baseScriptDir='.', baseLogDir='.', net='', - fout='output.log', fsum='summary.txt', level=None): +# initialized by luStart +LUtil = None + +# entry calls +def luStart( + baseScriptDir=".", + baseLogDir=".", + net="", + fout="output.log", + fsum="summary.txt", + level=None, +): global LUtil - #init class - LUtil=lUtil() + # init class + LUtil = lUtil() LUtil.base_script_dir = baseScriptDir LUtil.base_log_dir = baseLogDir LUtil.net = net - if fout != '': - LUtil.fout_name = baseLogDir + '/' + fout + if fout != "": + LUtil.fout_name = baseLogDir + "/" + fout if fsum != None: - LUtil.fsum_name = baseLogDir + '/' + fsum + LUtil.fsum_name = baseLogDir + "/" + fsum if level != None: LUtil.l_level = level LUtil.l_dotall_experiment = False LUtil.l_dotall_experiment = True -def luCommand(target, command, regexp='.', op='none', result='', time=10, returnJson=False, wait_time=0.5): - if op != 'wait': + +def luCommand( + target, + command, + regexp=".", + op="none", + result="", + time=10, + returnJson=False, + wait_time=0.5, +): + if op != "wait": return LUtil.command(target, command, regexp, op, result, returnJson) else: - return LUtil.wait(target, command, regexp, op, result, time, returnJson, wait_time) + return LUtil.wait( + target, command, regexp, op, result, time, returnJson, wait_time + ) + def luLast(usenl=False): if usenl: if LUtil.l_last_nl != None: - LUtil.log('luLast:%s:' % LUtil.l_last_nl.group(), 7) + LUtil.log("luLast:%s:" % LUtil.l_last_nl.group(), 7) return LUtil.l_last_nl else: if LUtil.l_last != None: - LUtil.log('luLast:%s:' % LUtil.l_last.group(), 7) + LUtil.log("luLast:%s:" % LUtil.l_last.group(), 7) return LUtil.l_last + def luInclude(filename, CallOnFail=None): - tstFile = LUtil.base_script_dir + '/' + filename + tstFile = LUtil.base_script_dir + "/" + filename LUtil.setFilename(filename) if CallOnFail != None: oldCallOnFail = LUtil.getCallOnFail() LUtil.setCallOnFail(CallOnFail) - if filename.endswith('.py'): - LUtil.log("luInclude: execfile "+tstFile) + if filename.endswith(".py"): + LUtil.log("luInclude: execfile " + tstFile) execfile(tstFile) else: - LUtil.log("luInclude: execTestFile "+tstFile) + LUtil.log("luInclude: execTestFile " + tstFile) LUtil.execTestFile(tstFile) if CallOnFail != None: LUtil.setCallOnFail(oldCallOnFail) + def luFinish(): global LUtil ret = LUtil.closeFiles() - #done + # done LUtil = None - return ret; + return ret + def luNumFail(): return LUtil.l_fail + def luNumPass(): return LUtil.l_pass + def luResult(target, success, str, logstr=None): return LUtil.result(target, success, str, logstr) + def luShowResults(prFunction): printed = 0 - sf = open(LUtil.fsum_name, 'r') + sf = open(LUtil.fsum_name, "r") for line in sf: - printed+=1 + printed += 1 prFunction(line.rstrip()) sf.close() + def luShowFail(): printed = 0 - sf = open(LUtil.fsum_name, 'r') + sf = open(LUtil.fsum_name, "r") for line in sf: if line[-2] != "0": - printed+=1 + printed += 1 logger.error(line.rstrip()) sf.close() if printed > 0: - logger.error("See %s for details of errors" % LUtil.fout_name) + logger.error("See %s for details of errors" % LUtil.fout_name) + -#for testing -if __name__ == '__main__': - print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/lib') +# for testing +if __name__ == "__main__": + print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "/lib") luStart() for arg in sys.argv[1:]: luInclude(arg) luFinish() sys.exit(0) - diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 9d6b8fa691..9f3d4841b0 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -26,12 +26,15 @@ import ipaddr from lib.topotest import frr_unicode # Import common_config to use commomnly used APIs -from lib.common_config import (create_common_configuration, - InvalidCLIError, retry, - generate_ips, - check_address_types, - validate_ip_address, - run_frr_cmd) +from lib.common_config import ( + create_common_configuration, + InvalidCLIError, + retry, + generate_ips, + check_address_types, + validate_ip_address, + run_frr_cmd, +) LOGDIR = "/tmp/topotests/" TMPDIR = None @@ -40,9 +43,8 @@ TMPDIR = None # Configure procs ################################ -def create_router_ospf( - tgen, topo, input_dict=None, build=False, - load_config=True): + +def create_router_ospf(tgen, topo, input_dict=None, build=False, load_config=True): """ API to configure ospf on router. @@ -84,19 +86,15 @@ def create_router_ospf( logger.debug("Router %s: 'ospf' not present in input_dict", router) continue - result = __create_ospf_global( - tgen, input_dict, router, build, load_config) + result = __create_ospf_global(tgen, input_dict, router, build, load_config) if result is True: ospf_data = input_dict[router]["ospf"] - logger.debug("Exiting lib API: create_router_ospf()") return result -def __create_ospf_global( - tgen, input_dict, router, build=False, - load_config=True): +def __create_ospf_global(tgen, input_dict, router, build=False, load_config=True): """ Helper API to create ospf global configuration. @@ -121,9 +119,9 @@ def __create_ospf_global( del_ospf_action = ospf_data.setdefault("delete", False) if del_ospf_action: config_data = ["no router ospf"] - result = create_common_configuration(tgen, router, config_data, - "ospf", build, - load_config) + result = create_common_configuration( + tgen, router, config_data, "ospf", build, load_config + ) return result config_data = [] @@ -137,34 +135,33 @@ def __create_ospf_global( if del_router_id: config_data.append("no ospf router-id") if router_id: - config_data.append("ospf router-id {}".format( - router_id)) + config_data.append("ospf router-id {}".format(router_id)) # redistribute command redistribute_data = ospf_data.setdefault("redistribute", {}) if redistribute_data: for redistribute in redistribute_data: if "redist_type" not in redistribute: - logger.debug("Router %s: 'redist_type' not present in " - "input_dict", router) + logger.debug( + "Router %s: 'redist_type' not present in " "input_dict", router + ) else: - cmd = "redistribute {}".format( - redistribute["redist_type"]) + cmd = "redistribute {}".format(redistribute["redist_type"]) for red_type in redistribute_data: if "route_map" in red_type: - cmd = cmd + " route-map {}".format(red_type[ - 'route_map']) + cmd = cmd + " route-map {}".format(red_type["route_map"]) del_action = redistribute.setdefault("delete", False) if del_action: cmd = "no {}".format(cmd) config_data.append(cmd) - #area information + # area information area_data = ospf_data.setdefault("area", {}) if area_data: for area in area_data: if "id" not in area: - logger.debug("Router %s: 'area id' not present in " - "input_dict", router) + logger.debug( + "Router %s: 'area id' not present in " "input_dict", router + ) else: cmd = "area {}".format(area["id"]) @@ -175,19 +172,21 @@ def __create_ospf_global( if del_action: cmd = "no {}".format(cmd) config_data.append(cmd) - result = create_common_configuration(tgen, router, config_data, - "ospf", build, load_config) + result = create_common_configuration( + tgen, router, config_data, "ospf", build, load_config + ) # summary information summary_data = ospf_data.setdefault("summary-address", {}) if summary_data: for summary in summary_data: if "prefix" not in summary: - logger.debug("Router %s: 'summary-address' not present in " - "input_dict", router) + logger.debug( + "Router %s: 'summary-address' not present in " "input_dict", + router, + ) else: - cmd = "summary {}/{}".format(summary["prefix"], summary[ - "mask"]) + cmd = "summary {}/{}".format(summary["prefix"], summary["mask"]) _tag = summary.setdefault("tag", None) if _tag: @@ -201,8 +200,9 @@ def __create_ospf_global( if del_action: cmd = "no {}".format(cmd) config_data.append(cmd) - result = create_common_configuration(tgen, router, config_data, - "ospf", build, load_config) + result = create_common_configuration( + tgen, router, config_data, "ospf", build, load_config + ) except InvalidCLIError: # Traceback @@ -214,9 +214,7 @@ def __create_ospf_global( return result -def create_router_ospf6( - tgen, topo, input_dict=None, build=False, - load_config=True): +def create_router_ospf6(tgen, topo, input_dict=None, build=False, load_config=True): """ API to configure ospf on router @@ -253,16 +251,13 @@ def create_router_ospf6( logger.debug("Router %s: 'ospf' not present in input_dict", router) continue - result = __create_ospf_global( - tgen, input_dict, router, build, load_config) + result = __create_ospf_global(tgen, input_dict, router, build, load_config) logger.debug("Exiting lib API: create_router_ospf()") return result -def __create_ospf6_global( - tgen, input_dict, router, build=False, - load_config=True): +def __create_ospf6_global(tgen, input_dict, router, build=False, load_config=True): """ Helper API to create ospf global configuration. @@ -286,9 +281,9 @@ def __create_ospf6_global( del_ospf_action = ospf_data.setdefault("delete", False) if del_ospf_action: config_data = ["no ipv6 router ospf"] - result = create_common_configuration(tgen, router, config_data, - "ospf", build, - load_config) + result = create_common_configuration( + tgen, router, config_data, "ospf", build, load_config + ) return result config_data = [] @@ -301,11 +296,11 @@ def __create_ospf6_global( if del_router_id: config_data.append("no ospf router-id") if router_id: - config_data.append("ospf router-id {}".format( - router_id)) + config_data.append("ospf router-id {}".format(router_id)) - result = create_common_configuration(tgen, router, config_data, - "ospf", build, load_config) + result = create_common_configuration( + tgen, router, config_data, "ospf", build, load_config + ) except InvalidCLIError: # Traceback errormsg = traceback.format_exc() @@ -315,8 +310,8 @@ def __create_ospf6_global( logger.debug("Exiting lib API: create_ospf_global()") return result -def config_ospf_interface (tgen, topo, input_dict=None, build=False, - load_config=True): + +def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config=True): """ API to configure ospf on router. @@ -356,22 +351,25 @@ def config_ospf_interface (tgen, topo, input_dict=None, build=False, input_dict = deepcopy(input_dict) for router in input_dict.keys(): config_data = [] - for lnk in input_dict[router]['links'].keys(): - if "ospf" not in input_dict[router]['links'][lnk]: - logger.debug("Router %s: ospf configs is not present in" - "input_dict, passed input_dict", router, - input_dict) + for lnk in input_dict[router]["links"].keys(): + if "ospf" not in input_dict[router]["links"][lnk]: + logger.debug( + "Router %s: ospf configs is not present in" + "input_dict, passed input_dict", + router, + input_dict, + ) continue - ospf_data = input_dict[router]['links'][lnk]['ospf'] + ospf_data = input_dict[router]["links"][lnk]["ospf"] data_ospf_area = ospf_data.setdefault("area", None) data_ospf_auth = ospf_data.setdefault("authentication", None) data_ospf_dr_priority = ospf_data.setdefault("priority", None) data_ospf_cost = ospf_data.setdefault("cost", None) try: - intf = topo['routers'][router]['links'][lnk]['interface'] + intf = topo["routers"][router]["links"][lnk]["interface"] except KeyError: - intf = topo['switches'][router]['links'][lnk]['interface'] + intf = topo["switches"][router]["links"][lnk]["interface"] # interface cmd = "interface {}".format(intf) @@ -383,58 +381,60 @@ def config_ospf_interface (tgen, topo, input_dict=None, build=False, config_data.append(cmd) # interface ospf auth if data_ospf_auth: - if data_ospf_auth == 'null': + if data_ospf_auth == "null": cmd = "ip ospf authentication null" - elif data_ospf_auth == 'message-digest': + elif data_ospf_auth == "message-digest": cmd = "ip ospf authentication message-digest" else: cmd = "ip ospf authentication" - if 'del_action' in ospf_data: + if "del_action" in ospf_data: cmd = "no {}".format(cmd) config_data.append(cmd) if "message-digest-key" in ospf_data: cmd = "ip ospf message-digest-key {} md5 {}".format( - ospf_data["message-digest-key"],ospf_data[ - "authentication-key"]) - if 'del_action' in ospf_data: + ospf_data["message-digest-key"], ospf_data["authentication-key"] + ) + if "del_action" in ospf_data: cmd = "no {}".format(cmd) config_data.append(cmd) - if "authentication-key" in ospf_data and \ - "message-digest-key" not in ospf_data: - cmd = "ip ospf authentication-key {}".format(ospf_data[ - "authentication-key"]) - if 'del_action' in ospf_data: + if ( + "authentication-key" in ospf_data + and "message-digest-key" not in ospf_data + ): + cmd = "ip ospf authentication-key {}".format( + ospf_data["authentication-key"] + ) + if "del_action" in ospf_data: cmd = "no {}".format(cmd) config_data.append(cmd) # interface ospf dr priority if data_ospf_dr_priority in ospf_data: - cmd = "ip ospf priority {}".format( - ospf_data["priority"]) - if 'del_action' in ospf_data: + cmd = "ip ospf priority {}".format(ospf_data["priority"]) + if "del_action" in ospf_data: cmd = "no {}".format(cmd) config_data.append(cmd) # interface ospf cost if data_ospf_cost in ospf_data: - cmd = "ip ospf cost {}".format( - ospf_data["cost"]) - if 'del_action' in ospf_data: + cmd = "ip ospf cost {}".format(ospf_data["cost"]) + if "del_action" in ospf_data: cmd = "no {}".format(cmd) config_data.append(cmd) if build: return config_data else: - result = create_common_configuration(tgen, router, config_data, - "interface_config", - build=build) + result = create_common_configuration( + tgen, router, config_data, "interface_config", build=build + ) logger.debug("Exiting lib API: create_igmp_config()") return result + def clear_ospf(tgen, router): """ This API is to clear ospf neighborship by running @@ -517,15 +517,16 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False): result = False if input_dict: for router, rnode in tgen.routers().items(): - if 'ospf' not in topo['routers'][router]: + if "ospf" not in topo["routers"][router]: continue if dut is not None and dut != router: continue logger.info("Verifying OSPF neighborship on router %s:", router) - show_ospf_json = run_frr_cmd(rnode, - "show ip ospf neighbor all json", isjson=True) + show_ospf_json = run_frr_cmd( + rnode, "show ip ospf neighbor all json", isjson=True + ) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): @@ -533,126 +534,134 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False): return errormsg ospf_data_list = input_dict[router]["ospf"] - ospf_nbr_list = ospf_data_list['neighbors'] + ospf_nbr_list = ospf_data_list["neighbors"] for ospf_nbr, nbr_data in ospf_nbr_list.items(): - data_ip = topo['routers'][ospf_nbr]['links'] - data_rid = topo['routers'][ospf_nbr]['ospf']['router_id'] + data_ip = topo["routers"][ospf_nbr]["links"] + data_rid = topo["routers"][ospf_nbr]["ospf"]["router_id"] if ospf_nbr in data_ip: nbr_details = nbr_data[ospf_nbr] elif lan: - for switch in topo['switches']: - if 'ospf' in topo['switches'][switch]['links'][router]: - neighbor_ip = data_ip[switch]['ipv4'].split("/")[0] + for switch in topo["switches"]: + if "ospf" in topo["switches"][switch]["links"][router]: + neighbor_ip = data_ip[switch]["ipv4"].split("/")[0] else: continue else: - neighbor_ip = data_ip[router]['ipv4'].split("/")[0] + neighbor_ip = data_ip[router]["ipv4"].split("/")[0] nh_state = None neighbor_ip = neighbor_ip.lower() nbr_rid = data_rid try: - nh_state = show_ospf_json[nbr_rid][0][ - 'state'].split('/')[0] - intf_state = show_ospf_json[nbr_rid][0][ - 'state'].split('/')[1] + nh_state = show_ospf_json[nbr_rid][0]["state"].split("/")[0] + intf_state = show_ospf_json[nbr_rid][0]["state"].split("/")[1] except KeyError: - errormsg = "[DUT: {}] OSPF peer {} missing".format(router, - nbr_rid) + errormsg = "[DUT: {}] OSPF peer {} missing".format(router, nbr_rid) return errormsg - nbr_state = nbr_data.setdefault("state",None) - nbr_role = nbr_data.setdefault("role",None) + nbr_state = nbr_data.setdefault("state", None) + nbr_role = nbr_data.setdefault("role", None) if nbr_state: if nbr_state == nh_state: - logger.info("[DUT: {}] OSPF Nbr is {}:{} State {}".format - (router, ospf_nbr, nbr_rid, nh_state)) + logger.info( + "[DUT: {}] OSPF Nbr is {}:{} State {}".format( + router, ospf_nbr, nbr_rid, nh_state + ) + ) result = True else: - errormsg = ("[DUT: {}] OSPF is not Converged, neighbor" - " state is {}".format(router, nh_state)) + errormsg = ( + "[DUT: {}] OSPF is not Converged, neighbor" + " state is {}".format(router, nh_state) + ) return errormsg if nbr_role: if nbr_role == intf_state: - logger.info("[DUT: {}] OSPF Nbr is {}: {} Role {}".format( - router, ospf_nbr, nbr_rid, nbr_role)) + logger.info( + "[DUT: {}] OSPF Nbr is {}: {} Role {}".format( + router, ospf_nbr, nbr_rid, nbr_role + ) + ) else: - errormsg = ("[DUT: {}] OSPF is not Converged with rid" - "{}, role is {}".format(router, nbr_rid, intf_state)) + errormsg = ( + "[DUT: {}] OSPF is not Converged with rid" + "{}, role is {}".format(router, nbr_rid, intf_state) + ) return errormsg continue else: for router, rnode in tgen.routers().items(): - if 'ospf' not in topo['routers'][router]: + if "ospf" not in topo["routers"][router]: continue if dut is not None and dut != router: continue logger.info("Verifying OSPF neighborship on router %s:", router) - show_ospf_json = run_frr_cmd(rnode, - "show ip ospf neighbor all json", isjson=True) + show_ospf_json = run_frr_cmd( + rnode, "show ip ospf neighbor all json", isjson=True + ) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" return errormsg ospf_data_list = topo["routers"][router]["ospf"] - ospf_neighbors = ospf_data_list['neighbors'] + ospf_neighbors = ospf_data_list["neighbors"] total_peer = 0 total_peer = len(ospf_neighbors.keys()) no_of_ospf_nbr = 0 - ospf_nbr_list = ospf_data_list['neighbors'] + ospf_nbr_list = ospf_data_list["neighbors"] no_of_peer = 0 for ospf_nbr, nbr_data in ospf_nbr_list.items(): if nbr_data: - data_ip = topo['routers'][nbr_data["nbr"]]['links'] - data_rid = topo['routers'][nbr_data["nbr"]][ - 'ospf']['router_id'] + data_ip = topo["routers"][nbr_data["nbr"]]["links"] + data_rid = topo["routers"][nbr_data["nbr"]]["ospf"]["router_id"] else: - data_ip = topo['routers'][ospf_nbr]['links'] - data_rid = topo['routers'][ospf_nbr]['ospf']['router_id'] + data_ip = topo["routers"][ospf_nbr]["links"] + data_rid = topo["routers"][ospf_nbr]["ospf"]["router_id"] if ospf_nbr in data_ip: nbr_details = nbr_data[ospf_nbr] elif lan: - for switch in topo['switches']: - if 'ospf' in topo['switches'][switch]['links'][router]: - neighbor_ip = data_ip[switch]['ipv4'].split("/")[0] + for switch in topo["switches"]: + if "ospf" in topo["switches"][switch]["links"][router]: + neighbor_ip = data_ip[switch]["ipv4"].split("/")[0] else: continue else: - neighbor_ip = data_ip[router]['ipv4'].split("/")[0] + neighbor_ip = data_ip[router]["ipv4"].split("/")[0] nh_state = None neighbor_ip = neighbor_ip.lower() nbr_rid = data_rid try: - nh_state = show_ospf_json[nbr_rid][0][ - 'state'].split('/')[0] + nh_state = show_ospf_json[nbr_rid][0]["state"].split("/")[0] except KeyError: - errormsg = "[DUT: {}] OSPF peer {} missing,from "\ - "{} ".format(router, - nbr_rid, ospf_nbr) + errormsg = "[DUT: {}] OSPF peer {} missing,from " "{} ".format( + router, nbr_rid, ospf_nbr + ) return errormsg - if nh_state == 'Full': + if nh_state == "Full": no_of_peer += 1 if no_of_peer == total_peer: logger.info("[DUT: {}] OSPF is Converged".format(router)) result = True else: - errormsg = ("[DUT: {}] OSPF is not Converged".format(router)) + errormsg = "[DUT: {}] OSPF is not Converged".format(router) return errormsg logger.debug("Exiting API: verify_ospf_neighbor()") return result + @retry(attempts=21, wait=2, return_is_str=True) -def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, - tag=None, metric=None, fib=None): +def verify_ospf_rib( + tgen, dut, input_dict, next_hop=None, tag=None, metric=None, fib=None +): """ This API is to verify ospf routes by running show ip ospf route command. @@ -706,25 +715,28 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, found_routes = [] missing_routes = [] - if "static_routes" in input_dict[routerInput] or \ - "prefix" in input_dict[routerInput]: + if ( + "static_routes" in input_dict[routerInput] + or "prefix" in input_dict[routerInput] + ): if "prefix" in input_dict[routerInput]: static_routes = input_dict[routerInput]["prefix"] else: static_routes = input_dict[routerInput]["static_routes"] - for static_route in static_routes: cmd = "{}".format(command) cmd = "{} json".format(cmd) - ospf_rib_json = run_frr_cmd(rnode, cmd, isjson=True) + ospf_rib_json = run_frr_cmd(rnode, cmd, isjson=True) # Verifying output dictionary ospf_rib_json is not empty if bool(ospf_rib_json) is False: - errormsg = "[DUT: {}] No routes found in OSPF route " \ + errormsg = ( + "[DUT: {}] No routes found in OSPF route " "table".format(router) + ) return errormsg network = static_route["network"] @@ -732,7 +744,6 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, _tag = static_route.setdefault("tag", None) _rtype = static_route.setdefault("routeType", None) - # Generating IPs for verification ip_list = generate_ips(network, no_of_ip) st_found = False @@ -742,7 +753,7 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, st_rt = str(ipaddr.IPNetwork(frr_unicode(st_rt))) _addr_type = validate_ip_address(st_rt) - if _addr_type != 'ipv4': + if _addr_type != "ipv4": continue if st_rt in ospf_rib_json: @@ -754,17 +765,26 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, next_hop = [next_hop] for mnh in range(0, len(ospf_rib_json[st_rt])): - if 'fib' in ospf_rib_json[st_rt][ - mnh]["nexthops"][0]: - found_hops.append([rib_r[ - "ip"] for rib_r in ospf_rib_json[ - st_rt][mnh]["nexthops"]]) + if ( + "fib" + in ospf_rib_json[st_rt][mnh]["nexthops"][0] + ): + found_hops.append( + [ + rib_r["ip"] + for rib_r in ospf_rib_json[st_rt][mnh][ + "nexthops" + ] + ] + ) if found_hops[0]: - missing_list_of_nexthops = \ - set(found_hops[0]).difference(next_hop) - additional_nexthops_in_required_nhs = \ - set(next_hop).difference(found_hops[0]) + missing_list_of_nexthops = set( + found_hops[0] + ).difference(next_hop) + additional_nexthops_in_required_nhs = set( + next_hop + ).difference(found_hops[0]) if additional_nexthops_in_required_nhs: logger.info( @@ -772,13 +792,18 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, "%s is not active for route %s in " "RIB of router %s\n", additional_nexthops_in_required_nhs, - st_rt, dut) + st_rt, + dut, + ) errormsg = ( "Nexthop {} is not active" " for route {} in RIB of router" " {}\n".format( - additional_nexthops_in_required_nhs, - st_rt, dut)) + additional_nexthops_in_required_nhs, + st_rt, + dut, + ) + ) return errormsg else: nh_found = True @@ -786,99 +811,111 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, elif next_hop and fib is None: if type(next_hop) is not list: next_hop = [next_hop] - found_hops = [rib_r["ip"] for rib_r in - ospf_rib_json[st_rt][ - "nexthops"]] + found_hops = [ + rib_r["ip"] + for rib_r in ospf_rib_json[st_rt]["nexthops"] + ] if found_hops: - missing_list_of_nexthops = \ - set(found_hops).difference(next_hop) - additional_nexthops_in_required_nhs = \ - set(next_hop).difference(found_hops) + missing_list_of_nexthops = set( + found_hops + ).difference(next_hop) + additional_nexthops_in_required_nhs = set( + next_hop + ).difference(found_hops) if additional_nexthops_in_required_nhs: logger.info( - "Missing nexthop %s for route"\ - " %s in RIB of router %s\n", \ - additional_nexthops_in_required_nhs, \ - st_rt, dut) - errormsg=("Nexthop {} is Missing for "\ - "route {} in RIB of router {}\n".format( + "Missing nexthop %s for route" + " %s in RIB of router %s\n", additional_nexthops_in_required_nhs, - st_rt, dut)) + st_rt, + dut, + ) + errormsg = ( + "Nexthop {} is Missing for " + "route {} in RIB of router {}\n".format( + additional_nexthops_in_required_nhs, + st_rt, + dut, + ) + ) return errormsg else: nh_found = True if _rtype: - if "routeType" not in ospf_rib_json[ - st_rt]: - errormsg = ("[DUT: {}]: routeType missing" - "for route {} in OSPF RIB \n".\ - format(dut, st_rt)) + if "routeType" not in ospf_rib_json[st_rt]: + errormsg = ( + "[DUT: {}]: routeType missing" + "for route {} in OSPF RIB \n".format(dut, st_rt) + ) return errormsg - elif _rtype != ospf_rib_json[st_rt][ - "routeType"]: - errormsg = ("[DUT: {}]: routeType mismatch" - "for route {} in OSPF RIB \n".\ - format(dut, st_rt)) + elif _rtype != ospf_rib_json[st_rt]["routeType"]: + errormsg = ( + "[DUT: {}]: routeType mismatch" + "for route {} in OSPF RIB \n".format(dut, st_rt) + ) return errormsg else: - logger.info("DUT: {}]: Found routeType {}" - "for route {}".\ - format(dut, _rtype, st_rt)) + logger.info( + "DUT: {}]: Found routeType {}" + "for route {}".format(dut, _rtype, st_rt) + ) if tag: - if "tag" not in ospf_rib_json[ - st_rt]: - errormsg = ("[DUT: {}]: tag is not" - " present for" - " route {} in RIB \n".\ - format(dut, st_rt - )) + if "tag" not in ospf_rib_json[st_rt]: + errormsg = ( + "[DUT: {}]: tag is not" + " present for" + " route {} in RIB \n".format(dut, st_rt) + ) return errormsg - if _tag != ospf_rib_json[ - st_rt]["tag"]: - errormsg = ("[DUT: {}]: tag value {}" - " is not matched for" - " route {} in RIB \n".\ - format(dut, _tag, st_rt, - )) + if _tag != ospf_rib_json[st_rt]["tag"]: + errormsg = ( + "[DUT: {}]: tag value {}" + " is not matched for" + " route {} in RIB \n".format(dut, _tag, st_rt,) + ) return errormsg if metric is not None: - if "type2cost" not in ospf_rib_json[ - st_rt]: - errormsg = ("[DUT: {}]: metric is" - " not present for" - " route {} in RIB \n".\ - format(dut, st_rt)) + if "type2cost" not in ospf_rib_json[st_rt]: + errormsg = ( + "[DUT: {}]: metric is" + " not present for" + " route {} in RIB \n".format(dut, st_rt) + ) return errormsg - if metric != ospf_rib_json[ - st_rt]["type2cost"]: - errormsg = ("[DUT: {}]: metric value " - "{} is not matched for " - "route {} in RIB \n".\ - format(dut, metric, st_rt, - )) + if metric != ospf_rib_json[st_rt]["type2cost"]: + errormsg = ( + "[DUT: {}]: metric value " + "{} is not matched for " + "route {} in RIB \n".format(dut, metric, st_rt,) + ) return errormsg else: missing_routes.append(st_rt) if nh_found: - logger.info("[DUT: {}]: Found next_hop {} for all OSPF" - " routes in RIB".format(router, next_hop)) + logger.info( + "[DUT: {}]: Found next_hop {} for all OSPF" + " routes in RIB".format(router, next_hop) + ) if len(missing_routes) > 0: - errormsg = ("[DUT: {}]: Missing route in RIB, " - "routes: {}".\ - format(dut, missing_routes)) + errormsg = "[DUT: {}]: Missing route in RIB, " "routes: {}".format( + dut, missing_routes + ) return errormsg if found_routes: - logger.info("[DUT: %s]: Verified routes in RIB, found" - " routes are: %s\n", dut, found_routes) + logger.info( + "[DUT: %s]: Verified routes in RIB, found" " routes are: %s\n", + dut, + found_routes, + ) result = True logger.info("Exiting lib API: verify_ospf_rib()") @@ -886,7 +923,7 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None, @retry(attempts=10, wait=2, return_is_str=True) -def verify_ospf_interface(tgen, topo, dut=None,lan=False, input_dict=None): +def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None): """ This API is to verify ospf routes by running show ip ospf interface command. @@ -928,15 +965,14 @@ def verify_ospf_interface(tgen, topo, dut=None,lan=False, input_dict=None): logger.debug("Entering lib API: verify_ospf_interface()") result = False for router, rnode in tgen.routers().items(): - if 'ospf' not in topo['routers'][router]: + if "ospf" not in topo["routers"][router]: continue if dut is not None and dut != router: continue logger.info("Verifying OSPF interface on router %s:", router) - show_ospf_json = run_frr_cmd(rnode, "show ip ospf interface json", - isjson=True) + show_ospf_json = run_frr_cmd(rnode, "show ip ospf interface json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): @@ -946,19 +982,29 @@ def verify_ospf_interface(tgen, topo, dut=None,lan=False, input_dict=None): # To find neighbor ip type ospf_intf_data = input_dict[router]["links"] for ospf_intf, intf_data in ospf_intf_data.items(): - intf = topo['routers'][router]['links'][ospf_intf]['interface'] - if intf in show_ospf_json['interfaces']: - for intf_attribute in intf_data['ospf']: - if intf_data['ospf'][intf_attribute] == show_ospf_json[ - 'interfaces'][intf][intf_attribute]: - logger.info("[DUT: %s] OSPF interface %s: %s is %s", - router, intf, intf_attribute, intf_data['ospf'][ - intf_attribute]) + intf = topo["routers"][router]["links"][ospf_intf]["interface"] + if intf in show_ospf_json["interfaces"]: + for intf_attribute in intf_data["ospf"]: + if ( + intf_data["ospf"][intf_attribute] + == show_ospf_json["interfaces"][intf][intf_attribute] + ): + logger.info( + "[DUT: %s] OSPF interface %s: %s is %s", + router, + intf, + intf_attribute, + intf_data["ospf"][intf_attribute], + ) else: - errormsg= "[DUT: {}] OSPF interface {}: {} is {}, \ - Expected is {}".format(router, intf, intf_attribute, - intf_data['ospf'][intf_attribute], show_ospf_json[ - 'interfaces'][intf][intf_attribute]) + errormsg = "[DUT: {}] OSPF interface {}: {} is {}, \ + Expected is {}".format( + router, + intf, + intf_attribute, + intf_data["ospf"][intf_attribute], + show_ospf_json["interfaces"][intf][intf_attribute], + ) return errormsg result = True logger.debug("Exiting API: verify_ospf_interface()") @@ -1016,16 +1062,14 @@ def verify_ospf_database(tgen, topo, dut, input_dict): router = dut logger.debug("Entering lib API: verify_ospf_database()") - if 'ospf' not in topo['routers'][dut]: - errormsg = "[DUT: {}] OSPF is not configured on the router.".format( - dut) + if "ospf" not in topo["routers"][dut]: + errormsg = "[DUT: {}] OSPF is not configured on the router.".format(dut) return errormsg rnode = tgen.routers()[dut] logger.info("Verifying OSPF interface on router %s:", dut) - show_ospf_json = run_frr_cmd(rnode, "show ip ospf database json", - isjson=True) + show_ospf_json = run_frr_cmd(rnode, "show ip ospf database json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): errormsg = "OSPF is not running" @@ -1033,82 +1077,103 @@ def verify_ospf_database(tgen, topo, dut, input_dict): # for inter and inter lsa's ospf_db_data = input_dict.setdefault("areas", None) - ospf_external_lsa = input_dict.setdefault( - 'AS External Link States', None) + ospf_external_lsa = input_dict.setdefault("AS External Link States", None) if ospf_db_data: - for ospf_area, area_lsa in ospf_db_data.items(): - if ospf_area in show_ospf_json['areas']: - if 'Router Link States' in area_lsa: - for lsa in area_lsa['Router Link States']: - if lsa in show_ospf_json['areas'][ospf_area][ - 'Router Link States']: - logger.info( - "[DUT: %s] OSPF LSDB area %s:Router " - "LSA %s", router, ospf_area, lsa) - result = True - else: - errormsg = \ - "[DUT: {}] OSPF LSDB area {}: expected" \ + for ospf_area, area_lsa in ospf_db_data.items(): + if ospf_area in show_ospf_json["areas"]: + if "Router Link States" in area_lsa: + for lsa in area_lsa["Router Link States"]: + if ( + lsa + in show_ospf_json["areas"][ospf_area]["Router Link States"] + ): + logger.info( + "[DUT: %s] OSPF LSDB area %s:Router " "LSA %s", + router, + ospf_area, + lsa, + ) + result = True + else: + errormsg = ( + "[DUT: {}] OSPF LSDB area {}: expected" " Router LSA is {}".format(router, ospf_area, lsa) - return errormsg - if 'Net Link States' in area_lsa: - for lsa in area_lsa['Net Link States']: - if lsa in show_ospf_json['areas'][ospf_area][ - 'Net Link States']: - logger.info( - "[DUT: %s] OSPF LSDB area %s:Network " - "LSA %s", router, ospf_area, lsa) - result = True - else: - errormsg = \ - "[DUT: {}] OSPF LSDB area {}: expected" \ + ) + return errormsg + if "Net Link States" in area_lsa: + for lsa in area_lsa["Net Link States"]: + if lsa in show_ospf_json["areas"][ospf_area]["Net Link States"]: + logger.info( + "[DUT: %s] OSPF LSDB area %s:Network " "LSA %s", + router, + ospf_area, + lsa, + ) + result = True + else: + errormsg = ( + "[DUT: {}] OSPF LSDB area {}: expected" " Network LSA is {}".format(router, ospf_area, lsa) - return errormsg - if 'Summary Link States' in area_lsa: - for lsa in area_lsa['Summary Link States']: - if lsa in show_ospf_json['areas'][ospf_area][ - 'Summary Link States']: - logger.info( - "[DUT: %s] OSPF LSDB area %s:Summary " - "LSA %s", router, ospf_area, lsa) - result = True - else: - errormsg = \ - "[DUT: {}] OSPF LSDB area {}: expected" \ + ) + return errormsg + if "Summary Link States" in area_lsa: + for lsa in area_lsa["Summary Link States"]: + if ( + lsa + in show_ospf_json["areas"][ospf_area]["Summary Link States"] + ): + logger.info( + "[DUT: %s] OSPF LSDB area %s:Summary " "LSA %s", + router, + ospf_area, + lsa, + ) + result = True + else: + errormsg = ( + "[DUT: {}] OSPF LSDB area {}: expected" " Summary LSA is {}".format(router, ospf_area, lsa) - return errormsg - if 'ASBR-Summary Link States' in area_lsa: - for lsa in area_lsa['ASBR-Summary Link States']: - if lsa in show_ospf_json['areas'][ospf_area][ - 'ASBR-Summary Link States']: - logger.info( - "[DUT: %s] OSPF LSDB area %s:ASBR Summary " - "LSA %s", router, ospf_area, lsa) - result = True - else: - errormsg = \ - "[DUT: {}] OSPF LSDB area {}: expected" \ - " ASBR Summary LSA is {}".format( - router, ospf_area, lsa) - return errormsg + ) + return errormsg + if "ASBR-Summary Link States" in area_lsa: + for lsa in area_lsa["ASBR-Summary Link States"]: + if ( + lsa + in show_ospf_json["areas"][ospf_area][ + "ASBR-Summary Link States" + ] + ): + logger.info( + "[DUT: %s] OSPF LSDB area %s:ASBR Summary " "LSA %s", + router, + ospf_area, + lsa, + ) + result = True + else: + errormsg = ( + "[DUT: {}] OSPF LSDB area {}: expected" + " ASBR Summary LSA is {}".format(router, ospf_area, lsa) + ) + return errormsg if ospf_external_lsa: - for ospf_ext_lsa, ext_lsa_data in ospf_external_lsa.items(): - if ospf_ext_lsa in show_ospf_json['AS External Link States']: - logger.info( - "[DUT: %s] OSPF LSDB:External LSA %s", - router, ospf_ext_lsa) - result = True - else: - errormsg = \ - "[DUT: {}] OSPF LSDB : expected" \ - " External LSA is {}".format(router, ospf_ext_lsa) - return errormsg + for ospf_ext_lsa, ext_lsa_data in ospf_external_lsa.items(): + if ospf_ext_lsa in show_ospf_json["AS External Link States"]: + logger.info( + "[DUT: %s] OSPF LSDB:External LSA %s", router, ospf_ext_lsa + ) + result = True + else: + errormsg = ( + "[DUT: {}] OSPF LSDB : expected" + " External LSA is {}".format(router, ospf_ext_lsa) + ) + return errormsg logger.debug("Exiting API: verify_ospf_database()") return result - @retry(attempts=10, wait=2, return_is_str=True) def verify_ospf_summary(tgen, topo, dut, input_dict): """ @@ -1146,14 +1211,12 @@ def verify_ospf_summary(tgen, topo, dut, input_dict): logger.info("Verifying OSPF summary on router %s:", router) - if 'ospf' not in topo['routers'][dut]: - errormsg = "[DUT: {}] OSPF is not configured on the router.".format( - router) + if "ospf" not in topo["routers"][dut]: + errormsg = "[DUT: {}] OSPF is not configured on the router.".format(router) return errormsg rnode = tgen.routers()[dut] - show_ospf_json = run_frr_cmd(rnode, "show ip ospf summary detail json", - isjson=True) + show_ospf_json = run_frr_cmd(rnode, "show ip ospf summary detail json", isjson=True) # Verifying output dictionary show_ospf_json is empty or not if not bool(show_ospf_json): @@ -1165,17 +1228,25 @@ def verify_ospf_summary(tgen, topo, dut, input_dict): for ospf_summ, summ_data in ospf_summary_data.items(): if ospf_summ not in show_ospf_json: continue - summary = ospf_summary_data[ospf_summ]['Summary address'] + summary = ospf_summary_data[ospf_summ]["Summary address"] if summary in show_ospf_json: for summ in summ_data: if summ_data[summ] == show_ospf_json[summary][summ]: - logger.info("[DUT: %s] OSPF summary %s:%s is %s", - router, summary, summ, summ_data[summ]) + logger.info( + "[DUT: %s] OSPF summary %s:%s is %s", + router, + summary, + summ, + summ_data[summ], + ) result = True else: - errormsg = ("[DUT: {}] OSPF summary {}:{} is %s, " - "Expected is {}".format(router,summary, summ, - show_ospf_json[summary][summ])) + errormsg = ( + "[DUT: {}] OSPF summary {}:{} is %s, " + "Expected is {}".format( + router, summary, summ, show_ospf_json[summary][summ] + ) + ) return errormsg logger.debug("Exiting API: verify_ospf_summary()") diff --git a/tests/topotests/lib/test/test_json.py b/tests/topotests/lib/test/test_json.py index 7a061a9bc6..b85e193d3b 100755 --- a/tests/topotests/lib/test/test_json.py +++ b/tests/topotests/lib/test/test_json.py @@ -296,7 +296,7 @@ def test_json_list_ordered(): ] dsub1 = [ - '__ordered__', + "__ordered__", "some string", {"id": 1, "value": "abc"}, 123, @@ -312,28 +312,28 @@ def test_json_list_exact_matching(): {"id": 1, "value": "abc"}, "some string", 123, - [1,2,3], + [1, 2, 3], ] dsub1 = [ "some string", {"id": 1, "value": "abc"}, 123, - [1,2,3], + [1, 2, 3], ] dsub2 = [ {"id": 1}, "some string", 123, - [1,2,3], + [1, 2, 3], ] dsub3 = [ {"id": 1, "value": "abc"}, "some string", 123, - [1,3,2], + [1, 3, 2], ] assert json_cmp(dcomplete, dsub1, exact=True) is not None @@ -344,30 +344,30 @@ def test_json_object_exact_matching(): "Test JSON object on exact matching using the 'exact' parameter." dcomplete = { - 'a': {"id": 1, "value": "abc"}, - 'b': "some string", - 'c': 123, - 'd': [1,2,3], + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], } dsub1 = { - 'a': {"id": 1, "value": "abc"}, - 'c': 123, - 'd': [1,2,3], + "a": {"id": 1, "value": "abc"}, + "c": 123, + "d": [1, 2, 3], } dsub2 = { - 'a': {"id": 1}, - 'b': "some string", - 'c': 123, - 'd': [1,2,3], + "a": {"id": 1}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], } dsub3 = { - 'a': {"id": 1, "value": "abc"}, - 'b': "some string", - 'c': 123, - 'd': [1,3], + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 3], } assert json_cmp(dcomplete, dsub1, exact=True) is not None @@ -382,35 +382,35 @@ def test_json_list_asterisk_matching(): {"id": 1, "value": "abc"}, "some string", 123, - [1,2,3], + [1, 2, 3], ] dsub1 = [ - '*', + "*", "some string", 123, - [1,2,3], + [1, 2, 3], ] dsub2 = [ - {"id": '*', "value": "abc"}, + {"id": "*", "value": "abc"}, "some string", 123, - [1,2,3], + [1, 2, 3], ] dsub3 = [ {"id": 1, "value": "abc"}, "some string", 123, - [1,'*',3], + [1, "*", 3], ] dsub4 = [ - '*', + "*", "some string", - '*', - [1,2,3], + "*", + [1, 2, 3], ] assert json_cmp(dcomplete, dsub1) is None @@ -423,38 +423,38 @@ def test_json_object_asterisk_matching(): "Test JSON object value elements on matching '*' as a placeholder for arbitrary data." dcomplete = { - 'a': {"id": 1, "value": "abc"}, - 'b': "some string", - 'c': 123, - 'd': [1,2,3], + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], } dsub1 = { - 'a': '*', - 'b': "some string", - 'c': 123, - 'd': [1,2,3], + "a": "*", + "b": "some string", + "c": 123, + "d": [1, 2, 3], } dsub2 = { - 'a': {"id": 1, "value": "abc"}, - 'b': "some string", - 'c': 123, - 'd': [1,'*',3], + "a": {"id": 1, "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, "*", 3], } dsub3 = { - 'a': {"id": '*', "value": "abc"}, - 'b': "some string", - 'c': 123, - 'd': [1,2,3], + "a": {"id": "*", "value": "abc"}, + "b": "some string", + "c": 123, + "d": [1, 2, 3], } dsub4 = { - 'a': '*', - 'b': "some string", - 'c': '*', - 'd': [1,2,3], + "a": "*", + "b": "some string", + "c": "*", + "d": [1, 2, 3], } assert json_cmp(dcomplete, dsub1) is None @@ -465,37 +465,12 @@ def test_json_object_asterisk_matching(): def test_json_list_nested_with_objects(): - dcomplete = [ - { - "key": 1, - "list": [ - 123 - ] - }, - { - "key": 2, - "list": [ - 123 - ] - } - ] + dcomplete = [{"key": 1, "list": [123]}, {"key": 2, "list": [123]}] - dsub1 = [ - { - "key": 2, - "list": [ - 123 - ] - }, - { - "key": 1, - "list": [ - 123 - ] - } - ] + dsub1 = [{"key": 2, "list": [123]}, {"key": 1, "list": [123]}] assert json_cmp(dcomplete, dsub1) is None + if __name__ == "__main__": sys.exit(pytest.main()) diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index ffdcb683e7..3e92bd7565 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -703,11 +703,9 @@ class TopoRouter(TopoGear): Stop router, private internal version * Kill daemons """ - self.logger.debug("stopping: wait {}, assert {}".format( - wait, assertOnError)) + self.logger.debug("stopping: wait {}, assert {}".format(wait, assertOnError)) return self.tgen.net[self.name].stopRouter(wait, assertOnError) - def stop(self): """ Stop router cleanly: @@ -724,7 +722,7 @@ class TopoRouter(TopoGear): * Start daemons (e.g. FRR) * Configure daemon logging files """ - self.logger.debug('starting') + self.logger.debug("starting") nrouter = self.tgen.net[self.name] result = nrouter.startRouterDaemons(daemons) @@ -734,10 +732,12 @@ class TopoRouter(TopoGear): for d in daemons: if enabled == 0: continue - self.vtysh_cmd('configure terminal\nlog commands\nlog file {}.log'.\ - format(daemon), daemon=daemon) + self.vtysh_cmd( + "configure terminal\nlog commands\nlog file {}.log".format(daemon), + daemon=daemon, + ) - if result != '': + if result != "": self.tgen.set_error(result) return result @@ -747,7 +747,7 @@ class TopoRouter(TopoGear): Kill specific daemon(user defined daemon only) forcefully using SIGKILL """ - self.logger.debug('Killing daemons using SIGKILL..') + self.logger.debug("Killing daemons using SIGKILL..") return self.tgen.net[self.name].killRouterDaemons(daemons, wait, assertOnError) def vtysh_cmd(self, command, isjson=False, daemon=None): @@ -1070,7 +1070,7 @@ def diagnose_env_linux(): "isisd", "pimd", "ldpd", - "pbrd" + "pbrd", ]: path = os.path.join(frrdir, fname) if not os.path.isfile(path): diff --git a/tests/topotests/lib/topojson.py b/tests/topotests/lib/topojson.py index 6535918e36..f2fafa5e2a 100644 --- a/tests/topotests/lib/topojson.py +++ b/tests/topotests/lib/topojson.py @@ -45,6 +45,7 @@ from lib.common_config import ( from lib.bgp import create_router_bgp from lib.ospf import create_router_ospf + ROUTER_LIST = [] @@ -214,13 +215,14 @@ def build_topo_from_json(tgen, topo): while listSwitches != []: curSwitch = listSwitches.pop(0) # Physical Interfaces - if "links" in topo['switches'][curSwitch]: + if "links" in topo["switches"][curSwitch]: for destRouterLink, data in sorted( - topo['switches'][curSwitch]['links'].items()): + topo["switches"][curSwitch]["links"].items() + ): # Loopback interfaces if "dst_node" in data: - destRouter = data['dst_node'] + destRouter = data["dst_node"] elif "-" in destRouterLink: # Spliting and storing destRouterLink data in tempList @@ -232,39 +234,55 @@ def build_topo_from_json(tgen, topo): if destRouter in listAllRouters: - topo['routers'][destRouter]['links'][curSwitch] = \ - deepcopy(topo['switches'][curSwitch]['links'][destRouterLink]) + topo["routers"][destRouter]["links"][curSwitch] = deepcopy( + topo["switches"][curSwitch]["links"][destRouterLink] + ) # Assigning name to interfaces - topo['routers'][destRouter]['links'][curSwitch]['interface'] = \ - '{}-{}-eth{}'.format(destRouter, curSwitch, topo['routers'] \ - [destRouter]['nextIfname']) + topo["routers"][destRouter]["links"][curSwitch][ + "interface" + ] = "{}-{}-eth{}".format( + destRouter, curSwitch, topo["routers"][destRouter]["nextIfname"] + ) - topo['switches'][curSwitch]['links'][destRouter]['interface'] = \ - '{}-{}-eth{}'.format(curSwitch, destRouter, topo['routers'] \ - [destRouter]['nextIfname']) + topo["switches"][curSwitch]["links"][destRouter][ + "interface" + ] = "{}-{}-eth{}".format( + curSwitch, destRouter, topo["routers"][destRouter]["nextIfname"] + ) - topo['routers'][destRouter]['nextIfname'] += 1 + topo["routers"][destRouter]["nextIfname"] += 1 # Add links - dictSwitches[curSwitch].add_link(tgen.gears[destRouter], \ - topo['switches'][curSwitch]['links'][destRouter]['interface'], - topo['routers'][destRouter]['links'][curSwitch]['interface'], - ) + dictSwitches[curSwitch].add_link( + tgen.gears[destRouter], + topo["switches"][curSwitch]["links"][destRouter]["interface"], + topo["routers"][destRouter]["links"][curSwitch]["interface"], + ) # IPv4 - if 'ipv4' in topo['routers'][destRouter]['links'][curSwitch]: - if topo['routers'][destRouter]['links'][curSwitch]['ipv4'] == 'auto': - topo['routers'][destRouter]['links'][curSwitch]['ipv4'] = \ - '{}/{}'.format(ipv4Next, topo['link_ip_start'][ \ - 'v4mask']) + if "ipv4" in topo["routers"][destRouter]["links"][curSwitch]: + if ( + topo["routers"][destRouter]["links"][curSwitch]["ipv4"] + == "auto" + ): + topo["routers"][destRouter]["links"][curSwitch][ + "ipv4" + ] = "{}/{}".format( + ipv4Next, topo["link_ip_start"]["v4mask"] + ) ipv4Next += 1 # IPv6 - if 'ipv6' in topo['routers'][destRouter]['links'][curSwitch]: - if topo['routers'][destRouter]['links'][curSwitch]['ipv6'] == 'auto': - topo['routers'][destRouter]['links'][curSwitch]['ipv6'] = \ - '{}/{}'.format(ipv6Next, topo['link_ip_start'][ \ - 'v6mask']) + if "ipv6" in topo["routers"][destRouter]["links"][curSwitch]: + if ( + topo["routers"][destRouter]["links"][curSwitch]["ipv6"] + == "auto" + ): + topo["routers"][destRouter]["links"][curSwitch][ + "ipv6" + ] = "{}/{}".format( + ipv6Next, topo["link_ip_start"]["v6mask"] + ) ipv6Next = ipaddr.IPv6Address(int(ipv6Next) + ipv6Step) logger.debug( @@ -294,7 +312,7 @@ def build_config_from_json(tgen, topo, save_bkup=True): ("bgp_community_list", create_bgp_community_lists), ("route_maps", create_route_maps), ("bgp", create_router_bgp), - ("ospf", create_router_ospf) + ("ospf", create_router_ospf), ] ) diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index a187971e41..4b18862101 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -51,8 +51,9 @@ from mininet.log import setLogLevel, info from mininet.cli import CLI from mininet.link import Intf + def gdb_core(obj, daemon, corefiles): - gdbcmds = ''' + gdbcmds = """ info threads bt full disassemble @@ -66,21 +67,21 @@ def gdb_core(obj, daemon, corefiles): disassemble up disassemble - ''' - gdbcmds = [['-ex', i.strip()] for i in gdbcmds.strip().split('\n')] + """ + gdbcmds = [["-ex", i.strip()] for i in gdbcmds.strip().split("\n")] gdbcmds = [item for sl in gdbcmds for item in sl] daemon_path = os.path.join(obj.daemondir, daemon) backtrace = subprocess.check_output( - ['gdb', daemon_path, corefiles[0], '--batch'] + gdbcmds + ["gdb", daemon_path, corefiles[0], "--batch"] + gdbcmds ) sys.stderr.write( - "\n%s: %s crashed. Core file found - Backtrace follows:\n" - % (obj.name, daemon) + "\n%s: %s crashed. Core file found - Backtrace follows:\n" % (obj.name, daemon) ) sys.stderr.write("%s" % backtrace) return backtrace + class json_cmp_result(object): "json_cmp result class for better assertion messages" @@ -739,7 +740,8 @@ def ip4_vrf_route(node): } """ output = normalize_text( - node.run("ip route show vrf {0}-cust1".format(node.name))).splitlines() + node.run("ip route show vrf {0}-cust1".format(node.name)) + ).splitlines() result = {} for line in output: @@ -821,7 +823,8 @@ def ip6_vrf_route(node): } """ output = normalize_text( - node.run("ip -6 route show vrf {0}-cust1".format(node.name))).splitlines() + node.run("ip -6 route show vrf {0}-cust1".format(node.name)) + ).splitlines() result = {} for line in output: columns = line.split(" ") @@ -992,7 +995,7 @@ class Router(Node): # Backward compatibility: # Load configuration defaults like topogen. self.config_defaults = configparser.ConfigParser( - defaults = { + defaults={ "verbosity": "info", "frrdir": "/usr/lib/frr", "routertype": "frr", @@ -1095,7 +1098,7 @@ class Router(Node): if re.search(r"No such file or directory", rundaemons): return 0 if rundaemons is not None: - bet = rundaemons.split('\n') + bet = rundaemons.split("\n") for d in bet[:-1]: daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip() if daemonpid.isdigit() and pid_exists(int(daemonpid)): @@ -1110,24 +1113,28 @@ class Router(Node): if re.search(r"No such file or directory", rundaemons): return errors if rundaemons is not None: - dmns = rundaemons.split('\n') + dmns = rundaemons.split("\n") # Exclude empty string at end of list for d in dmns[:-1]: daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip() if daemonpid.isdigit() and pid_exists(int(daemonpid)): daemonname = os.path.basename(d.rstrip().rsplit(".", 1)[0]) - logger.info( - "{}: stopping {}".format( - self.name, daemonname - ) - ) + logger.info("{}: stopping {}".format(self.name, daemonname)) try: os.kill(int(daemonpid), signal.SIGTERM) except OSError as err: if err.errno == errno.ESRCH: - logger.error("{}: {} left a dead pidfile (pid={})".format(self.name, daemonname, daemonpid)) + logger.error( + "{}: {} left a dead pidfile (pid={})".format( + self.name, daemonname, daemonpid + ) + ) else: - logger.info("{}: {} could not kill pid {}: {}".format(self.name, daemonname, daemonpid, str(err))) + logger.info( + "{}: {} could not kill pid {}: {}".format( + self.name, daemonname, daemonpid, str(err) + ) + ) if not wait: return errors @@ -1135,18 +1142,28 @@ class Router(Node): running = self.listDaemons() if running: - sleep(0.1, "{}: waiting for daemons stopping: {}".format(self.name, ', '.join(running))) + sleep( + 0.1, + "{}: waiting for daemons stopping: {}".format( + self.name, ", ".join(running) + ), + ) running = self.listDaemons() counter = 20 while counter > 0 and running: - sleep(0.5, "{}: waiting for daemons stopping: {}".format(self.name, ', '.join(running))) + sleep( + 0.5, + "{}: waiting for daemons stopping: {}".format( + self.name, ", ".join(running) + ), + ) running = self.listDaemons() counter -= 1 if running: # 2nd round of kill if daemons didn't exit - dmns = rundaemons.split('\n') + dmns = rundaemons.split("\n") # Exclude empty string at end of list for d in dmns[:-1]: daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip() @@ -1295,11 +1312,12 @@ class Router(Node): def startRouterDaemons(self, daemons=None): "Starts all FRR daemons for this router." - bundle_data = '' + bundle_data = "" - if os.path.exists('/etc/frr/support_bundle_commands.conf'): + if os.path.exists("/etc/frr/support_bundle_commands.conf"): bundle_data = subprocess.check_output( - ["cat /etc/frr/support_bundle_commands.conf"], shell=True) + ["cat /etc/frr/support_bundle_commands.conf"], shell=True + ) self.cmd( "echo '{}' > /etc/frr/support_bundle_commands.conf".format(bundle_data) ) @@ -1400,7 +1418,7 @@ class Router(Node): for daemon in daemons: if rundaemons is not None and daemon in rundaemons: numRunning = 0 - dmns = rundaemons.split('\n') + dmns = rundaemons.split("\n") # Exclude empty string at end of list for d in dmns[:-1]: if re.search(r"%s" % daemon, d): @@ -1738,8 +1756,9 @@ class LegacySwitch(OVSSwitch): OVSSwitch.__init__(self, name, failMode="standalone", **params) self.switchIP = None + def frr_unicode(s): - '''Convert string to unicode, depending on python version''' + """Convert string to unicode, depending on python version""" if sys.version_info[0] > 2: return s else: diff --git a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py index 86fc90e665..53322f432f 100644 --- a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py +++ b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py @@ -65,22 +65,22 @@ class OspfSrTopo(Topo): tgen.add_router("r{}".format(routern)) # Interconect router 1 and 2 with 2 links - switch = tgen.add_switch('s1') - switch.add_link(tgen.gears['r1']) - switch.add_link(tgen.gears['r2']) - switch = tgen.add_switch('s2') - switch.add_link(tgen.gears['r1']) - switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) # Interconect router 3 and 2 - switch = tgen.add_switch('s3') - switch.add_link(tgen.gears['r3']) - switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r2"]) # Interconect router 4 and 2 - switch = tgen.add_switch('s4') - switch.add_link(tgen.gears['r4']) - switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r2"]) def setup_module(mod): @@ -134,12 +134,13 @@ def test_ospf_sr(): # Run test function until we get an result. Wait at most 60 seconds. rt = tgen.gears[router] test_func = partial( - topotest.router_json_cmp, rt, 'show ip ospf database segment-routing json', expected + topotest.router_json_cmp, + rt, + "show ip ospf database segment-routing json", + expected, ) rv, diff = topotest.run_and_expect(test_func, None, count=25, wait=3) - assert rv, "OSPF did not start Segment Routing on {}:\n{}".format( - router, diff - ) + assert rv, "OSPF did not start Segment Routing on {}:\n{}".format(router, diff) def test_ospf_kernel_route(): @@ -169,7 +170,7 @@ def test_ospf_kernel_route(): } ] """ - out = rt.vtysh_cmd('show mpls table json', isjson=True) + out = rt.vtysh_cmd("show mpls table json", isjson=True) outlist = [] for key in out.keys(): diff --git a/tests/topotests/ospf-topo2/test_ospf_topo2.py b/tests/topotests/ospf-topo2/test_ospf_topo2.py index 79e8e6bf58..6451f5fb32 100644 --- a/tests/topotests/ospf-topo2/test_ospf_topo2.py +++ b/tests/topotests/ospf-topo2/test_ospf_topo2.py @@ -35,7 +35,7 @@ import json # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, '../')) +sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers @@ -46,28 +46,30 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo + class OSPFTopo(Topo): "Test topology builder" + def build(self, *_args, **_opts): "Build function" tgen = get_topogen(self) # Create 4 routers for routern in range(1, 3): - tgen.add_router('r{}'.format(routern)) + tgen.add_router("r{}".format(routern)) # Create a empty network for router 1 - switch = tgen.add_switch('s1') - switch.add_link(tgen.gears['r1']) + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) # Create a empty network for router 2 - switch = tgen.add_switch('s2') - switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"]) # Interconect router 1, 2 - switch = tgen.add_switch('s3') - switch.add_link(tgen.gears['r1']) - switch.add_link(tgen.gears['r2']) + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) def setup_module(mod): @@ -78,12 +80,10 @@ def setup_module(mod): router_list = tgen.routers() for rname, router in router_list.items(): router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, '{}/zebra.conf'.format(rname)) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) router.load_config( - TopoRouter.RD_OSPF, - os.path.join(CWD, '{}/ospfd.conf'.format(rname)) + TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) ) # What is this? OSPF Unnumbered depends on the rp_filter @@ -93,18 +93,15 @@ def setup_module(mod): # the rp_filter. Setting it to '0' allows the OS to pass # up the mcast packet not destined for the local routers # network. - topotest.set_sysctl(tgen.net['r1'], - 'net.ipv4.conf.r1-eth1.rp_filter', 0) - topotest.set_sysctl(tgen.net['r1'], - 'net.ipv4.conf.all.rp_filter', 0) - topotest.set_sysctl(tgen.net['r2'], - 'net.ipv4.conf.r2-eth1.rp_filter', 0) - topotest.set_sysctl(tgen.net['r2'], - 'net.ipv4.conf.all.rp_filter', 0) + topotest.set_sysctl(tgen.net["r1"], "net.ipv4.conf.r1-eth1.rp_filter", 0) + topotest.set_sysctl(tgen.net["r1"], "net.ipv4.conf.all.rp_filter", 0) + topotest.set_sysctl(tgen.net["r2"], "net.ipv4.conf.r2-eth1.rp_filter", 0) + topotest.set_sysctl(tgen.net["r2"], "net.ipv4.conf.all.rp_filter", 0) # Initialize all routers. tgen.start_router() - #tgen.mininet_cli() + # tgen.mininet_cli() + def teardown_module(mod): "Teardown the pytest environment" @@ -116,50 +113,54 @@ def test_ospf_convergence(): "Test OSPF daemon convergence and that we have received the ospf routes" tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") for router, rnode in tgen.routers().items(): logger.info('Waiting for router "%s" convergence', router) - json_file = '{}/{}/ospf-route.json'.format(CWD, router) + json_file = "{}/{}/ospf-route.json".format(CWD, router) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - rnode, 'show ip ospf route json', expected) + test_func = partial( + topotest.router_json_cmp, rnode, "show ip ospf route json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=160, wait=0.5) assertmsg = '"{}" JSON output mismatches'.format(router) assert result is None, assertmsg - #tgen.mininet_cli() + # tgen.mininet_cli() + def test_ospf_kernel_route(): "Test OSPF kernel route installation and we have the onlink success" tgen = get_topogen() if tgen.routers_have_failure(): - pytest.skip('skipped because of router(s) failure') + pytest.skip("skipped because of router(s) failure") rlist = tgen.routers().values() for router in rlist: logger.info('Checking OSPF IPv4 kernel routes in "%s"', router.name) - json_file = '{}/{}/v4_route.json'.format(CWD, router.name) + json_file = "{}/{}/v4_route.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) - test_func = partial(topotest.router_json_cmp, - router, 'show ip route json', expected) - _, result = topotest.run_and_expect(test_func, None, count=10, wait=.5) + test_func = partial( + topotest.router_json_cmp, router, "show ip route json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assertmsg = '"{}" JSON output mistmatches'.format(router) assert result is None, assertmsg - #tgen.mininet_cli() + # tgen.mininet_cli() def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() if not tgen.is_memleak_enabled(): - pytest.skip('Memory leak test/report is disabled') + pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() -if __name__ == '__main__': + +if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py index a2f9c03ab4..e92baefabf 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py @@ -48,7 +48,7 @@ from lib.common_config import ( reset_config_on_routers, step, shutdown_bringup_interface, - topo_daemons + topo_daemons, ) from lib.topolog import logger from lib.topojson import build_topo_from_json, build_config_from_json diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py index 399fa02230..3b37b8a92f 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py @@ -53,7 +53,7 @@ from lib.common_config import ( create_route_maps, shutdown_bringup_interface, create_interfaces_cfg, - topo_daemons + topo_daemons, ) from lib.topolog import logger diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py index 17a3676e2e..967bc44879 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py @@ -53,7 +53,7 @@ from lib.common_config import ( shutdown_bringup_interface, stop_router, start_router, - topo_daemons + topo_daemons, ) from lib.bgp import verify_bgp_convergence, create_router_bgp from lib.topolog import logger diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py index f261104206..1357a86c81 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py @@ -55,7 +55,7 @@ from lib.common_config import ( shutdown_bringup_interface, stop_router, start_router, - topo_daemons + topo_daemons, ) from lib.bgp import verify_bgp_convergence, create_router_bgp from lib.topolog import logger diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py index ff4399f19e..82a34d046c 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py @@ -44,7 +44,7 @@ from lib.common_config import ( create_route_maps, shutdown_bringup_interface, create_interfaces_cfg, - topo_daemons + topo_daemons, ) from ipaddress import IPv4Address from lib.topogen import Topogen, get_topogen diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py index 6ebc74a013..64edc1ebbf 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py @@ -52,7 +52,7 @@ from lib.common_config import ( step, create_route_maps, verify_prefix_lists, - topo_daemons + topo_daemons, ) from lib.topolog import logger from lib.topojson import build_topo_from_json, build_config_from_json diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py index 2c6bcf0162..6ac0b515df 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py @@ -50,7 +50,7 @@ from lib.common_config import ( create_static_routes, step, shutdown_bringup_interface, - topo_daemons + topo_daemons, ) from lib.bgp import verify_bgp_convergence, create_router_bgp from lib.topolog import logger @@ -278,8 +278,7 @@ def test_ospf_redistribution_tc5_p0(request): dut = "r1" for num in range(0, nretry): - result = verify_ospf_rib( - tgen, dut, input_dict, next_hop=nh, expected=False) + result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False) if result is not True: break @@ -399,8 +398,7 @@ def test_ospf_redistribution_tc6_p0(request): dut = "r1" for num in range(0, nretry): - result = verify_ospf_rib( - tgen, dut, input_dict, next_hop=nh, expected=False) + result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False) if result is not True: break assert result is not True, "Testcase {} : Failed \n Error: {}".format( @@ -409,13 +407,7 @@ def test_ospf_redistribution_tc6_p0(request): protocol = "ospf" result = verify_rib( - tgen, - "ipv4", - dut, - input_dict, - protocol=protocol, - next_hop=nh, - expected=False, + tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh, expected=False, ) assert result is not True, "Testcase {} : Failed \n Error: {}".format( tc_name, result diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py index 5a141224f1..f563637b3c 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py @@ -53,7 +53,7 @@ from lib.common_config import ( create_route_maps, shutdown_bringup_interface, create_interfaces_cfg, - topo_daemons + topo_daemons, ) from lib.topolog import logger from lib.topojson import build_topo_from_json, build_config_from_json diff --git a/tests/topotests/pbr-topo1/test_pbr_topo1.py b/tests/topotests/pbr-topo1/test_pbr_topo1.py index 91979a8f04..fcbe3c0adf 100644 --- a/tests/topotests/pbr-topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr-topo1/test_pbr_topo1.py @@ -147,7 +147,9 @@ def test_pbr_data(): expected = json.loads(open(intf_file).read()) # Actual output from router - test_func = partial(topotest.router_json_cmp, router, "show pbr interface json", expected) + test_func = partial( + topotest.router_json_cmp, router, "show pbr interface json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assertmsg = '"show pbr interface" mismatches on {}'.format(router.name) if result is not None: @@ -161,7 +163,9 @@ def test_pbr_data(): expected = json.loads(open(map_file).read()) # Actual output from router - test_func = partial(topotest.router_json_cmp, router, "show pbr map json", expected) + test_func = partial( + topotest.router_json_cmp, router, "show pbr map json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assertmsg = '"show pbr map" mismatches on {}'.format(router.name) if result is not None: @@ -175,13 +179,16 @@ def test_pbr_data(): expected = json.loads(open(nexthop_file).read()) # Actual output from router - test_func = partial(topotest.router_json_cmp, router, "show pbr nexthop-groups json", expected) + test_func = partial( + topotest.router_json_cmp, router, "show pbr nexthop-groups json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assertmsg = '"show pbr nexthop-groups" mismatches on {}'.format(router.name) if result is not None: gather_pbr_data_on_error(router) assert result is None, assertmsg + def test_pbr_flap(): "Test PBR interface flapping" @@ -212,7 +219,9 @@ def test_pbr_flap(): expected = json.loads(open(intf_file).read()) # Actual output from router - test_func = partial(topotest.router_json_cmp, router, "show pbr interface json", expected) + test_func = partial( + topotest.router_json_cmp, router, "show pbr interface json", expected + ) _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assertmsg = '"show pbr interface" mismatches on {}'.format(router.name) if result is not None: @@ -274,4 +283,3 @@ def gather_pbr_data_on_error(router): logger.info(router.run("ip route show table 10005")) logger.info(router.run("ip -6 route show table 10005")) logger.info(router.run("ip rule show")) - diff --git a/tests/topotests/pim-basic/mcast-rx.py b/tests/topotests/pim-basic/mcast-rx.py index 7aa4d4027e..862ad46af4 100755 --- a/tests/topotests/pim-basic/mcast-rx.py +++ b/tests/topotests/pim-basic/mcast-rx.py @@ -35,8 +35,9 @@ import time def ifname_to_ifindex(ifname): - output = subprocess.check_output("ip link show %s" % ifname, - shell=True, universal_newlines=True) + output = subprocess.check_output( + "ip link show %s" % ifname, shell=True, universal_newlines=True + ) first_line = output.split("\n")[0] re_index = re.search("^(\d+):", first_line) diff --git a/tests/topotests/pim-basic/mcast-tx.py b/tests/topotests/pim-basic/mcast-tx.py index 7fb980c647..87038ad5cf 100755 --- a/tests/topotests/pim-basic/mcast-tx.py +++ b/tests/topotests/pim-basic/mcast-tx.py @@ -39,9 +39,7 @@ logging.addLevelName( ) log = logging.getLogger(__name__) -parser = argparse.ArgumentParser( - description="Multicast packet generator" -) +parser = argparse.ArgumentParser(description="Multicast packet generator") parser.add_argument("group", help="Multicast IP") parser.add_argument("ifname", help="Interface name") parser.add_argument("--port", type=int, help="UDP port number", default=1000) @@ -62,8 +60,9 @@ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # if sys.version_info[0] > 2: sock.setsockopt( - socket.SOL_SOCKET, 25, struct.pack("%ds" % len(args.ifname), - args.ifname.encode('utf-8')) + socket.SOL_SOCKET, + 25, + struct.pack("%ds" % len(args.ifname), args.ifname.encode("utf-8")), ) else: sock.setsockopt( diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index 2e9c4901bc..6e8e749092 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -1,6 +1,6 @@ # Skip pytests example directory [pytest] -norecursedirs = .git example-test example-topojson-test lib docker evpn_type5_test_topo1 +norecursedirs = .git example-test example-topojson-test lib docker [topogen] # Default configuration values diff --git a/tests/topotests/route-scale/test_route_scale.py b/tests/topotests/route-scale/test_route_scale.py index 0bfae3b830..8aedfc198c 100644 --- a/tests/topotests/route-scale/test_route_scale.py +++ b/tests/topotests/route-scale/test_route_scale.py @@ -95,7 +95,8 @@ def setup_module(module): ) tgen.start_router() - #tgen.mininet_cli() + # tgen.mininet_cli() + def teardown_module(_mod): "Teardown the pytest environment" @@ -104,6 +105,7 @@ def teardown_module(_mod): # This function tears down the whole topology. tgen.stop_topology() + def test_converge_protocols(): "Wait for protocol convergence" @@ -112,37 +114,45 @@ def test_converge_protocols(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) + def run_one_setup(r1, s): "Run one ecmp config" # Extract params - expected_installed = s['expect_in'] - expected_removed = s['expect_rem'] + expected_installed = s["expect_in"] + expected_removed = s["expect_rem"] - count = s['count'] - wait = s['wait'] + count = s["count"] + wait = s["wait"] - logger.info("Testing 1 million routes X {} ecmp".format(s['ecmp'])) + logger.info("Testing 1 million routes X {} ecmp".format(s["ecmp"])) - r1.vtysh_cmd("sharp install route 1.0.0.0 \ - nexthop-group {} 1000000".format(s['nhg']), - isjson=False) + r1.vtysh_cmd( + "sharp install route 1.0.0.0 \ + nexthop-group {} 1000000".format( + s["nhg"] + ), + isjson=False, + ) - test_func = partial(topotest.router_json_cmp, r1, "show ip route summary json", expected_installed) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route summary json", expected_installed + ) success, result = topotest.run_and_expect(test_func, None, count, wait) assert success, "Route scale test install failed:\n{}".format(result) output = r1.vtysh_cmd("sharp data route", isjson=False) - logger.info("1 million routes X {} ecmp installed".format(s['ecmp'])) + logger.info("1 million routes X {} ecmp installed".format(s["ecmp"])) logger.info(output) r1.vtysh_cmd("sharp remove route 1.0.0.0 1000000", isjson=False) - test_func = partial(topotest.router_json_cmp, r1, "show ip route summary json", expected_removed) + test_func = partial( + topotest.router_json_cmp, r1, "show ip route summary json", expected_removed + ) success, result = topotest.run_and_expect(test_func, None, count, wait) assert success, "Route scale test remove failed:\n{}".format(result) output = r1.vtysh_cmd("sharp data route", isjson=False) - logger.info("1 million routes x {} ecmp removed".format( - s['ecmp'])) + logger.info("1 million routes x {} ecmp removed".format(s["ecmp"])) logger.info(output) @@ -164,19 +174,23 @@ def test_route_install(): # dict keys of params: ecmp number, corresponding nhg name, timeout, # number of times to wait - scale_keys = ['ecmp', 'nhg', 'wait', 'count', 'expect_in', 'expect_rem'] + scale_keys = ["ecmp", "nhg", "wait", "count", "expect_in", "expect_rem"] # Table of defaults, used for timeout values and 'expected' objects - scale_defaults = dict(zip(scale_keys, [None, None, 7, 30, - expected_installed, - expected_removed])) + scale_defaults = dict( + zip(scale_keys, [None, None, 7, 30, expected_installed, expected_removed]) + ) # List of params for each step in the test; note extra time given # for the highest ecmp steps. Executing 'show' at scale can be costly # so we widen the interval there too. scale_steps = [ - [1, 'one'], [2, 'two'], [4, 'four'], - [8, 'eight'], [16, 'sixteen', 10, 40], [32, 'thirtytwo', 10, 40] + [1, "one"], + [2, "two"], + [4, "four"], + [8, "eight"], + [16, "sixteen", 10, 40], + [32, "thirtytwo", 10, 40], ] # Build up a list of dicts with params for each step of the test; @@ -191,17 +205,18 @@ def test_route_install(): scale_setups.append(d) # Avoid top ecmp case for runs with < 4G memory - p = os.popen('free') + p = os.popen("free") l = p.readlines()[1].split() mem = int(l[1]) if mem < 4000000: - logger.info('Limited memory available: {}, skipping x32 testcase'.format(mem)) + logger.info("Limited memory available: {}, skipping x32 testcase".format(mem)) scale_setups = scale_setups[0:-1] # Run each step using the dicts we've built for s in scale_setups: run_one_setup(r1, s) + # Mem leak testcase def test_memory_leak(): "Run the memory leak test and report results." @@ -210,6 +225,7 @@ def test_memory_leak(): pytest.skip("Memory leak test/report is disabled") tgen.report_memory_leaks() + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tools/coccinelle/README.md b/tools/coccinelle/README.md new file mode 100644 index 0000000000..262ccc1da0 --- /dev/null +++ b/tools/coccinelle/README.md @@ -0,0 +1,14 @@ +Coccinelle patches +================== + +This collection of coccinelle patches represents some of the broader, +codebase-wide changes that have been made. If you maintain a fork of +FRR and find that your codebase needs to be updated to align with +these changes, the coccinelle tool should help you make that update. + +The coccinelle tool is documented at: + https://coccinelle.gitlabpages.inria.fr/website/ + +To run a coccinelle patch script: + + spatch --sp-file tools/coccinelle/semicolon.cocci zebra/*.c diff --git a/tools/coccinelle/thread_cancel_api.cocci b/tools/coccinelle/thread_cancel_api.cocci new file mode 100644 index 0000000000..cc34f9389a --- /dev/null +++ b/tools/coccinelle/thread_cancel_api.cocci @@ -0,0 +1,68 @@ +@ptrupdate@ +expression E; +@@ +- thread_cancel(E); ++ thread_cancel(&E); + +@nullcheckremove depends on ptrupdate@ +expression E; +@@ + +thread_cancel(&E); +- E = NULL; + +@cancelguardremove depends on nullcheckremove@ +expression E; +@@ +- if (E) +- { + thread_cancel(&E); +- } + +@cancelguardremove2 depends on nullcheckremove@ +expression E; +@@ +- if (E != NULL) +- { + thread_cancel(&E); +- } + +@cancelguardremove3 depends on nullcheckremove@ +expression E; +@@ +- if (E) + thread_cancel(&E); + +@cancelguardremove4 depends on nullcheckremove@ +expression E; +@@ +- if (E != NULL) + thread_cancel(&E); + +@replacetimeroff@ +expression E; +@@ + +- THREAD_TIMER_OFF(E); ++ thread_cancel(&E); + +@replacewriteoff@ +expression E; +@@ + +- THREAD_WRITE_OFF(E); ++ thread_cancel(&E); + +@replacereadoff@ +expression E; +@@ + +- THREAD_READ_OFF(E); ++ thread_cancel(&E); + +@replacethreadoff@ +expression E; +@@ + +- THREAD_OFF(E); ++ thread_cancel(&E);
\ No newline at end of file diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons index 0221b0c19e..f6d512be72 100644 --- a/tools/etc/frr/daemons +++ b/tools/etc/frr/daemons @@ -12,7 +12,7 @@ # When using "vtysh" such a config file is also needed. It should be owned by # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too. # -# The watchfrr and zebra daemons are always started. +# The watchfrr, zebra and staticd daemons are always started. # bgpd=no ospfd=no diff --git a/tools/fixup-deprecated.py b/tools/fixup-deprecated.py index 38958480a8..57f9df9065 100755 --- a/tools/fixup-deprecated.py +++ b/tools/fixup-deprecated.py @@ -8,48 +8,74 @@ import sys, re, subprocess, os + class replaceEntry: - compiled = None #compiled regex - repl = None #regex + compiled = None # compiled regex + repl = None # regex + def __init__(self, c, r): self.compiled = c self.repl = r + rList = [ # old #define VNL, VTYNL, VTY_NEWLINE - replaceEntry(re.compile(r'(VNL|VTYNL|VTY_NEWLINE)'), - r'"\\n"'), + replaceEntry(re.compile(r"(VNL|VTYNL|VTY_NEWLINE)"), r'"\\n"'), # old #define VTY_GET_INTEGER(desc, v, str) # old #define VTY_GET_INTEGER_RANGE(desc, v, str, min, max) # old #define VTY_GET_ULONG(desc, v, str) - replaceEntry(re.compile(r'(VTY_GET_INTEGER(_RANGE|)|VTY_GET_ULONG)[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S), - r'(\4) = strtoul((\5), NULL, 10);\t/* \3 */'), + replaceEntry( + re.compile( + r"(VTY_GET_INTEGER(_RANGE|)|VTY_GET_ULONG)[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;", + re.M | re.S, + ), + r"(\4) = strtoul((\5), NULL, 10);\t/* \3 */", + ), # old #define VTY_GET_ULL(desc, v, str) - replaceEntry(re.compile(r'VTY_GET_ULL[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S), - r'(\2) = strtoull((\3), NULL, 10);\t/* \1 */'), + replaceEntry( + re.compile( + r"VTY_GET_ULL[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;", + re.M | re.S, + ), + r"(\2) = strtoull((\3), NULL, 10);\t/* \1 */", + ), # old #define VTY_GET_IPV4_ADDRESS(desc, v, str) - replaceEntry(re.compile(r'VTY_GET_IPV4_ADDRESS[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S), - r'inet_aton((\3), &(\2));\t/* \1 */'), + replaceEntry( + re.compile( + r"VTY_GET_IPV4_ADDRESS[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;", + re.M | re.S, + ), + r"inet_aton((\3), &(\2));\t/* \1 */", + ), # old #define VTY_GET_IPV4_PREFIX(desc, v, str) - replaceEntry(re.compile(r'VTY_GET_IPV4_PREFIX[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S), - r'str2prefix_ipv4((\3), &(\2));\t/* \1 */'), + replaceEntry( + re.compile( + r"VTY_GET_IPV4_PREFIX[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;", + re.M | re.S, + ), + r"str2prefix_ipv4((\3), &(\2));\t/* \1 */", + ), # old #define vty_outln(vty, str, ...) - replaceEntry(re.compile(r'vty_outln[\s\(]*(.*?)\s*,\s*(".*?"|.*?)\s*(\)|,)', re.M | re.S), - r'vty_out(\1, \2 "\\n"\3'), - ] + replaceEntry( + re.compile(r'vty_outln[\s\(]*(.*?)\s*,\s*(".*?"|.*?)\s*(\)|,)', re.M | re.S), + r'vty_out(\1, \2 "\\n"\3', + ), +] + def fixup_file(fn): - with open(fn, 'r') as fd: + with open(fn, "r") as fd: text = fd.read() for re in rList: - text = re.compiled.sub(re.repl,text) + text = re.compiled.sub(re.repl, text) - tmpname = fn + '.fixup' - with open(tmpname, 'w') as ofd: + tmpname = fn + ".fixup" + with open(tmpname, "w") as ofd: ofd.write(text) os.rename(tmpname, fn) -if __name__ == '__main__': + +if __name__ == "__main__": for fn in sys.argv[1:]: fixup_file(fn) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 88873da904..951383beb2 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -39,6 +39,7 @@ import string import subprocess import sys from collections import OrderedDict + try: from ipaddress import IPv6Address, ip_network except ImportError: @@ -51,45 +52,49 @@ except AttributeError: # Python 3 def iteritems(d): return iter(d.items()) + + else: # Python 2 def iteritems(d): return d.iteritems() + log = logging.getLogger(__name__) class VtyshException(Exception): pass + class Vtysh(object): def __init__(self, bindir=None, confdir=None, sockdir=None, pathspace=None): self.bindir = bindir self.confdir = confdir self.pathspace = pathspace - self.common_args = [os.path.join(bindir or '', 'vtysh')] + self.common_args = [os.path.join(bindir or "", "vtysh")] if confdir: - self.common_args.extend(['--config_dir', confdir]) + self.common_args.extend(["--config_dir", confdir]) if sockdir: - self.common_args.extend(['--vty_socket', sockdir]) + self.common_args.extend(["--vty_socket", sockdir]) if pathspace: - self.common_args.extend(['-N', pathspace]) + self.common_args.extend(["-N", pathspace]) def _call(self, args, stdin=None, stdout=None, stderr=None): kwargs = {} if stdin is not None: - kwargs['stdin'] = stdin + kwargs["stdin"] = stdin if stdout is not None: - kwargs['stdout'] = stdout + kwargs["stdout"] = stdout if stderr is not None: - kwargs['stderr'] = stderr + kwargs["stderr"] = stderr return subprocess.Popen(self.common_args + args, **kwargs) def _call_cmd(self, command, stdin=None, stdout=None, stderr=None): if isinstance(command, list): - args = [item for sub in command for item in ['-c', sub]] + args = [item for sub in command for item in ["-c", sub]] else: - args = ['-c', command] + args = ["-c", command] return self._call(args, stdin, stdout, stderr) def __call__(self, command): @@ -102,9 +107,10 @@ class Vtysh(object): proc = self._call_cmd(command, stdout=subprocess.PIPE) stdout, stderr = proc.communicate() if proc.wait() != 0: - raise VtyshException('vtysh returned status %d for command "%s"' - % (proc.returncode, command)) - return stdout.decode('UTF-8') + raise VtyshException( + 'vtysh returned status %d for command "%s"' % (proc.returncode, command) + ) + return stdout.decode("UTF-8") def is_config_available(self): """ @@ -113,56 +119,69 @@ class Vtysh(object): configuration changes. """ - output = self('configure') + output = self("configure") - if 'VTY configuration is locked by other VTY' in output: + if "VTY configuration is locked by other VTY" in output: log.error("vtysh 'configure' returned\n%s\n" % (output)) return False return True def exec_file(self, filename): - child = self._call(['-f', filename]) + child = self._call(["-f", filename]) if child.wait() != 0: - raise VtyshException('vtysh (exec file) exited with status %d' - % (child.returncode)) + raise VtyshException( + "vtysh (exec file) exited with status %d" % (child.returncode) + ) def mark_file(self, filename, stdin=None): - child = self._call(['-m', '-f', filename], - stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + child = self._call( + ["-m", "-f", filename], + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + ) try: stdout, stderr = child.communicate() except subprocess.TimeoutExpired: child.kill() stdout, stderr = child.communicate() - raise VtyshException('vtysh call timed out!') + raise VtyshException("vtysh call timed out!") if child.wait() != 0: - raise VtyshException('vtysh (mark file) exited with status %d:\n%s' - % (child.returncode, stderr)) + raise VtyshException( + "vtysh (mark file) exited with status %d:\n%s" + % (child.returncode, stderr) + ) - return stdout.decode('UTF-8') + return stdout.decode("UTF-8") - def mark_show_run(self, daemon = None): - cmd = 'show running-config' + def mark_show_run(self, daemon=None): + cmd = "show running-config" if daemon: - cmd += ' %s' % daemon - cmd += ' no-header' + cmd += " %s" % daemon + cmd += " no-header" show_run = self._call_cmd(cmd, stdout=subprocess.PIPE) - mark = self._call(['-m', '-f', '-'], stdin=show_run.stdout, stdout=subprocess.PIPE) + mark = self._call( + ["-m", "-f", "-"], stdin=show_run.stdout, stdout=subprocess.PIPE + ) show_run.wait() stdout, stderr = mark.communicate() mark.wait() if show_run.returncode != 0: - raise VtyshException('vtysh (show running-config) exited with status %d:' - % (show_run.returncode)) + raise VtyshException( + "vtysh (show running-config) exited with status %d:" + % (show_run.returncode) + ) if mark.returncode != 0: - raise VtyshException('vtysh (mark running-config) exited with status %d' - % (mark.returncode)) + raise VtyshException( + "vtysh (mark running-config) exited with status %d" % (mark.returncode) + ) + + return stdout.decode("UTF-8") - return stdout.decode('UTF-8') class Context(object): @@ -222,15 +241,15 @@ class Config(object): The internal representation has been marked appropriately by passing it through vtysh with the -m parameter """ - log.info('Loading Config object from file %s', filename) + log.info("Loading Config object from file %s", filename) file_output = self.vtysh.mark_file(filename) - for line in file_output.split('\n'): + for line in file_output.split("\n"): line = line.strip() # Compress duplicate whitespaces - line = ' '.join(line.split()) + line = " ".join(line.split()) if ":" in line and not "ipv6 add": qv6_line = get_normalized_ipv6_line(line) @@ -246,16 +265,18 @@ class Config(object): The internal representation has been marked appropriately by passing it through vtysh with the -m parameter """ - log.info('Loading Config object from vtysh show running') + log.info("Loading Config object from vtysh show running") config_text = self.vtysh.mark_show_run(daemon) - for line in config_text.split('\n'): + for line in config_text.split("\n"): line = line.strip() - if (line == 'Building configuration...' or - line == 'Current configuration:' or - not line): + if ( + line == "Building configuration..." + or line == "Current configuration:" + or not line + ): continue self.lines.append(line) @@ -267,7 +288,7 @@ class Config(object): Return the lines read in from the configuration """ - return '\n'.join(self.lines) + return "\n".join(self.lines) def get_contexts(self): """ @@ -275,7 +296,7 @@ class Config(object): """ for (_, ctx) in sorted(iteritems(self.contexts)): - print(str(ctx) + '\n') + print(str(ctx) + "\n") def save_contexts(self, key, lines): """ @@ -285,99 +306,116 @@ class Config(object): if not key: return - ''' + """ IP addresses specified in "network" statements, "ip prefix-lists" etc. can differ in the host part of the specification the user provides and what the running config displays. For example, user can specify 11.1.1.1/24, and the running config displays this as 11.1.1.0/24. Ensure we don't do a needless operation for such lines. IS-IS & OSPFv3 have no "network" support. - ''' - re_key_rt = re.match(r'(ip|ipv6)\s+route\s+([A-Fa-f:.0-9/]+)(.*)$', key[0]) + """ + re_key_rt = re.match(r"(ip|ipv6)\s+route\s+([A-Fa-f:.0-9/]+)(.*)$", key[0]) if re_key_rt: addr = re_key_rt.group(2) - if '/' in addr: + if "/" in addr: try: - if 'ipaddress' not in sys.modules: + if "ipaddress" not in sys.modules: newaddr = IPNetwork(addr) - key[0] = '%s route %s/%s%s' % (re_key_rt.group(1), - newaddr.network, - newaddr.prefixlen, - re_key_rt.group(3)) + key[0] = "%s route %s/%s%s" % ( + re_key_rt.group(1), + newaddr.network, + newaddr.prefixlen, + re_key_rt.group(3), + ) else: newaddr = ip_network(addr, strict=False) - key[0] = '%s route %s/%s%s' % (re_key_rt.group(1), - str(newaddr.network_address), - newaddr.prefixlen, - re_key_rt.group(3)) + key[0] = "%s route %s/%s%s" % ( + re_key_rt.group(1), + str(newaddr.network_address), + newaddr.prefixlen, + re_key_rt.group(3), + ) except ValueError: pass re_key_rt = re.match( - r'(ip|ipv6)\s+prefix-list(.*)(permit|deny)\s+([A-Fa-f:.0-9/]+)(.*)$', - key[0] + r"(ip|ipv6)\s+prefix-list(.*)(permit|deny)\s+([A-Fa-f:.0-9/]+)(.*)$", key[0] ) if re_key_rt: addr = re_key_rt.group(4) - if '/' in addr: + if "/" in addr: try: - if 'ipaddress' not in sys.modules: - newaddr = '%s/%s' % (IPNetwork(addr).network, - IPNetwork(addr).prefixlen) + if "ipaddress" not in sys.modules: + newaddr = "%s/%s" % ( + IPNetwork(addr).network, + IPNetwork(addr).prefixlen, + ) else: network_addr = ip_network(addr, strict=False) - newaddr = '%s/%s' % (str(network_addr.network_address), - network_addr.prefixlen) + newaddr = "%s/%s" % ( + str(network_addr.network_address), + network_addr.prefixlen, + ) except ValueError: newaddr = addr else: newaddr = addr legestr = re_key_rt.group(5) - re_lege = re.search(r'(.*)le\s+(\d+)\s+ge\s+(\d+)(.*)', legestr) + re_lege = re.search(r"(.*)le\s+(\d+)\s+ge\s+(\d+)(.*)", legestr) if re_lege: - legestr = '%sge %s le %s%s' % (re_lege.group(1), - re_lege.group(3), - re_lege.group(2), - re_lege.group(4)) - re_lege = re.search(r'(.*)ge\s+(\d+)\s+le\s+(\d+)(.*)', legestr) - - if (re_lege and ((re_key_rt.group(1) == "ip" and - re_lege.group(3) == "32") or - (re_key_rt.group(1) == "ipv6" and - re_lege.group(3) == "128"))): - legestr = '%sge %s%s' % (re_lege.group(1), - re_lege.group(2), - re_lege.group(4)) - - key[0] = '%s prefix-list%s%s %s%s' % (re_key_rt.group(1), - re_key_rt.group(2), - re_key_rt.group(3), - newaddr, - legestr) - - if lines and key[0].startswith('router bgp'): + legestr = "%sge %s le %s%s" % ( + re_lege.group(1), + re_lege.group(3), + re_lege.group(2), + re_lege.group(4), + ) + re_lege = re.search(r"(.*)ge\s+(\d+)\s+le\s+(\d+)(.*)", legestr) + + if re_lege and ( + (re_key_rt.group(1) == "ip" and re_lege.group(3) == "32") + or (re_key_rt.group(1) == "ipv6" and re_lege.group(3) == "128") + ): + legestr = "%sge %s%s" % ( + re_lege.group(1), + re_lege.group(2), + re_lege.group(4), + ) + + key[0] = "%s prefix-list%s%s %s%s" % ( + re_key_rt.group(1), + re_key_rt.group(2), + re_key_rt.group(3), + newaddr, + legestr, + ) + + if lines and key[0].startswith("router bgp"): newlines = [] for line in lines: - re_net = re.match(r'network\s+([A-Fa-f:.0-9/]+)(.*)$', line) + re_net = re.match(r"network\s+([A-Fa-f:.0-9/]+)(.*)$", line) if re_net: addr = re_net.group(1) - if '/' not in addr and key[0].startswith('router bgp'): + if "/" not in addr and key[0].startswith("router bgp"): # This is most likely an error because with no # prefixlen, BGP treats the prefixlen as 8 - addr = addr + '/8' + addr = addr + "/8" try: - if 'ipaddress' not in sys.modules: + if "ipaddress" not in sys.modules: newaddr = IPNetwork(addr) - line = 'network %s/%s %s' % (newaddr.network, - newaddr.prefixlen, - re_net.group(2)) + line = "network %s/%s %s" % ( + newaddr.network, + newaddr.prefixlen, + re_net.group(2), + ) else: network_addr = ip_network(addr, strict=False) - line = 'network %s/%s %s' % (str(network_addr.network_address), - network_addr.prefixlen, - re_net.group(2)) + line = "network %s/%s %s" % ( + str(network_addr.network_address), + network_addr.prefixlen, + re_net.group(2), + ) newlines.append(line) except ValueError: # Really this should be an error. Whats a network @@ -387,13 +425,16 @@ class Config(object): newlines.append(line) lines = newlines - ''' + """ More fixups in user specification and what running config shows. "null0" in routes must be replaced by Null0. - ''' - if (key[0].startswith('ip route') or key[0].startswith('ipv6 route') and - 'null0' in key[0]): - key[0] = re.sub(r'\s+null0(\s*$)', ' Null0', key[0]) + """ + if ( + key[0].startswith("ip route") + or key[0].startswith("ipv6 route") + and "null0" in key[0] + ): + key[0] = re.sub(r"\s+null0(\s*$)", " Null0", key[0]) if lines: if tuple(key) not in self.contexts: @@ -416,7 +457,7 @@ class Config(object): current_context_lines = [] ctx_keys = [] - ''' + """ The end of a context is flagged via the 'end' keyword: ! @@ -460,7 +501,7 @@ router ospf timers throttle spf 0 50 5000 ! end - ''' + """ # The code assumes that its working on the output from the "vtysh -m" # command. That provides the appropriate markers to signify end of @@ -480,38 +521,40 @@ end # the keywords that we know are single line contexts. bgp in this case # is not the main router bgp block, but enabling multi-instance - oneline_ctx_keywords = ("access-list ", - "agentx", - "allow-external-route-update", - "bgp ", - "debug ", - "domainname ", - "dump ", - "enable ", - "frr ", - "hostname ", - "ip ", - "ipv6 ", - "log ", - "mpls lsp", - "mpls label", - "no ", - "password ", - "ptm-enable", - "router-id ", - "service ", - "table ", - "username ", - "zebra ", - "vrrp autoconfigure", - "evpn mh") + oneline_ctx_keywords = ( + "access-list ", + "agentx", + "allow-external-route-update", + "bgp ", + "debug ", + "domainname ", + "dump ", + "enable ", + "frr ", + "hostname ", + "ip ", + "ipv6 ", + "log ", + "mpls lsp", + "mpls label", + "no ", + "password ", + "ptm-enable", + "router-id ", + "service ", + "table ", + "username ", + "zebra ", + "vrrp autoconfigure", + "evpn mh", + ) for line in self.lines: if not line: continue - if line.startswith('!') or line.startswith('#'): + if line.startswith("!") or line.startswith("#"): continue # one line contexts @@ -519,22 +562,31 @@ end # as part of its 'mpls ldp' config context. If we are processing # ldp configuration and encounter a router-id we should NOT switch # to a new context - if new_ctx is True and any(line.startswith(keyword) for keyword in oneline_ctx_keywords) and not ( - ctx_keys and ctx_keys[0].startswith("mpls ldp") and line.startswith("router-id ")): + if ( + new_ctx is True + and any(line.startswith(keyword) for keyword in oneline_ctx_keywords) + and not ( + ctx_keys + and ctx_keys[0].startswith("mpls ldp") + and line.startswith("router-id ") + ) + ): self.save_contexts(ctx_keys, current_context_lines) # Start a new context main_ctx_key = [] - ctx_keys = [line, ] + ctx_keys = [ + line, + ] current_context_lines = [] - log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys) + log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys) self.save_contexts(ctx_keys, current_context_lines) new_ctx = True elif line == "end": self.save_contexts(ctx_keys, current_context_lines) - log.debug('LINE %-50s: exiting old context, %-50s', line, ctx_keys) + log.debug("LINE %-50s: exiting old context, %-50s", line, ctx_keys) # Start a new context new_ctx = True @@ -545,9 +597,11 @@ end elif line == "exit-vrf": self.save_contexts(ctx_keys, current_context_lines) current_context_lines.append(line) - log.debug('LINE %-50s: append to current_context_lines, %-50s', line, ctx_keys) + log.debug( + "LINE %-50s: append to current_context_lines, %-50s", line, ctx_keys + ) - #Start a new context + # Start a new context new_ctx = True main_ctx_key = [] ctx_keys = [] @@ -561,7 +615,11 @@ end # Start a new context ctx_keys = copy.deepcopy(main_ctx_key) current_context_lines = [] - log.debug('LINE %-50s: popping from subcontext to ctx%-50s', line, ctx_keys) + log.debug( + "LINE %-50s: popping from subcontext to ctx%-50s", + line, + ctx_keys, + ) elif line in ["exit-vni", "exit-ldp-if"]: if sub_main_ctx_key: @@ -570,70 +628,92 @@ end # Start a new context ctx_keys = copy.deepcopy(sub_main_ctx_key) current_context_lines = [] - log.debug('LINE %-50s: popping from sub-subcontext to ctx%-50s', line, ctx_keys) + log.debug( + "LINE %-50s: popping from sub-subcontext to ctx%-50s", + line, + ctx_keys, + ) elif new_ctx is True: if not main_ctx_key: - ctx_keys = [line, ] + ctx_keys = [ + line, + ] else: ctx_keys = copy.deepcopy(main_ctx_key) main_ctx_key = [] current_context_lines = [] new_ctx = False - log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys) - elif (line.startswith("address-family ") or - line.startswith("vnc defaults") or - line.startswith("vnc l2-group") or - line.startswith("vnc nve-group") or - line.startswith("peer") or - line.startswith("key ") or - line.startswith("member pseudowire")): + log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys) + elif ( + line.startswith("address-family ") + or line.startswith("vnc defaults") + or line.startswith("vnc l2-group") + or line.startswith("vnc nve-group") + or line.startswith("peer") + or line.startswith("key ") + or line.startswith("member pseudowire") + ): main_ctx_key = [] # Save old context first self.save_contexts(ctx_keys, current_context_lines) current_context_lines = [] main_ctx_key = copy.deepcopy(ctx_keys) - log.debug('LINE %-50s: entering sub-context, append to ctx_keys', line) + log.debug("LINE %-50s: entering sub-context, append to ctx_keys", line) - if line == "address-family ipv6" and not ctx_keys[0].startswith("mpls ldp"): + if line == "address-family ipv6" and not ctx_keys[0].startswith( + "mpls ldp" + ): ctx_keys.append("address-family ipv6 unicast") - elif line == "address-family ipv4" and not ctx_keys[0].startswith("mpls ldp"): + elif line == "address-family ipv4" and not ctx_keys[0].startswith( + "mpls ldp" + ): ctx_keys.append("address-family ipv4 unicast") elif line == "address-family evpn": ctx_keys.append("address-family l2vpn evpn") else: ctx_keys.append(line) - elif ((line.startswith("vni ") and - len(ctx_keys) == 2 and - ctx_keys[0].startswith('router bgp') and - ctx_keys[1] == 'address-family l2vpn evpn')): + elif ( + line.startswith("vni ") + and len(ctx_keys) == 2 + and ctx_keys[0].startswith("router bgp") + and ctx_keys[1] == "address-family l2vpn evpn" + ): # Save old context first self.save_contexts(ctx_keys, current_context_lines) current_context_lines = [] sub_main_ctx_key = copy.deepcopy(ctx_keys) - log.debug('LINE %-50s: entering sub-sub-context, append to ctx_keys', line) + log.debug( + "LINE %-50s: entering sub-sub-context, append to ctx_keys", line + ) ctx_keys.append(line) - - elif ((line.startswith("interface ") and - len(ctx_keys) == 2 and - ctx_keys[0].startswith('mpls ldp') and - ctx_keys[1].startswith('address-family'))): + + elif ( + line.startswith("interface ") + and len(ctx_keys) == 2 + and ctx_keys[0].startswith("mpls ldp") + and ctx_keys[1].startswith("address-family") + ): # Save old context first self.save_contexts(ctx_keys, current_context_lines) current_context_lines = [] sub_main_ctx_key = copy.deepcopy(ctx_keys) - log.debug('LINE %-50s: entering sub-sub-context, append to ctx_keys', line) + log.debug( + "LINE %-50s: entering sub-sub-context, append to ctx_keys", line + ) ctx_keys.append(line) else: # Continuing in an existing context, add non-commented lines to it current_context_lines.append(line) - log.debug('LINE %-50s: append to current_context_lines, %-50s', line, ctx_keys) + log.debug( + "LINE %-50s: append to current_context_lines, %-50s", line, ctx_keys + ) # Save the context of the last one self.save_contexts(ctx_keys, current_context_lines) @@ -647,20 +727,20 @@ def lines_to_config(ctx_keys, line, delete): if line: for (i, ctx_key) in enumerate(ctx_keys): - cmd.append(' ' * i + ctx_key) + cmd.append(" " * i + ctx_key) line = line.lstrip() - indent = len(ctx_keys) * ' ' + indent = len(ctx_keys) * " " # There are some commands that are on by default so their "no" form will be # displayed in the config. "no bgp default ipv4-unicast" is one of these. # If we need to remove this line we do so by adding "bgp default ipv4-unicast", # not by doing a "no no bgp default ipv4-unicast" if delete: - if line.startswith('no '): - cmd.append('%s%s' % (indent, line[3:])) + if line.startswith("no "): + cmd.append("%s%s" % (indent, line[3:])) else: - cmd.append('%sno %s' % (indent, line)) + cmd.append("%sno %s" % (indent, line)) else: cmd.append(indent + line) @@ -669,16 +749,16 @@ def lines_to_config(ctx_keys, line, delete): # context ('no router ospf' for example) else: for i, ctx_key in enumerate(ctx_keys[:-1]): - cmd.append('%s%s' % (' ' * i, ctx_key)) + cmd.append("%s%s" % (" " * i, ctx_key)) # Only put the 'no' on the last sub-context if delete: - if ctx_keys[-1].startswith('no '): - cmd.append('%s%s' % (' ' * (len(ctx_keys) - 1), ctx_keys[-1][3:])) + if ctx_keys[-1].startswith("no "): + cmd.append("%s%s" % (" " * (len(ctx_keys) - 1), ctx_keys[-1][3:])) else: - cmd.append('%sno %s' % (' ' * (len(ctx_keys) - 1), ctx_keys[-1])) + cmd.append("%sno %s" % (" " * (len(ctx_keys) - 1), ctx_keys[-1])) else: - cmd.append('%s%s' % (' ' * (len(ctx_keys) - 1), ctx_keys[-1])) + cmd.append("%s%s" % (" " * (len(ctx_keys) - 1), ctx_keys[-1])) return cmd @@ -691,23 +771,26 @@ def get_normalized_ipv6_line(line): the IPv6 word is a network """ norm_line = "" - words = line.split(' ') + words = line.split(" ") for word in words: if ":" in word: norm_word = None if "/" in word: try: - if 'ipaddress' not in sys.modules: + if "ipaddress" not in sys.modules: v6word = IPNetwork(word) - norm_word = '%s/%s' % (v6word.network, v6word.prefixlen) + norm_word = "%s/%s" % (v6word.network, v6word.prefixlen) else: v6word = ip_network(word, strict=False) - norm_word = '%s/%s' % (str(v6word.network_address), v6word.prefixlen) + norm_word = "%s/%s" % ( + str(v6word.network_address), + v6word.prefixlen, + ) except ValueError: pass if not norm_word: try: - norm_word = '%s' % IPv6Address(word) + norm_word = "%s" % IPv6Address(word) except ValueError: norm_word = word else: @@ -728,6 +811,7 @@ def line_exist(lines, target_ctx_keys, target_line, exact_match=True): return True return False + def check_for_exit_vrf(lines_to_add, lines_to_del): # exit-vrf is a bit tricky. If the new config is missing it but we @@ -740,25 +824,26 @@ def check_for_exit_vrf(lines_to_add, lines_to_del): for (ctx_keys, line) in lines_to_add: if add_exit_vrf == True: if ctx_keys[0] != prior_ctx_key: - insert_key=(prior_ctx_key), + insert_key = ((prior_ctx_key),) lines_to_add.insert(index, ((insert_key, "exit-vrf"))) add_exit_vrf = False - if ctx_keys[0].startswith('vrf') and line: + if ctx_keys[0].startswith("vrf") and line: if line is not "exit-vrf": add_exit_vrf = True - prior_ctx_key = (ctx_keys[0]) + prior_ctx_key = ctx_keys[0] else: add_exit_vrf = False - index+=1 + index += 1 for (ctx_keys, line) in lines_to_del: if line == "exit-vrf": - if (line_exist(lines_to_add, ctx_keys, line)): + if line_exist(lines_to_add, ctx_keys, line): lines_to_del.remove((ctx_keys, line)) return (lines_to_add, lines_to_del) + def ignore_delete_re_add_lines(lines_to_add, lines_to_del): # Quite possibly the most confusing (while accurate) variable names in history @@ -768,10 +853,10 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): for (ctx_keys, line) in lines_to_del: deleted = False - if ctx_keys[0].startswith('router bgp') and line: + if ctx_keys[0].startswith("router bgp") and line: - if line.startswith('neighbor '): - ''' + if line.startswith("neighbor "): + """ BGP changed how it displays swpX peers that are part of peer-group. Older versions of frr would display these on separate lines: neighbor swp1 interface @@ -788,10 +873,14 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): neighbor swp1 peer-group FOO If so then chop the del line and the corresponding add lines - ''' + """ - re_swpx_int_peergroup = re.search('neighbor (\S+) interface peer-group (\S+)', line) - re_swpx_int_v6only_peergroup = re.search('neighbor (\S+) interface v6only peer-group (\S+)', line) + re_swpx_int_peergroup = re.search( + "neighbor (\S+) interface peer-group (\S+)", line + ) + re_swpx_int_v6only_peergroup = re.search( + "neighbor (\S+) interface v6only peer-group (\S+)", line + ) if re_swpx_int_peergroup or re_swpx_int_v6only_peergroup: swpx_interface = None @@ -807,21 +896,29 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): swpx_interface = "neighbor %s interface v6only" % swpx swpx_peergroup = "neighbor %s peer-group %s" % (swpx, peergroup) - found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface) - found_add_swpx_peergroup = line_exist(lines_to_add, ctx_keys, swpx_peergroup) + found_add_swpx_interface = line_exist( + lines_to_add, ctx_keys, swpx_interface + ) + found_add_swpx_peergroup = line_exist( + lines_to_add, ctx_keys, swpx_peergroup + ) tmp_ctx_keys = tuple(list(ctx_keys)) if not found_add_swpx_peergroup: tmp_ctx_keys = list(ctx_keys) - tmp_ctx_keys.append('address-family ipv4 unicast') + tmp_ctx_keys.append("address-family ipv4 unicast") tmp_ctx_keys = tuple(tmp_ctx_keys) - found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup) + found_add_swpx_peergroup = line_exist( + lines_to_add, tmp_ctx_keys, swpx_peergroup + ) if not found_add_swpx_peergroup: tmp_ctx_keys = list(ctx_keys) - tmp_ctx_keys.append('address-family ipv6 unicast') + tmp_ctx_keys.append("address-family ipv6 unicast") tmp_ctx_keys = tuple(tmp_ctx_keys) - found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup) + found_add_swpx_peergroup = line_exist( + lines_to_add, tmp_ctx_keys, swpx_peergroup + ) if found_add_swpx_interface and found_add_swpx_peergroup: deleted = True @@ -829,30 +926,36 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): lines_to_add_to_del.append((ctx_keys, swpx_interface)) lines_to_add_to_del.append((tmp_ctx_keys, swpx_peergroup)) - ''' + """ Changing the bfd timers on neighbors is allowed without doing a delete/add process. Since doing a "no neighbor blah bfd ..." will cause the peer to bounce unnecessarily, just skip the delete and just do the add. - ''' - re_nbr_bfd_timers = re.search(r'neighbor (\S+) bfd (\S+) (\S+) (\S+)', line) + """ + re_nbr_bfd_timers = re.search( + r"neighbor (\S+) bfd (\S+) (\S+) (\S+)", line + ) if re_nbr_bfd_timers: nbr = re_nbr_bfd_timers.group(1) bfd_nbr = "neighbor %s" % nbr - bfd_search_string = bfd_nbr + r' bfd (\S+) (\S+) (\S+)' + bfd_search_string = bfd_nbr + r" bfd (\S+) (\S+) (\S+)" for (ctx_keys, add_line) in lines_to_add: - if ctx_keys[0].startswith('router bgp'): - re_add_nbr_bfd_timers = re.search(bfd_search_string, add_line) + if ctx_keys[0].startswith("router bgp"): + re_add_nbr_bfd_timers = re.search( + bfd_search_string, add_line + ) if re_add_nbr_bfd_timers: - found_add_bfd_nbr = line_exist(lines_to_add, ctx_keys, bfd_nbr, False) + found_add_bfd_nbr = line_exist( + lines_to_add, ctx_keys, bfd_nbr, False + ) if found_add_bfd_nbr: lines_to_del_to_del.append((ctx_keys, line)) - ''' + """ We changed how we display the neighbor interface command. Older versions of frr would display the following: neighbor swp1 interface @@ -874,9 +977,13 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): neighbor swp1 capability extended-nexthop If so then chop the del line and the corresponding add lines - ''' - re_swpx_int_remoteas = re.search('neighbor (\S+) interface remote-as (\S+)', line) - re_swpx_int_v6only_remoteas = re.search('neighbor (\S+) interface v6only remote-as (\S+)', line) + """ + re_swpx_int_remoteas = re.search( + "neighbor (\S+) interface remote-as (\S+)", line + ) + re_swpx_int_v6only_remoteas = re.search( + "neighbor (\S+) interface v6only remote-as (\S+)", line + ) if re_swpx_int_remoteas or re_swpx_int_v6only_remoteas: swpx_interface = None @@ -892,8 +999,12 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): swpx_interface = "neighbor %s interface v6only" % swpx swpx_remoteas = "neighbor %s remote-as %s" % (swpx, remoteas) - found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface) - found_add_swpx_remoteas = line_exist(lines_to_add, ctx_keys, swpx_remoteas) + found_add_swpx_interface = line_exist( + lines_to_add, ctx_keys, swpx_interface + ) + found_add_swpx_remoteas = line_exist( + lines_to_add, ctx_keys, swpx_remoteas + ) tmp_ctx_keys = tuple(list(ctx_keys)) if found_add_swpx_interface and found_add_swpx_remoteas: @@ -902,7 +1013,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): lines_to_add_to_del.append((ctx_keys, swpx_interface)) lines_to_add_to_del.append((tmp_ctx_keys, swpx_remoteas)) - ''' + """ We made the 'bgp bestpath as-path multipath-relax' command automatically assume 'no-as-set' since the lack of this option caused weird routing problems. When the running config is shown in @@ -910,10 +1021,12 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): is the default. This causes frr-reload to unnecessarily unapply this option only to apply it back again, causing unnecessary session resets. - ''' - if 'multipath-relax' in line: - re_asrelax_new = re.search('^bgp\s+bestpath\s+as-path\s+multipath-relax$', line) - old_asrelax_cmd = 'bgp bestpath as-path multipath-relax no-as-set' + """ + if "multipath-relax" in line: + re_asrelax_new = re.search( + "^bgp\s+bestpath\s+as-path\s+multipath-relax$", line + ) + old_asrelax_cmd = "bgp bestpath as-path multipath-relax no-as-set" found_asrelax_old = line_exist(lines_to_add, ctx_keys, old_asrelax_cmd) if re_asrelax_new and found_asrelax_old: @@ -921,34 +1034,36 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): lines_to_del_to_del.append((ctx_keys, line)) lines_to_add_to_del.append((ctx_keys, old_asrelax_cmd)) - ''' + """ If we are modifying the BGP table-map we need to avoid a del/add and instead modify the table-map in place via an add. This is needed to avoid installing all routes in the RIB the second the 'no table-map' is issued. - ''' - if line.startswith('table-map'): - found_table_map = line_exist(lines_to_add, ctx_keys, 'table-map', False) + """ + if line.startswith("table-map"): + found_table_map = line_exist(lines_to_add, ctx_keys, "table-map", False) if found_table_map: lines_to_del_to_del.append((ctx_keys, line)) - ''' + """ More old-to-new config handling. ip import-table no longer accepts distance, but we honor the old syntax. But 'show running' shows only the new syntax. This causes an unnecessary 'no import-table' followed by the same old 'ip import-table' which causes perturbations in announced routes leading to traffic blackholes. Fix this issue. - ''' - re_importtbl = re.search('^ip\s+import-table\s+(\d+)$', ctx_keys[0]) + """ + re_importtbl = re.search("^ip\s+import-table\s+(\d+)$", ctx_keys[0]) if re_importtbl: table_num = re_importtbl.group(1) for ctx in lines_to_add: - if ctx[0][0].startswith('ip import-table %s distance' % table_num): - lines_to_del_to_del.append((('ip import-table %s' % table_num,), None)) + if ctx[0][0].startswith("ip import-table %s distance" % table_num): + lines_to_del_to_del.append( + (("ip import-table %s" % table_num,), None) + ) lines_to_add_to_del.append((ctx[0], None)) - ''' + """ ip/ipv6 prefix-list can be specified without a seq number. However, the running config always adds 'seq x', where x is a number incremented by 5 for every element, to the prefix list. So, ignore such lines as @@ -956,24 +1071,36 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): ip prefix-list PR-TABLE-2 seq 5 permit 20.8.2.0/24 le 32 ip prefix-list PR-TABLE-2 seq 10 permit 20.8.2.0/24 le 32 ipv6 prefix-list vrfdev6-12 permit 2000:9:2::/64 gt 64 - ''' - re_ip_pfxlst = re.search('^(ip|ipv6)(\s+prefix-list\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$', - ctx_keys[0]) + """ + re_ip_pfxlst = re.search( + "^(ip|ipv6)(\s+prefix-list\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", + ctx_keys[0], + ) if re_ip_pfxlst: - tmpline = (re_ip_pfxlst.group(1) + re_ip_pfxlst.group(2) + - re_ip_pfxlst.group(3) + re_ip_pfxlst.group(5) + - re_ip_pfxlst.group(6)) + tmpline = ( + re_ip_pfxlst.group(1) + + re_ip_pfxlst.group(2) + + re_ip_pfxlst.group(3) + + re_ip_pfxlst.group(5) + + re_ip_pfxlst.group(6) + ) for ctx in lines_to_add: if ctx[0][0] == tmpline: lines_to_del_to_del.append((ctx_keys, None)) lines_to_add_to_del.append(((tmpline,), None)) - if (len(ctx_keys) == 3 and - ctx_keys[0].startswith('router bgp') and - ctx_keys[1] == 'address-family l2vpn evpn' and - ctx_keys[2].startswith('vni')): + if ( + len(ctx_keys) == 3 + and ctx_keys[0].startswith("router bgp") + and ctx_keys[1] == "address-family l2vpn evpn" + and ctx_keys[2].startswith("vni") + ): - re_route_target = re.search('^route-target import (.*)$', line) if line is not None else False + re_route_target = ( + re.search("^route-target import (.*)$", line) + if line is not None + else False + ) if re_route_target: rt = re_route_target.group(1).strip() @@ -981,10 +1108,14 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): route_target_export_line = "route-target export %s" % rt route_target_both_line = "route-target both %s" % rt - found_route_target_export_line = line_exist(lines_to_del, ctx_keys, route_target_export_line) - found_route_target_both_line = line_exist(lines_to_add, ctx_keys, route_target_both_line) + found_route_target_export_line = line_exist( + lines_to_del, ctx_keys, route_target_export_line + ) + found_route_target_both_line = line_exist( + lines_to_add, ctx_keys, route_target_both_line + ) - ''' + """ If the running configs has route-target import 1:1 route-target export 1:1 @@ -993,7 +1124,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): route-target both 1:1 then we can ignore deleting the import/export and ignore adding the 'both' - ''' + """ if found_route_target_export_line and found_route_target_both_line: lines_to_del_to_del.append((ctx_keys, route_target_import_line)) lines_to_del_to_del.append((ctx_keys, route_target_export_line)) @@ -1002,10 +1133,9 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): # Deleting static routes under a vrf can lead to time-outs if each is sent # as separate vtysh -c commands. Change them from being in lines_to_del and # put the "no" form in lines_to_add - if ctx_keys[0].startswith('vrf ') and line: - if (line.startswith('ip route') or - line.startswith('ipv6 route')): - add_cmd = ('no ' + line) + if ctx_keys[0].startswith("vrf ") and line: + if line.startswith("ip route") or line.startswith("ipv6 route"): + add_cmd = "no " + line lines_to_add.append((ctx_keys, add_cmd)) lines_to_del_to_del.append((ctx_keys, line)) @@ -1016,7 +1146,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): lines_to_del_to_del.append((ctx_keys, line)) lines_to_add_to_del.append((ctx_keys, line)) else: - ''' + """ We have commands that used to be displayed in the global part of 'router bgp' that are now displayed under 'address-family ipv4 unicast' @@ -1032,8 +1162,12 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): neighbor ISL advertisement-interval 0 Look to see if we are deleting it in one format just to add it back in the other - ''' - if ctx_keys[0].startswith('router bgp') and len(ctx_keys) > 1 and ctx_keys[1] == 'address-family ipv4 unicast': + """ + if ( + ctx_keys[0].startswith("router bgp") + and len(ctx_keys) > 1 + and ctx_keys[1] == "address-family ipv4 unicast" + ): tmp_ctx_keys = list(ctx_keys)[:-1] tmp_ctx_keys = tuple(tmp_ctx_keys) @@ -1061,16 +1195,18 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del): for (ctx_keys, line) in lines_to_del: - if (ctx_keys[0].startswith('frr version') or - ctx_keys[0].startswith('frr defaults') or - ctx_keys[0].startswith('username') or - ctx_keys[0].startswith('password') or - ctx_keys[0].startswith('line vty') or - + if ( + ctx_keys[0].startswith("frr version") + or ctx_keys[0].startswith("frr defaults") + or ctx_keys[0].startswith("username") + or ctx_keys[0].startswith("password") + or ctx_keys[0].startswith("line vty") + or # This is technically "no"able but if we did so frr-reload would # stop working so do not let the user shoot themselves in the foot # by removing this. - ctx_keys[0].startswith('service integrated-vtysh-config')): + ctx_keys[0].startswith("service integrated-vtysh-config") + ): log.info('"%s" cannot be removed' % (ctx_keys[-1],)) lines_to_del_to_del.append((ctx_keys, line)) @@ -1106,25 +1242,35 @@ def compare_context_objects(newconf, running): lines_to_del.append((running_ctx_keys, None)) # We cannot do 'no interface' or 'no vrf' in FRR, and so deal with it - elif running_ctx_keys[0].startswith('interface') or running_ctx_keys[0].startswith('vrf'): + elif running_ctx_keys[0].startswith("interface") or running_ctx_keys[ + 0 + ].startswith("vrf"): for line in running_ctx.lines: lines_to_del.append((running_ctx_keys, line)) # If this is an address-family under 'router bgp' and we are already deleting the # entire 'router bgp' context then ignore this sub-context - elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd: + elif ( + "router bgp" in running_ctx_keys[0] + and len(running_ctx_keys) > 1 + and delete_bgpd + ): continue # Delete an entire vni sub-context under "address-family l2vpn evpn" - elif ("router bgp" in running_ctx_keys[0] and - len(running_ctx_keys) > 2 and - running_ctx_keys[1].startswith('address-family l2vpn evpn') and - running_ctx_keys[2].startswith('vni ')): + elif ( + "router bgp" in running_ctx_keys[0] + and len(running_ctx_keys) > 2 + and running_ctx_keys[1].startswith("address-family l2vpn evpn") + and running_ctx_keys[2].startswith("vni ") + ): lines_to_del.append((running_ctx_keys, None)) - elif ("router bgp" in running_ctx_keys[0] and - len(running_ctx_keys) > 1 and - running_ctx_keys[1].startswith('address-family')): + elif ( + "router bgp" in running_ctx_keys[0] + and len(running_ctx_keys) > 1 + and running_ctx_keys[1].startswith("address-family") + ): # There's no 'no address-family' support and so we have to # delete each line individually again for line in running_ctx.lines: @@ -1134,24 +1280,31 @@ def compare_context_objects(newconf, running): # doing vtysh -c inefficient (and can time out.) For # these commands, instead of adding them to lines_to_del, # add the "no " version to lines_to_add. - elif (running_ctx_keys[0].startswith('ip route') or - running_ctx_keys[0].startswith('ipv6 route') or - running_ctx_keys[0].startswith('access-list') or - running_ctx_keys[0].startswith('ipv6 access-list') or - running_ctx_keys[0].startswith('ip prefix-list') or - running_ctx_keys[0].startswith('ipv6 prefix-list')): - add_cmd = ('no ' + running_ctx_keys[0],) + elif ( + running_ctx_keys[0].startswith("ip route") + or running_ctx_keys[0].startswith("ipv6 route") + or running_ctx_keys[0].startswith("access-list") + or running_ctx_keys[0].startswith("ipv6 access-list") + or running_ctx_keys[0].startswith("ip prefix-list") + or running_ctx_keys[0].startswith("ipv6 prefix-list") + ): + add_cmd = ("no " + running_ctx_keys[0],) lines_to_add.append((add_cmd, None)) # if this an interface sub-subcontext in an address-family block in ldpd and # we are already deleting the whole context, then ignore this - elif (len(running_ctx_keys) > 2 and running_ctx_keys[0].startswith('mpls ldp') and - running_ctx_keys[1].startswith('address-family') and - (running_ctx_keys[:2], None) in lines_to_del): + elif ( + len(running_ctx_keys) > 2 + and running_ctx_keys[0].startswith("mpls ldp") + and running_ctx_keys[1].startswith("address-family") + and (running_ctx_keys[:2], None) in lines_to_del + ): continue # Non-global context - elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys): + elif running_ctx_keys and not any( + "address-family" in key for key in running_ctx_keys + ): lines_to_del.append((running_ctx_keys, None)) elif running_ctx_keys and not any("vni" in key for key in running_ctx_keys): @@ -1186,33 +1339,78 @@ def compare_context_objects(newconf, running): lines_to_add.append((newconf_ctx_keys, line)) (lines_to_add, lines_to_del) = check_for_exit_vrf(lines_to_add, lines_to_del) - (lines_to_add, lines_to_del) = ignore_delete_re_add_lines(lines_to_add, lines_to_del) - (lines_to_add, lines_to_del) = ignore_unconfigurable_lines(lines_to_add, lines_to_del) + (lines_to_add, lines_to_del) = ignore_delete_re_add_lines( + lines_to_add, lines_to_del + ) + (lines_to_add, lines_to_del) = ignore_unconfigurable_lines( + lines_to_add, lines_to_del + ) return (lines_to_add, lines_to_del) -if __name__ == '__main__': +if __name__ == "__main__": # Command line options - parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs') - parser.add_argument('--input', help='Read running config from file instead of "show running"') + parser = argparse.ArgumentParser( + description="Dynamically apply diff in frr configs" + ) + parser.add_argument( + "--input", help='Read running config from file instead of "show running"' + ) group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--reload', action='store_true', help='Apply the deltas', default=False) - group.add_argument('--test', action='store_true', help='Show the deltas', default=False) + group.add_argument( + "--reload", action="store_true", help="Apply the deltas", default=False + ) + group.add_argument( + "--test", action="store_true", help="Show the deltas", default=False + ) level_group = parser.add_mutually_exclusive_group() - level_group.add_argument('--debug', action='store_true', - help='Enable debugs (synonym for --log-level=debug)', default=False) - level_group.add_argument('--log-level', help='Log level', default="info", - choices=("critical", "error", "warning", "info", "debug")) - parser.add_argument('--stdout', action='store_true', help='Log to STDOUT', default=False) - parser.add_argument('--pathspace', '-N', metavar='NAME', help='Reload specified path/namespace', default=None) - parser.add_argument('filename', help='Location of new frr config file') - parser.add_argument('--overwrite', action='store_true', help='Overwrite frr.conf with running config output', default=False) - parser.add_argument('--bindir', help='path to the vtysh executable', default='/usr/bin') - parser.add_argument('--confdir', help='path to the daemon config files', default='/etc/frr') - parser.add_argument('--rundir', help='path for the temp config file', default='/var/run/frr') - parser.add_argument('--vty_socket', help='socket to be used by vtysh to connect to the daemons', default=None) - parser.add_argument('--daemon', help='daemon for which want to replace the config', default='') + level_group.add_argument( + "--debug", + action="store_true", + help="Enable debugs (synonym for --log-level=debug)", + default=False, + ) + level_group.add_argument( + "--log-level", + help="Log level", + default="info", + choices=("critical", "error", "warning", "info", "debug"), + ) + parser.add_argument( + "--stdout", action="store_true", help="Log to STDOUT", default=False + ) + parser.add_argument( + "--pathspace", + "-N", + metavar="NAME", + help="Reload specified path/namespace", + default=None, + ) + parser.add_argument("filename", help="Location of new frr config file") + parser.add_argument( + "--overwrite", + action="store_true", + help="Overwrite frr.conf with running config output", + default=False, + ) + parser.add_argument( + "--bindir", help="path to the vtysh executable", default="/usr/bin" + ) + parser.add_argument( + "--confdir", help="path to the daemon config files", default="/etc/frr" + ) + parser.add_argument( + "--rundir", help="path for the temp config file", default="/var/run/frr" + ) + parser.add_argument( + "--vty_socket", + help="socket to be used by vtysh to connect to the daemons", + default=None, + ) + parser.add_argument( + "--daemon", help="daemon for which want to replace the config", default="" + ) args = parser.parse_args() @@ -1220,22 +1418,28 @@ if __name__ == '__main__': # For --test log to stdout # For --reload log to /var/log/frr/frr-reload.log if args.test or args.stdout: - logging.basicConfig(format='%(asctime)s %(levelname)5s: %(message)s') + logging.basicConfig(format="%(asctime)s %(levelname)5s: %(message)s") # Color the errors and warnings in red - logging.addLevelName(logging.ERROR, "\033[91m %s\033[0m" % logging.getLevelName(logging.ERROR)) - logging.addLevelName(logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING)) + logging.addLevelName( + logging.ERROR, "\033[91m %s\033[0m" % logging.getLevelName(logging.ERROR) + ) + logging.addLevelName( + logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING) + ) elif args.reload: - if not os.path.isdir('/var/log/frr/'): - os.makedirs('/var/log/frr/') + if not os.path.isdir("/var/log/frr/"): + os.makedirs("/var/log/frr/") - logging.basicConfig(filename='/var/log/frr/frr-reload.log', - format='%(asctime)s %(levelname)5s: %(message)s') + logging.basicConfig( + filename="/var/log/frr/frr-reload.log", + format="%(asctime)s %(levelname)5s: %(message)s", + ) # argparse should prevent this from happening but just to be safe... else: - raise Exception('Must specify --reload or --test') + raise Exception("Must specify --reload or --test") log = logging.getLogger(__name__) if args.debug: @@ -1269,40 +1473,59 @@ if __name__ == '__main__': sys.exit(1) # Verify that bindir is correct - if not os.path.isdir(args.bindir) or not os.path.isfile(args.bindir + '/vtysh'): + if not os.path.isdir(args.bindir) or not os.path.isfile(args.bindir + "/vtysh"): log.error("Bindir %s is not a valid path to vtysh" % args.bindir) sys.exit(1) # verify that the vty_socket, if specified, is valid if args.vty_socket and not os.path.isdir(args.vty_socket): - log.error('vty_socket %s is not a valid path' % args.vty_socket) + log.error("vty_socket %s is not a valid path" % args.vty_socket) sys.exit(1) # verify that the daemon, if specified, is valid - if args.daemon and args.daemon not in ['zebra', 'bgpd', 'fabricd', 'isisd', 'ospf6d', 'ospfd', 'pbrd', 'pimd', 'ripd', 'ripngd', 'sharpd', 'staticd', 'vrrpd', 'ldpd']: - log.error("Daemon %s is not a valid option for 'show running-config'" % args.daemon) + if args.daemon and args.daemon not in [ + "zebra", + "bgpd", + "fabricd", + "isisd", + "ospf6d", + "ospfd", + "pbrd", + "pimd", + "ripd", + "ripngd", + "sharpd", + "staticd", + "vrrpd", + "ldpd", + ]: + log.error( + "Daemon %s is not a valid option for 'show running-config'" % args.daemon + ) sys.exit(1) vtysh = Vtysh(args.bindir, args.confdir, args.vty_socket, args.pathspace) # Verify that 'service integrated-vtysh-config' is configured if args.pathspace: - vtysh_filename = args.confdir + '/' + args.pathspace + '/vtysh.conf' + vtysh_filename = args.confdir + "/" + args.pathspace + "/vtysh.conf" else: - vtysh_filename = args.confdir + '/vtysh.conf' + vtysh_filename = args.confdir + "/vtysh.conf" service_integrated_vtysh_config = True if os.path.isfile(vtysh_filename): - with open(vtysh_filename, 'r') as fh: + with open(vtysh_filename, "r") as fh: for line in fh.readlines(): line = line.strip() - if line == 'no service integrated-vtysh-config': + if line == "no service integrated-vtysh-config": service_integrated_vtysh_config = False break if not service_integrated_vtysh_config and not args.daemon: - log.error("'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'") + log.error( + "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'" + ) sys.exit(1) log.info('Called via "%s"', str(args)) @@ -1335,10 +1558,10 @@ if __name__ == '__main__': for (ctx_keys, line) in lines_to_del: - if line == '!': + if line == "!": continue - cmd = '\n'.join(lines_to_config(ctx_keys, line, True)) + cmd = "\n".join(lines_to_config(ctx_keys, line, True)) lines_to_configure.append(cmd) print(cmd) @@ -1348,10 +1571,10 @@ if __name__ == '__main__': for (ctx_keys, line) in lines_to_add: - if line == '!': + if line == "!": continue - cmd = '\n'.join(lines_to_config(ctx_keys, line, False)) + cmd = "\n".join(lines_to_config(ctx_keys, line, False)) lines_to_configure.append(cmd) print(cmd) @@ -1361,7 +1584,7 @@ if __name__ == '__main__': if not vtysh.is_config_available(): sys.exit(1) - log.debug('New Frr Config\n%s', newconf.get_lines()) + log.debug("New Frr Config\n%s", newconf.get_lines()) # This looks a little odd but we have to do this twice...here is why # If the user had this running bgp config: @@ -1403,7 +1626,7 @@ if __name__ == '__main__': for x in range(2): running = Config(vtysh) running.load_from_show_running(args.daemon) - log.debug('Running Frr Config (Pass #%d)\n%s', x, running.get_lines()) + log.debug("Running Frr Config (Pass #%d)\n%s", x, running.get_lines()) (lines_to_add, lines_to_del) = compare_context_objects(newconf, running) @@ -1428,7 +1651,7 @@ if __name__ == '__main__': if lines_to_del and x == 0: for (ctx_keys, line) in lines_to_del: - if line == '!': + if line == "!": continue # 'no' commands are tricky, we can't just put them in a file and @@ -1453,7 +1676,7 @@ if __name__ == '__main__': while True: try: - vtysh(['configure'] + cmd) + vtysh(["configure"] + cmd) except VtyshException: @@ -1461,17 +1684,20 @@ if __name__ == '__main__': # 'no ip ospf authentication message-digest 1.1.1.1' in # our example above # - Split that last entry by whitespace and drop the last word - log.info('Failed to execute %s', ' '.join(cmd)) - last_arg = cmd[-1].split(' ') + log.info("Failed to execute %s", " ".join(cmd)) + last_arg = cmd[-1].split(" ") if len(last_arg) <= 2: - log.error('"%s" we failed to remove this command', ' -- '.join(original_cmd)) + log.error( + '"%s" we failed to remove this command', + " -- ".join(original_cmd), + ) break new_last_arg = last_arg[0:-1] - cmd[-1] = ' '.join(new_last_arg) + cmd[-1] = " ".join(new_last_arg) else: - log.info('Executed "%s"', ' '.join(cmd)) + log.info('Executed "%s"', " ".join(cmd)) break if lines_to_add: @@ -1479,28 +1705,31 @@ if __name__ == '__main__': for (ctx_keys, line) in lines_to_add: - if line == '!': + if line == "!": continue # Don't run "no" commands twice since they can error # out the second time due to first deletion - if x == 1 and ctx_keys[0].startswith('no '): + if x == 1 and ctx_keys[0].startswith("no "): continue - cmd = '\n'.join(lines_to_config(ctx_keys, line, False)) + '\n' + cmd = "\n".join(lines_to_config(ctx_keys, line, False)) + "\n" lines_to_configure.append(cmd) if lines_to_configure: - random_string = ''.join(random.SystemRandom().choice( - string.ascii_uppercase + - string.digits) for _ in range(6)) + random_string = "".join( + random.SystemRandom().choice( + string.ascii_uppercase + string.digits + ) + for _ in range(6) + ) filename = args.rundir + "/reload-%s.txt" % random_string log.info("%s content\n%s" % (filename, pformat(lines_to_configure))) - with open(filename, 'w') as fh: + with open(filename, "w") as fh: for line in lines_to_configure: - fh.write(line + '\n') + fh.write(line + "\n") try: vtysh.exec_file(filename) @@ -1510,9 +1739,9 @@ if __name__ == '__main__': os.unlink(filename) # Make these changes persistent - target = str(args.confdir + '/frr.conf') + target = str(args.confdir + "/frr.conf") if args.overwrite or (not args.daemon and args.filename != target): - vtysh('write') + vtysh("write") if not reload_ok: sys.exit(1) diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in index 9a144b2b06..312ee88bf4 100644 --- a/tools/frrcommon.sh.in +++ b/tools/frrcommon.sh.in @@ -152,7 +152,7 @@ daemon_start() { daemon_prep "$daemon" "$inst" || return 1 if test ! -d "$V_PATH"; then mkdir -p "$V_PATH" - chown frr "$V_PATH" + chownfrr "$V_PATH" fi eval wrap="\$${daemon}_wrap" diff --git a/tools/gcc-plugins/format-test.py b/tools/gcc-plugins/format-test.py index df2437d5bc..ddf71aa0ef 100644 --- a/tools/gcc-plugins/format-test.py +++ b/tools/gcc-plugins/format-test.py @@ -4,58 +4,71 @@ import shlex import os import re -os.environ['LC_ALL'] = 'C' -os.environ['LANG'] = 'C' +os.environ["LC_ALL"] = "C" +os.environ["LANG"] = "C" for k in list(os.environ.keys()): - if k.startswith('LC_'): + if k.startswith("LC_"): os.environ.pop(k) if len(sys.argv) < 2: - sys.stderr.write('start as format-test.py gcc-123.45 [-options ...]\n') + sys.stderr.write("start as format-test.py gcc-123.45 [-options ...]\n") sys.exit(1) -c_re = re.compile(r'//\s+(NO)?WARN') +c_re = re.compile(r"//\s+(NO)?WARN") expect = {} lines = {} -with open('format-test.c', 'r') as fd: +with open("format-test.c", "r") as fd: for lno, line in enumerate(fd.readlines(), 1): lines[lno] = line.strip() m = c_re.search(line) if m is None: continue if m.group(1) is None: - expect[lno] = 'warn' + expect[lno] = "warn" else: - expect[lno] = 'nowarn' + expect[lno] = "nowarn" -cmd = shlex.split('-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c') +cmd = shlex.split( + "-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c" +) -gcc = subprocess.Popen(sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +gcc = subprocess.Popen( + sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE +) sout, serr = gcc.communicate() gcc.wait() -gcclines = serr.decode('UTF-8').splitlines() -line_re = re.compile(r'^format-test\.c:(\d+):(.*)$') +gcclines = serr.decode("UTF-8").splitlines() +line_re = re.compile(r"^format-test\.c:(\d+):(.*)$") gcc_warns = {} for line in gcclines: - if line.find('In function') >= 0: + if line.find("In function") >= 0: continue m = line_re.match(line) if m is None: - sys.stderr.write('cannot process GCC output: %s\n' % line) + sys.stderr.write("cannot process GCC output: %s\n" % line) continue lno = int(m.group(1)) gcc_warns.setdefault(lno, []).append(line) for lno, val in expect.items(): - if val == 'nowarn' and lno in gcc_warns: - sys.stderr.write('unexpected gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno]))) - if val == 'warn' and lno not in gcc_warns: - sys.stderr.write('expected warning on line %d but did not get one\n\t%s\n' % (lno, lines[lno])) + if val == "nowarn" and lno in gcc_warns: + sys.stderr.write( + "unexpected gcc warning on line %d:\n\t%s\n\t%s\n" + % (lno, lines[lno], "\n\t".join(gcc_warns[lno])) + ) + if val == "warn" and lno not in gcc_warns: + sys.stderr.write( + "expected warning on line %d but did not get one\n\t%s\n" + % (lno, lines[lno]) + ) leftover = set(gcc_warns.keys()) - set(expect.keys()) for lno in sorted(leftover): - sys.stderr.write('unmarked gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno]))) + sys.stderr.write( + "unmarked gcc warning on line %d:\n\t%s\n\t%s\n" + % (lno, lines[lno], "\n\t".join(gcc_warns[lno])) + ) diff --git a/tools/gcc-plugins/frr-format.c b/tools/gcc-plugins/frr-format.c index be56517171..6d91d2cdcd 100644 --- a/tools/gcc-plugins/frr-format.c +++ b/tools/gcc-plugins/frr-format.c @@ -2729,6 +2729,16 @@ tree type_normalize (tree type, tree *cousin, tree target = NULL) return type; } +/* gcc-10 asserts when you give a TYPE_DECL instead of the actual TYPE */ +static tree +decl_deref(tree typ) +{ + while (TREE_CODE (typ) == TYPE_DECL) + typ = DECL_ORIGINAL_TYPE (typ); + + return typ; +} + static void check_format_types (const substring_loc &fmt_loc, format_wanted_type *types, const format_kind_info *fki, @@ -2750,6 +2760,8 @@ check_format_types (const substring_loc &fmt_loc, wanted_type = types->wanted_type; arg_num = types->arg_num; + wanted_type = decl_deref(wanted_type); + /* The following should not occur here. */ gcc_assert (wanted_type); gcc_assert (wanted_type != void_type_node || types->pointer_count); @@ -2873,7 +2885,7 @@ check_format_types (const substring_loc &fmt_loc, || cur_type == signed_char_type_node || cur_type == unsigned_char_type_node); - int compat = lang_hooks.types_compatible_p (wanted_type, cur_type); + int compat = lang_hooks.types_compatible_p (decl_deref (wanted_type), decl_deref (cur_type)); /* Check the type of the "real" argument, if there's a type we want. */ if ((TREE_CODE (wanted_type) != INTEGER_TYPE || types->pointer_count) && compat) @@ -3180,6 +3192,9 @@ matching_type_p (tree spec_type, tree arg_type) gcc_assert (spec_type); gcc_assert (arg_type); + spec_type = decl_deref (spec_type); + arg_type = decl_deref (arg_type); + /* If any of the types requires structural equality, we can't compare their canonical types. */ if (TYPE_STRUCTURAL_EQUALITY_P (spec_type) diff --git a/tools/gen_northbound_callbacks.c b/tools/gen_northbound_callbacks.c index eaab932228..a785f43cdf 100644 --- a/tools/gen_northbound_callbacks.c +++ b/tools/gen_northbound_callbacks.c @@ -368,13 +368,12 @@ int main(int argc, char *argv[]) /* Generate callback prototypes. */ if (!static_cbs) { printf("/* prototypes */\n"); - yang_snodes_iterate_module(module->info, generate_prototypes, 0, - NULL); + yang_snodes_iterate(module->info, generate_prototypes, 0, NULL); printf("\n"); } /* Generate callback functions. */ - yang_snodes_iterate_module(module->info, generate_callbacks, 0, NULL); + yang_snodes_iterate(module->info, generate_callbacks, 0, NULL); strlcpy(module_name_underscores, module->name, sizeof(module_name_underscores)); @@ -386,7 +385,7 @@ int main(int argc, char *argv[]) "\t.name = \"%s\",\n" "\t.nodes = {\n", module_name_underscores, module->name); - yang_snodes_iterate_module(module->info, generate_nb_nodes, 0, NULL); + yang_snodes_iterate(module->info, generate_nb_nodes, 0, NULL); printf("\t\t{\n" "\t\t\t.xpath = NULL,\n" "\t\t},\n"); diff --git a/tools/gen_yang_deviations.c b/tools/gen_yang_deviations.c index f908e1fc69..53a53c943c 100644 --- a/tools/gen_yang_deviations.c +++ b/tools/gen_yang_deviations.c @@ -71,8 +71,8 @@ int main(int argc, char *argv[]) module = yang_module_load(argv[0]); /* Generate deviations. */ - yang_snodes_iterate_module(module->info, generate_yang_deviation, - YANG_ITER_FILTER_IMPLICIT, NULL); + yang_snodes_iterate(module->info, generate_yang_deviation, + YANG_ITER_FILTER_IMPLICIT, NULL); /* Cleanup and exit. */ yang_terminate(); diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py index 540b7a1357..ae258bddfe 100755 --- a/tools/generate_support_bundle.py +++ b/tools/generate_support_bundle.py @@ -7,9 +7,9 @@ import os import subprocess import datetime -TOOLS_DIR="tools/" -ETC_DIR="/etc/frr/" -LOG_DIR="/var/log/frr/" +TOOLS_DIR = "tools/" +ETC_DIR = "/etc/frr/" +LOG_DIR = "/var/log/frr/" SUCCESS = 1 FAIL = 0 @@ -17,96 +17,103 @@ inputFile = ETC_DIR + "support_bundle_commands.conf" # Open support bundle configuration file def openConfFile(i_file): - try: - with open(i_file) as supportBundleConfFile: - lines = filter(None, (line.rstrip() for line in supportBundleConfFile)) - return lines - except IOError: - return ([]) + try: + with open(i_file) as supportBundleConfFile: + lines = filter(None, (line.rstrip() for line in supportBundleConfFile)) + return lines + except IOError: + return [] + # Create the output file name def createOutputFile(procName): - fileName = procName + "_support_bundle.log" - oldFile = LOG_DIR + fileName - cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev" - rmFileCmd = "rm -rf " + oldFile - print("Making backup of " + oldFile) - os.system(cpFileCmd) - print("Removing " + oldFile) - os.system(rmFileCmd) - return fileName + fileName = procName + "_support_bundle.log" + oldFile = LOG_DIR + fileName + cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev" + rmFileCmd = "rm -rf " + oldFile + print("Making backup of " + oldFile) + os.system(cpFileCmd) + print("Removing " + oldFile) + os.system(rmFileCmd) + return fileName + # Open the output file for this process def openOutputFile(fileName): - crt_file_cmd = LOG_DIR + fileName - print(crt_file_cmd) - try: - outputFile = open(crt_file_cmd, "w") - return outputFile - except IOError: - return () + crt_file_cmd = LOG_DIR + fileName + print(crt_file_cmd) + try: + outputFile = open(crt_file_cmd, "w") + return outputFile + except IOError: + return () + # Close the output file for this process def closeOutputFile(file): - try: - file.close() - return SUCCESS - except IOError: - return FAIL + try: + file.close() + return SUCCESS + except IOError: + return FAIL + # Execute the command over vtysh and store in the # output file def executeCommand(cmd, outputFile): - cmd_exec_str = "vtysh -c \"" + cmd + "\" " - try: - cmd_output = subprocess.check_output(cmd_exec_str, shell=True) + cmd_exec_str = 'vtysh -c "' + cmd + '" ' try: - dateTime = datetime.datetime.now() - outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n") - outputFile.write(cmd_output) - outputFile.write("########################################################\n") - outputFile.write('\n') - except: - print("Writing to ouptut file Failed") - except subprocess.CalledProcessError as e: - dateTime = datetime.datetime.now() - outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n") - outputFile.write(e.output) - outputFile.write("########################################################\n") - outputFile.write('\n') - print("Error:" + e.output) + cmd_output = subprocess.check_output(cmd_exec_str, shell=True) + try: + dateTime = datetime.datetime.now() + outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n") + outputFile.write(cmd_output) + outputFile.write( + "########################################################\n" + ) + outputFile.write("\n") + except: + print("Writing to ouptut file Failed") + except subprocess.CalledProcessError as e: + dateTime = datetime.datetime.now() + outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n") + outputFile.write(e.output) + outputFile.write("########################################################\n") + outputFile.write("\n") + print("Error:" + e.output) # Process the support bundle configuration file # and call appropriate functions def processConfFile(lines): - for line in lines: - if line[0][0] == '#': - continue - cmd_line = line.split(':') - if cmd_line[0] == "PROC_NAME": - outputFileName = createOutputFile(cmd_line[1]) - if outputFileName: - print(outputFileName, "created for", cmd_line[1]) - elif cmd_line[0] == "CMD_LIST_START": - outputFile = openOutputFile(outputFileName) - if outputFile: - print(outputFileName, "opened") - else: - print(outputFileName, "open failed") - return FAIL - elif cmd_line[0] == "CMD_LIST_END": - if closeOutputFile(outputFile): - print(outputFileName, "closed") - else: - print(outputFileName, "close failed") - else: - print("Execute:" , cmd_line[0]) - executeCommand(cmd_line[0], outputFile) - + for line in lines: + if line[0][0] == "#": + continue + cmd_line = line.split(":") + if cmd_line[0] == "PROC_NAME": + outputFileName = createOutputFile(cmd_line[1]) + if outputFileName: + print(outputFileName, "created for", cmd_line[1]) + elif cmd_line[0] == "CMD_LIST_START": + outputFile = openOutputFile(outputFileName) + if outputFile: + print(outputFileName, "opened") + else: + print(outputFileName, "open failed") + return FAIL + elif cmd_line[0] == "CMD_LIST_END": + if closeOutputFile(outputFile): + print(outputFileName, "closed") + else: + print(outputFileName, "close failed") + else: + print("Execute:", cmd_line[0]) + executeCommand(cmd_line[0], outputFile) + + # Main Function lines = openConfFile(inputFile) if not lines: - print("File support_bundle_commands.conf not present in /etc/frr/ directory") + print("File support_bundle_commands.conf not present in /etc/frr/ directory") else: - processConfFile(lines) + processConfFile(lines) diff --git a/tools/git-reindent-branch.py b/tools/git-reindent-branch.py index c207f5946f..5f821b06c7 100644 --- a/tools/git-reindent-branch.py +++ b/tools/git-reindent-branch.py @@ -5,85 +5,100 @@ import sys, os import subprocess, argparse, tempfile import indent + def run(cmd): - proc = subprocess.Popen(cmd, stdout = subprocess.PIPE) - rv = proc.communicate('')[0].decode('UTF-8') + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + rv = proc.communicate("")[0].decode("UTF-8") proc.wait() return rv -clangfmt = run(['git', 'show', 'master:.clang-format']) -argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool') -argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD') +clangfmt = run(["git", "show", "master:.clang-format"]) + +argp = argparse.ArgumentParser(description="git whitespace-fixing tool") +argp.add_argument("branch", metavar="BRANCH", type=str, nargs="?", default="HEAD") args = argp.parse_args() branch = args.branch -commit = run(['git', 'rev-list', '-n', '1', branch, '--']).strip() +commit = run(["git", "rev-list", "-n", "1", branch, "--"]).strip() # frr-3.1-dev = first commit that is on master but not on stable/3.0 -masterid = run(['git', 'rev-list', '-n', '1', 'frr-3.1-dev', '--']).strip() -masterbase = run(['git', 'merge-base', commit, masterid]).strip() +masterid = run(["git", "rev-list", "-n", "1", "frr-3.1-dev", "--"]).strip() +masterbase = run(["git", "merge-base", commit, masterid]).strip() if masterbase == masterid: - refbranch = 'master' + refbranch = "master" else: - refbranch = '3.0' + refbranch = "3.0" -sys.stderr.write('autodetected base: %s (can be 3.0 or master)\n' % refbranch) +sys.stderr.write("autodetected base: %s (can be 3.0 or master)\n" % refbranch) -beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-before' % refbranch, '--']).strip() -afterid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-after' % refbranch, '--']).strip() +beforeid = run( + ["git", "rev-list", "-n", "1", "reindent-%s-before" % refbranch, "--"] +).strip() +afterid = run( + ["git", "rev-list", "-n", "1", "reindent-%s-after" % refbranch, "--"] +).strip() -beforebase = run(['git', 'merge-base', commit, beforeid]).strip() -afterbase = run(['git', 'merge-base', commit, afterid]).strip() +beforebase = run(["git", "merge-base", commit, beforeid]).strip() +afterbase = run(["git", "merge-base", commit, afterid]).strip() if afterbase == afterid: - sys.stderr.write('this branch was already rebased\n') + sys.stderr.write("this branch was already rebased\n") sys.exit(1) if beforebase != beforeid: - sys.stderr.write('you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch) + sys.stderr.write( + 'you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch + ) sys.exit(1) -revs = run(['git', 'rev-list', 'reindent-%s-before..%s' % (refbranch, commit)]).strip().split('\n') +revs = ( + run(["git", "rev-list", "reindent-%s-before..%s" % (refbranch, commit)]) + .strip() + .split("\n") +) revs.reverse() srcdir = os.getcwd() -tmpdir = tempfile.mkdtemp('frrindent') +tmpdir = tempfile.mkdtemp("frrindent") os.chdir(tmpdir) -sys.stderr.write('using temporary directory %s; %d revisions\n' % (tmpdir, len(revs))) -run(['git', 'clone', '-s', '-b', 'reindent-%s-after' % refbranch, srcdir, 'repo']) -os.chdir('repo') +sys.stderr.write("using temporary directory %s; %d revisions\n" % (tmpdir, len(revs))) +run(["git", "clone", "-s", "-b", "reindent-%s-after" % refbranch, srcdir, "repo"]) +os.chdir("repo") -with open('.clang-format', 'w') as fd: +with open(".clang-format", "w") as fd: fd.write(clangfmt) prev = beforeid for rev in revs: - filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0') + filestat = ( + run(["git", "diff", "-z", "--name-status", prev, rev]).rstrip("\0").split("\0") + ) changes = zip(filestat[0::2], filestat[1::2]) - sys.stderr.write('%s: %d files\n' % (rev, len(changes))) + sys.stderr.write("%s: %d files\n" % (rev, len(changes))) for typ, name in changes: - if typ == 'D': - run(['git', 'rm', name]) - elif typ in ['A', 'M']: - run(['git', 'checkout', rev, '--', name]) - if name.endswith('.c') or name.endswith('.h'): - for d in ['babeld/', 'ldpd/', 'nhrpd/']: + if typ == "D": + run(["git", "rm", name]) + elif typ in ["A", "M"]: + run(["git", "checkout", rev, "--", name]) + if name.endswith(".c") or name.endswith(".h"): + for d in ["babeld/", "ldpd/", "nhrpd/"]: if name.startswith(d): break else: - sys.stderr.write('\t%s\n' % name) + sys.stderr.write("\t%s\n" % name) indent.wrap_file(name) - run(['git', 'add', name]) + run(["git", "add", name]) - run(['git', 'commit', '-C', rev]) + run(["git", "commit", "-C", rev]) prev = rev -run(['git', 'push', 'origin', 'HEAD:refs/heads/reindented-branch']) +run(["git", "push", "origin", "HEAD:refs/heads/reindented-branch"]) sys.stderr.write('\n\n"reindented-branch" should now be OK.\n') -sys.stderr.write('you could use "git reset --hard reindented-branch" to set your current branch to the reindented output\n') -sys.stderr.write('\033[31;1mplease always double-check the output\033[m\n') - +sys.stderr.write( + 'you could use "git reset --hard reindented-branch" to set your current branch to the reindented output\n' +) +sys.stderr.write("\033[31;1mplease always double-check the output\033[m\n") diff --git a/tools/indent.py b/tools/indent.py index d2c41e1865..61a0fd4454 100755 --- a/tools/indent.py +++ b/tools/indent.py @@ -6,42 +6,47 @@ import sys, re, subprocess, os # find all DEFUNs defun_re = re.compile( - r'^((DEF(UN(|_ATTR|_CMD_(ELEMENT|FUNC_(DECL|TEXT))|_DEPRECATED|_NOSH|_HIDDEN|SH(|_ATTR|_DEPRECATED|_HIDDEN))?|PY|PY_ATTR|PY_HIDDEN)|ALIAS)\s*\(.*?)^(?=\s*\{)', - re.M | re.S) -define_re = re.compile( - r'((^#\s*define[^\n]+[^\\]\n)+)', - re.M | re.S) + r"^((DEF(UN(|_ATTR|_CMD_(ELEMENT|FUNC_(DECL|TEXT))|_DEPRECATED|_NOSH|_HIDDEN|SH(|_ATTR|_DEPRECATED|_HIDDEN))?|PY|PY_ATTR|PY_HIDDEN)|ALIAS)\s*\(.*?)^(?=\s*\{)", + re.M | re.S, +) +define_re = re.compile(r"((^#\s*define[^\n]+[^\\]\n)+)", re.M | re.S) # find clang-format control that we just inserted clean_re = re.compile( - r'^.*/\* \$FRR indent\$ \*/\s*\n\s*/\* clang-format (on|off) \*/\s*\n', - re.M) + r"^.*/\* \$FRR indent\$ \*/\s*\n\s*/\* clang-format (on|off) \*/\s*\n", re.M +) + def wrap_file(fn): - with open(fn, 'r') as fd: + with open(fn, "r") as fd: text = fd.read() - repl = r'/* $FRR indent$ */\n/* clang-format off */\n' + \ - r'\1' + \ - r'/* $FRR indent$ */\n/* clang-format on */\n' + repl = ( + r"/* $FRR indent$ */\n/* clang-format off */\n" + + r"\1" + + r"/* $FRR indent$ */\n/* clang-format on */\n" + ) # around each DEFUN, insert an indent-on/off comment text = defun_re.sub(repl, text) text = define_re.sub(repl, text) - ci = subprocess.Popen(['clang-format'], stdin = subprocess.PIPE, stdout = subprocess.PIPE) + ci = subprocess.Popen( + ["clang-format"], stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) stdout, ign = ci.communicate(text) ci.wait() if ci.returncode != 0: - raise IOError('clang-format returned %d' % (ci.returncode)) + raise IOError("clang-format returned %d" % (ci.returncode)) # remove the bits we inserted above - final = clean_re.sub('', stdout) + final = clean_re.sub("", stdout) - tmpname = fn + '.indent' - with open(tmpname, 'w') as ofd: + tmpname = fn + ".indent" + with open(tmpname, "w") as ofd: ofd.write(final) os.rename(tmpname, fn) -if __name__ == '__main__': + +if __name__ == "__main__": for fn in sys.argv[1:]: wrap_file(fn) diff --git a/tools/render_md.py b/tools/render_md.py index 16c4bbe8a3..7636496b62 100644 --- a/tools/render_md.py +++ b/tools/render_md.py @@ -2,7 +2,7 @@ # written 2016 by David Lamparter, placed in Public Domain. import sys, markdown -template = '''<html><head><meta charset="UTF-8"><style type="text/css"> +template = """<html><head><meta charset="UTF-8"><style type="text/css"> body { max-width: 45em; margin: auto; margin-top: 2em; margin-bottom: 2em; font-family:Fira Sans,sans-serif; text-align: justify; counter-reset: ch2; } @@ -18,11 +18,13 @@ img[alt~="float-right"] { float:right; margin-left:2em; margin-bottom:2em; } </style></head><body> %s </body></html> -''' +""" -md = markdown.Markdown(extensions=['extra', 'toc']) +md = markdown.Markdown(extensions=["extra", "toc"]) for fn in sys.argv[1:]: - with open(fn, 'r') as ifd: - with open('%s.html' % (fn), 'w') as ofd: - ofd.write((template % (md.convert(ifd.read().decode('UTF-8')))).encode('UTF-8')) + with open(fn, "r") as ifd: + with open("%s.html" % (fn), "w") as ofd: + ofd.write( + (template % (md.convert(ifd.read().decode("UTF-8")))).encode("UTF-8") + ) diff --git a/tools/stringmangle.py b/tools/stringmangle.py index a2eb37336a..1c75c86a0d 100644 --- a/tools/stringmangle.py +++ b/tools/stringmangle.py @@ -6,23 +6,24 @@ import re import argparse wrap_res = [ - (re.compile(r'(?<!\\n)"\s*\n\s*"', re.M), r''), + (re.compile(r'(?<!\\n)"\s*\n\s*"', re.M), r""), ] pri_res = [ - (re.compile(r'(PRI[udx][0-9]+)\s*\n\s*"', re.M), r'\1"'), - (re.compile(r'"\s*PRI([udx])32\s*"'), r'\1'), - (re.compile(r'"\s*PRI([udx])32'), r'\1"'), - (re.compile(r'"\s*PRI([udx])16\s*"'), r'h\1'), - (re.compile(r'"\s*PRI([udx])16'), r'h\1"'), - (re.compile(r'"\s*PRI([udx])8\s*"'), r'hh\1'), - (re.compile(r'"\s*PRI([udx])8'), r'hh\1"'), + (re.compile(r'(PRI[udx][0-9]+)\s*\n\s*"', re.M), r'\1"'), + (re.compile(r'"\s*PRI([udx])32\s*"'), r"\1"), + (re.compile(r'"\s*PRI([udx])32'), r'\1"'), + (re.compile(r'"\s*PRI([udx])16\s*"'), r"h\1"), + (re.compile(r'"\s*PRI([udx])16'), r'h\1"'), + (re.compile(r'"\s*PRI([udx])8\s*"'), r"hh\1"), + (re.compile(r'"\s*PRI([udx])8'), r'hh\1"'), ] + def main(): - argp = argparse.ArgumentParser(description = 'C string mangler') - argp.add_argument('--unwrap', action = 'store_const', const = True) - argp.add_argument('--pri8-16-32', action = 'store_const', const = True) - argp.add_argument('files', type = str, nargs = '+') + argp = argparse.ArgumentParser(description="C string mangler") + argp.add_argument("--unwrap", action="store_const", const=True) + argp.add_argument("--pri8-16-32", action="store_const", const=True) + argp.add_argument("files", type=str, nargs="+") args = argp.parse_args() regexes = [] @@ -31,14 +32,14 @@ def main(): if args.pri8_16_32: regexes.extend(pri_res) if len(regexes) == 0: - sys.stderr.write('no action selected to execute\n') + sys.stderr.write("no action selected to execute\n") sys.exit(1) l = 0 for fn in args.files: - sys.stderr.write(fn + '\033[K\r') - with open(fn, 'r') as ifd: + sys.stderr.write(fn + "\033[K\r") + with open(fn, "r") as ifd: data = ifd.read() newdata = data @@ -48,12 +49,13 @@ def main(): n += m if n > 0: - sys.stderr.write('changed: %s\n' % fn) - with open(fn + '.new', 'w') as ofd: + sys.stderr.write("changed: %s\n" % fn) + with open(fn + ".new", "w") as ofd: ofd.write(newdata) - os.rename(fn + '.new', fn) + os.rename(fn + ".new", fn) l += 1 - sys.stderr.write('%d files changed.\n' % (l)) + sys.stderr.write("%d files changed.\n" % (l)) + main() diff --git a/tools/symalyzer.py b/tools/symalyzer.py index cff21f9f93..ce0bfde0a5 100755 --- a/tools/symalyzer.py +++ b/tools/symalyzer.py @@ -21,18 +21,40 @@ import sys, os, subprocess import re from collections import namedtuple -sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'python')) +sys.path.insert( + 0, + os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "python"), +) from makevars import MakeVars -SymRowBase = namedtuple('SymRow', ['target', 'object', 'name', 'address', 'klass', 'typ', 'size', 'line', 'section', 'loc']) +SymRowBase = namedtuple( + "SymRow", + [ + "target", + "object", + "name", + "address", + "klass", + "typ", + "size", + "line", + "section", + "loc", + ], +) + + class SymRow(SymRowBase): - ''' + """ wrapper around a line of `nm` output - ''' - lib_re = re.compile(r'/lib[^/]+\.(so|la)$') + """ + + lib_re = re.compile(r"/lib[^/]+\.(so|la)$") + def is_global(self): - return self.klass.isupper() or self.klass in 'uvw' + return self.klass.isupper() or self.klass in "uvw" + def scope(self): if self.lib_re.search(self.target) is None: return self.target @@ -40,28 +62,29 @@ class SymRow(SymRowBase): return None def is_export(self): - ''' + """ FRR-specific list of symbols which are considered "externally used" e.g. hooks are by design APIs for external use, same for qobj_t_* frr_inet_ntop is here because it's used through an ELF alias to "inet_ntop()" - ''' - if self.name in ['main', 'frr_inet_ntop', '_libfrr_version']: + """ + if self.name in ["main", "frr_inet_ntop", "_libfrr_version"]: return True - if self.name.startswith('_hook_'): + if self.name.startswith("_hook_"): return True - if self.name.startswith('qobj_t_'): + if self.name.startswith("qobj_t_"): return True return False + class Symbols(dict): - ''' + """ dict of all symbols in all libs & executables - ''' + """ - from_re = re.compile(r'^Symbols from (.*?):$') - lt_re = re.compile(r'^(.*/)([^/]+)\.l[oa]$') + from_re = re.compile(r"^Symbols from (.*?):$") + lt_re = re.compile(r"^(.*/)([^/]+)\.l[oa]$") def __init__(self): super().__init__() @@ -69,26 +92,35 @@ class Symbols(dict): class ReportSym(object): def __init__(self, sym): self.sym = sym + def __repr__(self): - return '<%-25s %-40s [%s]>' % (self.__class__.__name__ + ':', self.sym.name, self.sym.loc) + return "<%-25s %-40s [%s]>" % ( + self.__class__.__name__ + ":", + self.sym.name, + self.sym.loc, + ) + def __lt__(self, other): return self.sym.name.__lt__(other.sym.name) class ReportSymCouldBeStaticAlreadyLocal(ReportSym): - idshort = 'Z' - idlong = 'extrastatic' + idshort = "Z" + idlong = "extrastatic" title = "symbol is local to library, but only used in its source file (make static?)" + class ReportSymCouldBeStatic(ReportSym): - idshort = 'S' - idlong = 'static' + idshort = "S" + idlong = "static" title = "symbol is only used in its source file (make static?)" + class ReportSymCouldBeLibLocal(ReportSym): - idshort = 'L' - idlong = 'liblocal' + idshort = "L" + idlong = "liblocal" title = "symbol is only used inside of library" + class ReportSymModuleAPI(ReportSym): - idshort = 'A' - idlong = 'api' + idshort = "A" + idlong = "api" title = "symbol (in executable) is referenced externally from a module" class Symbol(object): @@ -100,31 +132,38 @@ class Symbols(dict): def process(self, row): scope = row.scope() - if row.section == '*UND*': + if row.section == "*UND*": self.refs.append(row) else: self.defs.setdefault(scope, []).append(row) def evaluate(self, out): - ''' + """ generate output report invoked after all object files have been read in, so it can look at inter-object-file relationships - ''' + """ if len(self.defs) == 0: out.extsyms.add(self.name) return for scopename, symdefs in self.defs.items(): - common_defs = [symdef for symdef in symdefs if symdef.section == '*COM*'] - proper_defs = [symdef for symdef in symdefs if symdef.section != '*COM*'] + common_defs = [ + symdef for symdef in symdefs if symdef.section == "*COM*" + ] + proper_defs = [ + symdef for symdef in symdefs if symdef.section != "*COM*" + ] if len(proper_defs) > 1: - print(self.name, ' DUPLICATE') - print('\tD: %s %s' % (scopename, '\n\t\t'.join([repr(s) for s in symdefs]))) + print(self.name, " DUPLICATE") + print( + "\tD: %s %s" + % (scopename, "\n\t\t".join([repr(s) for s in symdefs])) + ) for syms in self.refs: - print('\tR: %s' % (syms, )) + print("\tR: %s" % (syms,)) return if len(proper_defs): @@ -140,7 +179,9 @@ class Symbols(dict): if scopename is not None and len(self.refs) > 0: for ref in self.refs: - if ref.target != primary_def.target and ref.target.endswith('.la'): + if ref.target != primary_def.target and ref.target.endswith( + ".la" + ): outobj = out.report.setdefault(primary_def.object, []) outobj.append(out.ReportSymModuleAPI(primary_def)) break @@ -152,7 +193,9 @@ class Symbols(dict): if primary_def.visible: outobj.append(out.ReportSymCouldBeStatic(primary_def)) else: - outobj.append(out.ReportSymCouldBeStaticAlreadyLocal(primary_def)) + outobj.append( + out.ReportSymCouldBeStaticAlreadyLocal(primary_def) + ) continue if scopename is None and primary_def.visible: @@ -164,7 +207,6 @@ class Symbols(dict): outobj = out.report.setdefault(primary_def.object, []) outobj.append(out.ReportSymCouldBeLibLocal(primary_def)) - def evaluate(self): self.extsyms = set() self.report = {} @@ -177,14 +219,14 @@ class Symbols(dict): m = self.lt_re.match(fn) if m is None: return fn - return m.group(1) + '.libs/' + m.group(2) + '.o' + return m.group(1) + ".libs/" + m.group(2) + ".o" def libtooltargetmustdie(fn): m = self.lt_re.match(fn) if m is None: - a, b = fn.rsplit('/', 1) - return '%s/.libs/%s' % (a, b) - return m.group(1) + '.libs/' + m.group(2) + '.so' + a, b = fn.rsplit("/", 1) + return "%s/.libs/%s" % (a, b) + return m.group(1) + ".libs/" + m.group(2) + ".so" files = list(set([libtoolmustdie(fn) for fn in files])) @@ -192,30 +234,30 @@ class Symbols(dict): filename = None path_rel_to = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - for line in text.split('\n'): - if line.strip() == '': + for line in text.split("\n"): + if line.strip() == "": continue m = self.from_re.match(line) if m is not None: filename = m.group(1) continue - if line.startswith('Name'): + if line.startswith("Name"): continue - items = [i.strip() for i in line.split('|')] + items = [i.strip() for i in line.split("|")] loc = None - if '\t' in items[-1]: - items[-1], loc = items[-1].split('\t', 1) - fn, lno = loc.rsplit(':', 1) + if "\t" in items[-1]: + items[-1], loc = items[-1].split("\t", 1) + fn, lno = loc.rsplit(":", 1) fn = os.path.relpath(fn, path_rel_to) - loc = '%s:%s' % (fn, lno) + loc = "%s:%s" % (fn, lno) - items[1] = int(items[1] if items[1] != '' else '0', 16) - items[4] = int(items[4] if items[4] != '' else '0', 16) + items[1] = int(items[1] if items[1] != "" else "0", 16) + items[4] = int(items[4] if items[4] != "" else "0", 16) items.append(loc) row = SymRow(target, filename, *items) - if row.section == '.group' or row.name == '_GLOBAL_OFFSET_TABLE_': + if row.section == ".group" or row.name == "_GLOBAL_OFFSET_TABLE_": continue if not row.is_global(): continue @@ -230,14 +272,19 @@ class Symbols(dict): # in the linked result (this covers ELF "hidden"/"internal" linkage) libfile = libtooltargetmustdie(target) - nmlib = subprocess.Popen(['nm', '-l', '-g', '--defined-only', '-f', 'sysv', libfile], stdout = subprocess.PIPE) - out = nmlib.communicate()[0].decode('US-ASCII') + nmlib = subprocess.Popen( + ["nm", "-l", "-g", "--defined-only", "-f", "sysv", libfile], + stdout=subprocess.PIPE, + ) + out = nmlib.communicate()[0].decode("US-ASCII") for row in parse_nm_output(out): visible_syms.add(row.name) - nm = subprocess.Popen(['nm', '-l', '-f', 'sysv'] + files, stdout = subprocess.PIPE) - out = nm.communicate()[0].decode('US-ASCII') + nm = subprocess.Popen( + ["nm", "-l", "-f", "sysv"] + files, stdout=subprocess.PIPE + ) + out = nm.communicate()[0].decode("US-ASCII") for row in parse_nm_output(out): row.visible = row.name in visible_syms @@ -249,95 +296,111 @@ def write_html_report(syms): try: import jinja2 except ImportError: - sys.stderr.write('jinja2 could not be imported, not writing HTML report!\n') + sys.stderr.write("jinja2 could not be imported, not writing HTML report!\n") return self_path = os.path.dirname(os.path.abspath(__file__)) jenv = jinja2.Environment(loader=jinja2.FileSystemLoader(self_path)) - template = jenv.get_template('symalyzer.html') + template = jenv.get_template("symalyzer.html") dirgroups = {} for fn, reports in syms.report.items(): - dirname, filename = fn.replace('.libs/', '').rsplit('/', 1) + dirname, filename = fn.replace(".libs/", "").rsplit("/", 1) dirgroups.setdefault(dirname, {})[fn] = reports klasses = { - 'T': 'code / plain old regular function (Text)', - 'D': 'global variable, read-write, with nonzero initializer (Data)', - 'B': 'global variable, read-write, with zero initializer (BSS)', - 'C': 'global variable, read-write, with zero initializer (Common)', - 'R': 'global variable, read-only (Rodata)', + "T": "code / plain old regular function (Text)", + "D": "global variable, read-write, with nonzero initializer (Data)", + "B": "global variable, read-write, with zero initializer (BSS)", + "C": "global variable, read-write, with zero initializer (Common)", + "R": "global variable, read-only (Rodata)", } - with open('symalyzer_report.html.tmp', 'w') as fd: - fd.write(template.render(dirgroups = dirgroups, klasses = klasses)) - os.rename('symalyzer_report.html.tmp', 'symalyzer_report.html') + with open("symalyzer_report.html.tmp", "w") as fd: + fd.write(template.render(dirgroups=dirgroups, klasses=klasses)) + os.rename("symalyzer_report.html.tmp", "symalyzer_report.html") - if not os.path.exists('jquery-3.4.1.min.js'): - url = 'https://code.jquery.com/jquery-3.4.1.min.js' + if not os.path.exists("jquery-3.4.1.min.js"): + url = "https://code.jquery.com/jquery-3.4.1.min.js" sys.stderr.write( - 'trying to grab a copy of jquery from %s\nif this fails, please get it manually (the HTML output is done.)\n' % (url)) + "trying to grab a copy of jquery from %s\nif this fails, please get it manually (the HTML output is done.)\n" + % (url) + ) import requests - r = requests.get('https://code.jquery.com/jquery-3.4.1.min.js') + + r = requests.get("https://code.jquery.com/jquery-3.4.1.min.js") if r.status_code != 200: - sys.stderr.write('failed -- please download jquery-3.4.1.min.js and put it next to the HTML report\n') + sys.stderr.write( + "failed -- please download jquery-3.4.1.min.js and put it next to the HTML report\n" + ) else: - with open('jquery-3.4.1.min.js.tmp', 'w') as fd: + with open("jquery-3.4.1.min.js.tmp", "w") as fd: fd.write(r.text) - os.rename('jquery-3.4.1.min.js.tmp', 'jquery-3.4.1.min.js') - sys.stderr.write('done.\n') + os.rename("jquery-3.4.1.min.js.tmp", "jquery-3.4.1.min.js") + sys.stderr.write("done.\n") + def automake_escape(s): - return s.replace('.', '_').replace('/', '_') + return s.replace(".", "_").replace("/", "_") -if __name__ == '__main__': + +if __name__ == "__main__": mv = MakeVars() - if not (os.path.exists('config.version') and os.path.exists('lib/.libs/libfrr.so')): - sys.stderr.write('please execute this script in the root directory of an FRR build tree\n') - sys.stderr.write('./configure && make need to have completed successfully\n') + if not (os.path.exists("config.version") and os.path.exists("lib/.libs/libfrr.so")): + sys.stderr.write( + "please execute this script in the root directory of an FRR build tree\n" + ) + sys.stderr.write("./configure && make need to have completed successfully\n") sys.exit(1) - amtargets = ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES'] + amtargets = [ + "bin_PROGRAMS", + "sbin_PROGRAMS", + "lib_LTLIBRARIES", + "module_LTLIBRARIES", + ] targets = [] mv.getvars(amtargets) for amtarget in amtargets: - targets.extend([item for item in mv[amtarget].strip().split() if item != 'tools/ssd']) + targets.extend( + [item for item in mv[amtarget].strip().split() if item != "tools/ssd"] + ) - mv.getvars(['%s_LDADD' % automake_escape(t) for t in targets]) + mv.getvars(["%s_LDADD" % automake_escape(t) for t in targets]) ldobjs = targets[:] for t in targets: - ldadd = mv['%s_LDADD' % automake_escape(t)].strip().split() + ldadd = mv["%s_LDADD" % automake_escape(t)].strip().split() for item in ldadd: - if item.startswith('-'): + if item.startswith("-"): continue - if item.endswith('.a'): + if item.endswith(".a"): ldobjs.append(item) - mv.getvars(['%s_OBJECTS' % automake_escape(o) for o in ldobjs]) + mv.getvars(["%s_OBJECTS" % automake_escape(o) for o in ldobjs]) syms = Symbols() for t in targets: - objs = mv['%s_OBJECTS' % automake_escape(t)].strip().split() - ldadd = mv['%s_LDADD' % automake_escape(t)].strip().split() + objs = mv["%s_OBJECTS" % automake_escape(t)].strip().split() + ldadd = mv["%s_LDADD" % automake_escape(t)].strip().split() for item in ldadd: - if item.startswith('-'): + if item.startswith("-"): continue - if item.endswith('.a'): - objs.extend(mv['%s_OBJECTS' % automake_escape(item)].strip().split()) + if item.endswith(".a"): + objs.extend(mv["%s_OBJECTS" % automake_escape(item)].strip().split()) - sys.stderr.write('processing %s...\n' % t) + sys.stderr.write("processing %s...\n" % t) sys.stderr.flush() - #print(t, '\n\t', objs) + # print(t, '\n\t', objs) syms.load(t, objs) syms.evaluate() for obj, reports in sorted(syms.report.items()): - print('%s:' % obj) + print("%s:" % obj) for report in reports: - print('\t%r' % report) + print("\t%r" % report) write_html_report(syms) diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index d3f9b0c730..7728717e99 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -700,7 +700,6 @@ static int vrrp_master_down_timer_expire(struct thread *thread); */ static int vrrp_bind_to_primary_connected(struct vrrp_router *r) { - char ipstr[INET6_ADDRSTRLEN]; struct interface *ifp; /* @@ -754,20 +753,15 @@ static int vrrp_bind_to_primary_connected(struct vrrp_router *r) if (bind(r->sock_tx, (const struct sockaddr *)&su, sizeof(su)) < 0) { zlog_err( VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM - "Failed to bind Tx socket to primary IP address %s: %s", - r->vr->vrid, family2str(r->family), - inet_ntop(r->family, - (const void *)&c->address->u.prefix, ipstr, - sizeof(ipstr)), + "Failed to bind Tx socket to primary IP address %pFX: %s", + r->vr->vrid, family2str(r->family), c->address, safe_strerror(errno)); ret = -1; } else { DEBUGD(&vrrp_dbg_sock, VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM - "Bound Tx socket to primary IP address %s", - r->vr->vrid, family2str(r->family), - inet_ntop(r->family, (const void *)&c->address->u.prefix, - ipstr, sizeof(ipstr))); + "Bound Tx socket to primary IP address %pFX", + r->vr->vrid, family2str(r->family), c->address); } return ret; @@ -1717,7 +1711,6 @@ static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r) struct listnode *ln; struct connected *c = NULL; bool is_v6_ll; - char ipbuf[INET6_ADDRSTRLEN]; if (!r->mvl_ifp) return; @@ -1730,12 +1723,10 @@ static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r) is_v6_ll = (c->address->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6)); if (c->address->family == r->family && !is_v6_ll) { - inet_ntop(r->family, &c->address->u.prefix, ipbuf, - sizeof(ipbuf)); DEBUGD(&vrrp_dbg_auto, VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM - "Adding %s", - r->vr->vrid, family2str(r->family), ipbuf); + "Adding %pFX", + r->vr->vrid, family2str(r->family), c->address); if (r->family == AF_INET) vrrp_add_ipv4(r->vr, c->address->u.prefix4); else if (r->vr->version == 3) diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index 3165ea119a..7d9cea3adc 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -775,8 +775,8 @@ void vrrp_vty_init(void) install_element(VIEW_NODE, &vrrp_vrid_show_cmd); install_element(VIEW_NODE, &vrrp_vrid_show_summary_cmd); - install_element(VIEW_NODE, &show_debugging_vrrp_cmd); - install_element(VIEW_NODE, &debug_vrrp_cmd); + install_element(ENABLE_NODE, &show_debugging_vrrp_cmd); + install_element(ENABLE_NODE, &debug_vrrp_cmd); install_element(CONFIG_NODE, &debug_vrrp_cmd); install_element(CONFIG_NODE, &vrrp_autoconfigure_cmd); install_element(CONFIG_NODE, &vrrp_default_cmd); diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c index a578921df6..37a1e4a624 100644 --- a/vrrpd/vrrp_zebra.c +++ b/vrrpd/vrrp_zebra.c @@ -56,8 +56,8 @@ static void vrrp_zebra_debug_if_dump_address(struct interface *ifp, for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { struct prefix *p = ifc->address; - DEBUGD(&vrrp_dbg_zebra, "%s: interface %s address %s %s", func, - ifp->name, inet_ntoa(p->u.prefix4), + DEBUGD(&vrrp_dbg_zebra, "%s: interface %s address %pFX %s", + func, ifp->name, p, CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); } diff --git a/vtysh/.gitignore b/vtysh/.gitignore index c1a39b8a12..118b84407b 100644 --- a/vtysh/.gitignore +++ b/vtysh/.gitignore @@ -1,3 +1,4 @@ vtysh vtysh_cmd.c extract.pl +vtysh_daemons.h diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 63610a3287..8a1e71a37d 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -40,7 +40,6 @@ #include "vtysh/vtysh.h" #include "vtysh/vtysh_daemons.h" #include "log.h" -#include "bgpd/bgp_vty.h" #include "ns.h" #include "vrf.h" #include "libfrr.h" @@ -1773,6 +1772,24 @@ DEFUNSH(VTYSH_BGPD, vnc_l2_group, vnc_l2_group_cmd, "vnc l2-group NAME", vty->node = BGP_VNC_L2_GROUP_NODE; return CMD_SUCCESS; } + +DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc", + "Exit from VNC configuration mode\n") +{ + if (vty->node == BGP_VNC_DEFAULTS_NODE + || vty->node == BGP_VNC_NVE_GROUP_NODE + || vty->node == BGP_VNC_L2_GROUP_NODE) + vty->node = BGP_NODE; + return CMD_SUCCESS; +} + +DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy", + "Exit from VRF policy configuration mode\n") +{ + if (vty->node == BGP_VRF_POLICY_NODE) + vty->node = BGP_NODE; + return CMD_SUCCESS; +} #endif #endif /* HAVE_BGPD */ @@ -2106,17 +2123,6 @@ DEFUNSH(VTYSH_BGPD, exit_vni, exit_vni_cmd, "exit-vni", "Exit from VNI mode\n") return CMD_SUCCESS; } -DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc", - "Exit from VNC configuration mode\n") -{ - if (vty->node == BGP_VNC_DEFAULTS_NODE - || vty->node == BGP_VNC_NVE_GROUP_NODE - || vty->node == BGP_VNC_L2_GROUP_NODE) - vty->node = BGP_NODE; - return CMD_SUCCESS; - -} - DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit", "Exit current mode and down to previous mode\n") { @@ -2142,14 +2148,6 @@ DEFUNSH(VTYSH_BGPD, bmp_quit, bmp_quit_cmd, "quit", { return bmp_exit(self, vty, argc, argv); } - -DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy", - "Exit from VRF policy configuration mode\n") -{ - if (vty->node == BGP_VRF_POLICY_NODE) - vty->node = BGP_NODE; - return CMD_SUCCESS; -} #endif /* HAVE_BGPD */ DEFUNSH(VTYSH_VRF, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf", @@ -4272,9 +4270,9 @@ void vtysh_init_vty(void) #endif /* debugging */ - install_element(VIEW_NODE, &vtysh_show_debugging_cmd); install_element(VIEW_NODE, &vtysh_show_error_code_cmd); - install_element(VIEW_NODE, &vtysh_show_debugging_hashtable_cmd); + install_element(ENABLE_NODE, &vtysh_show_debugging_cmd); + install_element(ENABLE_NODE, &vtysh_show_debugging_hashtable_cmd); install_element(ENABLE_NODE, &vtysh_debug_all_cmd); install_element(CONFIG_NODE, &vtysh_debug_all_cmd); install_element(ENABLE_NODE, &vtysh_debug_memstats_cmd); diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index d1003ad5fa..319bd6a771 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -409,8 +409,8 @@ static void sigchild(void) what = restart->what; restart->pid = 0; gs.numpids--; - thread_cancel(restart->t_kill); - restart->t_kill = NULL; + thread_cancel(&restart->t_kill); + /* Update restart time to reflect the time the command * completed. */ gettimeofday(&restart->time, NULL); @@ -585,8 +585,8 @@ static void restart_done(struct daemon *dmn) dmn->name, state_str[dmn->state]); return; } - if (dmn->t_wakeup) - THREAD_OFF(dmn->t_wakeup); + THREAD_OFF(dmn->t_wakeup); + if (try_connect(dmn) < 0) SET_WAKEUP_DOWN(dmn); } @@ -679,8 +679,7 @@ static int handle_read(struct thread *t_read) dmn->name, (long)delay.tv_sec, (long)delay.tv_usec); SET_READ_HANDLER(dmn); - if (dmn->t_wakeup) - thread_cancel(dmn->t_wakeup); + thread_cancel(&dmn->t_wakeup); SET_WAKEUP_ECHO(dmn); return 0; @@ -867,9 +866,8 @@ static int phase_hanging(struct thread *t_hanging) static void set_phase(restart_phase_t new_phase) { gs.phase = new_phase; - if (gs.t_phase_hanging) - thread_cancel(gs.t_phase_hanging); - gs.t_phase_hanging = NULL; + thread_cancel(&gs.t_phase_hanging); + thread_add_timer(master, phase_hanging, NULL, PHASE_TIMEOUT, &gs.t_phase_hanging); } diff --git a/yang/embedmodel.py b/yang/embedmodel.py index 0a25c93da7..39bf2bb922 100644 --- a/yang/embedmodel.py +++ b/yang/embedmodel.py @@ -19,13 +19,13 @@ if not os.path.isdir(outdir): # or python-yang. Cross-compiling FRR is already somewhat involved, no need # to make it even harder. -re_name = re.compile(r'\bmodule\s+([^\s]+)\s+\{') -re_subname = re.compile(r'\bsubmodule\s+([^\s]+)\s+\{') -re_mainname = re.compile(r'\bbelongs-to\s+([^\s]+)\s+\{') -re_rev = re.compile(r'\brevision\s+([\d-]+)\s+\{') +re_name = re.compile(r"\bmodule\s+([^\s]+)\s+\{") +re_subname = re.compile(r"\bsubmodule\s+([^\s]+)\s+\{") +re_mainname = re.compile(r"\bbelongs-to\s+([^\s]+)\s+\{") +re_rev = re.compile(r"\brevision\s+([\d-]+)\s+\{") -template = '''/* autogenerated by embedmodel.py. DO NOT EDIT */ +template = """/* autogenerated by embedmodel.py. DO NOT EDIT */ #include <zebra.h> #include "yang.h" @@ -47,23 +47,28 @@ static void embed_register(void) { \tyang_module_embed(&embed); } -''' +""" + +passchars = set(string.printable) - set("\\'\"%\r\n\t\x0b\x0c") + -passchars = set(string.printable) - set('\\\'"%\r\n\t\x0b\x0c') def escapech(char): if char in passchars: return char - if char == '\n': - return '\\n' - if char == '\t': - return '\\t' - if char in '"\\\'': - return '\\' + char - return '\\x%02x' % (ord(char)) + if char == "\n": + return "\\n" + if char == "\t": + return "\\t" + if char in "\"\\'": + return "\\" + char + return "\\x%02x" % (ord(char)) + + def escape(line): - return ''.join([escapech(i) for i in line]) + return "".join([escapech(i) for i in line]) + -with open(inname, 'r') as fd: +with open(inname, "r") as fd: data = fd.read() sub_name = "" @@ -72,29 +77,33 @@ sub_rev = "" # XML support isn't actively used currently, but it's here in case the need # arises. It does avoid the regex'ing. -if '<?xml' in data: +if "<?xml" in data: from xml.etree import ElementTree + xml = ElementTree.fromstring(data) - name = xml.get('name') - rev = xml.find('{urn:ietf:params:xml:ns:yang:yin:1}revision').get('date') - fmt = 'LYS_YIN' + name = xml.get("name") + rev = xml.find("{urn:ietf:params:xml:ns:yang:yin:1}revision").get("date") + fmt = "LYS_YIN" else: search_name = re_name.search(data) - if search_name : - name = search_name.group(1) - rev = re_rev.search(data).group(1) - else : - search_name = re_subname.search(data) - sub_name = search_name.group(1) - name = re_mainname.search(data).group(1) - sub_rev = re_rev.search(data).group(1) - fmt = 'LYS_YANG' + if search_name: + name = search_name.group(1) + rev = re_rev.search(data).group(1) + else: + search_name = re_subname.search(data) + sub_name = search_name.group(1) + name = re_mainname.search(data).group(1) + sub_rev = re_rev.search(data).group(1) + fmt = "LYS_YANG" if name is None or rev is None: - raise ValueError('cannot determine YANG module name and revision') + raise ValueError("cannot determine YANG module name and revision") -lines = [escape(row) for row in data.split('\n')] +lines = [escape(row) for row in data.split("\n")] text = '\\n"\n\t"'.join(lines) -with open(outname, 'w') as fd: - fd.write(template % (text, escape(name), escape(rev), escape(sub_name), escape(sub_rev), fmt)) +with open(outname, "w") as fd: + fd.write( + template + % (text, escape(name), escape(rev), escape(sub_name), escape(sub_rev), fmt) + ) diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang index 96ec9dc969..de78758dbb 100644 --- a/yang/frr-bgp-common.yang +++ b/yang/frr-bgp-common.yang @@ -195,7 +195,7 @@ submodule frr-bgp-common { leaf external-compare-router-id { type boolean; - default "true"; + default "false"; description "When comparing similar routes received from external BGP peers, use the router-id as a criterion to select the @@ -779,6 +779,48 @@ submodule frr-bgp-common { description "Apply route map to aggregate network."; } + + leaf origin { + type enumeration { + enum "igp" { + value 0; + description + "Local IGP."; + } + enum "egp" { + value 1; + description + "Remote EGP."; + } + enum "incomplete" { + value 2; + description + "Unknown heritage."; + } + enum "unspecified" { + value 255; + description + "Unspecified."; + } + } + default "unspecified"; + description + "BGP origin type."; + } + + leaf match-med { + type boolean; + default "false"; + description + "When set to 'true' aggregate-route matches only + med."; + } + + leaf suppress-map { + type string; + description + "Suppress more specific routes specified in route-map."; + } } grouping admin-distance { @@ -791,6 +833,7 @@ submodule frr-bgp-common { type uint8 { range "1..255"; } + default "20"; description "Administrative distance for routes learned from external BGP (EBGP)."; @@ -800,6 +843,7 @@ submodule frr-bgp-common { type uint8 { range "1..255"; } + default "200"; description "Administrative distance for routes learned from internal BGP (IBGP)."; @@ -809,6 +853,7 @@ submodule frr-bgp-common { type uint8 { range "1..255"; } + default "200"; description "Administrative distance for routes learned from local."; @@ -1017,6 +1062,7 @@ submodule frr-bgp-common { case import-export { uses rt-list; } + case both { leaf-list rt-list { type rt-types:route-target; @@ -1064,7 +1110,11 @@ submodule frr-bgp-common { grouping global-afi-safi-vpn-config { container vpn-config { - uses route-distinguisher-params; + leaf rd { + type string; + description + "Route distinguisher value as per RFC4364."; + } uses vpn-label-params; diff --git a/yang/frr-bgp.yang b/yang/frr-bgp.yang index 3e5b1da7d3..820c4b2861 100644 --- a/yang/frr-bgp.yang +++ b/yang/frr-bgp.yang @@ -90,10 +90,10 @@ module frr-bgp { "BGP protocol augmentation of ietf-routing module control-plane-protocol."; } + presence "Enables configuration of BGP"; description "Top-level configuration for the BGP router."; container global { - presence "Enables global configuration of BGP"; description "Global configuration for the BGP router."; leaf local-as { @@ -353,6 +353,8 @@ module frr-bgp { uses distance-per-route-config; } + uses route-flap-dampening; + uses mp-afi-unicast-common; uses global-filter-config; @@ -362,10 +364,14 @@ module frr-bgp { augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast" { uses global-group-use-multiple-paths; + + uses route-flap-dampening; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast" { uses global-group-use-multiple-paths; + + uses route-flap-dampening; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv4-multicast" { @@ -411,6 +417,8 @@ module frr-bgp { description "IPv4 multicast destination prefix."; } + + uses distance-per-route-config; } uses admin-distance; @@ -463,8 +471,12 @@ module frr-bgp { description "IPv6 multicast destination prefix."; } + + uses distance-per-route-config; } + uses route-flap-dampening; + uses admin-distance; } diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang index 1e44c2569e..400a093178 100644 --- a/yang/frr-filter.yang +++ b/yang/frr-filter.yang @@ -158,9 +158,17 @@ module frr-filter { description "Host to match"; type inet:ipv4-address; } - leaf network { - description "Network to match"; - type inet:ipv4-prefix; + container network { + leaf address { + mandatory true; + description "Network address part."; + type inet:ipv4-address; + } + leaf mask { + mandatory true; + description "Network mask/wildcard part."; + type inet:ipv4-address; + } } leaf source-any { /* @@ -178,9 +186,17 @@ module frr-filter { description "Host to match"; type inet:ipv4-address; } - leaf destination-network { - description "Network to match"; - type inet:ipv4-prefix; + container destination-network { + leaf address { + mandatory true; + description "Network address part."; + type inet:ipv4-address; + } + leaf mask { + mandatory true; + description "Network mask/wildcard part."; + type inet:ipv4-address; + } } leaf destination-any { description "Match any"; diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index 79941a50e7..c3b39e3750 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -336,6 +336,26 @@ module frr-isisd { } } + grouping interface-config-ti-lfa { + container ti-lfa { + description + "TI-LFA configuration."; + leaf enable { + type boolean; + default false; + description + "Enables TI-LFA computation."; + } + leaf node-protection { + type boolean; + must ". = 'false' or ../enable = 'true'"; + default false; + description + "Node protection is provided by the alternate."; + } + } + } + grouping interface-config { description "Interface configuration grouping"; @@ -638,6 +658,20 @@ module frr-isisd { } } + container fast-reroute { + description + "Interface IP Fast-reroute configuration."; + container level-1 { + description + "Level-1 IP Fast-reroute configuration."; + uses interface-config-ti-lfa; + } + container level-2 { + description + "Level-2 IP Fast-reroute configuration."; + uses interface-config-ti-lfa; + } + } } grouping adjacency-state { @@ -1347,6 +1381,12 @@ module frr-isisd { description "Configure last hop behavior."; } + leaf n-flag-clear { + type boolean; + default "false"; + description + "Not a node SID"; + } } } } diff --git a/yang/frr-nexthop.yang b/yang/frr-nexthop.yang index 52155dcd16..619514de7d 100644 --- a/yang/frr-nexthop.yang +++ b/yang/frr-nexthop.yang @@ -275,7 +275,7 @@ module frr-nexthop { description "List of nexthop groups, each contains group of nexthops"; leaf name { - type nexthop-group-ref; + type string; description "The nexthop-group name."; } diff --git a/yang/frr-route-types.yang b/yang/frr-route-types.yang index 057c32a7e7..5a0f58071f 100644 --- a/yang/frr-route-types.yang +++ b/yang/frr-route-types.yang @@ -76,6 +76,9 @@ module frr-route-types { enum vnc { value 17; } + enum vnc-direct { + value 18; + } enum babel { value 22; } @@ -120,6 +123,9 @@ module frr-route-types { enum vnc { value 17; } + enum vnc-direct { + value 18; + } enum babel { value 22; } diff --git a/yang/subdir.am b/yang/subdir.am index 6aae0e4701..5be93dc4e9 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -30,6 +30,7 @@ dist_yangmodels_DATA += yang/frr-route-types.yang dist_yangmodels_DATA += yang/frr-routing.yang dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang dist_yangmodels_DATA += yang/ietf/ietf-interfaces.yang +dist_yangmodels_DATA += yang/ietf/ietf-bgp-types.yang if BFDD dist_yangmodels_DATA += yang/frr-bfdd.yang @@ -68,3 +69,16 @@ dist_yangmodels_DATA += yang/frr-igmp.yang dist_yangmodels_DATA += yang/frr-pim.yang dist_yangmodels_DATA += yang/frr-pim-rp.yang endif + +if BGPD +dist_yangmodels_DATA += yang/frr-bgp-common-structure.yang +dist_yangmodels_DATA += yang/frr-bgp-common.yang +dist_yangmodels_DATA += yang/frr-bgp-common-multiprotocol.yang +dist_yangmodels_DATA += yang/frr-bgp-neighbor.yang +dist_yangmodels_DATA += yang/frr-bgp-peer-group.yang +dist_yangmodels_DATA += yang/frr-deviations-bgp-datacenter.yang +dist_yangmodels_DATA += yang/frr-bgp-rpki.yang +dist_yangmodels_DATA += yang/frr-bgp-bmp.yang +dist_yangmodels_DATA += yang/frr-bgp-types.yang +dist_yangmodels_DATA += yang/frr-bgp.yang +endif diff --git a/zebra/connected.c b/zebra/connected.c index 8c4ba163bd..6a1efc3e65 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -259,14 +259,10 @@ void connected_up(struct interface *ifp, struct connected *ifc) /* Schedule LSP forwarding entries for processing, if appropriate. */ if (zvrf->vrf->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) { - char buf[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_MPLS) zlog_debug( - "%u: IF %s IP %s address add/up, scheduling MPLS processing", - zvrf->vrf->vrf_id, ifp->name, - prefix2str(&p, buf, sizeof(buf))); - } + "%u: IF %s IP %pFX address add/up, scheduling MPLS processing", + zvrf->vrf->vrf_id, ifp->name, &p); mpls_mark_lsps_for_processing(zvrf, &p); } } @@ -312,8 +308,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, if (IPV4_ADDR_SAME(addr, dest)) flog_warn( EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER, - "warning: interface %s has same local and peer address %s, routing protocols may malfunction", - ifp->name, inet_ntoa(*addr)); + "warning: interface %s has same local and peer address %pI4, routing protocols may malfunction", + ifp->name, addr); } else { zlog_debug( "warning: %s called for interface %s with peer flag set, but no peer address supplied", @@ -326,8 +322,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, if (!dest && (prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) zlog_debug( - "warning: PtP interface %s with addr %s/%d needs a peer address", - ifp->name, inet_ntoa(*addr), prefixlen); + "warning: PtP interface %s with addr %pI4/%d needs a peer address", + ifp->name, addr, prefixlen); /* Label of this address. */ if (label) @@ -400,14 +396,10 @@ void connected_down(struct interface *ifp, struct connected *ifc) /* Schedule LSP forwarding entries for processing, if appropriate. */ if (zvrf->vrf->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) { - char buf[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_MPLS) zlog_debug( - "%u: IF %s IP %s address down, scheduling MPLS processing", - zvrf->vrf->vrf_id, ifp->name, - prefix2str(&p, buf, sizeof(buf))); - } + "%u: IF %s IP %pFX address down, scheduling MPLS processing", + zvrf->vrf->vrf_id, ifp->name, &p); mpls_mark_lsps_for_processing(zvrf, &p); } } @@ -424,14 +416,10 @@ static void connected_delete_helper(struct connected *ifc, struct prefix *p) /* Schedule LSP forwarding entries for processing, if appropriate. */ if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) { - char buf[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_MPLS) zlog_debug( - "%u: IF %s IP %s address delete, scheduling MPLS processing", - ifp->vrf_id, ifp->name, - prefix2str(p, buf, sizeof(buf))); - } + "%u: IF %s IP %pFX address delete, scheduling MPLS processing", + ifp->vrf_id, ifp->name, p); mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p); } } diff --git a/zebra/debug.c b/zebra/debug.c index 8c53ab73e4..87a10ea65d 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -671,7 +671,7 @@ void zebra_debug_init(void) install_node(&debug_node); - install_element(VIEW_NODE, &show_debugging_zebra_cmd); + install_element(ENABLE_NODE, &show_debugging_zebra_cmd); install_element(ENABLE_NODE, &debug_zebra_events_cmd); install_element(ENABLE_NODE, &debug_zebra_nht_cmd); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 90a08bbd6c..a68873882d 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -691,6 +691,36 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id, return 0; } +/* If the interface is and es bond member then it must follow EVPN's + * protodown setting + */ +static void netlink_proc_dplane_if_protodown(struct zebra_if *zif, + bool protodown) +{ + bool zif_protodown; + + zif_protodown = !!(zif->flags & ZIF_FLAG_PROTODOWN); + if (protodown == zif_protodown) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("interface %s dplane change, protdown %s", + zif->ifp->name, protodown ? "on" : "off"); + + if (zebra_evpn_is_es_bond_member(zif->ifp)) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug( + "bond mbr %s re-instate protdown %s in the dplane", + zif->ifp->name, zif_protodown ? "on" : "off"); + netlink_protodown(zif->ifp, zif_protodown); + } else { + if (protodown) + zif->flags |= ZIF_FLAG_PROTODOWN; + else + zif->flags &= ~ZIF_FLAG_PROTODOWN; + } +} + /* * Called from interface_lookup_netlink(). This function is only used * during bootstrap. @@ -849,11 +879,20 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) */ netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA], 1, link_nsid); + if (IS_ZEBRA_IF_BOND(ifp)) + zebra_l2if_update_bond(ifp, true); if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id); else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) zebra_l2if_update_bond_slave(ifp, bond_ifindex); + if (tb[IFLA_PROTO_DOWN]) { + uint8_t protodown; + + protodown = *(uint8_t *)RTA_DATA(tb[IFLA_PROTO_DOWN]); + netlink_proc_dplane_if_protodown(zif, !!protodown); + } + return 0; } @@ -1284,6 +1323,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) uint8_t old_hw_addr[INTERFACE_HWADDR_MAX]; struct zebra_if *zif; ns_id_t link_nsid = ns_id; + ifindex_t master_infindex = IFINDEX_INTERNAL; zns = zebra_ns_lookup(ns_id); ifi = NLMSG_DATA(h); @@ -1373,16 +1413,17 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (slave_kind && (strcmp(slave_kind, "vrf") == 0) && !vrf_is_backend_netns()) { zif_slave_type = ZEBRA_IF_SLAVE_VRF; - vrf_id = *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]); + master_infindex = vrf_id = + *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]); } else if (slave_kind && (strcmp(slave_kind, "bridge") == 0)) { zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE; - bridge_ifindex = + master_infindex = bridge_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); } else if (slave_kind && (strcmp(slave_kind, "bond") == 0)) { zif_slave_type = ZEBRA_IF_SLAVE_BOND; - bond_ifindex = + master_infindex = bond_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); } else zif_slave_type = ZEBRA_IF_SLAVE_OTHER; @@ -1396,7 +1437,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) zlog_debug( "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u flags 0x%x", name, ifi->ifi_index, vrf_id, zif_type, - zif_slave_type, bridge_ifindex, + zif_slave_type, master_infindex, ifi->ifi_flags); if (ifp == NULL) { @@ -1446,6 +1487,15 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) ns_id); else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) zebra_l2if_update_bond_slave(ifp, bond_ifindex); + + if (tb[IFLA_PROTO_DOWN]) { + uint8_t protodown; + + protodown = *(uint8_t *)RTA_DATA( + tb[IFLA_PROTO_DOWN]); + netlink_proc_dplane_if_protodown(ifp->info, + !!protodown); + } } else if (ifp->vrf_id != vrf_id) { /* VRF change for an interface. */ if (IS_ZEBRA_DEBUG_KERNEL) @@ -1463,7 +1513,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) zlog_debug( "RTM_NEWLINK update for %s(%u) sl_type %d master %u flags 0x%x", name, ifp->ifindex, zif_slave_type, - bridge_ifindex, ifi->ifi_flags); + master_infindex, ifi->ifi_flags); set_ifindex(ifp, ifi->ifi_index, zns); if (!tb[IFLA_MTU]) { @@ -1542,12 +1592,23 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) netlink_interface_update_l2info( ifp, linkinfo[IFLA_INFO_DATA], 0, link_nsid); + if (IS_ZEBRA_IF_BOND(ifp)) + zebra_l2if_update_bond(ifp, true); if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id); else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave) zebra_l2if_update_bond_slave(ifp, bond_ifindex); + + if (tb[IFLA_PROTO_DOWN]) { + uint8_t protodown; + + protodown = *(uint8_t *)RTA_DATA( + tb[IFLA_PROTO_DOWN]); + netlink_proc_dplane_if_protodown(ifp->info, + !!protodown); + } } zif = ifp->info; @@ -1572,6 +1633,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); + if (IS_ZEBRA_IF_BOND(ifp)) + zebra_l2if_update_bond(ifp, false); /* Special handling for bridge or VxLAN interfaces. */ if (IS_ZEBRA_IF_BRIDGE(ifp)) zebra_l2_bridge_del(ifp); diff --git a/zebra/interface.c b/zebra/interface.c index 3210855801..ddad9c9e56 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1069,6 +1069,9 @@ void if_up(struct interface *ifp) if (zif->es_info.es) zebra_evpn_es_if_oper_state_change(zif, true /*up*/); + + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) + zebra_evpn_mh_uplink_oper_update(zif); } /* Interface goes down. We have to manage different behavior of based @@ -1106,6 +1109,9 @@ void if_down(struct interface *ifp) if (zif->es_info.es) zebra_evpn_es_if_oper_state_change(zif, false /*up*/); + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) + zebra_evpn_mh_uplink_oper_update(zif); + /* Notify to the protocol daemons. */ zebra_interface_down_update(ifp); @@ -1156,6 +1162,18 @@ void zebra_if_update_all_links(void) if (!ifp) continue; zif = ifp->info; + /* update bond-member to bond linkages */ + if ((IS_ZEBRA_IF_BOND_SLAVE(ifp)) + && (zif->bondslave_info.bond_ifindex != IFINDEX_INTERNAL) + && !zif->bondslave_info.bond_if) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("bond mbr %s map to bond %d", + zif->ifp->name, + zif->bondslave_info.bond_ifindex); + zebra_l2_map_slave_to_bond(zif, ifp->vrf_id); + } + + /* update SVI linkages */ if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) { zif->link = if_lookup_by_index_per_ns(ns, zif->link_ifindex); @@ -1296,8 +1314,6 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf) bool print_header = true; FOR_ALL_INTERFACES (vrf, ifp) { - char global_pfx[PREFIX_STRLEN] = {0}; - char buf[PREFIX_STRLEN] = {0}; bool first_pfx_printed = false; if (print_header) { @@ -1329,17 +1345,17 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf) if (!CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY)) { p = connected->address; - prefix2str(p, buf, sizeof(buf)); if (first_pfx_printed) { - /* padding to prepare row only for ip addr */ + /* padding to prepare row only + * for ip addr */ vty_out(vty, "%-40s", ""); if (list_size > 1) vty_out(vty, "+ "); - vty_out(vty, "%s\n", buf); + vty_out(vty, "%pFX\n", p); } else { if (list_size > 1) vty_out(vty, "+ "); - vty_out(vty, "%s\n", buf); + vty_out(vty, "%pFX\n", p); } first_pfx_printed = true; break; @@ -1361,17 +1377,17 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf) p = connected->address; /* Don't print link local pfx */ if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) { - prefix2str(p, global_pfx, PREFIX_STRLEN); if (first_pfx_printed) { - /* padding to prepare row only for ip addr */ + /* padding to prepare row only + * for ip addr */ vty_out(vty, "%-40s", ""); if (v6_list_size > 1) vty_out(vty, "+ "); - vty_out(vty, "%s\n", global_pfx); + vty_out(vty, "%pFX\n", p); } else { if (v6_list_size > 1) vty_out(vty, "+ "); - vty_out(vty, "%s\n", global_pfx); + vty_out(vty, "%pFX\n", p); } first_pfx_printed = true; break; @@ -1384,6 +1400,34 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf) vty_out(vty, "\n"); } +const char *zebra_protodown_rc_str(enum protodown_reasons protodown_rc, + char *pd_buf, uint32_t pd_buf_len) +{ + bool first = true; + + pd_buf[0] = '\0'; + + strlcat(pd_buf, "(", pd_buf_len); + + if (protodown_rc & ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY) { + if (first) + first = false; + else + strlcat(pd_buf, ",", pd_buf_len); + strlcat(pd_buf, "startup-delay", pd_buf_len); + } + + if (protodown_rc & ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN) { + if (!first) + strlcat(pd_buf, ",", pd_buf_len); + strlcat(pd_buf, "uplinks-down", pd_buf_len); + } + + strlcat(pd_buf, ")", pd_buf_len); + + return pd_buf; +} + /* Interface's information print out to vty interface. */ static void if_dump_vty(struct vty *vty, struct interface *ifp) { @@ -1393,6 +1437,7 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) struct route_node *rn; struct zebra_if *zebra_if; struct vrf *vrf; + char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN]; zebra_if = ifp->info; @@ -1496,14 +1541,14 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) vxlan_info = &zebra_if->l2info.vxl; vty_out(vty, " VxLAN Id %u", vxlan_info->vni); if (vxlan_info->vtep_ip.s_addr != INADDR_ANY) - vty_out(vty, " VTEP IP: %s", - inet_ntoa(vxlan_info->vtep_ip)); + vty_out(vty, " VTEP IP: %pI4", + &vxlan_info->vtep_ip); if (vxlan_info->access_vlan) vty_out(vty, " Access VLAN Id %u\n", vxlan_info->access_vlan); if (vxlan_info->mcast_grp.s_addr != INADDR_ANY) - vty_out(vty, " Mcast Group %s", - inet_ntoa(vxlan_info->mcast_grp)); + vty_out(vty, " Mcast Group %pI4", + &vxlan_info->mcast_grp); if (vxlan_info->ifindex_link && (vxlan_info->link_nsid != NS_UNKNOWN)) { struct interface *ifp; @@ -1547,6 +1592,14 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) } zebra_evpn_if_es_print(vty, zebra_if); + vty_out(vty, " protodown: %s", + (zebra_if->flags & ZIF_FLAG_PROTODOWN) ? "on" : "off"); + if (zebra_if->protodown_rc) + vty_out(vty, " rc: %s\n", + zebra_protodown_rc_str(zebra_if->protodown_rc, pd_buf, + sizeof(pd_buf))); + else + vty_out(vty, "\n"); if (zebra_if->link_ifindex != IFINDEX_INTERNAL) { if (zebra_if->link) @@ -1609,8 +1662,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n", iflp->use_bw); if (IS_PARAM_SET(iflp, LP_RMT_AS)) - vty_out(vty, " Neighbor ASBR IP: %s AS: %u \n", - inet_ntoa(iflp->rmt_ip), iflp->rmt_as); + vty_out(vty, " Neighbor ASBR IP: %pI4 AS: %u \n", + &iflp->rmt_ip, iflp->rmt_as); } hook_call(zebra_if_extra_info, vty, ifp); @@ -3498,7 +3551,7 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp) if (IS_PARAM_SET(iflp, LP_USE_BW)) vty_out(vty, " use-bw %g\n", iflp->use_bw); if (IS_PARAM_SET(iflp, LP_RMT_AS)) - vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip), + vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip, iflp->rmt_as); vty_out(vty, " exit-link-params\n"); return 0; diff --git a/zebra/interface.h b/zebra/interface.h index 626225836e..ab1a245e5e 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -29,6 +29,7 @@ #include "zebra/zebra_l2.h" #include "zebra/zebra_nhg_private.h" +#include "zebra/zebra_router.h" #ifdef __cplusplus extern "C" { @@ -280,14 +281,28 @@ struct zebra_evpn_es; struct zebra_es_if_info { struct ethaddr sysmac; uint32_t lid; /* local-id; has to be unique per-ES-sysmac */ + uint16_t df_pref; struct zebra_evpn_es *es; /* local ES */ }; +enum zebra_if_flags { + /* device has been configured as an uplink for + * EVPN multihoming + */ + ZIF_FLAG_EVPN_MH_UPLINK = (1 << 0), + ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP = (1 << 1), + + /* Dataplane protodown-on */ + ZIF_FLAG_PROTODOWN = (1 << 2) +}; + /* `zebra' daemon local interface structure. */ struct zebra_if { /* back pointer to the interface */ struct interface *ifp; + enum zebra_if_flags flags; + /* Shutdown configuration. */ uint8_t shutdown; @@ -351,6 +366,7 @@ struct zebra_if { struct zebra_l2info_brslave brslave_info; struct zebra_l2info_bondslave bondslave_info; + struct zebra_l2info_bond bond_info; /* ethernet segment */ struct zebra_es_if_info es_info; @@ -358,6 +374,14 @@ struct zebra_if { /* bitmap of vlans associated with this interface */ bitfield_t vlan_bitmap; + /* An interface can be error-disabled if a protocol (such as EVPN or + * VRRP) detects a problem with keeping it operationally-up. + * If any of the protodown bits are set protodown-on is programmed + * in the dataplane. This results in a carrier/L1 down on the + * physical device. + */ + enum protodown_reasons protodown_rc; + /* Link fields - for sub-interfaces. */ ifindex_t link_ifindex; struct interface *link; @@ -399,6 +423,9 @@ DECLARE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp), #define IS_ZEBRA_IF_VETH(ifp) \ (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VETH) +#define IS_ZEBRA_IF_BOND(ifp) \ + (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_BOND) + #define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) \ (((struct zebra_if *)(ifp->info))->zif_slave_type \ == ZEBRA_IF_SLAVE_BRIDGE) @@ -462,6 +489,10 @@ extern unsigned int if_nhg_dependents_count(const struct interface *ifp); extern bool if_nhg_dependents_is_empty(const struct interface *ifp); extern void vrf_add_update(struct vrf *vrfp); +extern void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf); +extern void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif); +extern const char *zebra_protodown_rc_str(enum protodown_reasons protodown_rc, + char *pd_buf, uint32_t pd_buf_len); #ifdef HAVE_PROC_NET_DEV extern void ifstat_update_proc(void); diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 11b252fc18..42a5bfd9db 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -411,47 +411,91 @@ void if_get_flags(struct interface *ifp) { int ret; struct ifreq ifreq; -#ifdef HAVE_BSD_LINK_DETECT - struct ifmediareq ifmr; -#endif /* HAVE_BSD_LINK_DETECT */ ifreq_set_name(&ifreq, ifp); ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id); if (ret < 0) { flog_err_sys(EC_LIB_SYSTEM_CALL, - "vrf_if_ioctl(SIOCGIFFLAGS) failed: %s", - safe_strerror(errno)); + "vrf_if_ioctl(SIOCGIFFLAGS %s) failed: %s", + ifp->name, safe_strerror(errno)); return; } -#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ - /* Per-default, IFF_RUNNING is held high, unless link-detect says - * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag, - * following practice on Linux and Solaris kernels + if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) + goto out; + + /* Per-default, IFF_RUNNING is held high, unless link-detect + * says otherwise - we abuse IFF_RUNNING inside zebra as a + * link-state flag, following practice on Linux and Solaris + * kernels + */ + +#ifdef SIOCGIFDATA + /* + * BSD gets link state from ifi_link_link in struct if_data. + * All BSD's have this in getifaddrs(3) ifa_data for AF_LINK + * addresses. We can also access it via SIOCGIFDATA. + */ + +#ifdef __NetBSD__ + struct ifdatareq ifdr = {.ifdr_data.ifi_link_state = 0}; + struct if_data *ifdata = &ifdr.ifdr_data; + + strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name)); + ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifdr, ifp->vrf_id); +#else + struct if_data ifd = {.ifi_link_state = 0}; + struct if_data *ifdata = &ifd; + + ifreq.ifr_data = (caddr_t)ifdata; + ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreq, ifp->vrf_id); +#endif + + if (ret == -1) + /* Very unlikely. Did the interface disappear? */ + flog_err_sys(EC_LIB_SYSTEM_CALL, + "if_ioctl(SIOCGIFDATA %s) failed: %s", ifp->name, + safe_strerror(errno)); + else { + if (ifdata->ifi_link_state >= LINK_STATE_UP) + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN) + /* BSD traditionally treats UNKNOWN as UP */ + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + } + +#elif defined(HAVE_BSD_LINK_DETECT) + /* + * This is only needed for FreeBSD older than FreeBSD-13. + * Valid and active media generally means the link state is + * up, but this is not always the case. + * For example, some BSD's with a net80211 interface in MONITOR + * mode will treat the media as valid and active but the + * link state is down - because we cannot send anything. + * Also, virtual interfaces such as PPP, VLAN, etc generally + * don't support media at all, so the ioctl will just fail. */ - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + struct ifmediareq ifmr = {.ifm_status = 0}; - if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) { - (void)memset(&ifmr, 0, sizeof(ifmr)); - strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); + strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); - /* Seems not all interfaces implement this ioctl */ - if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1 && - errno != EINVAL) + if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) { + if (errno != EINVAL) flog_err_sys(EC_LIB_SYSTEM_CALL, - "if_ioctl(SIOCGIFMEDIA) failed: %s", - safe_strerror(errno)); - else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ - { - if (ifmr.ifm_status & IFM_ACTIVE) - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - else - UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - } + "if_ioctl(SIOCGIFMEDIA %s) failed: %s", + ifp->name, safe_strerror(errno)); + } else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */ + if (ifmr.ifm_status & IFM_ACTIVE) /* media is active */ + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); } #endif /* HAVE_BSD_LINK_DETECT */ +out: if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff)); } diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index b868d23a94..936206641f 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -175,7 +175,6 @@ static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s) { struct zebra_if *zi = ifp->info; struct irdp_interface *irdp = zi->irdp; - char buf[PREFIX_STRLEN]; uint32_t dst; uint32_t ttl = 1; @@ -190,10 +189,11 @@ static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s) dst = htonl(INADDR_ALLHOSTS_GROUP); if (irdp->flags & IF_DEBUG_MESSAGES) - zlog_debug("IRDP: TX Advert on %s %s Holdtime=%d Preference=%d", - ifp->name, prefix2str(p, buf, sizeof(buf)), - irdp->flags & IF_SHUTDOWN ? 0 : irdp->Lifetime, - get_pref(irdp, p)); + zlog_debug( + "IRDP: TX Advert on %s %pFX Holdtime=%d Preference=%d", + ifp->name, p, + irdp->flags & IF_SHUTDOWN ? 0 : irdp->Lifetime, + get_pref(irdp, p)); send_packet(ifp, s, dst, p, ttl); } @@ -263,9 +263,7 @@ void irdp_advert_off(struct interface *ifp) if (!irdp) return; - if (irdp->t_advertise) - thread_cancel(irdp->t_advertise); - irdp->t_advertise = NULL; + thread_cancel(&irdp->t_advertise); if (ifp->connected) for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) { @@ -300,9 +298,7 @@ void process_solicit(struct interface *ifp) return; irdp->flags |= IF_SOLICIT; - if (irdp->t_advertise) - thread_cancel(irdp->t_advertise); - irdp->t_advertise = NULL; + thread_cancel(&irdp->t_advertise); timer = (frr_weak_random() % MAX_RESPONSE_DELAY) + 1; diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 502a2f277c..56fd35a736 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -79,6 +79,7 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) struct zebra_if *zi; struct irdp_interface *irdp; uint16_t saved_chksum; + char buf[PREFIX_STRLEN]; zi = ifp->info; if (!zi) @@ -104,8 +105,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) if (iplen < ICMP_MINLEN) { flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH, - "IRDP: RX ICMP packet too short from %s\n", - inet_ntoa(src)); + "IRDP: RX ICMP packet too short from %pI4\n", + &src); return; } @@ -115,8 +116,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) len of IP-header) 14+20 */ if (iplen > IRDP_RX_BUF - 34) { flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH, - "IRDP: RX ICMP packet too long from %s\n", - inet_ntoa(src)); + "IRDP: RX ICMP packet too long from %pI4\n", + &src); return; } @@ -128,8 +129,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) if (in_cksum(icmp, datalen) != saved_chksum) { flog_warn( EC_ZEBRA_IRDP_BAD_CHECKSUM, - "IRDP: RX ICMP packet from %s. Bad checksum, silently ignored", - inet_ntoa(src)); + "IRDP: RX ICMP packet from %pI4 Bad checksum, silently ignored", + &src); return; } @@ -141,8 +142,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) if (icmp->code != 0) { flog_warn( EC_ZEBRA_IRDP_BAD_TYPE_CODE, - "IRDP: RX packet type %d from %s. Bad ICMP type code, silently ignored", - icmp->type, inet_ntoa(src)); + "IRDP: RX packet type %d from %pI4 Bad ICMP type code, silently ignored", + icmp->type, &src); return; } @@ -152,11 +153,12 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) && !(irdp->flags & IF_BROADCAST))) { flog_warn( EC_ZEBRA_IRDP_BAD_RX_FLAGS, - "IRDP: RX illegal from %s to %s while %s operates in %s; Please correct settings\n", - inet_ntoa(src), + "IRDP: RX illegal from %pI4 to %s while %s operates in %s; Please correct settings\n", + &src, ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP ? "multicast" - : inet_ntoa(ip->ip_dst), + : inet_ntop(AF_INET, &ip->ip_dst, + buf, sizeof(buf)), ifp->name, irdp->flags & IF_BROADCAST ? "broadcast" : "multicast"); return; @@ -169,8 +171,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) case ICMP_ROUTERSOLICIT: if (irdp->flags & IF_DEBUG_MESSAGES) - zlog_debug("IRDP: RX Solicit on %s from %s", - ifp->name, inet_ntoa(src)); + zlog_debug("IRDP: RX Solicit on %s from %pI4", + ifp->name, &src); process_solicit(ifp); break; @@ -178,8 +180,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp) default: flog_warn( EC_ZEBRA_IRDP_BAD_TYPE_CODE, - "IRDP: RX packet type %d from %s. Bad ICMP type code, silently ignored", - icmp->type, inet_ntoa(src)); + "IRDP: RX packet type %d from %pI4 Bad ICMP type code, silently ignored", + icmp->type, &src); } } diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index c53d28a18c..76da00c619 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -1051,7 +1051,7 @@ static int nl_batch_read_resp(struct nl_batch *bth) { struct nlmsghdr *h; struct sockaddr_nl snl; - struct msghdr msg; + struct msghdr msg = {}; int status, seq; const struct nlsock *nl; struct zebra_dplane_ctx *ctx; @@ -1321,6 +1321,7 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth, case DPLANE_OP_SYS_ROUTE_DELETE: case DPLANE_OP_ROUTE_NOTIFY: case DPLANE_OP_LSP_NOTIFY: + case DPLANE_OP_BR_PORT_UPDATE: return FRR_NETLINK_SUCCESS; case DPLANE_OP_NONE: @@ -1501,7 +1502,7 @@ void kernel_init(struct zebra_ns *zns) void kernel_terminate(struct zebra_ns *zns, bool complete) { - THREAD_READ_OFF(zns->t_netlink); + thread_cancel(&zns->t_netlink); if (zns->netlink.sock >= 0) { close(zns->netlink.sock); diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 40ac44b77f..9d74aeca28 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1001,7 +1001,7 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest, void rtm_read(struct rt_msghdr *rtm) { int flags; - uint8_t zebra_flags; + uint32_t zebra_flags; union sockunion dest, mask, gate; char ifname[INTERFACE_NAMSIZ + 1]; short ifnlen = 0; @@ -1340,13 +1340,27 @@ static int kernel_read(struct thread *thread) nbytes = read(sock, &buf, sizeof(buf)); - if (nbytes <= 0) { - if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN) + if (nbytes < 0) { + if (errno == ENOBUFS) { + flog_err(EC_ZEBRA_RECVMSG_OVERRUN, + "routing socket overrun: %s", + safe_strerror(errno)); + /* + * In this case we are screwed. + * There is no good way to + * recover zebra at this point. + */ + exit(-1); + } + if (errno != EAGAIN && errno != EWOULDBLOCK) flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s", safe_strerror(errno)); return 0; } + if (nbytes == 0) + return 0; + thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL); if (IS_ZEBRA_DEBUG_KERNEL) @@ -1412,6 +1426,15 @@ static void routing_socket(struct zebra_ns *zns) return; } +#ifdef SO_RERROR + /* Allow reporting of route(4) buffer overflow errors */ + int n = 1; + + if (setsockopt(routing_sock, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) < 0) + flog_err_sys(EC_LIB_SOCKET, + "Can't set SO_RERROR on routing socket"); +#endif + /* XXX: Socket should be NONBLOCK, however as we currently * discard failed writes, this will lead to inconsistencies. * For now, socket must be blocking. diff --git a/zebra/main.c b/zebra/main.c index 2afef46bb2..ced29e1a25 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -87,7 +87,6 @@ uint32_t nl_rcvbufsize = 4194304; const struct option longopts[] = { {"batch", no_argument, NULL, 'b'}, {"allow_delete", no_argument, NULL, 'a'}, - {"keep_kernel", no_argument, NULL, 'k'}, {"socket", required_argument, NULL, 'z'}, {"ecmp", required_argument, NULL, 'e'}, {"retain", no_argument, NULL, 'r'}, @@ -171,12 +170,14 @@ static void sigint(void) zebra_ptm_finish(); - if (retain_mode) + if (retain_mode) { + zebra_nhg_mark_keep(); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { zvrf = vrf->info; if (zvrf) SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN); } + } if (zrouter.lsp_process_q) work_queue_free_and_null(&zrouter.lsp_process_q); diff --git a/zebra/redistribute.c b/zebra/redistribute.c index c0f89e6afe..1f075cfb4b 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -119,18 +119,17 @@ static void zebra_redistribute(struct zserv *client, int type, for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) RNODE_FOREACH_RE (rn, newre) { const struct prefix *dst_p, *src_p; - char buf[PREFIX_STRLEN]; srcdest_rnode_prefixes(rn, &dst_p, &src_p); if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s: client %s %s(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d", + "%s: client %s %pFX(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d", __func__, zebra_route_string(client->proto), - prefix2str(dst_p, buf, sizeof(buf)), - vrf_id, CHECK_FLAG(newre->flags, - ZEBRA_FLAG_SELECTED), + dst_p, vrf_id, + CHECK_FLAG(newre->flags, + ZEBRA_FLAG_SELECTED), newre->type, newre->distance, newre->metric, zebra_check_addr(dst_p)); @@ -196,15 +195,13 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, struct listnode *node, *nnode; struct zserv *client; int afi; - char buf[PREFIX_STRLEN]; - if (IS_ZEBRA_DEBUG_RIB) { + if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "(%u:%u):%s: Redist update re %p (%s), old %p (%s)", - re->vrf_id, re->table, prefix2str(p, buf, sizeof(buf)), - re, zebra_route_string(re->type), prev_re, + "(%u:%u):%pFX: Redist update re %p (%s), old %p (%s)", + re->vrf_id, re->table, p, re, + zebra_route_string(re->type), prev_re, prev_re ? zebra_route_string(prev_re->type) : "None"); - } afi = family2afi(p->family); if (!afi) { @@ -214,8 +211,7 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, } if (!zebra_check_addr(p)) { if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("Redist update filter prefix %s", - prefix2str(p, buf, sizeof(buf))); + zlog_debug("Redist update filter prefix %pFX", p); return; } @@ -224,10 +220,9 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, if (zebra_redistribute_check(re, client, p, afi)) { if (IS_ZEBRA_DEBUG_RIB) { zlog_debug( - "%s: client %s %s(%u:%u), type=%d, distance=%d, metric=%d", + "%s: client %s %pFX(%u:%u), type=%d, distance=%d, metric=%d", __func__, - zebra_route_string(client->proto), - prefix2str(p, buf, sizeof(buf)), + zebra_route_string(client->proto), p, re->vrf_id, re->table, re->type, re->distance, re->metric); } @@ -254,7 +249,6 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, struct listnode *node, *nnode; struct zserv *client; int afi; - char buf[PREFIX_STRLEN]; vrf_id_t vrfid; if (old_re) @@ -265,13 +259,11 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, return; if (IS_ZEBRA_DEBUG_RIB) { - zlog_debug( - "%u:%s: Redist del: re %p (%s), new re %p (%s)", - vrfid, prefix2str(p, buf, sizeof(buf)), - old_re, - old_re ? zebra_route_string(old_re->type) : "None", - new_re, - new_re ? zebra_route_string(new_re->type) : "None"); + zlog_debug("%u:%pFX: Redist del: re %p (%s), new re %p (%s)", + vrfid, p, old_re, + old_re ? zebra_route_string(old_re->type) : "None", + new_re, + new_re ? zebra_route_string(new_re->type) : "None"); } /* Add DISTANCE_INFINITY check. */ @@ -293,8 +285,8 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, if (!zebra_check_addr(p)) { if (IS_ZEBRA_DEBUG_RIB) { zlog_debug( - "%u:%s: Redist del old: skipping invalid prefix", - vrfid, prefix2str(p, buf, sizeof(buf))); + "%u:%pFX: Redist del old: skipping invalid prefix", + vrfid, p); } return; } @@ -541,12 +533,10 @@ void zebra_interface_address_add_update(struct interface *ifp, struct prefix *p; if (IS_ZEBRA_DEBUG_EVENT) { - char buf[PREFIX_STRLEN]; - p = ifc->address; - zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)", - prefix2str(p, buf, sizeof(buf)), ifp->name, - ifp->vrf_id); + zlog_debug( + "MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s(%u)", + p, ifp->name, ifp->vrf_id); } if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) @@ -580,12 +570,10 @@ void zebra_interface_address_delete_update(struct interface *ifp, struct prefix *p; if (IS_ZEBRA_DEBUG_EVENT) { - char buf[PREFIX_STRLEN]; - p = ifc->address; - zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)", - prefix2str(p, buf, sizeof(buf)), - ifp->name, ifp->vrf_id); + zlog_debug( + "MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s(%u)", + p, ifp->name, ifp->vrf_id); } zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0); diff --git a/zebra/rib.h b/zebra/rib.h index 9ddc35b091..3bce62bfa8 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -165,13 +165,15 @@ struct route_entry { /* meta-queue structure: * sub-queue 0: nexthop group objects - * sub-queue 1: connected, kernel - * sub-queue 2: static - * sub-queue 3: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP - * sub-queue 4: iBGP, eBGP - * sub-queue 5: any other origin (if any) + * sub-queue 1: connected + * sub-queue 2: kernel + * sub-queue 3: static + * sub-queue 4: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP + * sub-queue 5: iBGP, eBGP + * sub-queue 6: any other origin (if any) typically those that + * don't generate routes */ -#define MQ_SIZE 6 +#define MQ_SIZE 7 struct meta_queue { struct list *subq[MQ_SIZE]; uint32_t size; /* sum of lengths of all subqueues */ @@ -364,7 +366,7 @@ extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re); * All rib_add function will not just add prefix into RIB, but * also implicitly withdraw equal prefix of same type. */ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, int flags, struct prefix *p, + unsigned short instance, uint32_t flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint32_t mtu, uint8_t distance, route_tag_t tag); @@ -380,10 +382,11 @@ extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, struct nhg_hash_entry *nhe); extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, int flags, struct prefix *p, - struct prefix_ipv6 *src_p, const struct nexthop *nh, - uint32_t nhe_id, uint32_t table_id, uint32_t metric, - uint8_t distance, bool fromkernel, bool connected_down); + unsigned short instance, uint32_t flags, + struct prefix *p, struct prefix_ipv6 *src_p, + const struct nexthop *nh, uint32_t nhe_id, + uint32_t table_id, uint32_t metric, uint8_t distance, + bool fromkernel, bool connected_down); extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id, union g_addr *addr, diff --git a/zebra/router-id.c b/zebra/router-id.c index 7e81f29827..7af60a389b 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -331,7 +331,7 @@ DEFUN (ip_router_id_in_vrf, ip_router_id_in_vrf_cmd, "ip router-id A.B.C.D", IP_STR - "Manuall set the router-id\n" + "Manually set the router-id\n" "IP address to use for router-id\n") { ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); @@ -361,7 +361,7 @@ DEFUN (ipv6_router_id_in_vrf, ipv6_router_id_in_vrf_cmd, "ipv6 router-id X:X::X:X", IP6_STR - "Manuall set the IPv6 router-id\n" + "Manually set the IPv6 router-id\n" "IPV6 address to use for router-id\n") { ZEBRA_DECLVAR_CONTEXT(vrf, zvrf); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 1ce3c435fe..ef51989a0c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -574,7 +574,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, int len; struct rtmsg *rtm; struct rtattr *tb[RTA_MAX + 1]; - uint8_t flags = 0; + uint32_t flags = 0; struct prefix p; struct prefix_ipv6 src_p = {}; vrf_id_t vrf_id; @@ -731,11 +731,10 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, p.prefixlen = rtm->rtm_dst_len; if (rtm->rtm_src_len != 0) { - char buf[PREFIX_STRLEN]; flog_warn( EC_ZEBRA_UNSUPPORTED_V4_SRCDEST, - "unsupported IPv4 sourcedest route (dest %s vrf %u)", - prefix2str(&p, buf, sizeof(buf)), vrf_id); + "unsupported IPv4 sourcedest route (dest %pFX vrf %u)", + &p, vrf_id); return 0; } @@ -786,12 +785,11 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, } if (IS_ZEBRA_DEBUG_KERNEL) { - char buf[PREFIX_STRLEN]; char buf2[PREFIX_STRLEN]; + zlog_debug( - "%s %s%s%s vrf %s(%u) table_id: %u metric: %d Admin Distance: %d", - nl_msg_type_to_str(h->nlmsg_type), - prefix2str(&p, buf, sizeof(buf)), + "%s %pFX%s%s vrf %s(%u) table_id: %u metric: %d Admin Distance: %d", + nl_msg_type_to_str(h->nlmsg_type), &p, src_p.prefixlen ? " from " : "", src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "", @@ -905,8 +903,6 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, int count; int oif[256]; int oif_count = 0; - char sbuf[40]; - char gbuf[40]; char oif_list[256] = "\0"; vrf_id_t vrf; int table; @@ -968,8 +964,6 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, struct interface *ifp = NULL; struct zebra_vrf *zvrf = NULL; - strlcpy(sbuf, inet_ntoa(m->sg.src), sizeof(sbuf)); - strlcpy(gbuf, inet_ntoa(m->sg.grp), sizeof(gbuf)); for (count = 0; count < oif_count; count++) { ifp = if_lookup_by_index(oif[count], vrf); char temp[256]; @@ -981,9 +975,10 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, zvrf = zebra_vrf_lookup_by_id(vrf); ifp = if_lookup_by_index(iif, vrf); zlog_debug( - "MCAST VRF: %s(%d) %s (%s,%s) IIF: %s(%d) OIF: %s jiffies: %lld", + "MCAST VRF: %s(%d) %s (%pI4,%pI4) IIF: %s(%d) OIF: %s jiffies: %lld", zvrf_name(zvrf), vrf, nl_msg_type_to_str(h->nlmsg_type), - sbuf, gbuf, ifp ? ifp->name : "Unknown", iif, oif_list, + &m->sg.src, &m->sg.grp, ifp ? ifp->name : "Unknown", + iif, oif_list, m->lastused); } return 0; @@ -2102,6 +2097,8 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, int num_labels = 0; uint32_t id = dplane_ctx_get_nhe_id(ctx); int type = dplane_ctx_get_nhe_type(ctx); + struct rtattr *nest; + uint16_t encap; if (!id) { flog_err( @@ -2230,34 +2227,21 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, */ if (req->nhm.nh_family == AF_MPLS) goto nexthop_done; -#if 0 - if (!nl_attr_put(&req->n, buflen, NHA_NEWDST, - &out_lse, - num_labels - * sizeof(mpls_lse_t))) - return 0; -#endif - else { - struct rtattr *nest; - uint16_t encap = LWTUNNEL_ENCAP_MPLS; - - if (!nl_attr_put16(&req->n, buflen, - NHA_ENCAP_TYPE, - encap)) - return 0; - nest = nl_attr_nest(&req->n, buflen, - NHA_ENCAP); - if (!nest) - return 0; - if (!nl_attr_put( - &req->n, buflen, - MPLS_IPTUNNEL_DST, &out_lse, - num_labels - * sizeof( - mpls_lse_t))) - return 0; - nl_attr_nest_end(&req->n, nest); - } + + encap = LWTUNNEL_ENCAP_MPLS; + if (!nl_attr_put16(&req->n, buflen, + NHA_ENCAP_TYPE, encap)) + return 0; + nest = nl_attr_nest(&req->n, buflen, NHA_ENCAP); + if (!nest) + return 0; + if (!nl_attr_put( + &req->n, buflen, MPLS_IPTUNNEL_DST, + &out_lse, + num_labels * sizeof(mpls_lse_t))) + return 0; + + nl_attr_nest_end(&req->n, nest); } nexthop_done: @@ -2267,9 +2251,9 @@ nexthop_done: __func__, id, nh, nh->ifindex, vrf_id_to_name(nh->vrf_id), nh->vrf_id, label_buf); -} + } -req->nhm.nh_protocol = zebra2proto(type); + req->nhm.nh_protocol = zebra2proto(type); } else if (cmd != RTM_DELNEXTHOP) { flog_err( @@ -2892,8 +2876,8 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) dst_present = 1; memcpy(&vtep_ip.s_addr, RTA_DATA(tb[NDA_DST]), IPV4_MAX_BYTELEN); - snprintf(dst_buf, sizeof(dst_buf), " dst %s", - inet_ntoa(vtep_ip)); + snprintfrr(dst_buf, sizeof(dst_buf), " dst %pI4", + &vtep_ip); } if (tb[NDA_NH_ID]) @@ -3950,8 +3934,8 @@ static int netlink_fdb_nh_update(uint32_t nh_id, struct in_addr vtep_ip) return -1; if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_EVPN_MH_NH) { - zlog_debug("Tx %s fdb-nh 0x%x %s", - nl_msg_type_to_str(cmd), nh_id, inet_ntoa(vtep_ip)); + zlog_debug("Tx %s fdb-nh 0x%x %pI4", + nl_msg_type_to_str(cmd), nh_id, &vtep_ip); } return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index a2e15cbd2b..a0f401c334 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -80,19 +80,15 @@ static int kernel_rtm(int cmd, const struct prefix *p, bool gate = false; int error; char gate_buf[INET6_BUFSIZ]; - char prefix_buf[PREFIX_STRLEN]; enum blackhole_type bh_type = BLACKHOLE_UNSPEC; - prefix2str(p, prefix_buf, sizeof(prefix_buf)); - /* * We only have the ability to ADD or DELETE at this point * in time. */ if (cmd != RTM_ADD && cmd != RTM_DELETE) { if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: %s odd command %s", - __func__, prefix_buf, + zlog_debug("%s: %pFX odd command %s", __func__, p, lookup_msg(rtm_type_str, cmd, NULL)); return 0; } @@ -237,8 +233,8 @@ static int kernel_rtm(int cmd, const struct prefix *p, if (IS_ZEBRA_DEBUG_KERNEL) { if (!gate) { zlog_debug( - "%s: %s: attention! gate not found for re", - __func__, prefix_buf); + "%s: %pFX: attention! gate not found for re", + __func__, p); } else { switch (p->family) { case AF_INET: @@ -266,8 +262,8 @@ static int kernel_rtm(int cmd, const struct prefix *p, case ZEBRA_ERR_NOERROR: nexthop_num++; if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: %s: successfully did NH %s", - __func__, prefix_buf, gate_buf); + zlog_debug("%s: %pFX: successfully did NH %s", + __func__, p, gate_buf); if (cmd == RTM_ADD) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); break; @@ -289,8 +285,8 @@ static int kernel_rtm(int cmd, const struct prefix *p, default: flog_err( EC_LIB_SYSTEM_CALL, - "%s: %s: rtm_write() unexpectedly returned %d for command %s", - __func__, prefix_buf, error, + "%s: %pFX: rtm_write() unexpectedly returned %d for command %s", + __func__, p, error, lookup_msg(rtm_type_str, cmd, NULL)); break; } @@ -300,8 +296,8 @@ static int kernel_rtm(int cmd, const struct prefix *p, if (nexthop_num == 0) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "%s: No useful nexthops were found in RIB prefix %s", - __func__, prefix_buf); + "%s: No useful nexthops were found in RIB prefix %pFX", + __func__, p); return 1; } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 13b7c150a3..c3add16c56 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -2337,7 +2337,6 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp) struct rtadv_prefix *rprefix; struct rtadv_rdnss *rdnss; struct rtadv_dnssl *dnssl; - char buf[PREFIX_STRLEN]; int interval; zif = ifp->info; @@ -2408,8 +2407,7 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp) for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) { if ((rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL) || (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH)) { - vty_out(vty, " ipv6 nd prefix %s", - prefix2str(&rprefix->prefix, buf, sizeof(buf))); + vty_out(vty, " ipv6 nd prefix %pFX", &rprefix->prefix); if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) || (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME)) { diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c index d6a34327a6..a63504992e 100644 --- a/zebra/rule_netlink.c +++ b/zebra/rule_netlink.c @@ -75,8 +75,6 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx, } *req = buf; const char *ifname = dplane_ctx_rule_get_ifname(ctx); - char buf1[PREFIX_STRLEN]; - char buf2[PREFIX_STRLEN]; if (buflen < sizeof(*req)) return 0; @@ -141,11 +139,9 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx, if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "Tx %s family %s IF %s Pref %u Fwmark %u Src %s Dst %s Table %u", + "Tx %s family %s IF %s Pref %u Fwmark %u Src %pFX Dst %pFX Table %u", nl_msg_type_to_str(cmd), nl_family_to_str(family), - ifname, priority, fwmark, - prefix2str(src_ip, buf1, sizeof(buf1)), - prefix2str(dst_ip, buf2, sizeof(buf2)), table); + ifname, priority, fwmark, src_ip, dst_ip, table); return NLMSG_ALIGN(req->n.nlmsg_len); } @@ -231,8 +227,6 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) int len; char *ifname; struct zebra_pbr_rule rule = {}; - char buf1[PREFIX_STRLEN]; - char buf2[PREFIX_STRLEN]; uint8_t proto = 0; /* Basic validation followed by extracting attributes. */ @@ -324,17 +318,14 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) ret = dplane_pbr_rule_delete(&rule); zlog_debug( - "%s: %s leftover rule: family %s IF %s Pref %u Src %s Dst %s Table %u", + "%s: %s leftover rule: family %s IF %s Pref %u Src %pFX Dst %pFX Table %u", __func__, ((ret == ZEBRA_DPLANE_REQUEST_FAILURE) ? "Failed to remove" : "Removed"), nl_family_to_str(frh->family), rule.ifname, - rule.rule.priority, - prefix2str(&rule.rule.filter.src_ip, buf1, - sizeof(buf1)), - prefix2str(&rule.rule.filter.dst_ip, buf2, - sizeof(buf2)), + rule.rule.priority, &rule.rule.filter.src_ip, + &rule.rule.filter.dst_ip, rule.rule.action.table); } @@ -350,15 +341,11 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "Rx %s family %s IF %s Pref %u Src %s Dst %s Table %u", + "Rx %s family %s IF %s Pref %u Src %pFX Dst %pFX Table %u", nl_msg_type_to_str(h->nlmsg_type), nl_family_to_str(frh->family), rule.ifname, - rule.rule.priority, - prefix2str(&rule.rule.filter.src_ip, buf1, - sizeof(buf1)), - prefix2str(&rule.rule.filter.dst_ip, buf2, - sizeof(buf2)), - rule.rule.action.table); + rule.rule.priority, &rule.rule.filter.src_ip, + &rule.rule.filter.dst_ip, rule.rule.action.table); return kernel_pbr_rule_del(&rule); } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index c33bca3d86..18017c9700 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -644,17 +644,12 @@ int zsend_redistribute_route(int cmd, struct zserv *client, return -1; } - if (IS_ZEBRA_DEBUG_SEND) { - char buf_prefix[PREFIX_STRLEN]; - - prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix)); - - zlog_debug("%s: %s to client %s: type %s, vrf_id %d, p %s", + if (IS_ZEBRA_DEBUG_SEND) + zlog_debug("%s: %s to client %s: type %s, vrf_id %d, p %pFX", __func__, zserv_command_string(cmd), zebra_route_string(client->proto), zebra_route_string(api.type), api.vrf_id, - buf_prefix); - } + &api.prefix); return zserv_send_message(client, s); } @@ -755,26 +750,18 @@ static int route_notify_internal(const struct prefix *p, int type, client = zserv_find_client(type, instance); if (!client || !client->notify_owner) { - if (IS_ZEBRA_DEBUG_PACKET) { - char buff[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_PACKET) zlog_debug( - "Not Notifying Owner: %s about prefix %s(%u) %d vrf: %u", - zebra_route_string(type), - prefix2str(p, buff, sizeof(buff)), table_id, - note, vrf_id); - } + "Not Notifying Owner: %s about prefix %pFX(%u) %d vrf: %u", + zebra_route_string(type), p, table_id, note, + vrf_id); return 0; } - if (IS_ZEBRA_DEBUG_PACKET) { - char buff[PREFIX_STRLEN]; - - zlog_debug("Notifying Owner: %s about prefix %s(%u) %d vrf: %u", - zebra_route_string(type), - prefix2str(p, buff, sizeof(buff)), table_id, note, - vrf_id); - } + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug( + "Notifying Owner: %s about prefix %pFX(%u) %d vrf: %u", + zebra_route_string(type), p, table_id, note, vrf_id); s = stream_new(ZEBRA_MAX_PACKET_SIZ); stream_reset(s); @@ -1903,14 +1890,10 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) vrf_id = zvrf_id(zvrf); - if (IS_ZEBRA_DEBUG_RECV) { - char buf_prefix[PREFIX_STRLEN]; - - prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix)); - zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x", - __func__, vrf_id, api.tableid, buf_prefix, + if (IS_ZEBRA_DEBUG_RECV) + zlog_debug("%s: p=(%u:%u)%pFX, msg flags=0x%x, flags=0x%x", + __func__, vrf_id, api.tableid, &api.prefix, (int)api.message, api.flags); - } /* Allocate new route. */ re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); @@ -2068,14 +2051,10 @@ static void zread_route_del(ZAPI_HANDLER_ARGS) else table_id = zvrf->table_id; - if (IS_ZEBRA_DEBUG_RECV) { - char buf_prefix[PREFIX_STRLEN]; - - prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix)); - zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x", - __func__, zvrf_id(zvrf), table_id, buf_prefix, + if (IS_ZEBRA_DEBUG_RECV) + zlog_debug("%s: p=(%u:%u)%pFX, msg flags=0x%x, flags=0x%x", + __func__, zvrf_id(zvrf), table_id, &api.prefix, (int)api.message, api.flags); - } rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance, api.flags, &api.prefix, src_p, NULL, 0, table_id, api.metric, diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 76d7d00e4a..22cc234b2f 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -36,15 +36,22 @@ #include "zebra/rt.h" #include "zebra/debug.h" #include "zebra/zebra_pbr.h" +#include "printfrr.h" /* Memory type for context blocks */ DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx") +DEFINE_MTYPE_STATIC(ZEBRA, DP_INTF, "Zebra DPlane Intf") DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider") #ifndef AOK # define AOK 0 #endif +/* Control for collection of extra interface info with route updates; a plugin + * can enable the extra info via a dplane api. + */ +static bool dplane_collect_extra_intf_info; + /* Enable test dataplane provider */ /*#define DPLANE_TEST_PROVIDER 1 */ @@ -84,6 +91,18 @@ struct dplane_nexthop_info { }; /* + * Optional extra info about interfaces used in route updates' nexthops. + */ +struct dplane_intf_extra { + vrf_id_t vrf_id; + uint32_t ifindex; + uint32_t flags; + uint32_t status; + + TAILQ_ENTRY(dplane_intf_extra) link; +}; + +/* * Route information captured for route updates. */ struct dplane_route_info { @@ -126,8 +145,8 @@ struct dplane_route_info { struct nexthop_group zd_old_ng; struct nexthop_group old_backup_ng; - /* TODO -- use fixed array of nexthops, to avoid mallocs? */ - + /* Optional list of extra interface info */ + TAILQ_HEAD(dp_intf_extra_q, dplane_intf_extra) intf_extra_q; }; /* @@ -149,6 +168,17 @@ struct dplane_pw_info { }; /* + * Bridge port info for the dataplane + */ +struct dplane_br_port_info { + uint32_t sph_filter_cnt; + struct in_addr sph_filters[ES_VTEP_MAX_CNT]; + /* DPLANE_BR_PORT_XXX - see zebra_dplane.h*/ + uint32_t flags; + uint32_t backup_nhg_id; +}; + +/* * Interface/prefix info for the dataplane */ struct dplane_intf_info { @@ -272,6 +302,7 @@ struct zebra_dplane_ctx { struct dplane_route_info rinfo; zebra_lsp_t lsp; struct dplane_pw_info pw; + struct dplane_br_port_info br_port; struct dplane_intf_info intf; struct dplane_mac_info macinfo; struct dplane_neigh_info neigh; @@ -390,6 +421,9 @@ static struct zebra_dplane_globals { _Atomic uint32_t dg_pws_in; _Atomic uint32_t dg_pw_errors; + _Atomic uint32_t dg_br_port_in; + _Atomic uint32_t dg_br_port_errors; + _Atomic uint32_t dg_intf_addrs_in; _Atomic uint32_t dg_intf_addr_errors; @@ -491,6 +525,8 @@ void dplane_enable_sys_route_notifs(void) */ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) { + struct dplane_intf_extra *if_extra, *if_tmp; + /* * Some internal allocations may need to be freed, depending on * the type of info captured in the ctx. @@ -533,6 +569,14 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) ctx->u.rinfo.old_backup_ng.nexthop = NULL; } + /* Optional extra interface info */ + TAILQ_FOREACH_SAFE(if_extra, &ctx->u.rinfo.intf_extra_q, + link, if_tmp) { + TAILQ_REMOVE(&ctx->u.rinfo.intf_extra_q, if_extra, + link); + XFREE(MTYPE_DP_INTF, if_extra); + } + break; case DPLANE_OP_NH_INSTALL: @@ -610,6 +654,7 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) case DPLANE_OP_RULE_DELETE: case DPLANE_OP_RULE_UPDATE: case DPLANE_OP_NEIGH_DISCOVER: + case DPLANE_OP_BR_PORT_UPDATE: case DPLANE_OP_NONE: break; } @@ -803,6 +848,10 @@ const char *dplane_op2str(enum dplane_op_e op) ret = "SYS_ROUTE_DEL"; break; + case DPLANE_OP_BR_PORT_UPDATE: + ret = "BR_PORT_UPDATE"; + break; + case DPLANE_OP_ADDR_INSTALL: ret = "ADDR_INSTALL"; break; @@ -1763,10 +1812,80 @@ dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx) return &(ctx->u.rule.old.dst_ip); } +uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.br_port.flags; +} + +uint32_t +dplane_ctx_get_br_port_sph_filter_cnt(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.br_port.sph_filter_cnt; +} + +const struct in_addr * +dplane_ctx_get_br_port_sph_filters(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.br_port.sph_filters; +} + +uint32_t +dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.br_port.backup_nhg_id; +} + /* * End of dplane context accessors */ +/* Optional extra info about interfaces in nexthops - a plugin must enable + * this extra info. + */ +const struct dplane_intf_extra * +dplane_ctx_get_intf_extra(const struct zebra_dplane_ctx *ctx) +{ + return TAILQ_FIRST(&ctx->u.rinfo.intf_extra_q); +} + +const struct dplane_intf_extra * +dplane_ctx_intf_extra_next(const struct zebra_dplane_ctx *ctx, + const struct dplane_intf_extra *ptr) +{ + return TAILQ_NEXT(ptr, link); +} + +vrf_id_t dplane_intf_extra_get_vrfid(const struct dplane_intf_extra *ptr) +{ + return ptr->vrf_id; +} + +uint32_t dplane_intf_extra_get_ifindex(const struct dplane_intf_extra *ptr) +{ + return ptr->ifindex; +} + +uint32_t dplane_intf_extra_get_flags(const struct dplane_intf_extra *ptr) +{ + return ptr->flags; +} + +uint32_t dplane_intf_extra_get_status(const struct dplane_intf_extra *ptr) +{ + return ptr->status; +} + +/* + * End of interface extra info accessors + */ /* * Retrieve the limit on the number of pending, unprocessed updates. @@ -1835,10 +1954,14 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, struct zebra_vrf *zvrf; struct nexthop *nexthop; zebra_l3vni_t *zl3vni; + const struct interface *ifp; + struct dplane_intf_extra *if_extra; if (!ctx || !rn || !re) goto done; + TAILQ_INIT(&ctx->u.rinfo.intf_extra_q); + ctx->zd_op = op; ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; @@ -1900,6 +2023,27 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, nexthop->nh_encap_type = NET_VXLAN; nexthop->nh_encap.vni = zl3vni->vni; } + + /* Optionally capture extra interface info while we're in the + * main zebra pthread - a plugin has to ask for this info. + */ + if (dplane_collect_extra_intf_info) { + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); + + if (ifp) { + if_extra = XCALLOC( + MTYPE_DP_INTF, + sizeof(struct dplane_intf_extra)); + if_extra->vrf_id = nexthop->vrf_id; + if_extra->ifindex = nexthop->ifindex; + if_extra->flags = ifp->flags; + if_extra->status = ifp->status; + + TAILQ_INSERT_TAIL(&ctx->u.rinfo.intf_extra_q, + if_extra, link); + } + } } /* Don't need some info when capturing a system notification */ @@ -2224,20 +2368,14 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx, struct zebra_pbr_rule *new_rule, struct zebra_pbr_rule *old_rule) { - if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) { - char buf1[PREFIX_STRLEN]; - char buf2[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "init dplane ctx %s: IF %s Prio %u Fwmark %u Src %s Dst %s Table %u", + "init dplane ctx %s: IF %s Prio %u Fwmark %u Src %pFX Dst %pFX Table %u", dplane_op2str(op), new_rule->ifname, new_rule->rule.priority, new_rule->rule.filter.fwmark, - prefix2str(&new_rule->rule.filter.src_ip, buf1, - sizeof(buf1)), - prefix2str(&new_rule->rule.filter.dst_ip, buf2, - sizeof(buf2)), + &new_rule->rule.filter.src_ip, + &new_rule->rule.filter.dst_ip, new_rule->rule.action.table); - } ctx->zd_op = op; ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; @@ -2845,6 +2983,80 @@ done: } /* + * Enqueue access br_port update. + */ +enum zebra_dplane_result +dplane_br_port_update(const struct interface *ifp, bool non_df, + uint32_t sph_filter_cnt, + const struct in_addr *sph_filters, uint32_t backup_nhg_id) +{ + enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; + uint32_t flags = 0; + int ret; + struct zebra_dplane_ctx *ctx = NULL; + struct zebra_ns *zns; + enum dplane_op_e op = DPLANE_OP_BR_PORT_UPDATE; + + if (non_df) + flags |= DPLANE_BR_PORT_NON_DF; + + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL || IS_ZEBRA_DEBUG_EVPN_MH_ES) { + uint32_t i; + char vtep_str[ES_VTEP_LIST_STR_SZ]; + + vtep_str[0] = '\0'; + for (i = 0; i < sph_filter_cnt; ++i) { + snprintfrr(vtep_str + strlen(vtep_str), + sizeof(vtep_str) - strlen(vtep_str), "%pI4 ", + &sph_filters[i]); + } + zlog_debug( + "init br_port ctx %s: ifp %s, flags 0x%x backup_nhg 0x%x sph %s", + dplane_op2str(op), ifp->name, flags, backup_nhg_id, + vtep_str); + } + + ctx = dplane_ctx_alloc(); + + ctx->zd_op = op; + ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; + ctx->zd_vrf_id = ifp->vrf_id; + + zns = zebra_ns_lookup(ifp->vrf_id); + dplane_ctx_ns_init(ctx, zns, false); + + ctx->zd_ifindex = ifp->ifindex; + strlcpy(ctx->zd_ifname, ifp->name, sizeof(ctx->zd_ifname)); + + /* Init the br-port-specific data area */ + memset(&ctx->u.br_port, 0, sizeof(ctx->u.br_port)); + + ctx->u.br_port.flags = flags; + ctx->u.br_port.backup_nhg_id = backup_nhg_id; + ctx->u.br_port.sph_filter_cnt = sph_filter_cnt; + memcpy(ctx->u.br_port.sph_filters, sph_filters, + sizeof(ctx->u.br_port.sph_filters[0]) * sph_filter_cnt); + + /* Enqueue for processing on the dplane pthread */ + ret = dplane_update_enqueue(ctx); + + /* Increment counter */ + atomic_fetch_add_explicit(&zdplane_info.dg_br_port_in, 1, + memory_order_relaxed); + + if (ret == AOK) { + result = ZEBRA_DPLANE_REQUEST_QUEUED; + } else { + /* Error counter */ + atomic_fetch_add_explicit(&zdplane_info.dg_br_port_errors, 1, + memory_order_relaxed); + dplane_ctx_free(&ctx); + } + + return result; +} + +/* * Enqueue interface address add for the dataplane. */ enum zebra_dplane_result dplane_intf_addr_set(const struct interface *ifp, @@ -2895,15 +3107,10 @@ static enum zebra_dplane_result intf_addr_update_internal( struct zebra_dplane_ctx *ctx = NULL; struct zebra_ns *zns; - if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) { - char addr_str[PREFIX_STRLEN]; - - prefix2str(ifc->address, addr_str, sizeof(addr_str)); - - zlog_debug("init intf ctx %s: idx %d, addr %u:%s", + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) + zlog_debug("init intf ctx %s: idx %d, addr %u:%pFX", dplane_op2str(op), ifp->ifindex, ifp->vrf_id, - addr_str); - } + ifc->address); ctx = dplane_ctx_alloc(); @@ -3220,8 +3427,8 @@ enum zebra_dplane_result dplane_vtep_add(const struct interface *ifp, struct ipaddr addr; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Install %s into flood list for VNI %u intf %s(%u)", - inet_ntoa(*ip), vni, ifp->name, ifp->ifindex); + zlog_debug("Install %pI4 into flood list for VNI %u intf %s(%u)", + ip, vni, ifp->name, ifp->ifindex); SET_IPADDR_V4(&addr); addr.ipaddr_v4 = *ip; @@ -3245,8 +3452,8 @@ enum zebra_dplane_result dplane_vtep_delete(const struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Uninstall %s from flood list for VNI %u intf %s(%u)", - inet_ntoa(*ip), vni, ifp->name, ifp->ifindex); + "Uninstall %pI4 from flood list for VNI %u intf %s(%u)", + ip, vni, ifp->name, ifp->ifindex); SET_IPADDR_V4(&addr); addr.ipaddr_v4 = *ip; @@ -3461,6 +3668,13 @@ int dplane_show_helper(struct vty *vty, bool detailed) vty_out(vty, "Rule updates: %" PRIu64 "\n", incoming); vty_out(vty, "Rule errors: %" PRIu64 "\n", errs); + incoming = atomic_load_explicit(&zdplane_info.dg_br_port_in, + memory_order_relaxed); + errs = atomic_load_explicit(&zdplane_info.dg_br_port_errors, + memory_order_relaxed); + vty_out(vty, "Bridge port updates: %" PRIu64 "\n", incoming); + vty_out(vty, "Bridge port errors: %" PRIu64 "\n", errs); + return CMD_SUCCESS; } @@ -3773,11 +3987,9 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) case DPLANE_OP_ROUTE_INSTALL: case DPLANE_OP_ROUTE_UPDATE: case DPLANE_OP_ROUTE_DELETE: - prefix2str(dplane_ctx_get_dest(ctx), buf, sizeof(buf)); - - zlog_debug("%u:%s Dplane route update ctx %p op %s", - dplane_ctx_get_vrf(ctx), buf, ctx, - dplane_op2str(dplane_ctx_get_op(ctx))); + zlog_debug("%u:%pFX Dplane route update ctx %p op %s", + dplane_ctx_get_vrf(ctx), dplane_ctx_get_dest(ctx), + ctx, dplane_op2str(dplane_ctx_get_op(ctx))); break; case DPLANE_OP_NH_INSTALL: @@ -3804,11 +4016,10 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) case DPLANE_OP_ADDR_INSTALL: case DPLANE_OP_ADDR_UNINSTALL: - prefix2str(dplane_ctx_get_intf_addr(ctx), buf, sizeof(buf)); - - zlog_debug("Dplane intf %s, idx %u, addr %s", + zlog_debug("Dplane intf %s, idx %u, addr %pFX", dplane_op2str(dplane_ctx_get_op(ctx)), - dplane_ctx_get_ifindex(ctx), buf); + dplane_ctx_get_ifindex(ctx), + dplane_ctx_get_intf_addr(ctx)); break; case DPLANE_OP_MAC_INSTALL: @@ -3848,6 +4059,7 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) case DPLANE_OP_SYS_ROUTE_DELETE: case DPLANE_OP_ROUTE_NOTIFY: case DPLANE_OP_LSP_NOTIFY: + case DPLANE_OP_BR_PORT_UPDATE: case DPLANE_OP_NONE: break; @@ -3952,6 +4164,7 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx) case DPLANE_OP_SYS_ROUTE_DELETE: case DPLANE_OP_ROUTE_NOTIFY: case DPLANE_OP_LSP_NOTIFY: + case DPLANE_OP_BR_PORT_UPDATE: break; case DPLANE_OP_NONE: @@ -4123,6 +4336,14 @@ bool dplane_is_in_shutdown(void) } /* + * Enable collection of extra info about interfaces in route updates. + */ +void dplane_enable_intf_extra_info(void) +{ + dplane_collect_extra_intf_info = true; +} + +/* * Early or pre-shutdown, de-init notification api. This runs pretty * early during zebra shutdown, as a signal to stop new work and prepare * for updates generated by shutdown/cleanup activity, as zebra tries to diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index fd70211f7c..1b2ea9d96b 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -152,6 +152,9 @@ enum dplane_op_e { /* Link layer address discovery */ DPLANE_OP_NEIGH_DISCOVER, + + /* bridge port update */ + DPLANE_OP_BR_PORT_UPDATE, }; /* @@ -184,6 +187,8 @@ enum dplane_op_e { #define DPLANE_NEIGH_SET_STATIC (1 << 2) #define DPLANE_NEIGH_SET_INACTIVE (1 << 3) +#define DPLANE_BR_PORT_NON_DF (1 << 0) + /* Enable system route notifications */ void dplane_enable_sys_route_notifs(void); @@ -199,6 +204,9 @@ void dplane_enable_sys_route_notifs(void); */ TAILQ_HEAD(dplane_ctx_q, zebra_dplane_ctx); +/* Declare a type for (optional) extended interface info objects. */ +TAILQ_HEAD(dplane_intf_extra_q, dplane_intf_extra); + /* Allocate a context object */ struct zebra_dplane_ctx *dplane_ctx_alloc(void); @@ -308,6 +316,21 @@ const struct nexthop_group *dplane_ctx_get_ng( const struct nexthop_group *dplane_ctx_get_old_ng( const struct zebra_dplane_ctx *ctx); +/* Optional extra info about interfaces in nexthops - a plugin must enable + * this extra info. + */ +const struct dplane_intf_extra * +dplane_ctx_get_intf_extra(const struct zebra_dplane_ctx *ctx); + +const struct dplane_intf_extra * +dplane_ctx_intf_extra_next(const struct zebra_dplane_ctx *ctx, + const struct dplane_intf_extra *ptr); + +vrf_id_t dplane_intf_extra_get_vrfid(const struct dplane_intf_extra *ptr); +uint32_t dplane_intf_extra_get_ifindex(const struct dplane_intf_extra *ptr); +uint32_t dplane_intf_extra_get_flags(const struct dplane_intf_extra *ptr); +uint32_t dplane_intf_extra_get_status(const struct dplane_intf_extra *ptr); + /* Backup nexthop information (list of nexthops) if present. */ const struct nexthop_group * dplane_ctx_get_backup_ng(const struct zebra_dplane_ctx *ctx); @@ -444,6 +467,15 @@ dplane_ctx_rule_get_dst_ip(const struct zebra_dplane_ctx *ctx); const struct prefix * dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx); +/* Accessors for bridge port information */ +uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx); +uint32_t +dplane_ctx_get_br_port_sph_filter_cnt(const struct zebra_dplane_ctx *ctx); +const struct in_addr * +dplane_ctx_get_br_port_sph_filters(const struct zebra_dplane_ctx *ctx); +uint32_t +dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx); + /* Namespace info - esp. for netlink communication */ const struct zebra_dplane_info *dplane_ctx_get_ns( const struct zebra_dplane_ctx *ctx); @@ -479,6 +511,12 @@ enum zebra_dplane_result dplane_route_notif_update( enum dplane_op_e op, struct zebra_dplane_ctx *ctx); +/* + * Enqueue bridge port changes for the dataplane. + */ +enum zebra_dplane_result dplane_br_port_update( + const struct interface *ifp, bool non_df, uint32_t sph_filter_cnt, + const struct in_addr *sph_filters, uint32_t backup_nhg_id); /* Forward ref of nhg_hash_entry */ struct nhg_hash_entry; @@ -723,6 +761,12 @@ void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov, /* Enqueue a context directly to zebra main. */ void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx); +/* Enable collection of extra info about interfaces in route updates; + * this allows a provider/plugin to see some extra info in route update + * context objects. + */ +void dplane_enable_intf_extra_info(void); + /* * Initialize the dataplane modules at zebra startup. This is currently called * by the rib module. Zebra registers a results callback with the dataplane. diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 56699c4e83..6722af117c 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -109,6 +109,7 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) json_object *json = NULL; json_object *json_vtep_list = NULL; json_object *json_ip_str = NULL; + char buf[PREFIX_STRLEN]; vty = ctxt[0]; json = ctxt[1]; @@ -134,18 +135,20 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) if (json == NULL) { vty_out(vty, " VxLAN interface: %s\n", zevpn->vxlan_if->name); vty_out(vty, " VxLAN ifIndex: %u\n", zevpn->vxlan_if->ifindex); - vty_out(vty, " Local VTEP IP: %s\n", - inet_ntoa(zevpn->local_vtep_ip)); - vty_out(vty, " Mcast group: %s\n", - inet_ntoa(zevpn->mcast_grp)); + vty_out(vty, " Local VTEP IP: %pI4\n", + &zevpn->local_vtep_ip); + vty_out(vty, " Mcast group: %pI4\n", + &zevpn->mcast_grp); } else { json_object_string_add(json, "vxlanInterface", zevpn->vxlan_if->name); json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex); json_object_string_add(json, "vtepIp", - inet_ntoa(zevpn->local_vtep_ip)); + inet_ntop(AF_INET, &zevpn->local_vtep_ip, + buf, sizeof(buf))); json_object_string_add(json, "mcastGroup", - inet_ntoa(zevpn->mcast_grp)); + inet_ntop(AF_INET, &zevpn->mcast_grp, + buf, sizeof(buf))); json_object_string_add(json, "advertiseGatewayMacip", zevpn->advertise_gw_macip ? "Yes" : "No"); json_object_int_add(json, "numMacs", num_macs); @@ -165,12 +168,14 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt) VXLAN_FLOOD_STR_DEFAULT); if (json == NULL) { - vty_out(vty, " %s flood: %s\n", - inet_ntoa(zvtep->vtep_ip), + vty_out(vty, " %pI4 flood: %s\n", + &zvtep->vtep_ip, flood_str); } else { json_ip_str = json_object_new_string( - inet_ntoa(zvtep->vtep_ip)); + inet_ntop(AF_INET, + &zvtep->vtep_ip, buf, + sizeof(buf))); json_object_array_add(json_vtep_list, json_ip_str); } @@ -207,6 +212,7 @@ void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[]) json_object *json_evpn = NULL; json_object *json_ip_str = NULL; json_object *json_vtep_list = NULL; + char buf[PREFIX_STRLEN]; vty = ctxt[0]; json = ctxt[1]; @@ -245,7 +251,8 @@ void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[]) json_vtep_list = json_object_new_array(); for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) { json_ip_str = json_object_new_string( - inet_ntoa(zvtep->vtep_ip)); + inet_ntop(AF_INET, &zvtep->vtep_ip, buf, + sizeof(buf))); json_object_array_add(json_vtep_list, json_ip_str); } @@ -349,7 +356,6 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p, { struct zserv *client = NULL; struct stream *s = NULL; - char buf[PREFIX_STRLEN]; client = zserv_find_client(ZEBRA_ROUTE_BGP, 0); /* BGP may not be running. */ @@ -365,8 +371,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p, stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Send ip prefix %s %s on vrf %s", - prefix2str(p, buf, sizeof(buf)), + zlog_debug("Send ip prefix %pFX %s on vrf %s", p, (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL", vrf_id_to_name(vrf_id)); @@ -1076,8 +1081,8 @@ int zebra_evpn_send_add_to_client(zebra_evpn_t *zevpn) stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Send EVPN_ADD %u %s tenant vrf %s to %s", zevpn->vni, - inet_ntoa(zevpn->local_vtep_ip), + zlog_debug("Send EVPN_ADD %u %pI4 tenant vrf %s to %s", zevpn->vni, + &zevpn->local_vtep_ip, vrf_id_to_name(zevpn->vrf_id), zebra_route_string(client->proto)); diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 75031ddba6..4a2d8db422 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -417,11 +417,11 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, if (mac->dad_count >= zvrf->dad_max_moves) { flog_warn(EC_ZEBRA_DUP_MAC_DETECTED, - "VNI %u: MAC %s detected as duplicate during %s VTEP %s", + "VNI %u: MAC %s detected as duplicate during %s VTEP %pI4", mac->zevpn->vni, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), is_local ? "local update, last" : - "remote update, from", inet_ntoa(vtep_ip)); + "remote update, from", &vtep_ip); SET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE); @@ -485,10 +485,13 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) struct listnode *node = NULL; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; + char addr_buf[PREFIX_STRLEN]; struct zebra_vrf *zvrf; struct timeval detect_start_time = {0, 0}; char timebuf[MONOTIME_STRLEN]; char thread_buf[THREAD_TIMER_STRLEN]; + time_t uptime; + char up_str[MONOTIME_STRLEN]; zvrf = zebra_vrf_get_evpn(); if (!zvrf) @@ -497,6 +500,11 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) vty = (struct vty *)ctxt; prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)); + uptime = monotime(NULL); + uptime -= mac->uptime; + + frrtime_to_interval(uptime, up_str, sizeof(up_str)); + if (json) { json_object *json_mac = json_object_new_object(); @@ -518,7 +526,8 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) json_object_string_add(json_mac, "type", "remote"); json_object_string_add( json_mac, "remoteVtep", - inet_ntoa(mac->fwd_info.r_vtep_ip)); + inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip, + addr_buf, sizeof(addr_buf))); } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) json_object_string_add(json_mac, "type", "auto"); @@ -533,6 +542,7 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) json_object_boolean_true_add(json_mac, "remoteGatewayMac"); + json_object_string_add(json_mac, "uptime", up_str); json_object_int_add(json_mac, "localSequence", mac->loc_seq); json_object_int_add(json_mac, "remoteSequence", mac->rem_seq); @@ -617,8 +627,8 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) vty_out(vty, " Remote ES: %s", mac->es->esi_str); else - vty_out(vty, " Remote VTEP: %s", - inet_ntoa(mac->fwd_info.r_vtep_ip)); + vty_out(vty, " Remote VTEP: %pI4", + &mac->fwd_info.r_vtep_ip); } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) { vty_out(vty, " Auto Mac "); } @@ -646,9 +656,9 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) sizeof(thread_buf), mac->hold_timer)); vty_out(vty, "\n"); - vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq, + vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq, mac->rem_seq); - vty_out(vty, "\n"); + vty_out(vty, " Uptime: %s\n", up_str); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { vty_out(vty, " Duplicate, detected at %s", @@ -709,6 +719,7 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt) json_object *json_mac_hdr = NULL, *json_mac = NULL; zebra_mac_t *mac; char buf1[ETHER_ADDR_STRLEN]; + char addr_buf[PREFIX_STRLEN]; struct mac_walk_ctx *wctx = ctxt; char flags_buf[6]; @@ -785,18 +796,22 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt) "Intf/Remote ES/VTEP", "VLAN", "Seq #'s"); } + if (mac->es == NULL) + inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip, + addr_buf, sizeof(addr_buf)); + vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %u/%u\n", buf1, "remote", zebra_evpn_print_mac_flags(mac, flags_buf, - sizeof(flags_buf)), - mac->es ? mac->es->esi_str - : inet_ntoa(mac->fwd_info.r_vtep_ip), + sizeof(flags_buf)), + mac->es ? mac->es->esi_str : addr_buf, "", mac->loc_seq, mac->rem_seq); } else { json_object_string_add(json_mac, "type", "remote"); json_object_string_add( json_mac, "remoteVtep", - inet_ntoa(mac->fwd_info.r_vtep_ip)); + inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip, + addr_buf, sizeof(addr_buf))); json_object_object_add(json_mac_hdr, buf1, json_mac); json_object_int_add(json_mac, "localSequence", mac->loc_seq); @@ -965,6 +980,7 @@ zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr) mac->neigh_list = list_new(); mac->neigh_list->cmp = neigh_list_cmp; + mac->uptime = monotime(NULL); if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char buf[ETHER_ADDR_STRLEN]; @@ -1452,6 +1468,8 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, bool sticky; bool remote_gw; + mac->uptime = monotime(NULL); + old_flags = mac->flags; sticky = !!CHECK_FLAG(old_flags, ZEBRA_MAC_STICKY); remote_gw = !!CHECK_FLAG(old_flags, ZEBRA_MAC_REMOTE_DEF_GW); @@ -1769,10 +1787,10 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, mac = zebra_evpn_mac_add(zevpn, macaddr); if (!mac) { zlog_warn( - "Failed to add MAC %s VNI %u Remote VTEP %s", + "Failed to add MAC %s VNI %u Remote VTEP %pI4", prefix_mac2str(macaddr, buf, sizeof(buf)), - zevpn->vni, inet_ntoa(vtep_ip)); + zevpn->vni, &vtep_ip); return -1; } @@ -2028,10 +2046,10 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) { flog_warn( EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT, - "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u", + "MAC %s already learnt as remote sticky MAC behind VTEP %pI4 VNI %u", prefix_mac2str(macaddr, buf, sizeof(buf)), - inet_ntoa(mac->fwd_info.r_vtep_ip), + &mac->fwd_info.r_vtep_ip, zevpn->vni); return 0; } diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index f9ca81445f..596fd0faad 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -129,6 +129,8 @@ struct zebra_mac_t_ { * ZEBRA_MAC_ES_PEER_ACTIVE or ZEBRA_NEIGH_ES_PEER_PROXY */ uint32_t sync_neigh_cnt; + + time_t uptime; }; /* diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index f71065cdcf..692dfca5d7 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -38,6 +38,7 @@ #include "zebra/rib.h" #include "zebra/rt.h" #include "zebra/rt_netlink.h" +#include "zebra/if_netlink.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_l2.h" #include "zebra/zebra_memory.h" @@ -63,6 +64,11 @@ static int zebra_evpn_es_evi_send_to_client(struct zebra_evpn_es *es, static void zebra_evpn_local_es_del(struct zebra_evpn_es **esp); static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid, struct ethaddr *sysmac); +static bool zebra_evpn_es_br_port_dplane_update(struct zebra_evpn_es *es, + const char *caller); +static void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set); +static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es); +static void zebra_evpn_mh_clear_protodown_es(struct zebra_evpn_es *es); esi_t zero_esi_buf, *zero_esi = &zero_esi_buf; @@ -253,12 +259,29 @@ static void zebra_evpn_local_es_evi_add(struct zebra_evpn_es *es, } static void zebra_evpn_es_evi_show_entry(struct vty *vty, - struct zebra_evpn_es_evi *es_evi, json_object *json) + struct zebra_evpn_es_evi *es_evi, + json_object *json_array) { char type_str[4]; - if (json) { - /* XXX */ + if (json_array) { + json_object *json; + json_object *json_types; + + /* Separate JSON object for each es-evi entry */ + json = json_object_new_object(); + + json_object_string_add(json, "esi", es_evi->es->esi_str); + json_object_int_add(json, "vni", es_evi->zevpn->vni); + if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL) { + json_types = json_object_new_array(); + if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL) + json_array_string_add(json_types, "local"); + json_object_object_add(json, "type", json_types); + } + + /* Add es-evi entry to json array */ + json_object_array_add(json_array, json); } else { type_str[0] = '\0'; if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL) @@ -270,13 +293,36 @@ static void zebra_evpn_es_evi_show_entry(struct vty *vty, } } -static void zebra_evpn_es_evi_show_entry_detail(struct vty *vty, - struct zebra_evpn_es_evi *es_evi, json_object *json) +static void +zebra_evpn_es_evi_show_entry_detail(struct vty *vty, + struct zebra_evpn_es_evi *es_evi, + json_object *json_array) { char type_str[4]; - if (json) { - /* XXX */ + if (json_array) { + json_object *json; + json_object *json_flags; + + /* Separate JSON object for each es-evi entry */ + json = json_object_new_object(); + + json_object_string_add(json, "esi", es_evi->es->esi_str); + json_object_int_add(json, "vni", es_evi->zevpn->vni); + if (es_evi->flags + & (ZEBRA_EVPNES_EVI_LOCAL + | ZEBRA_EVPNES_EVI_READY_FOR_BGP)) { + json_flags = json_object_new_array(); + if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL) + json_array_string_add(json_flags, "local"); + if (es_evi->flags & ZEBRA_EVPNES_EVI_READY_FOR_BGP) + json_array_string_add(json_flags, + "readyForBgp"); + json_object_object_add(json, "flags", json_flags); + } + + /* Add es-evi entry to json array */ + json_object_array_add(json_array, json); } else { type_str[0] = '\0'; if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL) @@ -294,15 +340,17 @@ static void zebra_evpn_es_evi_show_entry_detail(struct vty *vty, } static void zebra_evpn_es_evi_show_one_evpn(zebra_evpn_t *zevpn, - struct vty *vty, json_object *json, int detail) + struct vty *vty, + json_object *json_array, int detail) { struct zebra_evpn_es_evi *es_evi; RB_FOREACH(es_evi, zebra_es_evi_rb_head, &zevpn->es_evi_rb_tree) { if (detail) - zebra_evpn_es_evi_show_entry_detail(vty, es_evi, json); + zebra_evpn_es_evi_show_entry_detail(vty, es_evi, + json_array); else - zebra_evpn_es_evi_show_entry(vty, es_evi, json); + zebra_evpn_es_evi_show_entry(vty, es_evi, json_array); } } @@ -324,42 +372,64 @@ static void zebra_evpn_es_evi_show_one_evpn_hash_cb(struct hash_bucket *bucket, void zebra_evpn_es_evi_show(struct vty *vty, bool uj, int detail) { - json_object *json = NULL; + json_object *json_array = NULL; struct zebra_vrf *zvrf; struct evpn_mh_show_ctx wctx; zvrf = zebra_vrf_get_evpn(); + if (uj) + json_array = json_object_new_array(); memset(&wctx, 0, sizeof(wctx)); wctx.vty = vty; - wctx.json = json; + wctx.json = json_array; wctx.detail = detail; - if (!detail && !json) { + if (!detail && !json_array) { vty_out(vty, "Type: L local, R remote\n"); vty_out(vty, "%-8s %-30s %-4s\n", "VNI", "ESI", "Type"); } /* Display all L2-VNIs */ hash_iterate(zvrf->evpn_table, zebra_evpn_es_evi_show_one_evpn_hash_cb, &wctx); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); + } } void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj, vni_t vni, int detail) { - json_object *json = NULL; + json_object *json_array = NULL; zebra_evpn_t *zevpn; zevpn = zebra_evpn_lookup(vni); + if (uj) + json_array = json_object_new_array(); + if (zevpn) { - if (!detail && !json) { + if (!detail && !json_array) { vty_out(vty, "Type: L local, R remote\n"); vty_out(vty, "%-8s %-30s %-4s\n", "VNI", "ESI", "Type"); } } else { if (!uj) vty_out(vty, "VNI %d doesn't exist\n", vni); + + return; + } + + zebra_evpn_es_evi_show_one_evpn(zevpn, vty, json_array, detail); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); } - zebra_evpn_es_evi_show_one_evpn(zevpn, vty, json, detail); } /* Initialize the ES tables maintained per-L2_VNI */ @@ -687,6 +757,37 @@ void zebra_evpn_vl_mbr_deref(uint16_t vid, struct zebra_if *zif) zebra_evpn_acc_bd_free_on_deref(acc_bd); } +static void zebra_evpn_acc_vl_json_fill(struct zebra_evpn_access_bd *acc_bd, + json_object *json, bool detail) +{ + json_object_int_add(json, "vlan", acc_bd->vid); + if (acc_bd->vxlan_zif) + json_object_string_add(json, "vxlanIf", + acc_bd->vxlan_zif->ifp->name); + if (acc_bd->zevpn) + json_object_int_add(json, "vni", acc_bd->zevpn->vni); + if (acc_bd->mbr_zifs) + json_object_int_add(json, "memberIfCount", + listcount(acc_bd->mbr_zifs)); + + if (detail) { + json_object *json_mbrs; + json_object *json_mbr; + struct zebra_if *zif; + struct listnode *node; + + + json_mbrs = json_object_new_array(); + for (ALL_LIST_ELEMENTS_RO(acc_bd->mbr_zifs, node, zif)) { + json_mbr = json_object_new_object(); + json_object_string_add(json_mbr, "ifName", + zif->ifp->name); + json_object_array_add(json_mbrs, json_mbr); + } + json_object_object_add(json, "members", json_mbrs); + } +} + static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty, struct zebra_evpn_access_bd *acc_bd, json_object *json) { @@ -694,7 +795,7 @@ static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty, struct listnode *node; if (json) { - /* XXX */ + zebra_evpn_acc_vl_json_fill(acc_bd, json, true); } else { vty_out(vty, "VLAN: %u\n", acc_bd->vid); vty_out(vty, " VxLAN Interface: %s\n", @@ -714,58 +815,83 @@ static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty, static void zebra_evpn_acc_vl_show_entry(struct vty *vty, struct zebra_evpn_access_bd *acc_bd, json_object *json) { - if (!json) + if (json) { + zebra_evpn_acc_vl_json_fill(acc_bd, json, false); + } else { vty_out(vty, "%-5u %21s %-8d %u\n", acc_bd->vid, acc_bd->vxlan_zif ? acc_bd->vxlan_zif->ifp->name : "-", acc_bd->zevpn ? acc_bd->zevpn->vni : 0, listcount(acc_bd->mbr_zifs)); + } } static void zebra_evpn_acc_vl_show_hash(struct hash_bucket *bucket, void *ctxt) { struct evpn_mh_show_ctx *wctx = ctxt; struct zebra_evpn_access_bd *acc_bd = bucket->data; + json_object *json = NULL; + if (wctx->json) + json = json_object_new_object(); if (wctx->detail) - zebra_evpn_acc_vl_show_entry_detail(wctx->vty, - acc_bd, wctx->json); + zebra_evpn_acc_vl_show_entry_detail(wctx->vty, acc_bd, json); else - zebra_evpn_acc_vl_show_entry(wctx->vty, - acc_bd, wctx->json); + zebra_evpn_acc_vl_show_entry(wctx->vty, acc_bd, json); + if (json) + json_object_array_add(wctx->json, json); } void zebra_evpn_acc_vl_show(struct vty *vty, bool uj) { - json_object *json = NULL; struct evpn_mh_show_ctx wctx; + json_object *json_array = NULL; + + if (uj) + json_array = json_object_new_array(); memset(&wctx, 0, sizeof(wctx)); wctx.vty = vty; - wctx.json = json; + wctx.json = json_array; wctx.detail = false; - if (!json) + if (!uj) vty_out(vty, "%-5s %21s %-8s %s\n", "VLAN", "VxLAN-IF", "L2-VNI", "# Members"); hash_iterate(zmh_info->evpn_vlan_table, zebra_evpn_acc_vl_show_hash, &wctx); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); + } } void zebra_evpn_acc_vl_show_detail(struct vty *vty, bool uj) { - json_object *json = NULL; struct evpn_mh_show_ctx wctx; + json_object *json_array = NULL; + if (uj) + json_array = json_object_new_array(); memset(&wctx, 0, sizeof(wctx)); wctx.vty = vty; - wctx.json = json; + wctx.json = json_array; wctx.detail = true; hash_iterate(zmh_info->evpn_vlan_table, zebra_evpn_acc_vl_show_hash, &wctx); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); + } } void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid) @@ -773,14 +899,23 @@ void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid) json_object *json = NULL; struct zebra_evpn_access_bd *acc_bd; + if (uj) + json = json_object_new_object(); + acc_bd = zebra_evpn_acc_vl_find(vid); - if (!acc_bd) { - if (!json) { + if (acc_bd) { + zebra_evpn_acc_vl_show_entry_detail(vty, acc_bd, json); + } else { + if (!json) vty_out(vty, "VLAN %u not present\n", vid); - return; - } } - zebra_evpn_acc_vl_show_entry_detail(vty, acc_bd, json); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } } /* Initialize VLAN member bitmap on an interface. Although VLAN membership @@ -808,6 +943,7 @@ void zebra_evpn_if_init(struct zebra_if *zif) void zebra_evpn_if_cleanup(struct zebra_if *zif) { vlanid_t vid; + struct zebra_evpn_es *es; if (!bf_is_inited(zif->vlan_bitmap)) return; @@ -819,8 +955,9 @@ void zebra_evpn_if_cleanup(struct zebra_if *zif) bf_free(zif->vlan_bitmap); /* Delete associated Ethernet Segment */ - if (zif->es_info.es) - zebra_evpn_local_es_del(&zif->es_info.es); + es = zif->es_info.es; + if (es) + zebra_evpn_local_es_del(&es); } /***************************************************************************** @@ -893,12 +1030,23 @@ static void zebra_evpn_nhg_update(struct zebra_evpn_es *es) es->flags |= ZEBRA_EVPNES_NHG_ACTIVE; kernel_upd_mac_nhg(es->nhg_id, nh_cnt, nh_ids); + if (!(es->flags & ZEBRA_EVPNES_NHG_ACTIVE)) { + es->flags |= ZEBRA_EVPNES_NHG_ACTIVE; + /* add backup NHG to the br-port */ + if ((es->flags & ZEBRA_EVPNES_LOCAL)) + zebra_evpn_es_br_port_dplane_update(es, + __func__); + } } else { if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) { if (IS_ZEBRA_DEBUG_EVPN_MH_NH) zlog_debug("es %s nhg 0x%x del", es->esi_str, es->nhg_id); es->flags &= ~ZEBRA_EVPNES_NHG_ACTIVE; + /* remove backup NHG from the br-port */ + if ((es->flags & ZEBRA_EVPNES_LOCAL)) + zebra_evpn_es_br_port_dplane_update(es, + __func__); kernel_del_mac_nhg(es->nhg_id); } } @@ -917,9 +1065,9 @@ static void zebra_evpn_nh_add(struct zebra_evpn_es_vtep *es_vtep) return; if (IS_ZEBRA_DEBUG_EVPN_MH_NH) - zlog_debug("es %s vtep %s nh 0x%x add", + zlog_debug("es %s vtep %pI4 nh 0x%x add", es_vtep->es->esi_str, - inet_ntoa(es_vtep->vtep_ip), es_vtep->nh_id); + &es_vtep->vtep_ip, es_vtep->nh_id); /* install the NH */ kernel_upd_mac_nh(es_vtep->nh_id, es_vtep->vtep_ip); /* add the NH to the parent NHG */ @@ -934,9 +1082,9 @@ static void zebra_evpn_nh_del(struct zebra_evpn_es_vtep *es_vtep) return; if (IS_ZEBRA_DEBUG_EVPN_MH_NH) - zlog_debug("es %s vtep %s nh 0x%x del", + zlog_debug("es %s vtep %pI4 nh 0x%x del", es_vtep->es->esi_str, - inet_ntoa(es_vtep->vtep_ip), es_vtep->nh_id); + &es_vtep->vtep_ip, es_vtep->nh_id); nh_id = es_vtep->nh_id; es_vtep->nh_id = 0; @@ -1013,34 +1161,215 @@ static struct zebra_evpn_es_vtep *zebra_evpn_es_vtep_find( return NULL; } +/* flush all the dataplane br-port info associated with the ES */ +static bool zebra_evpn_es_br_port_dplane_clear(struct zebra_evpn_es *es) +{ + struct in_addr sph_filters[ES_VTEP_MAX_CNT]; + + if (!(es->flags & ZEBRA_EVPNES_BR_PORT)) + return false; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("es %s br-port dplane clear", es->esi_str); + + memset(&sph_filters, 0, sizeof(sph_filters)); + dplane_br_port_update(es->zif->ifp, false /* non_df */, 0, sph_filters, + 0 /* backup_nhg_id */); + return true; +} + +static inline bool +zebra_evpn_es_br_port_dplane_update_needed(struct zebra_evpn_es *es) +{ + return (es->flags & ZEBRA_EVPNES_NON_DF) + || (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) + || listcount(es->es_vtep_list); +} + +/* returns TRUE if dplane entry was updated */ +static bool zebra_evpn_es_br_port_dplane_update(struct zebra_evpn_es *es, + const char *caller) +{ + uint32_t backup_nhg_id; + struct in_addr sph_filters[ES_VTEP_MAX_CNT]; + struct listnode *node = NULL; + struct zebra_evpn_es_vtep *es_vtep; + uint32_t sph_filter_cnt = 0; + + if (!(es->flags & ZEBRA_EVPNES_LOCAL)) + return zebra_evpn_es_br_port_dplane_clear(es); + + /* If the ES is not a bridge port there is nothing + * in the dataplane + */ + if (!(es->flags & ZEBRA_EVPNES_BR_PORT)) + return false; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("es %s br-port dplane update by %s", es->esi_str, caller); + backup_nhg_id = (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) ? es->nhg_id : 0; + + memset(&sph_filters, 0, sizeof(sph_filters)); + if (listcount(es->es_vtep_list) > ES_VTEP_MAX_CNT) { + zlog_warn("es %s vtep count %d exceeds filter cnt %d", + es->esi_str, listcount(es->es_vtep_list), + ES_VTEP_MAX_CNT); + } else { + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { + if (es_vtep->flags & ZEBRA_EVPNES_VTEP_DEL_IN_PROG) + continue; + sph_filters[sph_filter_cnt] = es_vtep->vtep_ip; + ++sph_filter_cnt; + } + } + + dplane_br_port_update(es->zif->ifp, !!(es->flags & ZEBRA_EVPNES_NON_DF), + sph_filter_cnt, sph_filters, backup_nhg_id); + + return true; +} + +/* returns TRUE if dplane entry was updated */ +static bool zebra_evpn_es_df_change(struct zebra_evpn_es *es, bool new_non_df, + const char *caller) +{ + bool old_non_df; + + old_non_df = !!(es->flags & ZEBRA_EVPNES_NON_DF); + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("df-change(%s) es %s old %s new %s", caller, + es->esi_str, old_non_df ? "non-df" : "df", + new_non_df ? "non-df" : "df"); + + if (old_non_df == new_non_df) + return false; + + if (new_non_df) + es->flags |= ZEBRA_EVPNES_NON_DF; + else + es->flags &= ~ZEBRA_EVPNES_NON_DF; + + /* update non-DF block filter in the dataplane */ + return zebra_evpn_es_br_port_dplane_update(es, __func__); +} + + +/* returns TRUE if dplane entry was updated */ +static bool zebra_evpn_es_run_df_election(struct zebra_evpn_es *es, + const char *caller) +{ + struct listnode *node = NULL; + struct zebra_evpn_es_vtep *es_vtep; + bool new_non_df = false; + + /* If the ES is not ready (i.e. not completely configured) there + * is no need to setup the BUM block filter + */ + if (!(es->flags & ZEBRA_EVPNES_LOCAL) + || !zmh_info->es_originator_ip.s_addr) + return zebra_evpn_es_df_change(es, new_non_df, caller); + + /* if oper-state is down DF filtering must be on. when the link comes + * up again dataplane should block BUM till FRR has had the chance + * to run DF election again + */ + if (!(es->flags & ZEBRA_EVPNES_OPER_UP)) { + new_non_df = true; + return zebra_evpn_es_df_change(es, new_non_df, caller); + } + + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { + /* Only VTEPs that have advertised the ESR can participate + * in DF election + */ + if (!(es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR)) + continue; + + /* If the DF alg is not the same we should fall back to + * service-carving. But as service-carving is not supported + * we will stop forwarding BUM + */ + if (es_vtep->df_alg != EVPN_MH_DF_ALG_PREF) { + new_non_df = true; + break; + } + + /* Peer VTEP wins DF election if - + * the peer-VTEP has higher preference (or) + * the pref is the same but peer's IP address is lower + */ + if ((es_vtep->df_pref > es->df_pref) + || ((es_vtep->df_pref == es->df_pref) + && (es_vtep->vtep_ip.s_addr + < zmh_info->es_originator_ip.s_addr))) { + new_non_df = true; + break; + } + } + + return zebra_evpn_es_df_change(es, new_non_df, caller); +} + static void zebra_evpn_es_vtep_add(struct zebra_evpn_es *es, - struct in_addr vtep_ip) + struct in_addr vtep_ip, bool esr_rxed, + uint8_t df_alg, uint16_t df_pref) { struct zebra_evpn_es_vtep *es_vtep; + bool old_esr_rxed; + bool dplane_updated = false; es_vtep = zebra_evpn_es_vtep_find(es, vtep_ip); if (!es_vtep) { if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("es %s vtep %s add", - es->esi_str, inet_ntoa(vtep_ip)); + zlog_debug("es %s vtep %pI4 add", + es->esi_str, &vtep_ip); es_vtep = zebra_evpn_es_vtep_new(es, vtep_ip); /* update the L2-NHG associated with the ES */ zebra_evpn_nh_add(es_vtep); } + + old_esr_rxed = !!(es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR); + if ((old_esr_rxed != esr_rxed) || (es_vtep->df_alg != df_alg) + || (es_vtep->df_pref != df_pref)) { + /* If any of the DF election params changed we need to re-run + * DF election + */ + if (esr_rxed) + es_vtep->flags |= ZEBRA_EVPNES_VTEP_RXED_ESR; + else + es_vtep->flags &= ~ZEBRA_EVPNES_VTEP_RXED_ESR; + es_vtep->df_alg = df_alg; + es_vtep->df_pref = df_pref; + dplane_updated = zebra_evpn_es_run_df_election(es, __func__); + } + /* add the vtep to the SPH list */ + if (!dplane_updated && (es->flags & ZEBRA_EVPNES_LOCAL)) + zebra_evpn_es_br_port_dplane_update(es, __func__); } static void zebra_evpn_es_vtep_del(struct zebra_evpn_es *es, struct in_addr vtep_ip) { struct zebra_evpn_es_vtep *es_vtep; + bool dplane_updated = false; es_vtep = zebra_evpn_es_vtep_find(es, vtep_ip); if (es_vtep) { if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("es %s vtep %s del", - es->esi_str, inet_ntoa(vtep_ip)); + zlog_debug("es %s vtep %pI4 del", + es->esi_str, &vtep_ip); + es_vtep->flags |= ZEBRA_EVPNES_VTEP_DEL_IN_PROG; + if (es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR) { + es_vtep->flags &= ~ZEBRA_EVPNES_VTEP_RXED_ESR; + dplane_updated = + zebra_evpn_es_run_df_election(es, __func__); + } + /* remove the vtep from the SPH list */ + if (!dplane_updated && (es->flags & ZEBRA_EVPNES_LOCAL)) + zebra_evpn_es_br_port_dplane_update(es, __func__); zebra_evpn_es_vtep_free(es_vtep); } } @@ -1161,15 +1490,16 @@ static int zebra_evpn_es_send_add_to_client(struct zebra_evpn_es *es) stream_put_ipv4(s, zmh_info->es_originator_ip.s_addr); oper_up = !!(es->flags & ZEBRA_EVPNES_OPER_UP); stream_putc(s, oper_up); + stream_putw(s, es->df_pref); /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("send add local es %s %s to %s", - es->esi_str, - inet_ntoa(zmh_info->es_originator_ip), - zebra_route_string(client->proto)); + zlog_debug("send add local es %s %pI4 active %u df_pref %u to %s", + es->esi_str, &zmh_info->es_originator_ip, + oper_up, es->df_pref, + zebra_route_string(client->proto)); client->local_es_add_cnt++; return zserv_send_message(client, s); @@ -1306,6 +1636,30 @@ static void zebra_evpn_es_local_mac_update(struct zebra_evpn_es *es, } } +void zebra_evpn_es_local_br_port_update(struct zebra_if *zif) +{ + struct zebra_evpn_es *es = zif->es_info.es; + bool old_br_port = !!(es->flags & ZEBRA_EVPNES_BR_PORT); + bool new_br_port; + + if (zif->brslave_info.bridge_ifindex != IFINDEX_INTERNAL) + es->flags |= ZEBRA_EVPNES_BR_PORT; + else + es->flags &= ~ZEBRA_EVPNES_BR_PORT; + + new_br_port = !!(es->flags & ZEBRA_EVPNES_BR_PORT); + if (old_br_port == new_br_port) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("es %s br_port change old %u new %u", es->esi_str, + old_br_port, new_br_port); + + /* update the dataplane br_port attrs */ + if (new_br_port && zebra_evpn_es_br_port_dplane_update_needed(es)) + zebra_evpn_es_br_port_dplane_update(es, __func__); +} + static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, struct zebra_if *zif) { @@ -1322,12 +1676,17 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, /* attach es to interface */ zif->es_info.es = es; + es->df_pref = zif->es_info.df_pref ? zif->es_info.df_pref + : EVPN_MH_DF_PREF_DEFAULT; /* attach interface to es */ es->zif = zif; if (if_is_operative(zif->ifp)) es->flags |= ZEBRA_EVPNES_OPER_UP; + if (zif->brslave_info.bridge_ifindex != IFINDEX_INTERNAL) + es->flags |= ZEBRA_EVPNES_BR_PORT; + /* setup base-vni if one doesn't already exist; the ES will get sent * to BGP as a part of that process */ @@ -1338,6 +1697,16 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, zebra_evpn_es_re_eval_send_to_client(es, false /* es_evi_re_reval */); + /* See if the local VTEP can function as DF on the ES */ + if (!zebra_evpn_es_run_df_election(es, __func__)) { + /* check if the dplane entry needs to be re-programmed as a + * result of some thing other than DF status change + */ + if (zebra_evpn_es_br_port_dplane_update_needed(es)) + zebra_evpn_es_br_port_dplane_update(es, __func__); + } + + /* Setup ES-EVIs for all VxLAN stretched VLANs associated with * the zif */ @@ -1348,29 +1717,46 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es, */ zebra_evpn_es_local_mac_update(es, false /* force_clear_static */); + + /* inherit EVPN protodown flags on the access port */ + zebra_evpn_mh_update_protodown_es(es); } static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es **esp) { struct zebra_if *zif; struct zebra_evpn_es *es = *esp; + bool dplane_updated = false; if (!(es->flags & ZEBRA_EVPNES_LOCAL)) return; es->flags &= ~(ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_READY_FOR_BGP); + /* remove the DF filter */ + dplane_updated = zebra_evpn_es_run_df_election(es, __func__); + + /* clear EVPN protodown flags on the access port */ + zebra_evpn_mh_clear_protodown_es(es); + /* if there any local macs referring to the ES as dest we * need to clear the static reference on them */ zebra_evpn_es_local_mac_update(es, true /* force_clear_static */); + /* flush the BUM filters and backup NHG */ + if (!dplane_updated) + zebra_evpn_es_br_port_dplane_clear(es); + /* clear the es from the parent interface */ zif = es->zif; zif->es_info.es = NULL; es->zif = NULL; + /* clear all local flags associated with the ES */ + es->flags &= ~(ZEBRA_EVPNES_OPER_UP | ZEBRA_EVPNES_BR_PORT); + /* remove from the ES list */ list_delete_node(zmh_info->local_es_list, &es->local_es_listnode); @@ -1448,7 +1834,7 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid, if (!lid || is_zero_mac(sysmac)) { /* if in ES is attached to zif delete it */ if (old_es) - zebra_evpn_local_es_del(&zif->es_info.es); + zebra_evpn_local_es_del(&old_es); return 0; } @@ -1473,7 +1859,7 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid, /* release the old_es against the zif */ if (old_es) - zebra_evpn_local_es_del(&zif->es_info.es); + zebra_evpn_local_es_del(&old_es); es = zebra_evpn_es_find(&esi); if (es) { @@ -1496,9 +1882,8 @@ static int zebra_evpn_remote_es_del(esi_t *esi, struct in_addr vtep_ip) struct zebra_evpn_es *es; if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("remote es %s vtep %s del", - esi_to_str(esi, buf, sizeof(buf)), - inet_ntoa(vtep_ip)); + zlog_debug("remote es %s vtep %pI4 del", + esi_to_str(esi, buf, sizeof(buf)), &vtep_ip); es = zebra_evpn_es_find(esi); if (!es) { @@ -1523,23 +1908,26 @@ static void zebra_evpn_remote_es_flush(struct zebra_evpn_es **esp) for (ALL_LIST_ELEMENTS(es->es_vtep_list, node, nnode, es_vtep)) { if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("es %s vtep %s flush", + zlog_debug("es %s vtep %pI4 flush", es->esi_str, - inet_ntoa(es_vtep->vtep_ip)); + &es_vtep->vtep_ip); zebra_evpn_es_vtep_free(es_vtep); } zebra_evpn_es_remote_info_re_eval(esp); } -static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip) +static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip, + bool esr_rxed, uint8_t df_alg, + uint16_t df_pref) { char buf[ESI_STR_LEN]; struct zebra_evpn_es *es; if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("remote es %s vtep %s add", - esi_to_str(esi, buf, sizeof(buf)), - inet_ntoa(vtep_ip)); + zlog_debug("remote es %s vtep %pI4 add %s df_alg %d df_pref %d", + esi_to_str(esi, buf, sizeof(buf)), + &vtep_ip, esr_rxed ? "esr" : "", df_alg, + df_pref); es = zebra_evpn_es_find(esi); if (!es) { @@ -1552,7 +1940,13 @@ static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip) } } - zebra_evpn_es_vtep_add(es, vtep_ip); + if (df_alg != EVPN_MH_DF_ALG_PREF) + zlog_warn( + "remote es %s vtep %pI4 add %s with unsupported df_alg %d", + esi_to_str(esi, buf, sizeof(buf)), &vtep_ip, + esr_rxed ? "esr" : "", df_alg); + + zebra_evpn_es_vtep_add(es, vtep_ip, esr_rxed, df_alg, df_pref); zebra_evpn_es_remote_info_re_eval(&es); return 0; @@ -1577,10 +1971,22 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS) stream_get(&esi, s, sizeof(esi_t)); vtep_ip.s_addr = stream_get_ipv4(s); - if (hdr->command == ZEBRA_REMOTE_ES_VTEP_ADD) - zebra_evpn_remote_es_add(&esi, vtep_ip); - else + if (hdr->command == ZEBRA_REMOTE_ES_VTEP_ADD) { + uint32_t zapi_flags; + uint8_t df_alg; + uint16_t df_pref; + bool esr_rxed; + + zapi_flags = stream_getl(s); + esr_rxed = (zapi_flags & ZAPI_ES_VTEP_FLAG_ESR_RXED) ? true + : false; + df_alg = stream_getc(s); + df_pref = stream_getw(s); + zebra_evpn_remote_es_add(&esi, vtep_ip, esr_rxed, df_alg, + df_pref); + } else { zebra_evpn_remote_es_del(&esi, vtep_ip); + } } void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac) @@ -1706,6 +2112,35 @@ void zebra_evpn_es_cleanup(void) } } +static void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref) +{ + struct zebra_evpn_es *es; + uint16_t tmp_pref; + + if (zif->es_info.df_pref == df_pref) + return; + + zif->es_info.df_pref = df_pref; + es = zif->es_info.es; + + if (!es) + return; + + tmp_pref = zif->es_info.df_pref ? zif->es_info.df_pref + : EVPN_MH_DF_PREF_DEFAULT; + + if (es->df_pref == tmp_pref) + return; + + es->df_pref = tmp_pref; + /* run df election */ + zebra_evpn_es_run_df_election(es, __func__); + /* notify bgp */ + if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) + zebra_evpn_es_send_add_to_client(es); +} + + /* Only certain types of access ports can be setup as an Ethernet Segment */ bool zebra_evpn_is_if_es_capable(struct zebra_if *zif) { @@ -1719,12 +2154,34 @@ bool zebra_evpn_is_if_es_capable(struct zebra_if *zif) void zebra_evpn_if_es_print(struct vty *vty, struct zebra_if *zif) { char buf[ETHER_ADDR_STRLEN]; + char mh_buf[80]; + bool vty_print = false; + + mh_buf[0] = '\0'; + snprintf(mh_buf + strlen(mh_buf), sizeof(mh_buf) - strlen(mh_buf), + " EVPN-MH:"); + if (zif->es_info.lid || !is_zero_mac(&zif->es_info.sysmac)) { + vty_print = true; + snprintf( + mh_buf + strlen(mh_buf), + sizeof(mh_buf) - strlen(mh_buf), + " ES id %u ES sysmac %s", zif->es_info.lid, + prefix_mac2str(&zif->es_info.sysmac, buf, sizeof(buf))); + } - if (zif->es_info.lid || !is_zero_mac(&zif->es_info.sysmac)) - vty_out(vty, " EVPN MH: ES id %u ES sysmac %s\n", - zif->es_info.lid, - prefix_mac2str(&zif->es_info.sysmac, - buf, sizeof(buf))); + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) { + vty_print = true; + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) + snprintf(mh_buf + strlen(mh_buf), + sizeof(mh_buf) - strlen(mh_buf), " uplink-up"); + else + snprintf(mh_buf + strlen(mh_buf), + sizeof(mh_buf) - strlen(mh_buf), + " uplink-down"); + } + + if (vty_print) + vty_out(vty, "%s\n", mh_buf); } void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up) @@ -1744,6 +2201,8 @@ void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up) else es->flags &= ~ZEBRA_EVPNES_OPER_UP; + zebra_evpn_es_run_df_election(es, __func__); + /* inform BGP of the ES oper state change */ if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) zebra_evpn_es_send_add_to_client(es); @@ -1755,36 +2214,100 @@ static char *zebra_evpn_es_vtep_str(char *vtep_str, struct zebra_evpn_es *es, struct zebra_evpn_es_vtep *zvtep; struct listnode *node; bool first = true; + char ip_buf[INET6_ADDRSTRLEN]; vtep_str[0] = '\0'; for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, zvtep)) { if (first) { first = false; - strlcat(vtep_str, inet_ntoa(zvtep->vtep_ip), + strlcat(vtep_str, + inet_ntop(AF_INET, &zvtep->vtep_ip, ip_buf, + sizeof(ip_buf)), vtep_str_size); } else { strlcat(vtep_str, ",", vtep_str_size); - strlcat(vtep_str, inet_ntoa(zvtep->vtep_ip), + strlcat(vtep_str, + inet_ntop(AF_INET, &zvtep->vtep_ip, ip_buf, + sizeof(ip_buf)), vtep_str_size); } } return vtep_str; } -static void zebra_evpn_es_show_entry(struct vty *vty, - struct zebra_evpn_es *es, json_object *json) +static void zebra_evpn_es_json_vtep_fill(struct zebra_evpn_es *es, + json_object *json_vteps) +{ + struct zebra_evpn_es_vtep *es_vtep; + struct listnode *node; + json_object *json_vtep_entry; + char alg_buf[EVPN_DF_ALG_STR_LEN]; + char ip_buf[INET6_ADDRSTRLEN]; + + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { + json_vtep_entry = json_object_new_object(); + json_object_string_add(json_vtep_entry, "vtep", + inet_ntop(AF_INET, &es_vtep->vtep_ip, + ip_buf, sizeof(ip_buf))); + if (es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR) { + json_object_string_add( + json_vtep_entry, "dfAlgorithm", + evpn_es_df_alg2str(es_vtep->df_alg, alg_buf, + sizeof(alg_buf))); + json_object_int_add(json_vtep_entry, "dfPreference", + es_vtep->df_pref); + } + json_object_int_add(json_vtep_entry, "nexthopId", + es_vtep->nh_id); + json_object_array_add(json_vteps, json_vtep_entry); + } +} + +static void zebra_evpn_es_show_entry(struct vty *vty, struct zebra_evpn_es *es, + json_object *json_array) { char type_str[4]; char vtep_str[ES_VTEP_LIST_STR_SZ]; - if (json) { - /* XXX */ + if (json_array) { + json_object *json = NULL; + json_object *json_vteps; + json_object *json_flags; + + json = json_object_new_object(); + json_object_string_add(json, "esi", es->esi_str); + + if (es->flags + & (ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_REMOTE + | ZEBRA_EVPNES_NON_DF)) { + json_flags = json_object_new_array(); + if (es->flags & ZEBRA_EVPNES_LOCAL) + json_array_string_add(json_flags, "local"); + if (es->flags & ZEBRA_EVPNES_REMOTE) + json_array_string_add(json_flags, "remote"); + if (es->flags & ZEBRA_EVPNES_NON_DF) + json_array_string_add(json_flags, "nonDF"); + json_object_object_add(json, "flags", json_flags); + } + + if (es->zif) + json_object_string_add(json, "accessPort", + es->zif->ifp->name); + + if (listcount(es->es_vtep_list)) { + json_vteps = json_object_new_array(); + zebra_evpn_es_json_vtep_fill(es, json_vteps); + json_object_object_add(json, "vteps", json_vteps); + } + json_object_array_add(json_array, json); } else { type_str[0] = '\0'; if (es->flags & ZEBRA_EVPNES_LOCAL) strlcat(type_str, "L", sizeof(type_str)); if (es->flags & ZEBRA_EVPNES_REMOTE) strlcat(type_str, "R", sizeof(type_str)); + if (es->flags & ZEBRA_EVPNES_NON_DF) + strlcat(type_str, "N", sizeof(type_str)); zebra_evpn_es_vtep_str(vtep_str, es, sizeof(vtep_str)); @@ -1799,11 +2322,51 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty, struct zebra_evpn_es *es, json_object *json) { char type_str[80]; - struct zebra_evpn_es_vtep *zvtep; + char alg_buf[EVPN_DF_ALG_STR_LEN]; + struct zebra_evpn_es_vtep *es_vtep; struct listnode *node; if (json) { - /* XXX */ + json_object *json_vteps; + json_object *json_flags; + + json_object_string_add(json, "esi", es->esi_str); + if (es->zif) + json_object_string_add(json, "accessPort", + es->zif->ifp->name); + + + if (es->flags) { + json_flags = json_object_new_array(); + if (es->flags & ZEBRA_EVPNES_LOCAL) + json_array_string_add(json_flags, "local"); + if (es->flags & ZEBRA_EVPNES_REMOTE) + json_array_string_add(json_flags, "remote"); + if (es->flags & ZEBRA_EVPNES_NON_DF) + json_array_string_add(json_flags, "nonDF"); + if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) + json_array_string_add(json_flags, + "readyForBgp"); + if (es->flags & ZEBRA_EVPNES_BR_PORT) + json_array_string_add(json_flags, "bridgePort"); + if (es->flags & ZEBRA_EVPNES_OPER_UP) + json_array_string_add(json_flags, "operUp"); + if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) + json_array_string_add(json_flags, + "nexthopGroupActive"); + json_object_object_add(json, "flags", json_flags); + } + + json_object_int_add(json, "vniCount", + listcount(es->es_evi_list)); + json_object_int_add(json, "macCount", listcount(es->mac_list)); + json_object_int_add(json, "dfPreference", es->df_pref); + json_object_int_add(json, "nexthopGroup", es->nhg_id); + if (listcount(es->es_vtep_list)) { + json_vteps = json_object_new_array(); + zebra_evpn_es_json_vtep_fill(es, json_vteps); + json_object_object_add(json, "vteps", json_vteps); + } } else { type_str[0] = '\0'; if (es->flags & ZEBRA_EVPNES_LOCAL) @@ -1819,20 +2382,35 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty, vty_out(vty, " Interface: %s\n", (es->zif) ? es->zif->ifp->name : "-"); - vty_out(vty, " State: %s\n", - (es->flags & ZEBRA_EVPNES_OPER_UP) ? - "up" : "down"); + if (es->flags & ZEBRA_EVPNES_LOCAL) { + vty_out(vty, " State: %s\n", + (es->flags & ZEBRA_EVPNES_OPER_UP) ? "up" + : "down"); + vty_out(vty, " Bridge port: %s\n", + (es->flags & ZEBRA_EVPNES_BR_PORT) ? "yes" + : "no"); + } vty_out(vty, " Ready for BGP: %s\n", (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) ? "yes" : "no"); vty_out(vty, " VNI Count: %d\n", listcount(es->es_evi_list)); vty_out(vty, " MAC Count: %d\n", listcount(es->mac_list)); + vty_out(vty, " DF: status: %s preference: %u\n", + (es->flags & ZEBRA_EVPNES_NON_DF) ? "non-df" : "df", + es->df_pref); vty_out(vty, " Nexthop group: 0x%x\n", es->nhg_id); vty_out(vty, " VTEPs:\n"); - for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, zvtep)) - vty_out(vty, " %s nh: 0x%x\n", - inet_ntoa(zvtep->vtep_ip), - zvtep->nh_id); + for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) { + vty_out(vty, " %pI4", + &es_vtep->vtep_ip); + if (es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR) + vty_out(vty, " df_alg: %s df_pref: %d", + evpn_es_df_alg2str(es_vtep->df_alg, + alg_buf, + sizeof(alg_buf)), + es_vtep->df_pref); + vty_out(vty, " nh: 0x%x\n", es_vtep->nh_id); + } vty_out(vty, "\n"); } @@ -1841,27 +2419,51 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty, void zebra_evpn_es_show(struct vty *vty, bool uj) { struct zebra_evpn_es *es; - json_object *json = NULL; + json_object *json_array = NULL; if (uj) { - /* XXX */ + json_array = json_object_new_array(); } else { - vty_out(vty, "Type: L local, R remote\n"); + vty_out(vty, "Type: L local, R remote, N non-DF\n"); vty_out(vty, "%-30s %-4s %-21s %s\n", "ESI", "Type", "ES-IF", "VTEPs"); } RB_FOREACH(es, zebra_es_rb_head, &zmh_info->es_rb_tree) - zebra_evpn_es_show_entry(vty, es, json); + zebra_evpn_es_show_entry(vty, es, json_array); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); + } } void zebra_evpn_es_show_detail(struct vty *vty, bool uj) { struct zebra_evpn_es *es; - json_object *json = NULL; + json_object *json_array = NULL; - RB_FOREACH(es, zebra_es_rb_head, &zmh_info->es_rb_tree) + if (uj) + json_array = json_object_new_array(); + + RB_FOREACH (es, zebra_es_rb_head, &zmh_info->es_rb_tree) { + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); zebra_evpn_es_show_entry_detail(vty, es, json); + if (uj) + json_object_array_add(json_array, json); + } + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_array, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_array); + } } void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi) @@ -1870,15 +2472,26 @@ void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi) char esi_str[ESI_STR_LEN]; json_object *json = NULL; + if (uj) + json = json_object_new_object(); + es = zebra_evpn_es_find(esi); - if (!es) { - esi_to_str(esi, esi_str, sizeof(esi_str)); - vty_out(vty, "ESI %s does not exist\n", esi_str); - return; + if (es) { + zebra_evpn_es_show_entry_detail(vty, es, json); + } else { + if (!uj) { + esi_to_str(esi, esi_str, sizeof(esi_str)); + vty_out(vty, "ESI %s does not exist\n", esi_str); + } } - zebra_evpn_es_show_entry_detail(vty, es, json); + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } } int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp) @@ -1893,12 +2506,44 @@ int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp) vty_out(vty, " evpn mh es-sys-mac %s\n", prefix_mac2str(&zif->es_info.sysmac, buf, sizeof(buf))); + + if (zif->es_info.df_pref) + vty_out(vty, " evpn mh es-df-pref %u\n", zif->es_info.df_pref); + + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) + vty_out(vty, " evpn mh uplink\n"); + return 0; } #ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_evpn_mh_clippy.c" #endif +/* CLI for configuring DF preference part for an ES */ +DEFPY(zebra_evpn_es_pref, zebra_evpn_es_pref_cmd, + "[no$no] evpn mh es-df-pref [(1-65535)$df_pref]", + NO_STR "EVPN\n" EVPN_MH_VTY_STR + "preference value used for DF election\n" + "ID\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif; + + zif = ifp->info; + + if (no) { + zebra_evpn_es_df_pref_update(zif, 0); + } else { + if (!zebra_evpn_is_if_es_capable(zif)) { + vty_out(vty, + "%%DF preference cannot be associated with this interface type\n"); + return CMD_WARNING; + } + zebra_evpn_es_df_pref_update(zif, df_pref); + } + return CMD_SUCCESS; +} + /* CLI for setting up sysmac part of ESI on an access port */ DEFPY(zebra_evpn_es_sys_mac, zebra_evpn_es_sys_mac_cmd, @@ -1990,6 +2635,70 @@ DEFPY(zebra_evpn_es_id, return CMD_SUCCESS; } +/* CLI for tagging an interface as an uplink */ +DEFPY(zebra_evpn_mh_uplink, zebra_evpn_mh_uplink_cmd, "[no] evpn mh uplink", + NO_STR "EVPN\n" EVPN_MH_VTY_STR "uplink to the VxLAN core\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif; + + zif = ifp->info; + zebra_evpn_mh_uplink_cfg_update(zif, no ? false : true); + + return CMD_SUCCESS; +} + +void zebra_evpn_mh_json(json_object *json) +{ + json_object *json_array; + char thread_buf[THREAD_TIMER_STRLEN]; + + json_object_int_add(json, "macHoldtime", zmh_info->mac_hold_time); + json_object_int_add(json, "neighHoldtime", zmh_info->neigh_hold_time); + json_object_int_add(json, "startupDelay", zmh_info->startup_delay_time); + json_object_string_add( + json, "startupDelayTimer", + thread_timer_to_hhmmss(thread_buf, sizeof(thread_buf), + zmh_info->startup_delay_timer)); + json_object_int_add(json, "uplinkConfigCount", + zmh_info->uplink_cfg_cnt); + json_object_int_add(json, "uplinkActiveCount", + zmh_info->uplink_oper_up_cnt); + + if (zmh_info->protodown_rc) { + json_array = json_object_new_array(); + if (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY) + json_object_array_add( + json_array, + json_object_new_string("startupDelay")); + if (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN) + json_object_array_add( + json_array, + json_object_new_string("uplinkDown")); + json_object_object_add(json, "protodownReasons", json_array); + } +} + +void zebra_evpn_mh_print(struct vty *vty) +{ + char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN]; + char thread_buf[THREAD_TIMER_STRLEN]; + + vty_out(vty, "EVPN MH:\n"); + vty_out(vty, " mac-holdtime: %ds, neigh-holdtime: %ds\n", + zmh_info->mac_hold_time, zmh_info->neigh_hold_time); + vty_out(vty, " startup-delay: %ds, start-delay-timer: %s\n", + zmh_info->startup_delay_time, + thread_timer_to_hhmmss(thread_buf, sizeof(thread_buf), + zmh_info->startup_delay_timer)); + vty_out(vty, " uplink-cfg-cnt: %u, uplink-active-cnt: %u\n", + zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt); + if (zmh_info->protodown_rc) + vty_out(vty, " protodown: %s\n", + zebra_protodown_rc_str(zmh_info->protodown_rc, pd_buf, + sizeof(pd_buf))); +} + /*****************************************************************************/ /* A base L2-VNI is maintained to derive parameters such as ES originator-IP. * XXX: once single vxlan device model becomes available this will not be @@ -2027,11 +2736,13 @@ void zebra_evpn_es_set_base_evpn(zebra_evpn_t *zevpn) zmh_info->es_base_evpn->local_vtep_ip.s_addr; if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("es originator ip set to %s", - inet_ntoa(zmh_info->es_base_evpn->local_vtep_ip)); + zlog_debug("es originator ip set to %pI4", + &zmh_info->es_base_evpn->local_vtep_ip); /* if originator ip changes we need to update bgp */ for (ALL_LIST_ELEMENTS_RO(zmh_info->local_es_list, node, es)) { + zebra_evpn_es_run_df_election(es, __func__); + if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) zebra_evpn_es_send_add_to_client(es); else @@ -2093,23 +2804,316 @@ static void zebra_evpn_es_get_one_base_evpn(void) hash_walk(zvrf->evpn_table, zebra_evpn_es_get_one_base_evpn_cb, NULL); } +/***************************************************************************** + * local ethernet segments can be error-disabled if the switch is not + * ready to start transmitting traffic via the VxLAN overlay + */ +bool zebra_evpn_is_es_bond(struct interface *ifp) +{ + struct zebra_if *zif = ifp->info; + + return !!(struct zebra_if *)zif->es_info.es; +} + +bool zebra_evpn_is_es_bond_member(struct interface *ifp) +{ + struct zebra_if *zif = ifp->info; + + return IS_ZEBRA_IF_BOND_SLAVE(zif->ifp) && zif->bondslave_info.bond_if + && ((struct zebra_if *)zif->bondslave_info.bond_if->info) + ->es_info.es; +} + +void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif, bool clear, + const char *caller) +{ + bool old_protodown; + bool new_protodown; + enum protodown_reasons old_protodown_rc = 0; + enum protodown_reasons protodown_rc = 0; + + if (!clear) { + struct zebra_if *bond_zif; + + bond_zif = zif->bondslave_info.bond_if->info; + protodown_rc = bond_zif->protodown_rc; + } + + if (zif->protodown_rc == protodown_rc) + return; + + old_protodown = !!(zif->flags & ZIF_FLAG_PROTODOWN); + old_protodown_rc = zif->protodown_rc; + zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL; + zif->protodown_rc |= (protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL); + new_protodown = !!zif->protodown_rc; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug( + "%s bond mbr %s protodown_rc changed; old 0x%x new 0x%x", + caller, zif->ifp->name, old_protodown_rc, + zif->protodown_rc); + + if (old_protodown == new_protodown) + return; + + if (new_protodown) + zif->flags |= ZIF_FLAG_PROTODOWN; + else + zif->flags &= ~ZIF_FLAG_PROTODOWN; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("%s protodown %s", zif->ifp->name, + new_protodown ? "on" : "off"); + + zebra_if_set_protodown(zif->ifp, new_protodown); +} + +/* The bond members inherit the protodown reason code from the bond */ +static void zebra_evpn_mh_update_protodown_bond(struct zebra_if *bond_zif) +{ + struct zebra_if *zif; + struct listnode *node; + + if (!bond_zif->bond_info.mbr_zifs) + return; + + for (ALL_LIST_ELEMENTS_RO(bond_zif->bond_info.mbr_zifs, node, zif)) { + zebra_evpn_mh_update_protodown_bond_mbr(zif, false /*clear*/, + __func__); + } +} + +/* The global EVPN MH protodown rc is applied to all local ESs */ +static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es) +{ + struct zebra_if *zif; + enum protodown_reasons old_protodown_rc; + + zif = es->zif; + if ((zif->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL) + == (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL)) + return; + + old_protodown_rc = zif->protodown_rc; + zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL; + zif->protodown_rc |= + (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL); + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug( + "es %s ifp %s protodown_rc changed; old 0x%x new 0x%x", + es->esi_str, zif->ifp->name, old_protodown_rc, + zif->protodown_rc); + + /* update dataplane with the new protodown setting */ + zebra_evpn_mh_update_protodown_bond(zif); +} + +static void zebra_evpn_mh_clear_protodown_es(struct zebra_evpn_es *es) +{ + struct zebra_if *zif; + enum protodown_reasons old_protodown_rc; + + zif = es->zif; + if (!(zif->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL)) + return; + + old_protodown_rc = zif->protodown_rc; + zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug( + "clear: es %s ifp %s protodown_rc cleared; old 0x%x new 0x%x", + es->esi_str, zif->ifp->name, old_protodown_rc, + zif->protodown_rc); + + /* update dataplane with the new protodown setting */ + zebra_evpn_mh_update_protodown_bond(zif); +} + +static void zebra_evpn_mh_update_protodown_es_all(void) +{ + struct listnode *node; + struct zebra_evpn_es *es; + + for (ALL_LIST_ELEMENTS_RO(zmh_info->local_es_list, node, es)) + zebra_evpn_mh_update_protodown_es(es); +} + +static void zebra_evpn_mh_update_protodown(enum protodown_reasons protodown_rc, + bool set) +{ + enum protodown_reasons old_protodown_rc = zmh_info->protodown_rc; + + if (set) { + if ((protodown_rc & zmh_info->protodown_rc) == protodown_rc) + return; + + zmh_info->protodown_rc |= protodown_rc; + } else { + if (!(protodown_rc & zmh_info->protodown_rc)) + return; + zmh_info->protodown_rc &= ~protodown_rc; + } + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("mh protodown_rc changed; old 0x%x new 0x%x", + old_protodown_rc, zmh_info->protodown_rc); + zebra_evpn_mh_update_protodown_es_all(); +} + +static inline bool zebra_evpn_mh_is_all_uplinks_down(void) +{ + return zmh_info->uplink_cfg_cnt && !zmh_info->uplink_oper_up_cnt; +} + +static void zebra_evpn_mh_uplink_oper_flags_update(struct zebra_if *zif, + bool set) +{ + if (set) { + if (if_is_operative(zif->ifp)) { + if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)) { + zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP; + ++zmh_info->uplink_oper_up_cnt; + } + } else { + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) { + zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP; + if (zmh_info->uplink_oper_up_cnt) + --zmh_info->uplink_oper_up_cnt; + } + } + } else { + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) { + zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP; + if (zmh_info->uplink_oper_up_cnt) + --zmh_info->uplink_oper_up_cnt; + } + } +} + +static void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set) +{ + bool old_protodown = zebra_evpn_mh_is_all_uplinks_down(); + bool new_protodown; + + if (set) { + if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) + return; + + zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK; + ++zmh_info->uplink_cfg_cnt; + } else { + if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)) + return; + + zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK; + if (zmh_info->uplink_cfg_cnt) + --zmh_info->uplink_cfg_cnt; + } + + zebra_evpn_mh_uplink_oper_flags_update(zif, set); + new_protodown = zebra_evpn_mh_is_all_uplinks_down(); + if (old_protodown == new_protodown) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug( + "mh-uplink-cfg-chg on if %s/%d %s uplinks cfg %u up %u", + zif->ifp->name, zif->ifp->ifindex, set ? "set" : "down", + zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt); + + zebra_evpn_mh_update_protodown(ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN, + new_protodown); +} + +void zebra_evpn_mh_uplink_oper_update(struct zebra_if *zif) +{ + bool old_protodown = zebra_evpn_mh_is_all_uplinks_down(); + bool new_protodown; + + zebra_evpn_mh_uplink_oper_flags_update(zif, true /*set*/); + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug( + "mh-uplink-oper-chg on if %s/%d %s; uplinks cfg %u up %u", + zif->ifp->name, zif->ifp->ifindex, + if_is_operative(zif->ifp) ? "up" : "down", + zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt); + + new_protodown = zebra_evpn_mh_is_all_uplinks_down(); + if (old_protodown == new_protodown) + return; + + zebra_evpn_mh_update_protodown(ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN, + new_protodown); +} + +static int zebra_evpn_mh_startup_delay_exp_cb(struct thread *t) +{ + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("startup-delay expired"); + + zebra_evpn_mh_update_protodown(ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY, + false /* set */); + + return 0; +} + +static void zebra_evpn_mh_startup_delay_timer_start(bool init) +{ + /* 1. This timer can be started during init. + * 2. It can also be restarted if it is alreay running and the + * admin wants to increase or decrease its value + */ + if (!init && !zmh_info->startup_delay_timer) + return; + + if (zmh_info->startup_delay_timer) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("startup-delay timer cancelled"); + thread_cancel(&zmh_info->startup_delay_timer); + zmh_info->startup_delay_timer = NULL; + } + + if (zmh_info->startup_delay_time) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("startup-delay timer started for %d sec", + zmh_info->startup_delay_time); + thread_add_timer(zrouter.master, + zebra_evpn_mh_startup_delay_exp_cb, NULL, + zmh_info->startup_delay_time, + &zmh_info->startup_delay_timer); + zebra_evpn_mh_update_protodown( + ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY, true /* set */); + } else { + zebra_evpn_mh_update_protodown( + ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY, false /* set */); + } +} + /*****************************************************************************/ void zebra_evpn_mh_config_write(struct vty *vty) { - if (zmh_info->mac_hold_time != EVPN_MH_MAC_HOLD_TIME_DEF) - vty_out(vty, "evpn mh mac-holdtime %ld\n", + if (zmh_info->mac_hold_time != ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF) + vty_out(vty, "evpn mh mac-holdtime %d\n", zmh_info->mac_hold_time); - if (zmh_info->neigh_hold_time != EVPN_MH_NEIGH_HOLD_TIME_DEF) - vty_out(vty, "evpn mh neigh-holdtime %ld\n", + if (zmh_info->neigh_hold_time != ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF) + vty_out(vty, "evpn mh neigh-holdtime %d\n", zmh_info->neigh_hold_time); + + if (zmh_info->startup_delay_time != ZEBRA_EVPN_MH_STARTUP_DELAY_DEF) + vty_out(vty, "evpn mh startup-delay %d\n", + zmh_info->startup_delay_time); } int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty, uint32_t duration, bool set_default) { if (set_default) - duration = EVPN_MH_NEIGH_HOLD_TIME_DEF; + duration = ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF; zmh_info->neigh_hold_time = duration; @@ -2120,25 +3124,39 @@ int zebra_evpn_mh_mac_holdtime_update(struct vty *vty, uint32_t duration, bool set_default) { if (set_default) - duration = EVPN_MH_MAC_HOLD_TIME_DEF; + duration = ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF; zmh_info->mac_hold_time = duration; return 0; } +int zebra_evpn_mh_startup_delay_update(struct vty *vty, uint32_t duration, + bool set_default) +{ + if (set_default) + duration = ZEBRA_EVPN_MH_STARTUP_DELAY_DEF; + + zmh_info->startup_delay_time = duration; + zebra_evpn_mh_startup_delay_timer_start(false /* init */); + + return 0; +} + void zebra_evpn_interface_init(void) { install_element(INTERFACE_NODE, &zebra_evpn_es_id_cmd); install_element(INTERFACE_NODE, &zebra_evpn_es_sys_mac_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_es_pref_cmd); + install_element(INTERFACE_NODE, &zebra_evpn_mh_uplink_cmd); } void zebra_evpn_mh_init(void) { zrouter.mh_info = XCALLOC(MTYPE_ZMH_INFO, sizeof(*zrouter.mh_info)); - zmh_info->mac_hold_time = EVPN_MH_MAC_HOLD_TIME_DEF; - zmh_info->neigh_hold_time = EVPN_MH_NEIGH_HOLD_TIME_DEF; + zmh_info->mac_hold_time = ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF; + zmh_info->neigh_hold_time = ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF; /* setup ES tables */ RB_INIT(zebra_es_rb_head, &zmh_info->es_rb_tree); zmh_info->local_es_list = list_new(); @@ -2150,6 +3168,9 @@ void zebra_evpn_mh_init(void) /* setup broadcast domain tables */ zmh_info->evpn_vlan_table = hash_create(zebra_evpn_acc_vl_hash_keymake, zebra_evpn_acc_vl_cmp, "access VLAN hash table"); + + zmh_info->startup_delay_time = ZEBRA_EVPN_MH_STARTUP_DELAY_DEF; + zebra_evpn_mh_startup_delay_timer_start(true /*init*/); } void zebra_evpn_mh_terminate(void) diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 72b7f9b675..09af26a3a3 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -51,6 +51,14 @@ struct zebra_evpn_es { #define ZEBRA_EVPNES_OPER_UP (1 << 2) /* es->ifp is oper-up */ #define ZEBRA_EVPNES_READY_FOR_BGP (1 << 3) /* ready to be sent to BGP */ #define ZEBRA_EVPNES_NHG_ACTIVE (1 << 4) /* NHG has been installed */ +/* This flag is only applicable to local ESs and signifies that this + * VTEP is not the DF + */ +#define ZEBRA_EVPNES_NON_DF (1 << 5) +/* When the ES becomes a bridge port we need to activate the BUM non-DF + * filter, SPH filter and backup NHG for fast-failover + */ +#define ZEBRA_EVPNES_BR_PORT (1 << 6) /* memory used for adding the es to zmh_info->es_rb_tree */ RB_ENTRY(zebra_evpn_es) rb_node; @@ -74,6 +82,11 @@ struct zebra_evpn_es { /* Nexthop group id */ uint32_t nhg_id; + + /* Preference config for BUM-DF election. Sent to BGP and + * advertised via the ESR + */ + uint16_t df_pref; }; RB_HEAD(zebra_es_rb_head, zebra_evpn_es); RB_PROTOTYPE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp); @@ -115,12 +128,21 @@ struct zebra_evpn_es_vtep { struct zebra_evpn_es *es; /* parent ES */ struct in_addr vtep_ip; + uint32_t flags; + /* Rxed Type-4 route from this VTEP */ +#define ZEBRA_EVPNES_VTEP_RXED_ESR (1 << 0) +#define ZEBRA_EVPNES_VTEP_DEL_IN_PROG (1 << 1) + /* memory used for adding the entry to es->es_vtep_list */ struct listnode es_listnode; /* MAC nexthop */ uint32_t nh_id; + /* Parameters for DF election */ + uint8_t df_alg; + uint32_t df_pref; + /* XXX - maintain a backpointer to zebra_vtep_t */ }; @@ -173,10 +195,25 @@ struct zebra_evpn_mh_info { #define EVPN_NHG_ID_TYPE_BIT (2 << EVPN_NH_ID_TYPE_POS) /* XXX - re-visit the default hold timer value */ -#define EVPN_MH_MAC_HOLD_TIME_DEF (18 * 60) - long mac_hold_time; -#define EVPN_MH_NEIGH_HOLD_TIME_DEF (18 * 60) - long neigh_hold_time; + int mac_hold_time; +#define ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF (18 * 60) + int neigh_hold_time; +#define ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF (18 * 60) + + /* During this period access ports will be held in a protodown + * state + */ + int startup_delay_time; /* seconds */ +#define ZEBRA_EVPN_MH_STARTUP_DELAY_DEF (3 * 60) + struct thread *startup_delay_timer; + + /* Number of configured uplinks */ + uint32_t uplink_cfg_cnt; + /* Number of operationally-up uplinks */ + uint32_t uplink_oper_up_cnt; + + /* These protodown bits are inherited by all ES bonds */ + enum protodown_reasons protodown_rc; }; static inline bool zebra_evpn_mac_is_es_local(zebra_mac_t *mac) @@ -235,5 +272,17 @@ extern int zebra_evpn_mh_mac_holdtime_update(struct vty *vty, void zebra_evpn_mh_config_write(struct vty *vty); int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty, uint32_t duration, bool set_default); +void zebra_evpn_es_local_br_port_update(struct zebra_if *zif); +extern int zebra_evpn_mh_startup_delay_update(struct vty *vty, + uint32_t duration, + bool set_default); +extern void zebra_evpn_mh_uplink_oper_update(struct zebra_if *zif); +extern void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif, + bool clear, + const char *caller); +extern bool zebra_evpn_is_es_bond(struct interface *ifp); +extern bool zebra_evpn_is_es_bond_member(struct interface *ifp); +extern void zebra_evpn_mh_print(struct vty *vty); +extern void zebra_evpn_mh_json(json_object *json); #endif /* _ZEBRA_EVPN_MH_H */ diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index 6a76a475e6..e4f38008ac 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -592,6 +592,7 @@ static zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn, n->zevpn = zevpn; n->dad_ip_auto_recovery_timer = NULL; n->flags = n_flags; + n->uptime = monotime(NULL); if (!zmac) zmac = zebra_evpn_mac_lookup(zevpn, mac); @@ -722,9 +723,8 @@ zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n, n->state, false /*force*/); old_bgp_ready = false; } - if (n->mac) - zebra_evpn_local_neigh_deref_mac( - n, false /*send_mac_update*/); + zebra_evpn_local_neigh_deref_mac(n, + false /*send_mac_update*/); } /* clear old fwd info */ n->rem_seq = 0; @@ -803,6 +803,8 @@ zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n, n->ifindex = ifindex; inform_dataplane = true; } + + n->uptime = monotime(NULL); } /* update the neigh seq. we don't bother with the mac seq as @@ -1284,12 +1286,12 @@ zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr, if (nbr->dad_count >= zvrf->dad_max_moves) { flog_warn( EC_ZEBRA_DUP_IP_DETECTED, - "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %s", + "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %pI4", nbr->zevpn->vni, prefix_mac2str(&nbr->emac, buf, sizeof(buf)), ipaddr2str(&nbr->ip, buf1, sizeof(buf1)), is_local ? "local update, last" : "remote update, from", - inet_ntoa(vtep_ip)); + &vtep_ip); SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE); @@ -1791,6 +1793,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) struct vty *vty; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; + char addr_buf[PREFIX_STRLEN]; const char *type_str; const char *state_str; bool flags_present = false; @@ -1798,11 +1801,18 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) struct timeval detect_start_time = {0, 0}; char timebuf[MONOTIME_STRLEN]; char thread_buf[THREAD_TIMER_STRLEN]; + time_t uptime; + char up_str[MONOTIME_STRLEN]; zvrf = zebra_vrf_get_evpn(); if (!zvrf) return; + uptime = monotime(NULL); + uptime -= n->uptime; + + frrtime_to_interval(uptime, up_str, sizeof(up_str)); + ipaddr2str(&n->ip, buf2, sizeof(buf2)); prefix_mac2str(&n->emac, buf1, sizeof(buf1)); type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? "local" : "remote"; @@ -1815,6 +1825,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) ipaddr2str(&n->ip, buf2, sizeof(buf2))); vty_out(vty, " Type: %s\n", type_str); vty_out(vty, " State: %s\n", state_str); + vty_out(vty, " Uptime: %s\n", up_str); vty_out(vty, " MAC: %s\n", prefix_mac2str(&n->emac, buf1, sizeof(buf1))); vty_out(vty, " Sync-info:"); @@ -1841,6 +1852,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) vty_out(vty, " -"); vty_out(vty, "\n"); } else { + json_object_string_add(json, "uptime", up_str); json_object_string_add(json, "ip", buf2); json_object_string_add(json, "type", type_str); json_object_string_add(json, "state", state_str); @@ -1868,11 +1880,13 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json) n->mac->es->esi_str); } else { if (json) - json_object_string_add(json, "remoteVtep", - inet_ntoa(n->r_vtep_ip)); + json_object_string_add( + json, "remoteVtep", + inet_ntop(AF_INET, &n->r_vtep_ip, + addr_buf, sizeof(addr_buf))); else - vty_out(vty, " Remote VTEP: %s\n", - inet_ntoa(n->r_vtep_ip)); + vty_out(vty, " Remote VTEP: %pI4\n", + &n->r_vtep_ip); } } if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) { @@ -1953,6 +1967,7 @@ void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt) zebra_neigh_t *n; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; + char addr_buf[PREFIX_STRLEN]; struct neigh_walk_ctx *wctx = ctxt; const char *state_str; char flags_buf[6]; @@ -2007,12 +2022,16 @@ void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt) if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) && (wctx->count == 0)) zebra_evpn_print_neigh_hdr(vty, wctx); + + if (n->mac->es == NULL) + inet_ntop(AF_INET, &n->r_vtep_ip, + addr_buf, sizeof(addr_buf)); + vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n", -wctx->addr_width, buf2, "remote", zebra_evpn_print_neigh_flags(n, flags_buf, sizeof(flags_buf)), state_str, buf1, - n->mac->es ? n->mac->es->esi_str - : inet_ntoa(n->r_vtep_ip), + n->mac->es ? n->mac->es->esi_str : addr_buf, n->loc_seq, n->rem_seq); } else { json_object_string_add(json_row, "type", "remote"); @@ -2022,8 +2041,10 @@ void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt) json_object_string_add(json_row, "remoteEs", n->mac->es->esi_str); else - json_object_string_add(json_row, "remoteVtep", - inet_ntoa(n->r_vtep_ip)); + json_object_string_add( + json_row, "remoteVtep", + inet_ntop(AF_INET, &n->r_vtep_ip, + addr_buf, sizeof(addr_buf))); if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) json_object_boolean_true_add(json_row, "defaultGateway"); @@ -2134,11 +2155,11 @@ void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, mac, 0); if (!n) { zlog_warn( - "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s", + "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %pI4", ipaddr2str(ipaddr, buf1, sizeof(buf1)), prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - zevpn->vni, inet_ntoa(vtep_ip)); + zevpn->vni, &vtep_ip); return; } diff --git a/zebra/zebra_evpn_neigh.h b/zebra/zebra_evpn_neigh.h index 4b98266c86..50efdc0e0d 100644 --- a/zebra/zebra_evpn_neigh.h +++ b/zebra/zebra_evpn_neigh.h @@ -113,6 +113,8 @@ struct zebra_neigh_t_ { time_t dad_dup_detect_time; + time_t uptime; + /* used for ageing out the PEER_ACTIVE flag */ struct thread *hold_timer; }; diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index f84c8c1fcc..2bf48c6277 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -489,7 +489,7 @@ static inline void zfpm_write_on(void) */ static inline void zfpm_read_off(void) { - THREAD_READ_OFF(zfpm_g->t_read); + thread_cancel(&zfpm_g->t_read); } /* @@ -497,12 +497,12 @@ static inline void zfpm_read_off(void) */ static inline void zfpm_write_off(void) { - THREAD_WRITE_OFF(zfpm_g->t_write); + thread_cancel(&zfpm_g->t_write); } static inline void zfpm_connect_off(void) { - THREAD_TIMER_OFF(zfpm_g->t_connect); + thread_cancel(&zfpm_g->t_connect); } /* @@ -1437,7 +1437,6 @@ static inline int zfpm_conn_is_up(void) static int zfpm_trigger_update(struct route_node *rn, const char *reason) { rib_dest_t *dest; - char buf[PREFIX_STRLEN]; /* * Ignore if the connection is down. We will update the FPM about @@ -1454,8 +1453,8 @@ static int zfpm_trigger_update(struct route_node *rn, const char *reason) } if (reason) { - zfpm_debug("%s triggering update to FPM - Reason: %s", - prefix2str(&rn->p, buf, sizeof(buf)), reason); + zfpm_debug("%pFX triggering update to FPM - Reason: %s", &rn->p, + reason); } SET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM); @@ -1688,7 +1687,7 @@ static void zfpm_stop_stats_timer(void) return; zfpm_debug("Stopping existing stats timer"); - THREAD_TIMER_OFF(zfpm_g->t_stats); + thread_cancel(&zfpm_g->t_stats); } /* @@ -1934,7 +1933,7 @@ static int fpm_remote_srv_write(struct vty *vty) if ((zfpm_g->fpm_server != FPM_DEFAULT_IP && zfpm_g->fpm_server != INADDR_ANY) || (zfpm_g->fpm_port != FPM_DEFAULT_PORT && zfpm_g->fpm_port != 0)) - vty_out(vty, "fpm connection ip %s port %d\n", inet_ntoa(in), + vty_out(vty, "fpm connection ip %pI4 port %d\n", &in, zfpm_g->fpm_port); return 0; diff --git a/zebra/zebra_fpm_dt.c b/zebra/zebra_fpm_dt.c index 81437e72f5..e392722030 100644 --- a/zebra/zebra_fpm_dt.c +++ b/zebra/zebra_fpm_dt.c @@ -181,6 +181,7 @@ static void zfpm_dt_log_fpm_message(Fpm__Message *msg) char *if_name; size_t i; char buf[INET6_ADDRSTRLEN]; + char addr_buf[PREFIX_STRLEN]; union g_addr nh_addr; if (msg->type != FPM__MESSAGE__TYPE__ADD_ROUTE) @@ -213,7 +214,9 @@ static void zfpm_dt_log_fpm_message(Fpm__Message *msg) zfpm_debug("Nexthop - if_index: %d (%s), gateway: %s, ", if_index, if_name ? if_name : "name not specified", - nexthop->address ? inet_ntoa(nh_addr.ipv4) : "None"); + nexthop->address ? + inet_ntop(AF_INET, &nh_addr.ipv4, + addr_buf, sizeof(addr_buf)) : "None"); } } diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 2c07413638..44f574073c 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -44,41 +44,6 @@ #include "zebra/zebra_vxlan_private.h" /* - * addr_to_a - * - * Returns string representation of an address of the given AF. - */ -static inline const char *addr_to_a(uint8_t af, void *addr) -{ - if (!addr) - return "<No address>"; - - switch (af) { - - case AF_INET: - return inet_ntoa(*((struct in_addr *)addr)); - case AF_INET6: - return inet6_ntoa(*((struct in6_addr *)addr)); - default: - return "<Addr in unknown AF>"; - } -} - -/* - * prefix_addr_to_a - * - * Convience wrapper that returns a human-readable string for the - * address in a prefix. - */ -static const char *prefix_addr_to_a(struct prefix *prefix) -{ - if (!prefix) - return "<No address>"; - - return addr_to_a(prefix->family, &prefix->u.prefix); -} - -/* * af_addr_size * * The size of an address in a given address family. @@ -525,18 +490,24 @@ static void zfpm_log_route_info(struct netlink_route_info *ri, { struct netlink_nh_info *nhi; unsigned int i; + char buf[PREFIX_STRLEN]; - zfpm_debug("%s : %s %s/%d, Proto: %s, Metric: %u", label, + zfpm_debug("%s : %s %s, Proto: %s, Metric: %u", label, nl_msg_type_to_str(ri->nlmsg_type), - prefix_addr_to_a(ri->prefix), ri->prefix->prefixlen, + prefix2str(ri->prefix, buf, sizeof(buf)), nl_rtproto_to_str(ri->rtm_protocol), ri->metric ? *ri->metric : 0); for (i = 0; i < ri->num_nhs; i++) { nhi = &ri->nhs[i]; + + if (ri->af == AF_INET) + inet_ntop(AF_INET, &nhi->gateway, buf, sizeof(buf)); + else + inet_ntop(AF_INET6, &nhi->gateway, buf, sizeof(buf)); + zfpm_debug(" Intf: %u, Gateway: %s, Recursive: %s, Type: %s, Encap type: %s", - nhi->if_index, addr_to_a(ri->af, nhi->gateway), - nhi->recursive ? "yes" : "no", + nhi->if_index, buf, nhi->recursive ? "yes" : "no", nexthop_type_to_str(nhi->type), fpm_nh_encap_type_to_str(nhi->encap_info.encap_type) ); @@ -621,11 +592,11 @@ int zfpm_netlink_encode_mac(struct fpm_mac_info_t *mac, char *in_buf, assert(req->hdr.nlmsg_len < in_buf_len); - zfpm_debug("Tx %s family %s ifindex %u MAC %s DEST %s", + zfpm_debug("Tx %s family %s ifindex %u MAC %s DEST %pI4", nl_msg_type_to_str(req->hdr.nlmsg_type), nl_family_to_str(req->ndm.ndm_family), req->ndm.ndm_ifindex, prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)), - inet_ntoa(mac->r_vtep_ip)); + &mac->r_vtep_ip); return req->hdr.nlmsg_len; } diff --git a/zebra/zebra_gr.c b/zebra/zebra_gr.c index a4f32dbf39..ca6a33cd52 100644 --- a/zebra/zebra_gr.c +++ b/zebra/zebra_gr.c @@ -490,19 +490,15 @@ static void zebra_gr_process_route_entry(struct zserv *client, struct route_node *rn, struct route_entry *re) { - char buf[PREFIX2STR_BUFFER]; - if ((client == NULL) || (rn == NULL) || (re == NULL)) return; /* If the route is not refreshed after restart, delete the entry */ if (re->uptime < client->restart_time) { - if (IS_ZEBRA_DEBUG_RIB) { - prefix2str(&rn->p, buf, sizeof(buf)); - zlog_debug("%s: Client %s stale route %s is deleted", + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s: Client %s stale route %pFX is deleted", __func__, zebra_route_string(client->proto), - buf); - } + &rn->p); rib_delnode(rn, re); } } diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 417056ecb0..c1ad91c8ca 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -41,6 +41,7 @@ #include "zebra/zebra_memory.h" #include "zebra/zebra_vrf.h" #include "zebra/rt_netlink.h" +#include "zebra/interface.h" #include "zebra/zebra_l2.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_evpn_mh.h" @@ -109,24 +110,99 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave) br_slave->br_if = NULL; } -void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, - vrf_id_t vrf_id) +void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id) { struct interface *bond_if; + struct zebra_if *bond_zif; + struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info; - /* TODO: Handle change of master */ bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex); - if (bond_if) - bond_slave->bond_if = bond_if; - else - bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex, - vrf_id); + if (bond_if == bond_slave->bond_if) + return; + + /* unlink the slave from the old master */ + zebra_l2_unmap_slave_from_bond(zif); + + /* If the bond is present and ready link the bond-member + * to it + */ + if (bond_if && (bond_zif = bond_if->info)) { + if (bond_zif->bond_info.mbr_zifs) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s linked to %s", + zif->ifp->name, bond_if->name); + bond_slave->bond_if = bond_if; + /* link the slave to the new bond master */ + listnode_add(bond_zif->bond_info.mbr_zifs, zif); + /* inherit protodown flags from the es-bond */ + if (zebra_evpn_is_es_bond(bond_if)) + zebra_evpn_mh_update_protodown_bond_mbr( + zif, false /*clear*/, __func__); + } + } else { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s link to bond skipped", + zif->ifp->name); + } +} + +void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif) +{ + struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info; + struct zebra_if *bond_zif; + + if (!bond_slave->bond_if) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s unlink from bond skipped", + zif->ifp->name); + return; + } + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s un-linked from %s", zif->ifp->name, + bond_slave->bond_if->name); + + /* unlink the slave from the bond master */ + bond_zif = bond_slave->bond_if->info; + /* clear protodown flags */ + if (zebra_evpn_is_es_bond(bond_zif->ifp)) + zebra_evpn_mh_update_protodown_bond_mbr(zif, true /*clear*/, + __func__); + listnode_delete(bond_zif->bond_info.mbr_zifs, zif); + bond_slave->bond_if = NULL; } -void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave) +void zebra_l2if_update_bond(struct interface *ifp, bool add) { - if (bond_slave != NULL) - bond_slave->bond_if = NULL; + struct zebra_if *zif; + struct zebra_l2info_bond *bond; + + zif = ifp->info; + assert(zif); + bond = &zif->bond_info; + + if (add) { + if (!bond->mbr_zifs) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond %s mbr list create", + ifp->name); + bond->mbr_zifs = list_new(); + } + } else { + struct listnode *node; + struct listnode *nnode; + struct zebra_if *bond_mbr; + + if (!bond->mbr_zifs) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond %s mbr list delete", ifp->name); + for (ALL_LIST_ELEMENTS(bond->mbr_zifs, node, nnode, bond_mbr)) + zebra_l2_unmap_slave_from_bond(bond_mbr); + + list_delete(&bond->mbr_zifs); + } } /* @@ -286,6 +362,8 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp, /* In the case of VxLAN, invoke the handler for EVPN. */ if (zif->zif_type == ZEBRA_IF_VXLAN) zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE); + if (zif->es_info.es) + zebra_evpn_es_local_br_port_update(zif); } else if (old_bridge_ifindex != IFINDEX_INTERNAL) { /* * In the case of VxLAN, invoke the handler for EVPN. @@ -294,6 +372,8 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp, */ if (zif->zif_type == ZEBRA_IF_VXLAN) zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE); + if (zif->es_info.es) + zebra_evpn_es_local_br_port_update(zif); zebra_l2_unmap_slave_from_bridge(&zif->brslave_info); } } @@ -314,9 +394,9 @@ void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex) /* Set up or remove link with master */ if (bond_ifindex != IFINDEX_INTERNAL) - zebra_l2_map_slave_to_bond(&zif->bondslave_info, ifp->vrf_id); + zebra_l2_map_slave_to_bond(zif, ifp->vrf_id); else if (old_bond_ifindex != IFINDEX_INTERNAL) - zebra_l2_unmap_slave_from_bond(&zif->bondslave_info); + zebra_l2_unmap_slave_from_bond(zif); } void zebra_vlan_bitmap_compute(struct interface *ifp, diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h index f3b15c7770..4b84eb071e 100644 --- a/zebra/zebra_l2.h +++ b/zebra/zebra_l2.h @@ -40,6 +40,10 @@ struct zebra_l2info_brslave { ns_id_t ns_id; /* network namespace where bridge is */ }; +struct zebra_l2info_bond { + struct list *mbr_zifs; /* slaves using this bond as a master */ +}; + /* zebra L2 interface information - bridge interface */ struct zebra_l2info_bridge { uint8_t vlan_aware; /* VLAN-aware bridge? */ @@ -86,10 +90,6 @@ extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave, struct zebra_ns *zns); extern void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave); -extern void -zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, vrf_id_t); -extern void -zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave); extern void zebra_l2_bridge_add_update(struct interface *ifp, struct zebra_l2info_bridge *bridge_info, int add); @@ -112,6 +112,7 @@ extern void zebra_vlan_bitmap_compute(struct interface *ifp, uint32_t vid_start, uint16_t vid_end); extern void zebra_vlan_mbr_re_eval(struct interface *ifp, bitfield_t vlan_bitmap); +extern void zebra_l2if_update_bond(struct interface *ifp, bool add); #ifdef __cplusplus } diff --git a/zebra/zebra_mlag_private.c b/zebra/zebra_mlag_private.c index 343e7801db..8a66d6de72 100644 --- a/zebra/zebra_mlag_private.c +++ b/zebra/zebra_mlag_private.c @@ -74,9 +74,10 @@ static void zebra_mlag_sched_read(void) static int zebra_mlag_read(struct thread *thread) { + static uint32_t mlag_rd_buf_offset; uint32_t *msglen; uint32_t h_msglen; - uint32_t tot_len, curr_len = 0; + uint32_t tot_len, curr_len = mlag_rd_buf_offset; /* * Received message in sock_stream looks like below @@ -99,6 +100,7 @@ static int zebra_mlag_read(struct thread *thread) zebra_mlag_handle_process_state(MLAG_DOWN); return -1; } + mlag_rd_buf_offset += data_len; if (data_len != (ssize_t)(ZEBRA_MLAG_LEN_SIZE - curr_len)) { /* Try again later */ zebra_mlag_sched_read(); @@ -136,6 +138,7 @@ static int zebra_mlag_read(struct thread *thread) zebra_mlag_handle_process_state(MLAG_DOWN); return -1; } + mlag_rd_buf_offset += data_len; if (data_len != (ssize_t)(tot_len - curr_len)) { /* Try again later */ zebra_mlag_sched_read(); @@ -157,6 +160,7 @@ static int zebra_mlag_read(struct thread *thread) /* Register read thread. */ zebra_mlag_reset_read_buffer(); + mlag_rd_buf_offset = 0; zebra_mlag_sched_read(); return 0; } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 03b8c8de1f..dc49695019 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -52,10 +52,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object") -DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config") DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname") int mpls_enabled; @@ -101,7 +98,8 @@ static void lsp_check_free(struct hash *lsp_table, zebra_lsp_t **plsp); /* Free lsp; sets caller's pointer to NULL */ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp); -static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size); +static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size); +static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size); static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, const union g_addr *gate, ifindex_t ifindex); static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list, @@ -124,19 +122,6 @@ static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty, const char *indent); static void lsp_print(struct vty *vty, zebra_lsp_t *lsp); -static void *slsp_alloc(void *p); -static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex); -static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex); -static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex, - mpls_label_t out_label); -static int snhlfe_del(zebra_snhlfe_t *snhlfe); -static int snhlfe_del_all(zebra_slsp_t *slsp); -static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size); static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt); static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi, enum lsp_types_t lsp_type); @@ -145,9 +130,6 @@ static int lsp_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type, static int lsp_backup_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type, const struct zapi_nexthop *znh); -/* List implementations - declare internal linkage */ -DECLARE_DLIST(snhlfe_list, struct zebra_snhlfe_t_, list); - /* Static functions */ /* @@ -349,7 +331,6 @@ static void fec_evaluate(struct zebra_vrf *zvrf) zebra_fec_t *fec; uint32_t old_label, new_label; int af; - char buf[BUFSIZ]; for (af = AFI_IP; af < AFI_MAX; af++) { if (zvrf->fec_table[af] == NULL) @@ -366,9 +347,6 @@ static void fec_evaluate(struct zebra_vrf *zvrf) || fec->label_index == MPLS_INVALID_LABEL_INDEX) continue; - if (IS_ZEBRA_DEBUG_MPLS) - prefix2str(&rn->p, buf, BUFSIZ); - /* Save old label, determine new label. */ old_label = fec->label; new_label = @@ -382,8 +360,8 @@ static void fec_evaluate(struct zebra_vrf *zvrf) if (IS_ZEBRA_DEBUG_MPLS) zlog_debug( - "Update fec %s new label %u upon label block", - buf, new_label); + "Update fec %pRN new label %u upon label block", + rn, new_label); fec->label = new_label; fec_update_clients(fec); @@ -512,8 +490,7 @@ static void fec_print(zebra_fec_t *fec, struct vty *vty) char buf[BUFSIZ]; rn = fec->rn; - prefix2str(&rn->p, buf, BUFSIZ); - vty_out(vty, "%s\n", buf); + vty_out(vty, "%pRN\n", rn); vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ)); if (fec->label_index != MPLS_INVALID_LABEL_INDEX) vty_out(vty, ", Label Index: %u", fec->label_index); @@ -1173,9 +1150,9 @@ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp) /* * Create printable string for NHLFE entry. */ -static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size) +static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size) { - struct nexthop *nexthop; + const struct nexthop *nexthop; buf[0] = '\0'; nexthop = nhlfe->nexthop; @@ -1414,7 +1391,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, continue; if (IS_ZEBRA_DEBUG_MPLS) { - nhlfe2str(nhlfe, buf, BUFSIZ); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Del LSP in-label %u type %d nexthop %s flags 0x%x", lsp->ile.in_label, type, buf, nhlfe->flags); @@ -1435,7 +1412,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, continue; if (IS_ZEBRA_DEBUG_MPLS) { - nhlfe2str(nhlfe, buf, BUFSIZ); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Del backup LSP in-label %u type %d nexthop %s flags 0x%x", lsp->ile.in_label, type, buf, nhlfe->flags); @@ -1520,7 +1497,8 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe) case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: json_object_string_add(json_nhlfe, "nexthop", - inet_ntoa(nexthop->gate.ipv4)); + inet_ntop(AF_INET, &nexthop->gate.ipv4, + buf, sizeof(buf))); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1578,7 +1556,7 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); + vty_out(vty, " via %pI4", &nexthop->gate.ipv4); if (nexthop->ifindex) vty_out(vty, " dev %s", ifindex2ifname(nexthop->ifindex, @@ -1711,188 +1689,6 @@ static int lsp_cmp(const zebra_lsp_t *lsp1, const zebra_lsp_t *lsp2) } /* - * Callback to allocate static LSP. - */ -static void *slsp_alloc(void *p) -{ - const zebra_ile_t *ile = p; - zebra_slsp_t *slsp; - - slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t)); - slsp->ile = *ile; - snhlfe_list_init(&slsp->snhlfe_list); - - return ((void *)slsp); -} - -/* - * Compare two static LSPs based on their label values. - */ -static int slsp_cmp(const zebra_slsp_t *slsp1, const zebra_slsp_t *slsp2) -{ - if (slsp1->ile.in_label < slsp2->ile.in_label) - return -1; - - if (slsp1->ile.in_label > slsp2->ile.in_label) - return 1; - - return 0; -} - -/* - * Check if static NHLFE matches with search info passed. - */ -static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex) -{ - int cmp = 1; - - if (snhlfe->gtype != gtype) - return 1; - - switch (snhlfe->gtype) { - case NEXTHOP_TYPE_IPV4: - cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4), - sizeof(struct in_addr)); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6), - sizeof(struct in6_addr)); - if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX) - cmp = !(snhlfe->ifindex == ifindex); - break; - default: - break; - } - - return cmp; -} - -/* - * Locate static NHLFE that matches with passed info. - */ -static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex) -{ - zebra_snhlfe_t *snhlfe; - - if (!slsp) - return NULL; - - frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) { - if (!snhlfe_match(snhlfe, gtype, gate, ifindex)) - break; - } - - return snhlfe; -} - - -/* - * Add static NHLFE. Base LSP config entry must have been created - * and duplicate check done. - */ -static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, - enum nexthop_types_t gtype, - const union g_addr *gate, ifindex_t ifindex, - mpls_label_t out_label) -{ - zebra_snhlfe_t *snhlfe; - - if (!slsp) - return NULL; - - snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t)); - snhlfe->slsp = slsp; - snhlfe->out_label = out_label; - snhlfe->gtype = gtype; - switch (gtype) { - case NEXTHOP_TYPE_IPV4: - snhlfe->gate.ipv4 = gate->ipv4; - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - snhlfe->gate.ipv6 = gate->ipv6; - if (ifindex) - snhlfe->ifindex = ifindex; - break; - default: - XFREE(MTYPE_SNHLFE, snhlfe); - return NULL; - } - - snhlfe_list_add_head(&slsp->snhlfe_list, snhlfe); - - return snhlfe; -} - -/* - * Delete static NHLFE. Entry must be present on list. - */ -static int snhlfe_del(zebra_snhlfe_t *snhlfe) -{ - zebra_slsp_t *slsp; - - if (!snhlfe) - return -1; - - slsp = snhlfe->slsp; - if (!slsp) - return -1; - - snhlfe_list_del(&slsp->snhlfe_list, snhlfe); - - XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname); - XFREE(MTYPE_SNHLFE, snhlfe); - - return 0; -} - -/* - * Delete all static NHLFE entries for this LSP (in label). - */ -static int snhlfe_del_all(zebra_slsp_t *slsp) -{ - zebra_snhlfe_t *snhlfe; - - if (!slsp) - return -1; - - frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) { - snhlfe_del(snhlfe); - } - - return 0; -} - -/* - * Create printable string for NHLFE configuration. - */ -static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size) -{ - buf[0] = '\0'; - switch (snhlfe->gtype) { - case NEXTHOP_TYPE_IPV4: - inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size); - if (snhlfe->ifindex) - strlcat(buf, - ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT), - size); - break; - default: - break; - } - - return buf; -} - -/* * Initialize work queue for processing changed LSPs. */ static int mpls_processq_init(void) @@ -2443,7 +2239,6 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, { struct route_table *table; zebra_fec_t *fec; - char buf[BUFSIZ]; bool new_client; bool label_change = false; uint32_t old_label; @@ -2454,14 +2249,11 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, if (!table) return -1; - if (IS_ZEBRA_DEBUG_MPLS) - prefix2str(p, buf, BUFSIZ); - if (label != MPLS_INVALID_LABEL && have_label_index) { flog_err( EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT, - "Rejecting FEC register for %s with both label %u and Label Index %u specified, client %s", - buf, label, label_index, + "Rejecting FEC register for %pFX with both label %u and Label Index %u specified, client %s", + p, label, label_index, zebra_route_string(client->proto)); return -1; } @@ -2473,8 +2265,8 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, if (!fec) { flog_err( EC_ZEBRA_FEC_ADD_FAILED, - "Failed to add FEC %s upon register, client %s", - buf, zebra_route_string(client->proto)); + "Failed to add FEC %pFX upon register, client %s", + p, zebra_route_string(client->proto)); return -1; } @@ -2500,7 +2292,7 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p, listnode_add(fec->client_list, client); if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug("FEC %s label%s %u %s by client %s%s", buf, + zlog_debug("FEC %pFX label%s %u %s by client %s%s", p, have_label_index ? " index" : "", have_label_index ? label_index : label, new_client ? "registered" : "updated", @@ -2551,28 +2343,23 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p, { struct route_table *table; zebra_fec_t *fec; - char buf[BUFSIZ]; table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))]; if (!table) return -1; - if (IS_ZEBRA_DEBUG_MPLS) - prefix2str(p, buf, BUFSIZ); - fec = fec_find(table, p); if (!fec) { - prefix2str(p, buf, BUFSIZ); flog_err(EC_ZEBRA_FEC_RM_FAILED, - "Failed to find FEC %s upon unregister, client %s", - buf, zebra_route_string(client->proto)); + "Failed to find FEC %pFX upon unregister, client %s", + p, zebra_route_string(client->proto)); return -1; } listnode_delete(fec->client_list, client); if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug("FEC %s unregistered by client %s", buf, + zlog_debug("FEC %pFX unregistered by client %s", p, zebra_route_string(client->proto)); /* If not a configured entry, delete the FEC if no other clients. Before @@ -2713,7 +2500,6 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p, { struct route_table *table; zebra_fec_t *fec; - char buf[BUFSIZ]; mpls_label_t old_label; int ret = 0; @@ -2721,23 +2507,19 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p, if (!table) return -1; - if (IS_ZEBRA_DEBUG_MPLS) - prefix2str(p, buf, BUFSIZ); - /* Update existing FEC or create a new one. */ fec = fec_find(table, p); if (!fec) { fec = fec_add(table, p, in_label, FEC_FLAG_CONFIGURED, MPLS_INVALID_LABEL_INDEX); if (!fec) { - prefix2str(p, buf, BUFSIZ); flog_err(EC_ZEBRA_FEC_ADD_FAILED, - "Failed to add FEC %s upon config", buf); + "Failed to add FEC %pFX upon config", p); return -1; } if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug("Add fec %s label %u", buf, in_label); + zlog_debug("Add fec %pFX label %u", p, in_label); } else { fec->flags |= FEC_FLAG_CONFIGURED; if (fec->label == in_label) @@ -2747,7 +2529,7 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p, /* Label change, update clients. */ old_label = fec->label; if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug("Update fec %s new label %u", buf, in_label); + zlog_debug("Update fec %pFX new label %u", p, in_label); fec->label = in_label; fec_update_clients(fec); @@ -2770,7 +2552,6 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p) struct route_table *table; zebra_fec_t *fec; mpls_label_t old_label; - char buf[BUFSIZ]; table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))]; if (!table) @@ -2778,15 +2559,13 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p) fec = fec_find(table, p); if (!fec) { - prefix2str(p, buf, BUFSIZ); flog_err(EC_ZEBRA_FEC_RM_FAILED, - "Failed to find FEC %s upon delete", buf); + "Failed to find FEC %pFX upon delete", p); return -1; } if (IS_ZEBRA_DEBUG_MPLS) { - prefix2str(p, buf, BUFSIZ); - zlog_debug("Delete fec %s label %u label index %u", buf, + zlog_debug("Delete fec %pFX label %u label index %u", p, fec->label, fec->label_index); } @@ -2820,7 +2599,6 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf) struct route_node *rn; int af; zebra_fec_t *fec; - char buf[BUFSIZ]; int write = 0; for (af = AFI_IP; af < AFI_MAX; af++) { @@ -2839,8 +2617,7 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf) continue; write = 1; - prefix2str(&rn->p, buf, BUFSIZ); - vty_out(vty, "mpls label bind %s %s\n", buf, + vty_out(vty, "mpls label bind %pFX %s\n", &rn->p, label2str(fec->label, lstr, BUFSIZ)); } } @@ -3046,7 +2823,7 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf, const struct zapi_labels *zl) { int i, counter, ret = 0; - char buf[NEXTHOP_STRLEN], prefix_buf[PREFIX_STRLEN]; + char buf[NEXTHOP_STRLEN]; const struct zapi_nexthop *znh; struct route_table *table; struct route_node *rn = NULL; @@ -3110,12 +2887,10 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf, * attempted to manage LSPs before trying to * find a route/FEC, so we'll continue that way. */ - if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_MPLS) { - prefix2str(prefix, prefix_buf, - sizeof(prefix_buf)); - zlog_debug("%s: FTN update requested: no route for prefix %s", - __func__, prefix_buf); - } + if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_MPLS) + zlog_debug( + "%s: FTN update requested: no route for prefix %pFX", + __func__, prefix); } } @@ -3157,9 +2932,9 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf, counter++; } else if (IS_ZEBRA_DEBUG_RECV | IS_ZEBRA_DEBUG_MPLS) { zapi_nexthop2str(znh, buf, sizeof(buf)); - prefix2str(prefix, prefix_buf, sizeof(prefix_buf)); - zlog_debug("%s: Unable to update FEC: prefix %s, label %u, znh %s", - __func__, prefix_buf, zl->local_label, buf); + zlog_debug( + "%s: Unable to update FEC: prefix %pFX, label %u, znh %s", + __func__, prefix, zl->local_label, buf); } } @@ -3207,9 +2982,9 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf, counter++; } else if (IS_ZEBRA_DEBUG_RECV | IS_ZEBRA_DEBUG_MPLS) { zapi_nexthop2str(znh, buf, sizeof(buf)); - prefix2str(prefix, prefix_buf, sizeof(prefix_buf)); - zlog_debug("%s: Unable to update backup FEC: prefix %s, label %u, znh %s", - __func__, prefix_buf, zl->local_label, buf); + zlog_debug( + "%s: Unable to update backup FEC: prefix %pFX, label %u, znh %s", + __func__, prefix, zl->local_label, buf); } } @@ -3633,8 +3408,9 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, { struct hash *slsp_table; zebra_ile_t tmp_ile; - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; + const struct nexthop *nh; /* Lookup table. */ slsp_table = zvrf->slsp_table; @@ -3643,26 +3419,37 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, /* If entry is not present, exit. */ tmp_ile.in_label = in_label; - slsp = hash_lookup(slsp_table, &tmp_ile); - if (!slsp) + lsp = hash_lookup(slsp_table, &tmp_ile); + if (!lsp) return 1; - snhlfe = snhlfe_find(slsp, gtype, gate, ifindex); - if (snhlfe) { - if (snhlfe->out_label == out_label) + nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, + gtype, gate, ifindex); + if (nhlfe) { + nh = nhlfe->nexthop; + + if (nh == NULL || nh->nh_label == NULL) + return 0; + + if (nh->nh_label->label[0] == out_label) return 1; /* If not only NHLFE, cannot allow label change. */ - if (snhlfe != snhlfe_list_first(&slsp->snhlfe_list) || - snhlfe_list_next(&slsp->snhlfe_list, snhlfe) != NULL) + if (nhlfe != nhlfe_list_first(&lsp->nhlfe_list) || + nhlfe_list_next(&lsp->nhlfe_list, nhlfe) != NULL) return 0; } else { /* If other NHLFEs exist, label operation must match. */ - snhlfe = snhlfe_list_first(&slsp->snhlfe_list); - if (snhlfe != NULL) { + nhlfe = nhlfe_list_first(&lsp->nhlfe_list); + if (nhlfe != NULL) { int cur_op, new_op; - cur_op = (snhlfe->out_label == + nh = nhlfe->nexthop; + + if (nh == NULL || nh->nh_label == NULL) + return 0; + + cur_op = (nh->nh_label->label[0] == MPLS_LABEL_IMPLICIT_NULL); new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL); if (cur_op != new_op) @@ -3689,8 +3476,8 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, { struct hash *slsp_table; zebra_ile_t tmp_ile; - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; char buf[BUFSIZ]; /* Lookup table. */ @@ -3700,31 +3487,47 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, /* Find or create LSP. */ tmp_ile.in_label = in_label; - slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc); - if (!slsp) + lsp = hash_get(slsp_table, &tmp_ile, lsp_alloc); + if (!lsp) return -1; - snhlfe = snhlfe_find(slsp, gtype, gate, ifindex); - if (snhlfe) { - if (snhlfe->out_label == out_label) + nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, gtype, gate, + ifindex); + if (nhlfe) { + struct nexthop *nh = nhlfe->nexthop; + + assert(nh); + assert(nh->nh_label); + + /* Compare existing nexthop */ + if (nh->nh_label->num_labels == 1 && + nh->nh_label->label[0] == out_label) /* No change */ return 0; if (IS_ZEBRA_DEBUG_MPLS) { - snhlfe2str(snhlfe, buf, sizeof(buf)); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Upd static LSP in-label %u nexthop %s out-label %u (old %u)", - in_label, buf, out_label, snhlfe->out_label); + in_label, buf, out_label, + nh->nh_label->label[0]); + } + if (nh->nh_label->num_labels == 1) + nh->nh_label->label[0] = out_label; + else { + nexthop_del_labels(nh); + nexthop_add_labels(nh, ZEBRA_LSP_STATIC, 1, &out_label); } - snhlfe->out_label = out_label; + } else { /* Add static LSP entry to this nexthop */ - snhlfe = snhlfe_add(slsp, gtype, gate, ifindex, out_label); - if (!snhlfe) + nhlfe = nhlfe_add(lsp, ZEBRA_LSP_STATIC, gtype, gate, + ifindex, 1, &out_label, false /*backup*/); + if (!nhlfe) return -1; if (IS_ZEBRA_DEBUG_MPLS) { - snhlfe2str(snhlfe, buf, sizeof(buf)); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug( "Add static LSP in-label %u nexthop %s out-label %u", in_label, buf, out_label); @@ -3752,8 +3555,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, { struct hash *slsp_table; zebra_ile_t tmp_ile; - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; /* Lookup table. */ slsp_table = zvrf->slsp_table; @@ -3762,8 +3565,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, /* If entry is not present, exit. */ tmp_ile.in_label = in_label; - slsp = hash_lookup(slsp_table, &tmp_ile); - if (!slsp) + lsp = hash_lookup(slsp_table, &tmp_ile); + if (!lsp) return 0; /* Is it delete of entire LSP or a specific NHLFE? */ @@ -3775,16 +3578,19 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, mpls_static_lsp_uninstall_all(zvrf, in_label); /* Delete all static NHLFEs */ - snhlfe_del_all(slsp); + frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) { + nhlfe_del(nhlfe); + } } else { /* Find specific NHLFE, exit if not found. */ - snhlfe = snhlfe_find(slsp, gtype, gate, ifindex); - if (!snhlfe) + nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, + gtype, gate, ifindex); + if (!nhlfe) return 0; if (IS_ZEBRA_DEBUG_MPLS) { char buf[BUFSIZ]; - snhlfe2str(snhlfe, buf, BUFSIZ); + nhlfe2str(nhlfe, buf, sizeof(buf)); zlog_debug("Del static LSP in-label %u nexthop %s", in_label, buf); } @@ -3794,14 +3600,15 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, gate, ifindex, false); /* Delete static LSP NHLFE */ - snhlfe_del(snhlfe); + nhlfe_del(nhlfe); } /* Remove entire static LSP entry if no NHLFE - valid in either case - * above. */ - if (snhlfe_list_first(&slsp->snhlfe_list) == NULL) { - slsp = hash_release(slsp_table, &tmp_ile); - XFREE(MTYPE_SLSP, slsp); + * above. + */ + if (nhlfe_list_first(&lsp->nhlfe_list) == NULL) { + lsp = hash_release(slsp_table, &tmp_ile); + XFREE(MTYPE_LSP, lsp); } return 0; @@ -3949,23 +3756,58 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, } /* + * Create printable string for static LSP configuration. + */ +static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size) +{ + const struct nexthop *nh; + + nh = nhlfe->nexthop; + + buf[0] = '\0'; + switch (nh->type) { + case NEXTHOP_TYPE_IPV4: + inet_ntop(AF_INET, &nh->gate.ipv4, buf, size); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + inet_ntop(AF_INET6, &nh->gate.ipv6, buf, size); + if (nh->ifindex) + strlcat(buf, + ifindex2ifname(nh->ifindex, VRF_DEFAULT), + size); + break; + default: + break; + } + + return buf; +} + +/* * Display MPLS LSP configuration of all static LSPs (VTY command handler). */ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) { - zebra_slsp_t *slsp; - zebra_snhlfe_t *snhlfe; + zebra_lsp_t *lsp; + zebra_nhlfe_t *nhlfe; + struct nexthop *nh; struct listnode *node; struct list *slsp_list = - hash_get_sorted_list(zvrf->slsp_table, slsp_cmp); + hash_get_sorted_list(zvrf->slsp_table, lsp_cmp); - for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) { - frr_each(snhlfe_list, &slsp->snhlfe_list, snhlfe) { + for (ALL_LIST_ELEMENTS_RO(slsp_list, node, lsp)) { + frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) { char buf[BUFSIZ]; char lstr[30]; - snhlfe2str(snhlfe, buf, sizeof(buf)); - switch (snhlfe->out_label) { + nh = nhlfe->nexthop; + if (nh == NULL || nh->nh_label == NULL) + continue; + + nhlfe_config_str(nhlfe, buf, sizeof(buf)); + + switch (nh->nh_label->label[0]) { case MPLS_LABEL_IPV4_EXPLICIT_NULL: case MPLS_LABEL_IPV6_EXPLICIT_NULL: strlcpy(lstr, "explicit-null", sizeof(lstr)); @@ -3975,11 +3817,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) break; default: snprintf(lstr, sizeof(lstr), "%u", - snhlfe->out_label); + nh->nh_label->label[0]); break; } - vty_out(vty, "mpls lsp %u %s %s\n", slsp->ile.in_label, + vty_out(vty, "mpls lsp %u %s %s\n", lsp->ile.in_label, buf, lstr); } } diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index c0e58c44e3..5167233040 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -50,37 +50,14 @@ extern "C" { /* Typedefs */ typedef struct zebra_ile_t_ zebra_ile_t; -typedef struct zebra_snhlfe_t_ zebra_snhlfe_t; -typedef struct zebra_slsp_t_ zebra_slsp_t; typedef struct zebra_nhlfe_t_ zebra_nhlfe_t; typedef struct zebra_lsp_t_ zebra_lsp_t; typedef struct zebra_fec_t_ zebra_fec_t; /* Declare LSP nexthop list types */ -PREDECL_DLIST(snhlfe_list); PREDECL_DLIST(nhlfe_list); /* - * (Outgoing) nexthop label forwarding entry configuration - */ -struct zebra_snhlfe_t_ { - /* Nexthop information */ - enum nexthop_types_t gtype; - union g_addr gate; - char *ifname; - ifindex_t ifindex; - - /* Out label. */ - mpls_label_t out_label; - - /* Backpointer to base entry. */ - zebra_slsp_t *slsp; - - /* Linkage for LSPs' lists */ - struct snhlfe_list_item list; -}; - -/* * (Outgoing) nexthop label forwarding entry */ struct zebra_nhlfe_t_ { @@ -116,17 +93,6 @@ struct zebra_ile_t_ { }; /* - * Label swap entry static configuration. - */ -struct zebra_slsp_t_ { - /* Incoming label */ - zebra_ile_t ile; - - /* List of outgoing nexthop static configuration */ - struct snhlfe_list_head snhlfe_list; -}; - -/* * Label swap entry (ile -> list of nhlfes) */ struct zebra_lsp_t_ { diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index 583b666e66..3af805558d 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -47,8 +47,8 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS) char sbuf[40]; char gbuf[40]; - strlcpy(sbuf, inet_ntoa(mroute.sg.src), sizeof(sbuf)); - strlcpy(gbuf, inet_ntoa(mroute.sg.grp), sizeof(gbuf)); + inet_ntop(AF_INET, &mroute.sg.src, sbuf, sizeof(sbuf)); + inet_ntop(AF_INET, &mroute.sg.grp, gbuf, sizeof(gbuf)); zlog_debug("Asking for (%s,%s)[%s(%u)] mroute information", sbuf, gbuf, zvrf->vrf->name, zvrf->vrf->vrf_id); diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index b4ed910b4d..df95770307 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -21,6 +21,7 @@ #include "lib/log.h" #include "lib/northbound.h" +#include "lib/printfrr.h" #include "libfrr.h" #include "lib/command.h" #include "lib/routemap.h" @@ -839,7 +840,6 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) { struct interface *ifp; struct prefix prefix; - char buf[PREFIX_STRLEN] = {0}; ifp = nb_running_get_entry(args->dnode, NULL, true); // addr_family = yang_dnode_get_enum(dnode, "./address-family"); @@ -850,15 +850,13 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) case NB_EV_VALIDATE: if (prefix.family == AF_INET && ipv4_martian(&prefix.u.prefix4)) { - snprintf(args->errmsg, args->errmsg_len, - "invalid address %s", - prefix2str(&prefix, buf, sizeof(buf))); + snprintfrr(args->errmsg, args->errmsg_len, + "invalid address %pFX", &prefix); return NB_ERR_VALIDATION; } else if (prefix.family == AF_INET6 && ipv6_martian(&prefix.u.prefix6)) { - snprintf(args->errmsg, args->errmsg_len, - "invalid address %s", - prefix2str(&prefix, buf, sizeof(buf))); + snprintfrr(args->errmsg, args->errmsg_len, + "invalid address %pFX", &prefix); return NB_ERR_VALIDATION; } break; @@ -1554,7 +1552,7 @@ int lib_route_map_entry_set_action_source_v4_modify( } if (pif == NULL) { snprintf(args->errmsg, args->errmsg_len, - "is not a local adddress: %s", + "is not a local address: %s", yang_dnode_get_string(args->dnode, NULL)); return NB_ERR_VALIDATION; } diff --git a/zebra/zebra_nb_rpcs.c b/zebra/zebra_nb_rpcs.c index 204cc5da6d..e7d438b1af 100644 --- a/zebra/zebra_nb_rpcs.c +++ b/zebra/zebra_nb_rpcs.c @@ -65,19 +65,22 @@ int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args) if (yang_dup_mac) { yang_str2mac(yang_dup_mac->value, &mac); ret = zebra_vxlan_clear_dup_detect_vni_mac( - zvrf, vni, &mac); + zvrf, vni, &mac, args->errmsg, + args->errmsg_len); } else if (yang_dup_ip) { yang_str2ip(yang_dup_ip->value, &host_ip); ret = zebra_vxlan_clear_dup_detect_vni_ip( - zvrf, vni, &host_ip); + zvrf, vni, &host_ip, args->errmsg, + args->errmsg_len); } else ret = zebra_vxlan_clear_dup_detect_vni(zvrf, vni); } } - ret = (ret != CMD_SUCCESS) ? NB_ERR : NB_OK; + if (ret < 0) + return NB_ERR; - return ret; + return NB_OK; } /* diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 995fa6fb5a..ee2dc7a0ed 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -378,7 +378,7 @@ void zebra_ns_notify_close(void) fd = zebra_netns_notify_current->u.fd; if (zebra_netns_notify_current->master != NULL) - thread_cancel(zebra_netns_notify_current); + thread_cancel(&zebra_netns_notify_current); /* auto-removal of notify items */ if (fd > 0) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index de79c59caa..196e3c83d0 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -56,12 +56,12 @@ static bool g_nexthops_enabled = true; static bool proto_nexthops_only; static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi, - int type); + int type, bool from_dplane); static void depends_add(struct nhg_connected_tree_head *head, struct nhg_hash_entry *depend); static struct nhg_hash_entry * depends_find_add(struct nhg_connected_tree_head *head, struct nexthop *nh, - afi_t afi, int type); + afi_t afi, int type, bool from_dplane); static struct nhg_hash_entry * depends_find_id_add(struct nhg_connected_tree_head *head, uint32_t id); static void depends_decrement_free(struct nhg_connected_tree_head *head); @@ -442,11 +442,8 @@ static void *zebra_nhg_hash_alloc(void *arg) /* Mark duplicate nexthops in a group at creation time. */ nexthop_group_mark_duplicates(&(nhe->nhg)); - zebra_nhg_connect_depends(nhe, &(copy->nhg_depends)); - /* Add the ifp now if it's not a group or recursive and has ifindex */ - if (zebra_nhg_depends_is_empty(nhe) && nhe->nhg.nexthop - && nhe->nhg.nexthop->ifindex) { + if (nhe->nhg.nexthop && nhe->nhg.nexthop->ifindex) { struct interface *ifp = NULL; ifp = if_lookup_by_index(nhe->nhg.nexthop->ifindex, @@ -461,7 +458,6 @@ static void *zebra_nhg_hash_alloc(void *arg) nhe->nhg.nexthop->vrf_id, nhe->id); } - return nhe; } @@ -672,7 +668,7 @@ static void handle_recursive_depend(struct nhg_connected_tree_head *nhg_depends, static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ struct nhg_hash_entry *lookup, struct nhg_connected_tree_head *nhg_depends, - afi_t afi) + afi_t afi, bool from_dplane) { bool created = false; bool recursive = false; @@ -680,10 +676,11 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ struct nexthop *nh = NULL; if (IS_ZEBRA_DEBUG_NHG_DETAIL) - zlog_debug("%s: id %u, lookup %p, vrf %d, type %d, depends %p", - __func__, lookup->id, lookup, - lookup->vrf_id, lookup->type, - nhg_depends); + zlog_debug( + "%s: id %u, lookup %p, vrf %d, type %d, depends %p%s", + __func__, lookup->id, lookup, lookup->vrf_id, + lookup->type, nhg_depends, + (from_dplane ? " (from dplane)" : "")); if (lookup->id) (*nhe) = zebra_nhg_lookup_id(lookup->id); @@ -705,7 +702,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ if (lookup->id == 0) lookup->id = nhg_get_next_id(); - if (lookup->id < ZEBRA_NHG_PROTO_LOWER) { + if (!from_dplane && lookup->id < ZEBRA_NHG_PROTO_LOWER) { /* * This is a zebra hashed/owned NHG. * @@ -715,7 +712,8 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ zebra_nhg_insert_id(newnhe); } else { /* - * This is upperproto owned NHG and should not be hashed to. + * This is upperproto owned NHG or one we read in from dataplane + * and should not be hashed to. * * It goes in ID table. */ @@ -752,7 +750,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ * resolving nexthop; or a group of nexthops, where we need * relationships with the corresponding singletons. */ - zebra_nhg_depends_init(lookup); + zebra_nhg_depends_init(newnhe); nh = newnhe->nhg.nexthop; @@ -779,12 +777,19 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ "(R)" : ""); depends_find_add(&newnhe->nhg_depends, nh, afi, - newnhe->type); + newnhe->type, from_dplane); } } if (recursive) - SET_FLAG((*nhe)->flags, NEXTHOP_GROUP_RECURSIVE); + SET_FLAG(newnhe->flags, NEXTHOP_GROUP_RECURSIVE); + + /* Attach dependent backpointers to singletons */ + zebra_nhg_connect_depends(newnhe, &newnhe->nhg_depends); + + /** + * Backup Nexthops + */ if (zebra_nhg_get_backup_nhg(newnhe) == NULL || zebra_nhg_get_backup_nhg(newnhe)->nexthop == NULL) @@ -820,7 +825,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */ "(R)" : ""); depends_find_add(&backup_nhe->nhg_depends, nh, afi, - backup_nhe->type); + backup_nhe->type, from_dplane); } } @@ -838,7 +843,8 @@ done: static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id, struct nexthop_group *nhg, struct nhg_connected_tree_head *nhg_depends, - vrf_id_t vrf_id, afi_t afi, int type) + vrf_id_t vrf_id, afi_t afi, int type, + bool from_dplane) { struct nhg_hash_entry lookup = {}; bool created = false; @@ -854,7 +860,7 @@ static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id, lookup.nhg = *nhg; lookup.vrf_id = vrf_id; - if (lookup.nhg.nexthop->next) { + if (nhg_depends || lookup.nhg.nexthop->next) { /* Groups can have all vrfs and AF's in them */ lookup.afi = AFI_UNSPEC; } else { @@ -882,14 +888,16 @@ static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id, } } - created = zebra_nhe_find(nhe, &lookup, nhg_depends, afi); + created = zebra_nhe_find(nhe, &lookup, nhg_depends, afi, from_dplane); return created; } /* Find/create a single nexthop */ -static struct nhg_hash_entry * -zebra_nhg_find_nexthop(uint32_t id, struct nexthop *nh, afi_t afi, int type) +static struct nhg_hash_entry *zebra_nhg_find_nexthop(uint32_t id, + struct nexthop *nh, + afi_t afi, int type, + bool from_dplane) { struct nhg_hash_entry *nhe = NULL; struct nexthop_group nhg = {}; @@ -897,7 +905,7 @@ zebra_nhg_find_nexthop(uint32_t id, struct nexthop *nh, afi_t afi, int type) nexthop_group_add_sorted(&nhg, nh); - zebra_nhg_find(&nhe, id, &nhg, NULL, vrf_id, afi, type); + zebra_nhg_find(&nhe, id, &nhg, NULL, vrf_id, afi, type, from_dplane); if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: nh %pNHv => %p (%u)", @@ -1151,14 +1159,14 @@ static int nhg_ctx_process_new(struct nhg_ctx *ctx) } if (!zebra_nhg_find(&nhe, id, nhg, &nhg_depends, vrf_id, afi, - type)) + type, true)) depends_decrement_free(&nhg_depends); /* These got copied over in zebra_nhg_alloc() */ nexthop_group_delete(&nhg); } else - nhe = zebra_nhg_find_nexthop(id, nhg_ctx_get_nh(ctx), afi, - type); + nhe = zebra_nhg_find_nexthop(id, nhg_ctx_get_nh(ctx), afi, type, + true); if (!nhe) { flog_err( @@ -1325,7 +1333,7 @@ static struct nhg_hash_entry *depends_find_recursive(const struct nexthop *nh, lookup = nexthop_dup(nh, NULL); - nhe = zebra_nhg_find_nexthop(0, lookup, afi, type); + nhe = zebra_nhg_find_nexthop(0, lookup, afi, type, false); nexthops_free(lookup); @@ -1333,7 +1341,8 @@ static struct nhg_hash_entry *depends_find_recursive(const struct nexthop *nh, } static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh, - afi_t afi, int type) + afi_t afi, int type, + bool from_dplane) { struct nhg_hash_entry *nhe; struct nexthop lookup = {}; @@ -1343,7 +1352,7 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh, */ nexthop_copy_no_recurse(&lookup, nh, NULL); - nhe = zebra_nhg_find_nexthop(0, &lookup, afi, type); + nhe = zebra_nhg_find_nexthop(0, &lookup, afi, type, from_dplane); /* The copy may have allocated labels; free them if necessary. */ nexthop_del_labels(&lookup); @@ -1356,7 +1365,7 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh, } static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi, - int type) + int type, bool from_dplane) { struct nhg_hash_entry *nhe = NULL; @@ -1369,7 +1378,7 @@ static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi, if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) nhe = depends_find_recursive(nh, afi, type); else - nhe = depends_find_singleton(nh, afi, type); + nhe = depends_find_singleton(nh, afi, type, from_dplane); if (IS_ZEBRA_DEBUG_NHG_DETAIL) { @@ -1402,11 +1411,11 @@ static void depends_add(struct nhg_connected_tree_head *head, static struct nhg_hash_entry * depends_find_add(struct nhg_connected_tree_head *head, struct nexthop *nh, - afi_t afi, int type) + afi_t afi, int type, bool from_dplane) { struct nhg_hash_entry *depend = NULL; - depend = depends_find(nh, afi, type); + depend = depends_find(nh, afi, type, from_dplane); if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: nh %pNHv => %p", @@ -1452,7 +1461,7 @@ struct nhg_hash_entry *zebra_nhg_rib_find(uint32_t id, assert(nhg->nexthop); vrf_id = !vrf_is_backend_netns() ? VRF_DEFAULT : nhg->nexthop->vrf_id; - zebra_nhg_find(&nhe, id, nhg, NULL, vrf_id, rt_afi, type); + zebra_nhg_find(&nhe, id, nhg, NULL, vrf_id, rt_afi, type, false); if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: => nhe %p (%u)", @@ -1476,7 +1485,7 @@ zebra_nhg_rib_find_nhe(struct nhg_hash_entry *rt_nhe, afi_t rt_afi) if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: rt_nhe %p (%u)", __func__, rt_nhe, rt_nhe->id); - zebra_nhe_find(&nhe, rt_nhe, NULL, rt_afi); + zebra_nhe_find(&nhe, rt_nhe, NULL, rt_afi, false); if (IS_ZEBRA_DEBUG_NHG_DETAIL) zlog_debug("%s: => nhe %p (%u)", @@ -1582,6 +1591,7 @@ void zebra_nhg_free(struct nhg_hash_entry *nhe) void zebra_nhg_hash_free(void *p) { + zebra_nhg_release_all_deps((struct nhg_hash_entry *)p); zebra_nhg_free((struct nhg_hash_entry *)p); } @@ -2682,6 +2692,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx) case DPLANE_OP_RULE_DELETE: case DPLANE_OP_RULE_UPDATE: case DPLANE_OP_NEIGH_DISCOVER: + case DPLANE_OP_BR_PORT_UPDATE: case DPLANE_OP_NONE: break; } @@ -2705,6 +2716,30 @@ void zebra_nhg_sweep_table(struct hash *hash) hash_iterate(hash, zebra_nhg_sweep_entry, NULL); } +static void zebra_nhg_mark_keep_entry(struct hash_bucket *bucket, void *arg) +{ + struct nhg_hash_entry *nhe = bucket->data; + + UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED); +} + +/* + * When we are shutting down and we have retain mode enabled + * in zebra the process is to mark each vrf that it's + * routes should not be deleted. The problem with that + * is that shutdown actually free's up memory which + * causes the nexthop group's ref counts to go to zero + * we need a way to subtly tell the system to not remove + * the nexthop groups from the kernel at the same time. + * The easiest just looks like that we should not mark + * the nhg's as installed any more and when the ref count + * goes to zero we'll attempt to delete and do nothing + */ +void zebra_nhg_mark_keep(void) +{ + hash_iterate(zrouter.nhgs_id, zebra_nhg_mark_keep_entry, NULL); +} + /* Global control to disable use of kernel nexthops, if available. We can't * force the kernel to support nexthop ids, of course, but we can disable * zebra's use of them, for testing e.g. By default, if the kernel supports @@ -2808,10 +2843,15 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type, if (old) { /* * This is a replace, just release NHE from ID for now, The - * depends/dependents may still be used in the replacement. + * depends/dependents may still be used in the replacement so + * we don't touch them other than to remove their refs to their + * old parent. */ replace = true; hash_release(zrouter.nhgs_id, old); + + /* Free all the things */ + zebra_nhg_release_all_deps(old); } new = zebra_nhg_rib_find_nhe(&lookup, afi); @@ -2848,9 +2888,6 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type, zebra_nhg_decrement_ref(rb_node_dep->nhe); } - /* Free all the things */ - zebra_nhg_release_all_deps(old); - /* Dont call the dec API, we dont want to uninstall the ID */ old->refcnt = 0; zebra_nhg_free(old); diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index 052fa65d06..b2ef88bb61 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -324,9 +324,16 @@ struct zebra_dplane_ctx; extern void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx); -/* Sweet the nhg hash tables for old entries on restart */ +/* Sweep the nhg hash tables for old entries on restart */ extern void zebra_nhg_sweep_table(struct hash *hash); +/* + * We are shutting down but the nexthops should be kept + * as that -r has been specified and we don't want to delete + * the routes unintentionally + */ +extern void zebra_nhg_mark_keep(void); + /* Nexthop resolution processing */ struct route_entry; /* Forward ref to avoid circular includes */ extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); diff --git a/zebra/zebra_opaque.c b/zebra/zebra_opaque.c index 41e278f71b..1d59e0ab34 100644 --- a/zebra/zebra_opaque.c +++ b/zebra/zebra_opaque.c @@ -258,7 +258,7 @@ uint32_t zebra_opaque_enqueue_batch(struct stream_fifo *batch) /* Schedule module pthread to process the batch */ if (counter > 0) { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: received %u messages", __func__, counter); thread_add_event(zo_info.master, process_messages, NULL, 0, @@ -315,7 +315,7 @@ static int process_messages(struct thread *event) goto done; } - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: processing %u messages", __func__, i); /* @@ -381,7 +381,7 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) /* Look up registered ZAPI client(s) */ reg = opq_reg_lookup(info.type); if (reg == NULL) { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: no registrations for opaque type %u, flags %#x", __func__, info.type, info.flags); goto drop_it; @@ -401,7 +401,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) client->session_id != info.session_id) continue; - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && + IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: found matching unicast client %s", __func__, opq_client2str(buf, @@ -423,7 +424,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) client->instance, client->session_id); if (zclient) { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_SEND && + IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: sending %s to client %s", __func__, (dup ? "dup" : "msg"), @@ -444,7 +446,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo) zserv_release_client(zclient); } else { - if (IS_ZEBRA_DEBUG_RECV) + if (IS_ZEBRA_DEBUG_RECV && + IS_ZEBRA_DEBUG_DETAIL) zlog_debug("%s: type %u: no zclient for %s", __func__, info.type, opq_client2str(buf, @@ -615,10 +618,6 @@ static int handle_opq_unregistration(const struct zmsghdr *hdr, /* Is registration empty now? */ if (reg->clients == NULL) { - if (IS_ZEBRA_DEBUG_RECV) - zlog_debug("%s: free empty reg %u", __func__, - reg->type); - opq_regh_del(&opq_reg_hash, reg); opq_reg_free(®); } diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 9a3b567b5a..1e7b38086b 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -156,13 +156,10 @@ void zebra_ptm_finish(void) if (ptm_cb.in_data) free(ptm_cb.in_data); - /* Release threads. */ - if (ptm_cb.t_read) - thread_cancel(ptm_cb.t_read); - if (ptm_cb.t_write) - thread_cancel(ptm_cb.t_write); - if (ptm_cb.t_timer) - thread_cancel(ptm_cb.t_timer); + /* Cancel events. */ + thread_cancel(&ptm_cb.t_read); + thread_cancel(&ptm_cb.t_write); + thread_cancel(&ptm_cb.t_timer); if (ptm_cb.wb) buffer_free(ptm_cb.wb); @@ -218,7 +215,7 @@ static int zebra_ptm_send_message(char *data, int size) ptm_cb.reconnect_time, &ptm_cb.t_timer); return -1; case BUFFER_EMPTY: - THREAD_OFF(ptm_cb.t_write); + thread_cancel(&ptm_cb.t_write); break; case BUFFER_PENDING: thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL, diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index cdcca1e930..ecae021dba 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -102,7 +102,7 @@ void zebra_pw_del(struct zebra_vrf *zvrf, struct zebra_pw *pw) hook_call(pw_uninstall, pw); dplane_pw_uninstall(pw); } else if (pw->install_retry_timer) - THREAD_TIMER_OFF(pw->install_retry_timer); + thread_cancel(&pw->install_retry_timer); /* unlink and release memory */ RB_REMOVE(zebra_pw_head, &zvrf->pseudowires, pw); @@ -219,7 +219,7 @@ void zebra_pw_install_failure(struct zebra_pw *pw, int pwstatus) pw->vrf_id, pw->ifname, PW_INSTALL_RETRY_INTERVAL); /* schedule to retry later */ - THREAD_TIMER_OFF(pw->install_retry_timer); + thread_cancel(&pw->install_retry_timer); thread_add_timer(zrouter.master, zebra_pw_install_retry, pw, PW_INSTALL_RETRY_INTERVAL, &pw->install_retry_timer); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index aac0e628fe..e76ecc85a6 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -79,35 +79,35 @@ static const struct { uint8_t meta_q_map; } route_info[ZEBRA_ROUTE_MAX] = { [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Uneeded for nhg's */, 0}, - [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 5}, - [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 1}, + [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 6}, + [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 2}, [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 1}, - [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 2}, - [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 3}, - [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 3}, - [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 3}, - [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 3}, - [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 3}, - [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 4}, - [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 5}, - [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 3}, - [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 3}, - [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 5}, - [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 5}, - [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 2}, - [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 5}, - [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 4}, - [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 4}, - [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 4}, - [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 4}, - [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 4}, - [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 3}, - [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 5}, - [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 5}, - [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 5}, - [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 3}, - [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 5}, - [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 5}, + [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 3}, + [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 4}, + [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 4}, + [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 4}, + [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 4}, + [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 4}, + [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 5}, + [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 6}, + [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 4}, + [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 4}, + [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 6}, + [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 6}, + [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 3}, + [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 6}, + [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 5}, + [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 5}, + [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 5}, + [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 5}, + [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 5}, + [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 4}, + [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 6}, + [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 6}, + [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 6}, + [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 4}, + [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 6}, + [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 6}, /* Any new route type added to zebra, should be mirrored here */ /* no entry/default: 150 */ @@ -694,15 +694,13 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) if (IS_ZEBRA_DEBUG_NHT_DETAILED) { char buf1[PREFIX_STRLEN]; - char buf2[PREFIX_STRLEN]; zlog_debug( - "%s(%u):%s has Nexthop(%s) Type: %s depending on it, evaluating %u:%u", + "%s(%u):%s has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u", zvrf_name(zvrf), zvrf_id(zvrf), srcdest_rnode2str(rn, buf1, sizeof(buf1)), - prefix2str(p, buf2, sizeof(buf2)), - rnh_type2str(rnh->type), seq, + p, rnh_type2str(rnh->type), seq, rnh->seqno); } @@ -921,11 +919,22 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, zebra_route_string(new->type)); } - /* If labeled-unicast route, uninstall transit LSP. */ - if (zebra_rib_labeled_unicast(old)) - zebra_mpls_lsp_uninstall(zvrf, rn, old); + /* + * When we have gotten to this point + * the new route entry has no nexthops + * that are usable and as such we need + * to remove the old route, but only + * if we were the one who installed + * the old route + */ + if (!RIB_SYSTEM_ROUTE(old)) { + /* If labeled-unicast route, uninstall transit + * LSP. */ + if (zebra_rib_labeled_unicast(old)) + zebra_mpls_lsp_uninstall(zvrf, rn, old); - rib_uninstall_kernel(rn, old); + rib_uninstall_kernel(rn, old); + } } } else { /* @@ -1087,46 +1096,56 @@ static void rib_process(struct route_node *rn) if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) continue; - /* Skip unreachable nexthop. */ - /* This first call to nexthop_active_update is merely to - * determine if there's any change to nexthops associated - * with this RIB entry. Now, rib_process() can be invoked due - * to an external event such as link down or due to - * next-hop-tracking evaluation. In the latter case, - * a decision has already been made that the NHs have changed. - * So, no need to invoke a potentially expensive call again. - * Further, since the change might be in a recursive NH which - * is not caught in the nexthop_active_update() code. Thus, we - * might miss changes to recursive NHs. + /* + * If the route entry has changed, verify/resolve + * the nexthops associated with the entry. + * + * In any event if we have nexthops that are not active + * then we cannot use this particular route entry so + * skip it. */ - if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) - && !nexthop_active_update(rn, re)) { - if (re->type == ZEBRA_ROUTE_TABLE) { - /* XXX: HERE BE DRAGONS!!!!! - * In all honesty, I have not yet figured out - * what this part does or why the - * ROUTE_ENTRY_CHANGED test above is correct - * or why we need to delete a route here, and - * also not whether this concerns both selected - * and fib route, or only selected - * or only fib - * - * This entry was denied by the 'ip protocol - * table' route-map, we need to delete it */ - if (re != old_selected) { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug( - "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map", - __func__, - VRF_LOGNAME(vrf), - vrf_id, buf); - rib_unlink(rn, re); - } else - SET_FLAG(re->status, - ROUTE_ENTRY_REMOVED); - } + if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) { + if (!nexthop_active_update(rn, re)) { + if (re->type == ZEBRA_ROUTE_TABLE) { + /* XXX: HERE BE DRAGONS!!!!! + * In all honesty, I have not yet + * figured out what this part does or + * why the ROUTE_ENTRY_CHANGED test + * above is correct or why we need to + * delete a route here, and also not + * whether this concerns both selected + * and fib route, or only selected + * or only fib + * + * This entry was denied by the 'ip + * protocol + * table' route-map, we need to delete + * it */ + if (re != old_selected) { + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug( + "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map", + __func__, + VRF_LOGNAME( + vrf), + vrf_id, buf); + rib_unlink(rn, re); + } else + SET_FLAG(re->status, + ROUTE_ENTRY_REMOVED); + } - continue; + continue; + } + } else { + /* + * If the re has not changed and the nhg we have is + * not usable, then we cannot use this route entry + * for consideration, as that the route will just + * not install if it is selected. + */ + if (!nexthop_group_active_nexthop_num(&re->nhe->nhg)) + continue; } /* Infinite distance. */ @@ -1357,8 +1376,6 @@ static void zebra_rib_fixup_system(struct route_node *rn) static bool rib_compare_routes(const struct route_entry *re1, const struct route_entry *re2) { - bool result = false; - if (re1->type != re2->type) return false; @@ -1372,17 +1389,14 @@ static bool rib_compare_routes(const struct route_entry *re1, re1->distance != re2->distance) return false; - /* Only connected routes need more checking, nexthop-by-nexthop */ + /* We support multiple connected routes: this supports multiple + * v6 link-locals, and we also support multiple addresses in the same + * subnet on a single interface. + */ if (re1->type != ZEBRA_ROUTE_CONNECT) return true; - /* Quick check if shared nhe */ - if (re1->nhe == re2->nhe) - return true; - - result = nexthop_group_equal_no_recurse(&re1->nhe->nhg, &re2->nhe->nhg); - - return result; + return false; } /* @@ -1481,7 +1495,6 @@ static bool rib_update_re_from_ctx(struct route_entry *re, struct route_node *rn, struct zebra_dplane_ctx *ctx) { - char dest_str[PREFIX_STRLEN] = ""; struct nexthop *nexthop; bool matched; const struct nexthop_group *ctxnhg; @@ -1493,19 +1506,13 @@ static bool rib_update_re_from_ctx(struct route_entry *re, vrf = vrf_lookup_by_id(re->vrf_id); - /* Note well: only capturing the prefix string if debug is enabled here; - * unconditional log messages will have to generate the string. - */ - if (IS_ZEBRA_DEBUG_RIB) - prefix2str(&(rn->p), dest_str, sizeof(dest_str)); - dest = rib_dest_from_rnode(rn); if (dest) is_selected = (re == dest->selected_fib); if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("update_from_ctx: %s(%u:%u):%s: %sSELECTED, re %p", - VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str, + zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn, (is_selected ? "" : "NOT "), re); /* Update zebra's nexthop FIB flag for each nexthop that was installed. @@ -1531,9 +1538,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re, if (matched) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): existing fib nhg, no change", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str); + "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn); goto check_backups; } else if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG)) { @@ -1542,9 +1548,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re, */ if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): replacing fib nhg", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str); + "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn); nexthops_free(re->fib_ng.nexthop); re->fib_ng.nexthop = NULL; @@ -1554,9 +1559,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re, changed_p = true; } else { if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u:%u):%s update_from_ctx(): no fib nhg", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str); + zlog_debug( + "%s(%u:%u):%pRN update_from_ctx(): no fib nhg", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn); } /* @@ -1583,9 +1588,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re, if (matched) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): rib nhg matched, changed '%s'", - VRF_LOGNAME(vrf), re->vrf_id, re->table, - dest_str, (changed_p ? "true" : "false")); + "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn, + (changed_p ? "true" : "false")); goto check_backups; } @@ -1596,8 +1601,8 @@ no_nexthops: */ if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u:%u):%s update_from_ctx(): changed %s, adding new fib nhg%s", - VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str, + "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s", + VRF_LOGNAME(vrf), re->vrf_id, re->table, rn, (changed_p ? "true" : "false"), ctxnhg->nexthop != NULL ? "" : " (empty)"); @@ -1631,8 +1636,8 @@ check_backups: if (matched) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u):%s update_from_ctx(): existing fib backup nhg, no change", - VRF_LOGNAME(vrf), re->vrf_id, dest_str); + "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change", + VRF_LOGNAME(vrf), re->vrf_id, rn); goto done; } else if (re->fib_backup_ng.nexthop) { @@ -1642,8 +1647,8 @@ check_backups: */ if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s(%u):%s update_from_ctx(): replacing fib backup nhg", - VRF_LOGNAME(vrf), re->vrf_id, dest_str); + "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg", + VRF_LOGNAME(vrf), re->vrf_id, rn); nexthops_free(re->fib_backup_ng.nexthop); re->fib_backup_ng.nexthop = NULL; @@ -1651,8 +1656,9 @@ check_backups: changed_p = true; } else { if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u):%s update_from_ctx(): no fib backup nhg", - VRF_LOGNAME(vrf), re->vrf_id, dest_str); + zlog_debug( + "%s(%u):%pRN update_from_ctx(): no fib backup nhg", + VRF_LOGNAME(vrf), re->vrf_id, rn); } /* @@ -1671,9 +1677,10 @@ check_backups: goto done; if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s(%u):%s update_from_ctx(): changed %s, adding new backup fib nhg", - VRF_LOGNAME(vrf), re->vrf_id, dest_str, - (changed_p ? "true" : "false")); + zlog_debug( + "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg", + VRF_LOGNAME(vrf), re->vrf_id, rn, + (changed_p ? "true" : "false")); copy_nexthops(&(re->fib_backup_ng.nexthop), ctxnhg->nexthop, NULL); @@ -1735,7 +1742,6 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) struct route_node *rn = NULL; struct route_entry *re = NULL, *old_re = NULL, *rib; bool is_update = false; - char dest_str[PREFIX_STRLEN] = ""; enum dplane_op_e op; enum zebra_dplane_result status; const struct prefix *dest_pfx, *src_pfx; @@ -1747,20 +1753,14 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); dest_pfx = dplane_ctx_get_dest(ctx); - /* Note well: only capturing the prefix string if debug is enabled here; - * unconditional log messages will have to generate the string. - */ - if (IS_ZEBRA_DEBUG_DPLANE) - prefix2str(dest_pfx, dest_str, sizeof(dest_str)); - /* Locate rn and re(s) from ctx */ rn = rib_find_rn_from_ctx(ctx); if (rn == NULL) { if (IS_ZEBRA_DEBUG_DPLANE) { zlog_debug( - "Failed to process dplane results: no route for %s(%u):%s", + "Failed to process dplane results: no route for %s(%u):%pFX", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dest_str); + dest_pfx); } goto done; } @@ -1773,9 +1773,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u:%u):%s Processing dplane result ctx %p, op %s result %s", + "%s(%u:%u):%pFX Processing dplane result ctx %p, op %s result %s", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, ctx, + dplane_ctx_get_table(ctx), dest_pfx, ctx, dplane_op2str(op), dplane_res2str(status)); /* @@ -1815,9 +1815,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (re->dplane_sequence != seq) { if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u):%s Stale dplane result for re %p", + "%s(%u):%pFX Stale dplane result for re %p", VRF_LOGNAME(vrf), - dplane_ctx_get_vrf(ctx), dest_str, re); + dplane_ctx_get_vrf(ctx), dest_pfx, re); } else UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); } @@ -1826,10 +1826,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx)) { if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u:%u):%s Stale dplane result for old_re %p", + "%s(%u:%u):%pFX Stale dplane result for old_re %p", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), old_re->table, - dest_str, old_re); + dest_pfx, old_re); } else UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED); } @@ -1867,12 +1867,12 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) if (!fib_changed) { if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug( - "%s(%u:%u):%s no fib change for re", + "%s(%u:%u):%pFX no fib change for re", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), dplane_ctx_get_table( ctx), - dest_str); + dest_pfx); } /* Redistribute if this is the selected re */ @@ -1908,11 +1908,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) zsend_route_notify_owner(re, dest_pfx, ZAPI_ROUTE_FAIL_INSTALL); - zlog_warn("%s(%u:%u):%s: Route install failed", + zlog_warn("%s(%u:%u):%pFX: Route install failed", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), - prefix2str(dest_pfx, dest_str, - sizeof(dest_str))); + dplane_ctx_get_table(ctx), dest_pfx); } break; case DPLANE_OP_ROUTE_DELETE: @@ -1938,11 +1936,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_REMOVE_FAIL); - zlog_warn("%s(%u:%u):%s: Route Deletion failure", + zlog_warn("%s(%u:%u):%pFX: Route Deletion failure", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), - prefix2str(dest_pfx, dest_str, - sizeof(dest_str))); + dplane_ctx_get_table(ctx), dest_pfx); } /* @@ -2017,7 +2013,6 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) struct route_entry *re = NULL; struct vrf *vrf; struct nexthop *nexthop; - char dest_str[PREFIX_STRLEN] = ""; const struct prefix *dest_pfx, *src_pfx; rib_dest_t *dest; bool fib_changed = false; @@ -2026,20 +2021,14 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) dest_pfx = dplane_ctx_get_dest(ctx); vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx)); - /* Note well: only capturing the prefix string if debug is enabled here; - * unconditional log messages will have to generate the string. - */ - if (debug_p) - prefix2str(dest_pfx, dest_str, sizeof(dest_str)); - /* Locate rn and re(s) from ctx */ rn = rib_find_rn_from_ctx(ctx); if (rn == NULL) { if (debug_p) { zlog_debug( - "Failed to process dplane notification: no routes for %s(%u:%u):%s", + "Failed to process dplane notification: no routes for %s(%u:%u):%pFX", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); } goto done; } @@ -2048,9 +2037,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) srcdest_rnode_prefixes(rn, &dest_pfx, &src_pfx); if (debug_p) - zlog_debug("%s(%u:%u):%s Processing dplane notif ctx %p", + zlog_debug("%s(%u:%u):%pFX Processing dplane notif ctx %p", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, ctx); + dplane_ctx_get_table(ctx), dest_pfx, ctx); /* * Take a pass through the routes, look for matches with the context @@ -2065,9 +2054,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (re == NULL) { if (debug_p) zlog_debug( - "%s(%u:%u):%s Unable to process dplane notification: no entry for type %s", + "%s(%u:%u):%pFX Unable to process dplane notification: no entry for type %s", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, + dplane_ctx_get_table(ctx), dest_pfx, zebra_route_string(dplane_ctx_get_type(ctx))); goto done; @@ -2099,20 +2088,20 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); if (debug_p) zlog_debug( - "%s(%u:%u):%s dplane notif, uninstalled type %s route", + "%s(%u:%u):%pFX dplane notif, uninstalled type %s route", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, + dplane_ctx_get_table(ctx), dest_pfx, zebra_route_string( dplane_ctx_get_type(ctx))); } else { /* At least report on the event. */ if (debug_p) zlog_debug( - "%s(%u:%u):%s dplane notif, but type %s not selected_fib", + "%s(%u:%u):%pFX dplane notif, but type %s not selected_fib", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str, + dplane_ctx_get_table(ctx), dest_pfx, zebra_route_string( dplane_ctx_get_type(ctx))); } @@ -2136,9 +2125,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (!fib_changed) { if (debug_p) zlog_debug( - "%s(%u:%u):%s dplane notification: rib_update returns FALSE", + "%s(%u:%u):%pFX dplane notification: rib_update returns FALSE", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); } /* @@ -2153,9 +2142,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) if (start_count > 0 && end_count > 0) { if (debug_p) zlog_debug( - "%s(%u:%u):%s applied nexthop changes from dplane notification", + "%s(%u:%u):%pFX applied nexthop changes from dplane notification", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); /* Changed nexthops - update kernel/others */ dplane_route_notif_update(rn, re, @@ -2164,9 +2153,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) } else if (start_count == 0 && end_count > 0) { if (debug_p) zlog_debug( - "%s(%u:%u):%s installed transition from dplane notification", + "%s(%u:%u):%pFX installed transition from dplane notification", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); /* We expect this to be the selected route, so we want * to tell others about this transition. @@ -2182,9 +2171,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) } else if (start_count > 0 && end_count == 0) { if (debug_p) zlog_debug( - "%s(%u:%u):%s un-installed transition from dplane notification", + "%s(%u:%u):%pFX un-installed transition from dplane notification", VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), - dplane_ctx_get_table(ctx), dest_str); + dplane_ctx_get_table(ctx), dest_pfx); /* Transition from _something_ installed to _nothing_ * installed. @@ -2247,9 +2236,18 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) rib_process(rnode); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { - struct route_entry *re = re_list_first(&dest->routes); + struct route_entry *re = NULL; char buf[SRCDEST2STR_BUFFER]; + /* + * rib_process may have freed the dest + * as part of the garbage collection. Let's + * prevent stupidity from happening. + */ + dest = rib_dest_from_rnode(rnode); + if (dest) + re = re_list_first(&dest->routes); + srcdest_rnode2str(rnode, buf, sizeof(buf)); zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u", zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, buf, @@ -2264,7 +2262,7 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) else { zlog_debug ("%s: called for route_node (%p, %d) with no ribs", - __func__, rnode, rnode->lock); + __func__, rnode, route_node_get_lock_count(rnode)); zlog_backtrace(LOG_DEBUG); } #endif @@ -2439,8 +2437,8 @@ int rib_queue_add(struct route_node *rn) /* Pointless to queue a route_node with no RIB entries to add or remove */ if (!rnode_to_ribs(rn)) { - zlog_debug("%s: called for route_node (%p, %d) with no ribs", - __func__, (void *)rn, rn->lock); + zlog_debug("%s: called for route_node (%p, %u) with no ribs", + __func__, (void *)rn, route_node_get_lock_count(rn)); zlog_backtrace(LOG_DEBUG); return -1; } @@ -2806,7 +2804,6 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) struct route_node *rn; struct route_entry *re; struct vrf *vrf; - char prefix_buf[INET_ADDRSTRLEN]; vrf = vrf_lookup_by_id(vrf_id); @@ -2824,10 +2821,8 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) /* No route for this prefix. */ if (!rn) { - zlog_debug("%s:%s(%u) lookup failed for %s", __func__, - VRF_LOGNAME(vrf), vrf_id, - prefix2str((struct prefix *)p, prefix_buf, - sizeof(prefix_buf))); + zlog_debug("%s:%s(%u) lookup failed for %pFX", __func__, + VRF_LOGNAME(vrf), vrf_id, (struct prefix *)p); return; } @@ -2886,14 +2881,13 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) */ if (dest->selected_fib) { if (IS_ZEBRA_DEBUG_RIB) { - char buf[PREFIX_STRLEN]; struct vrf *vrf = vrf_lookup_by_id(dest->selected_fib->vrf_id); zlog_debug( - "%s(%u):%s: freeing way for connected prefix", + "%s(%u):%pFX: freeing way for connected prefix", VRF_LOGNAME(vrf), dest->selected_fib->vrf_id, - prefix2str(&rn->p, buf, sizeof(buf))); + &rn->p); route_entry_dump(&rn->p, NULL, dest->selected_fib); } rib_uninstall(rn, dest->selected_fib); @@ -2944,14 +2938,12 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, /* Lookup nhe from route information */ nhe = zebra_nhg_rib_find_nhe(re_nhe, afi); if (!nhe) { - char buf[PREFIX_STRLEN] = ""; char buf2[PREFIX_STRLEN] = ""; flog_err( EC_ZEBRA_TABLE_LOOKUP_FAILED, - "Zebra failed to find or create a nexthop hash entry for %s%s%s", - prefix2str(p, buf, sizeof(buf)), - src_p ? " from " : "", + "Zebra failed to find or create a nexthop hash entry for %pFX%s%s", + p, src_p ? " from " : "", src_p ? prefix2str(src_p, buf2, sizeof(buf2)) : ""); @@ -3061,7 +3053,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, } void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, int flags, struct prefix *p, + unsigned short instance, uint32_t flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint8_t distance, bool fromkernel, bool connected_down) @@ -3091,19 +3083,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, /* Lookup route node. */ rn = srcdest_rnode_lookup(table, p, src_p); if (!rn) { - char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN]; - - prefix2str(p, dst_buf, sizeof(dst_buf)); - if (src_p && src_p->prefixlen) - prefix2str(src_p, src_buf, sizeof(src_buf)); - else - src_buf[0] = '\0'; - if (IS_ZEBRA_DEBUG_RIB) { + char src_buf[PREFIX_STRLEN]; struct vrf *vrf = vrf_lookup_by_id(vrf_id); - zlog_debug("%s[%d]:%s%s%s doesn't exist in rib", - vrf->name, table_id, dst_buf, + if (src_p && src_p->prefixlen) + prefix2str(src_p, src_buf, sizeof(src_buf)); + else + src_buf[0] = '\0'; + + zlog_debug("%s[%d]:%pFX%s%s doesn't exist in rib", + vrf->name, table_id, p, (src_buf[0] != '\0') ? " from " : "", src_buf); } @@ -3291,7 +3281,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, int flags, struct prefix *p, + unsigned short instance, uint32_t flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint32_t mtu, uint8_t distance, route_tag_t tag) @@ -3840,6 +3830,7 @@ static int rib_process_dplane_results(struct thread *thread) case DPLANE_OP_VTEP_ADD: case DPLANE_OP_VTEP_DELETE: case DPLANE_OP_NEIGH_DISCOVER: + case DPLANE_OP_BR_PORT_UPDATE: case DPLANE_OP_NONE: /* Don't expect this: just return the struct? */ dplane_ctx_fini(&ctx); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index cdc00f6026..521f969fcc 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -86,12 +86,6 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, afi_t afi, return t; } -char *rnh_str(struct rnh *rnh, char *buf, int size) -{ - prefix2str(&(rnh->node->p), buf, size); - return buf; -} - static void zebra_rnh_remove_from_routing_table(struct rnh *rnh) { struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id); @@ -106,15 +100,10 @@ static void zebra_rnh_remove_from_routing_table(struct rnh *rnh) if (!rn) return; - if (IS_ZEBRA_DEBUG_NHT_DETAILED) { - char buf[PREFIX_STRLEN]; - char buf1[PREFIX_STRLEN]; - - zlog_debug("%s: %u:%s removed from tracking on %s", __func__, - rnh->vrf_id, - prefix2str(&rnh->node->p, buf, sizeof(buf)), - srcdest_rnode2str(rn, buf1, sizeof(buf))); - } + if (IS_ZEBRA_DEBUG_NHT_DETAILED) + zlog_debug("%s: %s(%u):%pRN removed from tracking on %pRN", + __func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id, + rnh->node, rn); dest = rib_dest_from_rnode(rn); rnh_list_del(&dest->nht, rnh); @@ -132,15 +121,10 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh) if (!rn) return; - if (IS_ZEBRA_DEBUG_NHT_DETAILED) { - char buf[PREFIX_STRLEN]; - char buf1[PREFIX_STRLEN]; - - zlog_debug("%s: %u:%s added for tracking on %s", __func__, - rnh->vrf_id, - prefix2str(&rnh->node->p, buf, sizeof(buf)), - srcdest_rnode2str(rn, buf1, sizeof(buf))); - } + if (IS_ZEBRA_DEBUG_NHT_DETAILED) + zlog_debug("%s: %s(%u):%pRN added for tracking on %pRN", + __func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id, + rnh->node, rn); dest = rib_dest_from_rnode(rn); rnh_list_add_tail(&dest->nht, rnh); @@ -153,20 +137,21 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type, struct route_table *table; struct route_node *rn; struct rnh *rnh = NULL; - char buf[PREFIX2STR_BUFFER]; afi_t afi = family2afi(p->family); if (IS_ZEBRA_DEBUG_NHT) { - prefix2str(p, buf, sizeof(buf)); - zlog_debug("%u: Add RNH %s type %s", vrfid, buf, - rnh_type2str(type)); + struct vrf *vrf = vrf_lookup_by_id(vrfid); + + zlog_debug("%s(%u): Add RNH %pFX type %s", VRF_LOGNAME(vrf), + vrfid, p, rnh_type2str(type)); } table = get_rnh_table(vrfid, afi, type); if (!table) { - prefix2str(p, buf, sizeof(buf)); + struct vrf *vrf = vrf_lookup_by_id(vrfid); + flog_warn(EC_ZEBRA_RNH_NO_TABLE, - "%u: Add RNH %s type %s - table not found", vrfid, - buf, rnh_type2str(type)); + "%s(%u): Add RNH %pFX type %s - table not found", + VRF_LOGNAME(vrf), vrfid, p, rnh_type2str(type)); exists = false; return NULL; } @@ -270,9 +255,10 @@ static void zebra_delete_rnh(struct rnh *rnh, enum rnh_type type) return; if (IS_ZEBRA_DEBUG_NHT) { - char buf[PREFIX2STR_BUFFER]; - zlog_debug("%u: Del RNH %s type %s", rnh->vrf_id, - rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type)); + struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id); + + zlog_debug("%s(%u): Del RNH %pRN type %s", VRF_LOGNAME(vrf), + rnh->vrf_id, rnh->node, rnh_type2str(type)); } zebra_free_rnh(rnh); @@ -292,10 +278,12 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, enum rnh_type type, vrf_id_t vrf_id) { if (IS_ZEBRA_DEBUG_NHT) { - char buf[PREFIX2STR_BUFFER]; - zlog_debug("%u: Client %s registers for RNH %s type %s", vrf_id, - zebra_route_string(client->proto), - rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type)); + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + + zlog_debug("%s(%u): Client %s registers for RNH %pRN type %s", + VRF_LOGNAME(vrf), vrf_id, + zebra_route_string(client->proto), rnh->node, + rnh_type2str(type)); } if (!listnode_lookup(rnh->client_list, client)) listnode_add(rnh->client_list, client); @@ -311,10 +299,11 @@ void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, enum rnh_type type) { if (IS_ZEBRA_DEBUG_NHT) { - char buf[PREFIX2STR_BUFFER]; - zlog_debug("Client %s unregisters for RNH %s type %s", - zebra_route_string(client->proto), - rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type)); + struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id); + + zlog_debug("Client %s unregisters for RNH %s(%u)%pRN type %s", + zebra_route_string(client->proto), VRF_LOGNAME(vrf), + vrf->vrf_id, rnh->node, rnh_type2str(type)); } listnode_delete(rnh->client_list, client); zebra_delete_rnh(rnh, type); @@ -456,13 +445,9 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi, return NULL; if (IS_ZEBRA_DEBUG_NHT_DETAILED) { - char buf[PREFIX_STRLEN]; - char buf1[SRCDEST2STR_BUFFER]; - - zlog_debug("%s: %u:%s Resolved Import Entry to %s", __func__, - rnh->vrf_id, - prefix2str(&rnh->node->p, buf, sizeof(buf)), - srcdest_rnode2str(rn, buf1, sizeof(buf1))); + zlog_debug("%s: %s(%u):%pRN Resolved Import Entry to %pRN", + __func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id, + rnh->node, rn); } /* Identify appropriate route entry. */ @@ -495,7 +480,6 @@ static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi, { int state_changed = 0; struct zserv *client; - char bufn[INET6_ADDRSTRLEN]; struct listnode *node; zebra_rnh_remove_from_routing_table(rnh); @@ -521,13 +505,11 @@ static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi, } if (state_changed || force) { - if (IS_ZEBRA_DEBUG_NHT) { - prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); - zlog_debug("%u:%s: Route import check %s %s", - zvrf->vrf->vrf_id, - bufn, rnh->state ? "passed" : "failed", + if (IS_ZEBRA_DEBUG_NHT) + zlog_debug("%s(%u):%pRN: Route import check %s %s", + VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, + nrn, rnh->state ? "passed" : "failed", state_changed ? "(state changed)" : ""); - } /* state changed, notify clients */ for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) { zebra_send_rnh_update(rnh, client, @@ -548,19 +530,17 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi, { struct listnode *node; struct zserv *client; - char bufn[INET6_ADDRSTRLEN]; - char bufp[INET6_ADDRSTRLEN]; int num_resolving_nh; if (IS_ZEBRA_DEBUG_NHT) { - prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); if (prn && re) { - srcdest_rnode2str(prn, bufp, INET6_ADDRSTRLEN); - zlog_debug("%u:%s: NH resolved over route %s", - zvrf->vrf->vrf_id, bufn, bufp); + zlog_debug("%s(%u):%pRN: NH resolved over route %pRN", + VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, + nrn, prn); } else - zlog_debug("%u:%s: NH has become unresolved", - zvrf->vrf->vrf_id, bufn); + zlog_debug("%s(%u):%pRN: NH has become unresolved", + VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, + nrn); } for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) { @@ -579,8 +559,9 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi, if (IS_ZEBRA_DEBUG_NHT) zlog_debug( - "%u:%s: Notifying client %s about NH %s", - zvrf->vrf->vrf_id, bufn, + "%s(%u):%pRN: Notifying client %s about NH %s", + VRF_LOGNAME(zvrf->vrf), + zvrf->vrf->vrf_id, nrn, zebra_route_string(client->proto), num_resolving_nh ? "" @@ -589,8 +570,9 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi, rnh->filtered[client->proto] = 0; if (IS_ZEBRA_DEBUG_NHT) zlog_debug( - "%u:%s: Notifying client %s about NH (unreachable)", - zvrf->vrf->vrf_id, bufn, + "%s(%u):%pRN: Notifying client %s about NH (unreachable)", + VRF_LOGNAME(zvrf->vrf), + zvrf->vrf->vrf_id, nrn, zebra_route_string(client->proto)); } @@ -648,15 +630,10 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi, * most-specific match. Do similar logic as in zebra_rib.c */ while (rn) { - if (IS_ZEBRA_DEBUG_NHT_DETAILED) { - char buf[PREFIX_STRLEN]; - char buf1[PREFIX_STRLEN]; - - zlog_debug("%s: %u:%s Possible Match to %s", __func__, - rnh->vrf_id, - prefix2str(&rnh->node->p, buf, sizeof(buf)), - srcdest_rnode2str(rn, buf1, sizeof(buf))); - } + if (IS_ZEBRA_DEBUG_NHT_DETAILED) + zlog_debug("%s: %s(%u):%pRN Possible Match to %pRN", + __func__, VRF_LOGNAME(zvrf->vrf), + rnh->vrf_id, rnh->node, rn); /* Do not resolve over default route unless allowed && * match route to be exact if so specified @@ -819,12 +796,11 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi, struct rnh *rnh; struct route_entry *re; struct route_node *prn; - char bufn[INET6_ADDRSTRLEN]; if (IS_ZEBRA_DEBUG_NHT) { - prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); - zlog_debug("%u:%s: Evaluate RNH, type %s %s", zvrf->vrf->vrf_id, - bufn, rnh_type2str(type), force ? "(force)" : ""); + zlog_debug("%s(%u):%pRN: Evaluate RNH, type %s %s", + VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, nrn, + rnh_type2str(type), force ? "(force)" : ""); } rnh = nrn->info; @@ -1221,7 +1197,7 @@ static void print_nh(struct nexthop *nexthop, struct vty *vty) switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); + vty_out(vty, " via %pI4", &nexthop->gate.ipv4); if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname_per_ns(zns, nexthop->ifindex)); @@ -1289,10 +1265,15 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, struct route_node *nrn; struct rnh *rnh; - if (IS_ZEBRA_DEBUG_NHT) - zlog_debug("%u: Client %s RNH cleanup for family %s type %s", - vrf_id, zebra_route_string(client->proto), - afi2str(afi), rnh_type2str(type)); + if (IS_ZEBRA_DEBUG_NHT) { + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + + zlog_debug( + "%s(%u): Client %s RNH cleanup for family %s type %s", + VRF_LOGNAME(vrf), vrf_id, + zebra_route_string(client->proto), afi2str(afi), + rnh_type2str(type)); + } ntable = get_rnh_table(vrf_id, afi, type); if (!ntable) { diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index ba12b1738f..c71a2b9cce 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -61,7 +61,6 @@ extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force, enum rnh_type type, struct prefix *p); extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty, enum rnh_type type, struct prefix *p); -extern char *rnh_str(struct rnh *rnh, char *buf, int size); extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 8155f9acfe..294f2c17ff 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1695,7 +1695,7 @@ static void zebra_route_map_set_delay_timer(uint32_t value) if (!value && zebra_t_rmap_update) { /* Event driven route map updates is being disabled */ /* But there's a pending timer. Fire it off now */ - thread_cancel(zebra_t_rmap_update); + thread_cancel(&zebra_t_rmap_update); zebra_route_map_update_timer(zebra_t_rmap_update); } } @@ -1705,7 +1705,7 @@ void zebra_routemap_finish(void) /* Set zebra_rmap_update_timer to 0 so that it wont schedule again */ zebra_rmap_update_timer = 0; /* Thread off if any scheduled already */ - THREAD_TIMER_OFF(zebra_t_rmap_update); + thread_cancel(&zebra_t_rmap_update); route_map_finish(); } diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 67f94bfcfe..8651a01e9f 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -61,6 +61,29 @@ enum multicast_mode { /* on equal value, MRIB wins for last 2 */ }; +/* An interface can be error-disabled if a protocol (such as EVPN or + * VRRP) detects a problem with keeping it operationally-up. + * If any of the protodown bits are set protodown-on is programmed + * in the dataplane. This results in a carrier/L1 down on the + * physical device. + */ +enum protodown_reasons { + /* On startup local ESs are held down for some time to + * allow the underlay to converge and EVPN routes to + * get learnt + */ + ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY = (1 << 0), + /* If all the uplinks are down the switch has lost access + * to the VxLAN overlay and must shut down the access + * ports to allow servers to re-direct their traffic to + * other switches on the Ethernet Segment + */ + ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN = (1 << 1), + ZEBRA_PROTODOWN_EVPN_ALL = (ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN + | ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY) +}; +#define ZEBRA_PROTODOWN_RC_STR_LEN 80 + struct zebra_mlag_info { /* Role this zebra router is playing */ enum mlag_role role; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index d102b02a21..b7cbf5262a 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -315,6 +315,9 @@ static int zebra_vrf_delete(struct vrf *vrf) list_delete_all_node(zvrf->rid_all_sorted_list); list_delete_all_node(zvrf->rid_lo_sorted_list); + list_delete_all_node(zvrf->rid6_all_sorted_list); + list_delete_all_node(zvrf->rid6_lo_sorted_list); + otable_fini(&zvrf->other_tables); XFREE(MTYPE_ZEBRA_VRF, zvrf); vrf->info = NULL; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 6785151705..ab7d2845e7 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -304,8 +304,8 @@ static void show_nexthop_detail_helper(struct vty *vty, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, " %s", - inet_ntoa(nexthop->gate.ipv4)); + vty_out(vty, " %pI4", + &nexthop->gate.ipv4); if (nexthop->ifindex) vty_out(vty, ", via %s", ifindex2ifname( @@ -508,7 +508,7 @@ static void show_route_nexthop_helper(struct vty *vty, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); + vty_out(vty, " via %pI4", &nexthop->gate.ipv4); if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, @@ -636,7 +636,8 @@ static void show_nexthop_json_helper(json_object *json_nexthop, case NEXTHOP_TYPE_IPV4_IFINDEX: json_object_string_add( json_nexthop, "ip", - inet_ntoa(nexthop->gate.ipv4)); + inet_ntop(AF_INET, &nexthop->gate.ipv4, + buf, sizeof(buf))); json_object_string_add(json_nexthop, "afi", "ipv4"); @@ -1404,6 +1405,7 @@ struct nhe_show_context { struct vty *vty; vrf_id_t vrf_id; afi_t afi; + int type; }; static int nhe_show_walker(struct hash_bucket *bucket, void *arg) @@ -1419,6 +1421,9 @@ static int nhe_show_walker(struct hash_bucket *bucket, void *arg) if (ctx->vrf_id && nhe->vrf_id != ctx->vrf_id) goto done; + if (ctx->type && nhe->type != ctx->type) + goto done; + show_nexthop_group_out(ctx->vty, nhe); done: @@ -1426,14 +1431,15 @@ done: } static void show_nexthop_group_cmd_helper(struct vty *vty, - struct zebra_vrf *zvrf, - afi_t afi) + struct zebra_vrf *zvrf, afi_t afi, + int type) { struct nhe_show_context ctx; ctx.vty = vty; ctx.afi = afi; ctx.vrf_id = zvrf->vrf->vrf_id; + ctx.type = type; hash_walk(zrouter.nhgs_id, nhe_show_walker, &ctx); } @@ -1492,7 +1498,7 @@ DEFPY (show_interface_nexthop_group, DEFPY (show_nexthop_group, show_nexthop_group_cmd, - "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>", + "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [<kernel|zebra|bgp|sharp>$type_str] [vrf <NAME$vrf_name|all$vrf_all>]>", SHOW_STR "Show Nexthop Groups\n" "RIB information\n" @@ -1500,11 +1506,16 @@ DEFPY (show_nexthop_group, "Show Singleton Nexthop-Groups\n" IP_STR IP6_STR + "Kernel (not installed via the zebra RIB)\n" + "Zebra (implicitly created by zebra)\n" + "Border Gateway Protocol (BGP)\n" + "Super Happy Advanced Routing Protocol (SHARP)\n" VRF_FULL_CMD_HELP_STR) { struct zebra_vrf *zvrf = NULL; afi_t afi = AFI_UNSPEC; + int type = 0; if (id) return show_nexthop_group_id_cmd_helper(vty, id); @@ -1514,6 +1525,14 @@ DEFPY (show_nexthop_group, else if (v6) afi = AFI_IP6; + if (type_str) { + type = proto_redistnum((afi ? afi : AFI_IP), type_str); + if (type < 0) { + /* assume zebra */ + type = ZEBRA_ROUTE_NHG; + } + } + if (!vrf_is_backend_netns() && (vrf_name || vrf_all)) { vty_out(vty, "VRF subcommand does not make any sense in l3mdev based vrf's\n"); @@ -1531,7 +1550,7 @@ DEFPY (show_nexthop_group, continue; vty_out(vty, "VRF: %s\n", vrf->name); - show_nexthop_group_cmd_helper(vty, zvrf, afi); + show_nexthop_group_cmd_helper(vty, zvrf, afi, type); } return CMD_SUCCESS; @@ -1548,7 +1567,7 @@ DEFPY (show_nexthop_group, return CMD_WARNING; } - show_nexthop_group_cmd_helper(vty, zvrf, afi); + show_nexthop_group_cmd_helper(vty, zvrf, afi, type); return CMD_SUCCESS; } @@ -1747,9 +1766,11 @@ DEFPY (show_route, if (vrf_name) VRF_GET_ID(vrf_id, vrf_name, !!json); vrf = vrf_lookup_by_id(vrf_id); - if (vrf) - zvrf = vrf->info; - if (!vrf || !zvrf) + if (!vrf) + return CMD_SUCCESS; + + zvrf = vrf->info; + if (!zvrf) return CMD_SUCCESS; if (table_all) @@ -1768,6 +1789,15 @@ DEFPY (show_route, return CMD_SUCCESS; } +ALIAS_HIDDEN (show_route, + show_ro_cmd, + "show <ip$ipv4|ipv6$ipv6> ro", + SHOW_STR + IP_STR + IPV6_STR + "IP routing table\n"); + + DEFPY (show_route_detail, show_route_detail_cmd, "show\ @@ -2405,6 +2435,20 @@ DEFPY (evpn_mh_neigh_holdtime, no ? true : false); } +DEFPY (evpn_mh_startup_delay, + evpn_mh_startup_delay_cmd, + "[no] evpn mh startup-delay(0-3600)$duration", + NO_STR + "EVPN\n" + "Multihoming\n" + "Startup delay\n" + "duration in seconds\n") +{ + + return zebra_evpn_mh_startup_delay_update(vty, duration, + no ? true : false); +} + DEFUN (default_vrf_vni_mapping, default_vrf_vni_mapping_cmd, "vni " CMD_VNI_RANGE "[prefix-routes-only]", @@ -2586,7 +2630,7 @@ DEFUN (show_evpn_global, DEFPY(show_evpn_es, show_evpn_es_cmd, - "show evpn es [NAME$esi_str] [json$json] [detail$detail]", + "show evpn es [NAME$esi_str|detail$detail] [json$json]", SHOW_STR "EVPN\n" "Ethernet Segment\n" @@ -2615,14 +2659,14 @@ DEFPY(show_evpn_es, DEFPY(show_evpn_es_evi, show_evpn_es_evi_cmd, - "show evpn es-evi [vni (1-16777215)$vni] [json$json] [detail$detail]", + "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]", SHOW_STR "EVPN\n" "Ethernet Segment per EVI\n" "VxLAN Network Identifier\n" "VNI\n" - JSON_STR - "Detailed information\n") + "Detailed information\n" + JSON_STR) { bool uj = !!json; bool ud = !!detail; @@ -2637,13 +2681,13 @@ DEFPY(show_evpn_es_evi, DEFPY(show_evpn_access_vlan, show_evpn_access_vlan_cmd, - "show evpn access-vlan [(1-4094)$vid] [json$json] [detail$detail]", + "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]", SHOW_STR "EVPN\n" "Access VLANs\n" "VLAN ID\n" - JSON_STR - "Detailed information\n") + "Detailed information\n" + JSON_STR) { bool uj = !!json; @@ -3264,7 +3308,8 @@ DEFPY (clear_evpn_dup_addr, if (yang_dup) { listnode_add(input, yang_dup); - ret = nb_cli_rpc("/frr-zebra:clear-evpn-dup-addr", input, NULL); + ret = nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", input, + NULL); } list_delete(&input); @@ -3904,6 +3949,7 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_vrf_cmd); install_element(VIEW_NODE, &show_vrf_vni_cmd); install_element(VIEW_NODE, &show_route_cmd); + install_element(VIEW_NODE, &show_ro_cmd); install_element(VIEW_NODE, &show_route_detail_cmd); install_element(VIEW_NODE, &show_route_summary_cmd); install_element(VIEW_NODE, &show_ip_nht_cmd); @@ -3960,6 +4006,7 @@ void zebra_vty_init(void) install_element(CONFIG_NODE, &evpn_mh_mac_holdtime_cmd); install_element(CONFIG_NODE, &evpn_mh_neigh_holdtime_cmd); + install_element(CONFIG_NODE, &evpn_mh_startup_delay_cmd); install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd); install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd); install_element(VRF_NODE, &vrf_vni_mapping_cmd); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index d8ed58edef..4b3b142d40 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -36,6 +36,7 @@ #ifdef GNU_LINUX #include <linux/neighbour.h> #endif +#include "lib/printfrr.h" #include "zebra/zebra_router.h" #include "zebra/debug.h" @@ -309,8 +310,7 @@ static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty, rb_host_count(&n->host_rb)); vty_out(vty, " Prefixes:\n"); RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb) - vty_out(vty, " %s\n", - prefix2str(&hle->p, buf2, sizeof(buf2))); + vty_out(vty, " %pFX\n", &hle->p); } else { json_hosts = json_object_new_array(); json_object_string_add( @@ -340,20 +340,21 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty, if (!json) { vty_out(vty, "MAC: %s\n", prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1))); - vty_out(vty, " Remote VTEP: %s\n", - inet_ntoa(zrmac->fwd_info.r_vtep_ip)); + vty_out(vty, " Remote VTEP: %pI4\n", + &zrmac->fwd_info.r_vtep_ip); vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb)); vty_out(vty, " Prefixes:\n"); RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb) - vty_out(vty, " %s\n", - prefix2str(&hle->p, buf2, sizeof(buf2))); + vty_out(vty, " %pFX\n", &hle->p); } else { json_hosts = json_object_new_array(); json_object_string_add( json, "routerMac", prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1))); json_object_string_add(json, "vtepIp", - inet_ntoa(zrmac->fwd_info.r_vtep_ip)); + inet_ntop(AF_INET, + &zrmac->fwd_info.r_vtep_ip, + buf1, sizeof(buf1))); json_object_int_add(json, "refCount", rb_host_count(&zrmac->host_rb)); json_object_int_add(json, "localSequence", zrmac->loc_seq); @@ -630,7 +631,7 @@ static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx) struct vty *vty = NULL; struct json_object *json = NULL; struct json_object *json_rmac = NULL; - char buf[ETHER_ADDR_STRLEN]; + char buf[PREFIX_STRLEN]; wctx = (struct rmac_walk_ctx *)ctx; vty = wctx->vty; @@ -640,15 +641,17 @@ static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx) zrmac = (zebra_mac_t *)bucket->data; if (!json) { - vty_out(vty, "%-17s %-21s\n", + vty_out(vty, "%-17s %-21pI4\n", prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)), - inet_ntoa(zrmac->fwd_info.r_vtep_ip)); + &zrmac->fwd_info.r_vtep_ip); } else { json_object_string_add( json_rmac, "routerMac", prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf))); json_object_string_add(json_rmac, "vtepIp", - inet_ntoa(zrmac->fwd_info.r_vtep_ip)); + inet_ntop(AF_INET, + &zrmac->fwd_info.r_vtep_ip, + buf, sizeof(buf))); json_object_object_add( json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)), json_rmac); @@ -658,7 +661,7 @@ static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx) /* print a specific L3 VNI entry */ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx) { - char buf[ETHER_ADDR_STRLEN]; + char buf[PREFIX_STRLEN]; struct vty *vty = NULL; json_object *json = NULL; zebra_evpn_t *zevpn = NULL; @@ -672,8 +675,8 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx) vty_out(vty, "VNI: %u\n", zl3vni->vni); vty_out(vty, " Type: %s\n", "L3"); vty_out(vty, " Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni)); - vty_out(vty, " Local Vtep Ip: %s\n", - inet_ntoa(zl3vni->local_vtep_ip)); + vty_out(vty, " Local Vtep Ip: %pI4\n", + &zl3vni->local_vtep_ip); vty_out(vty, " Vxlan-Intf: %s\n", zl3vni_vxlan_if_name(zl3vni)); vty_out(vty, " SVI-If: %s\n", zl3vni_svi_if_name(zl3vni)); @@ -694,8 +697,10 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx) json_evpn_list = json_object_new_array(); json_object_int_add(json, "vni", zl3vni->vni); json_object_string_add(json, "type", "L3"); - json_object_string_add(json, "localVtepIp", - inet_ntoa(zl3vni->local_vtep_ip)); + json_object_string_add( + json, "localVtepIp", + inet_ntop(AF_INET, &zl3vni->local_vtep_ip, buf, + sizeof(buf))); json_object_string_add(json, "vxlanIntf", zl3vni_vxlan_if_name(zl3vni)); json_object_string_add(json, "sviIntf", @@ -944,9 +949,9 @@ static int zevpn_build_hash_table_zns(struct ns *ns, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s", + "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %pI4", ifp->name, ifp->ifindex, vni, - inet_ntoa(vxl->vtep_ip)); + &vxl->vtep_ip); /* EVPN hash entry is expected to exist, if the BGP process is killed */ zevpn = zebra_evpn_lookup(vni); @@ -1269,7 +1274,6 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, { char buf[ETHER_ADDR_STRLEN]; char buf1[INET6_ADDRSTRLEN]; - char buf2[PREFIX_STRLEN]; zebra_mac_t *zrmac = NULL; zrmac = zl3vni_rmac_lookup(zl3vni, rmac); @@ -1279,11 +1283,11 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, zrmac = zl3vni_rmac_add(zl3vni, rmac); if (!zrmac) { zlog_debug( - "Failed to add RMAC %s L3VNI %u Remote VTEP %s, prefix %s", + "Failed to add RMAC %s L3VNI %u Remote VTEP %s, prefix %pFX", prefix_mac2str(rmac, buf, sizeof(buf)), zl3vni->vni, ipaddr2str(vtep_ip, buf1, sizeof(buf1)), - prefix2str(host_prefix, buf2, sizeof(buf2))); + host_prefix); return -1; } memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info)); @@ -1299,12 +1303,12 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, &vtep_ip->ipaddr_v4)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "L3VNI %u Remote VTEP change(%s -> %s) for RMAC %s, prefix %s", + "L3VNI %u Remote VTEP change(%pI4 -> %s) for RMAC %s, prefix %pFX", zl3vni->vni, - inet_ntoa(zrmac->fwd_info.r_vtep_ip), + &zrmac->fwd_info.r_vtep_ip, ipaddr2str(vtep_ip, buf1, sizeof(buf1)), prefix_mac2str(rmac, buf, sizeof(buf)), - prefix2str(host_prefix, buf2, sizeof(buf2))); + host_prefix); zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; @@ -1464,7 +1468,6 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, char buf[ETHER_ADDR_STRLEN]; char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; - char buf3[PREFIX_STRLEN]; zebra_neigh_t *nh = NULL; /* Create the next hop entry, or update its mac, if necessary. */ @@ -1473,11 +1476,10 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac); if (!nh) { zlog_debug( - "Failed to add NH %s as Neigh (RMAC %s L3-VNI %u prefix %s)", + "Failed to add NH %s as Neigh (RMAC %s L3-VNI %u prefix %pFX)", ipaddr2str(vtep_ip, buf1, sizeof(buf2)), prefix_mac2str(rmac, buf, sizeof(buf)), - zl3vni->vni, - prefix2str(host_prefix, buf2, sizeof(buf2))); + zl3vni->vni, host_prefix); return -1; } @@ -1485,12 +1487,13 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, zl3vni_nh_install(zl3vni, nh); } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("L3VNI %u RMAC change(%s --> %s) for nexthop %s, prefix %s", - zl3vni->vni, - prefix_mac2str(&nh->emac, buf, sizeof(buf)), - prefix_mac2str(rmac, buf1, sizeof(buf1)), - ipaddr2str(vtep_ip, buf2, sizeof(buf2)), - prefix2str(host_prefix, buf3, sizeof(buf3))); + zlog_debug( + "L3VNI %u RMAC change(%s --> %s) for nexthop %s, prefix %pFX", + zl3vni->vni, + prefix_mac2str(&nh->emac, buf, sizeof(buf)), + prefix_mac2str(rmac, buf1, sizeof(buf1)), + ipaddr2str(vtep_ip, buf2, sizeof(buf2)), + host_prefix); memcpy(&nh->emac, rmac, ETH_ALEN); /* install (update) the nh neigh in kernel */ @@ -1912,11 +1915,11 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Send L3_VNI_ADD %u VRF %s RMAC %s VRR %s local-ip %s filter %s to %s", + "Send L3_VNI_ADD %u VRF %s RMAC %s VRR %s local-ip %pI4 filter %s to %s", zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)), prefix_mac2str(&svi_rmac, buf, sizeof(buf)), prefix_mac2str(&vrr_rmac, buf1, sizeof(buf1)), - inet_ntoa(zl3vni->local_vtep_ip), + &zl3vni->local_vtep_ip, CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY) ? "prefix-routes-only" : "none", @@ -2994,7 +2997,8 @@ void zebra_vxlan_print_macs_vni_dad(struct vty *vty, } int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni, - struct ethaddr *macaddr) + struct ethaddr *macaddr, char *errmsg, + size_t errmsg_len) { zebra_evpn_t *zevpn; zebra_mac_t *mac; @@ -3006,18 +3010,20 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni, zevpn = zebra_evpn_lookup(vni); if (!zevpn) { - zlog_warn("VNI %u does not exist\n", vni); + snprintfrr(errmsg, errmsg_len, "VNI %u does not exist", vni); return -1; } mac = zebra_evpn_mac_lookup(zevpn, macaddr); if (!mac) { - zlog_warn("Requested MAC does not exist in VNI %u\n", vni); + snprintf(errmsg, errmsg_len, + "Requested MAC does not exist in VNI %u\n", vni); return -1; } if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { - zlog_warn("Requested MAC is not duplicate detected\n"); + snprintfrr(errmsg, errmsg_len, + "Requested MAC is not duplicate detected\n"); return -1; } @@ -3079,7 +3085,8 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni, } int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni, - struct ipaddr *ip) + struct ipaddr *ip, char *errmsg, + size_t errmsg_len) { zebra_evpn_t *zevpn; zebra_neigh_t *nbr; @@ -3092,28 +3099,31 @@ int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni, zevpn = zebra_evpn_lookup(vni); if (!zevpn) { - zlog_debug("VNI %u does not exist\n", vni); + snprintfrr(errmsg, errmsg_len, "VNI %u does not exist\n", vni); return -1; } nbr = zebra_evpn_neigh_lookup(zevpn, ip); if (!nbr) { - zlog_warn("Requested host IP does not exist in VNI %u\n", vni); + snprintfrr(errmsg, errmsg_len, + "Requested host IP does not exist in VNI %u\n", vni); return -1; } ipaddr2str(&nbr->ip, buf, sizeof(buf)); if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) { - zlog_warn("Requested host IP %s is not duplicate detected\n", - buf); + snprintfrr(errmsg, errmsg_len, + "Requested host IP %s is not duplicate detected\n", + buf); return -1; } mac = zebra_evpn_mac_lookup(zevpn, &nbr->emac); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { - zlog_warn( + snprintfrr( + errmsg, errmsg_len, "Requested IP's associated MAC %s is still in duplicate state\n", prefix_mac2str(&nbr->emac, buf2, sizeof(buf2))); return -1; @@ -3417,7 +3427,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) json_object_int_add(json, "detectionTime", zvrf->dad_time); json_object_int_add(json, "detectionFreezeTime", zvrf->dad_freeze_time); - + zebra_evpn_mh_json(json); } else { vty_out(vty, "L2 VNIs: %u\n", num_l2vnis); vty_out(vty, "L3 VNIs: %u\n", num_l3vnis); @@ -3437,6 +3447,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) vty_out(vty, " Detection freeze %s\n", "permanent"); } + zebra_evpn_mh_print(vty); } if (uj) { @@ -3758,14 +3769,13 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS) l += res_length; if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s", + "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %pI4 from %s", vni, prefix_mac2str(&macaddr, buf, sizeof(buf)), ipa_len ? " IP " : "", ipa_len ? ipaddr2str(&ip, buf1, sizeof(buf1)) : "", - inet_ntoa(vtep_ip), - zebra_route_string(client->proto)); + &vtep_ip, zebra_route_string(client->proto)); process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip); } @@ -3820,7 +3830,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) else strlcpy(esi_buf, "-", ESI_STR_LEN); zlog_debug( - "Recv %sMACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s ESI %s from %s", + "Recv %sMACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %pI4 ESI %s from %s", (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) ? "sync-" : "", vni, @@ -3828,7 +3838,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS) ipa_len ? " IP " : "", ipa_len ? ipaddr2str(&ip, buf1, sizeof(buf1)) : "", - flags, seq, inet_ntoa(vtep_ip), esi_buf, + flags, seq, &vtep_ip, esi_buf, zebra_route_string(client->proto)); } @@ -3879,8 +3889,8 @@ int zebra_vxlan_check_readd_vtep(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Del MAC for remote VTEP %s intf %s(%u) VNI %u - readd", - inet_ntoa(vtep_ip), ifp->name, ifp->ifindex, vni); + "Del MAC for remote VTEP %pI4 intf %s(%u) VNI %u - readd", + &vtep_ip, ifp->name, ifp->ifindex, vni); zebra_evpn_vtep_install(zevpn, zvtep); return 0; @@ -4120,8 +4130,8 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS) l += 4; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Recv VTEP_DEL %s VNI %u from %s", - inet_ntoa(vtep_ip), vni, + zlog_debug("Recv VTEP_DEL %pI4 VNI %u from %s", + &vtep_ip, vni, zebra_route_string(client->proto)); /* Locate VNI hash entry - expected to exist. */ @@ -4204,8 +4214,8 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS) l += IPV4_MAX_BYTELEN + 4; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("Recv VTEP_ADD %s VNI %u flood %d from %s", - inet_ntoa(vtep_ip), vni, flood_control, + zlog_debug("Recv VTEP_ADD %pI4 VNI %u flood %d from %s", + &vtep_ip, vni, flood_control, zebra_route_string(client->proto)); /* Locate VNI hash entry - expected to exist. */ @@ -4787,9 +4797,9 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x", + "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x", vni, ifp->name, ifp->ifindex, vxl->access_vlan, - inet_ntoa(vxl->vtep_ip), + &vxl->vtep_ip, zif->brslave_info.bridge_ifindex, chgflags); /* Removed from bridge? Cleanup and return */ @@ -4851,9 +4861,9 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x", + "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x", vni, ifp->name, ifp->ifindex, vxl->access_vlan, - inet_ntoa(vxl->vtep_ip), + &vxl->vtep_ip, zif->brslave_info.bridge_ifindex, chgflags); /* Removed from bridge? Cleanup and return */ @@ -4958,9 +4968,9 @@ int zebra_vxlan_if_add(struct interface *ifp) /* process if-add for l3-vni*/ if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u", + "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u", vni, ifp->name, ifp->ifindex, vxl->access_vlan, - inet_ntoa(vxl->vtep_ip), + &vxl->vtep_ip, zif->brslave_info.bridge_ifindex); /* associate with vxlan_if */ diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 9c8af9d1fc..534e29936d 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -208,9 +208,12 @@ extern void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id, struct prefix *host_prefix); extern int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni, - struct ethaddr *macaddr); + struct ethaddr *macaddr, + char *errmsg, + size_t errmsg_len); extern int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, - vni_t vni, struct ipaddr *ip); + vni_t vni, struct ipaddr *ip, + char *errmsg, size_t errmsg_len); extern int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf); extern int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni); extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx); diff --git a/zebra/zserv.c b/zebra/zserv.c index 44f4641fcf..4b5791530d 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1172,11 +1172,9 @@ static void zebra_show_stale_client_detail(struct vty *vty, } } vty_out(vty, "Current AFI : %d\n", info->current_afi); - if (info->current_prefix) { - prefix2str(info->current_prefix, buf, - sizeof(buf)); - vty_out(vty, "Current prefix : %s\n", buf); - } + if (info->current_prefix) + vty_out(vty, "Current prefix : %pFX\n", + info->current_prefix); } } vty_out(vty, "\n"); |
