ospf6d : Transformation changes for ospf6 vrf support.
---
+<!--
+
+*** 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.
+-->
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
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;
}
}
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;
}
}
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;
}
}
{
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;
}
/* 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) {
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);
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);
}
{
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);
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);
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;
}
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);
&& !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
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)
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;
/* 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 */
#include "log.h"
#include "memory.h"
#include "stream.h"
+#include "vxlan.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
return 0;
}
+/*
+ * 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.
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);
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 */
return 0;
}
+#if HAVE_BFDD > 0
/**
* Set peer BFD profile configuration.
*/
return 0;
}
+#endif
/*
* bgp_bfd_peer_config_write - Write the peer BFD configuration.
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);
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);
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);
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");
}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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 */
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);
#include <zebra.h>
#include <lib/version.h>
+#include "lib/printfrr.h"
#include "prefix.h"
#include "linklist.h"
#include "stream.h"
{
struct bgp_debug_filter *filter;
struct listnode *node, *nnode;
- char buf[PREFIX2STR_BUFFER];
vty_out(vty, "%s", 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);
}
}
{
struct bgp_debug_filter *filter;
struct listnode *node, *nnode;
- char buf[PREFIX2STR_BUFFER];
int write = 0;
if (list && !list_isempty(list)) {
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++;
}
}
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",
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),
", 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;
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)))
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
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));
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();
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;
}
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);
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
"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;
bool found_prefix = false;
int ret = CMD_SUCCESS;
- char buf[PREFIX2STR_BUFFER];
argv_p = prefix_new();
}
}
- 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);
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
}
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;
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;
}
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;
#include "jhash.h"
#include "stream.h"
+#include "lib/printfrr.h"
+
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_lcommunity.h"
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 */
(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) {
#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
#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"
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);
}
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 *)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
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));
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 {
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) {
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. */
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. */
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;
}
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. */
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);
*/
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;
struct bgp_table *table;
struct bgp_path_info *pi;
int ret;
- char buf[PREFIX_STRLEN];
struct bgp *bgp_evpn = NULL;
afi = AFI_L2VPN;
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;
struct bgp_path_info *pi,
struct list *vrfs, int install)
{
- char buf[PREFIX2STR_BUFFER];
struct bgp *bgp_vrf;
struct listnode *node, *nnode;
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;
}
{
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 */
{
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
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);
}
#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"
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);
&& !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(dest);
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)
*/
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;
}
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. */
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)
/*****************************************************************************
* 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,
{
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;
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);
}
/* Create or update route entry. */
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 %s",
- bgp->vrf_id, es->esi_str,
- inet_ntoa(es->originator_ip));
- }
+ 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;
int ret;
afi_t afi;
safi_t safi;
- char buf[PREFIX_STRLEN];
struct bgp_dest *rd_dest, *dest;
struct bgp_table *table;
struct bgp_path_info *pi;
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;
}
}
/* Create or update route entry. */
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 %s",
- bgp->vrf_id, es->esi_str, vpn->vni,
- inet_ntoa(es->originator_ip));
- }
+ 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 */
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;
}
{
struct bgp_evpn_es *es = es_vtep->es;
struct stream *s;
+ uint32_t flags = 0;
/* Check socket. */
if (!zclient || zclient->sock < 0)
return 0;
}
+ if (es_vtep->flags & BGP_EVPNES_VTEP_ESR)
+ flags |= ZAPI_ES_VTEP_FLAG_ESR_RXED;
+
s = zclient->obuf;
stream_reset(s);
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;
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);
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;
}
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);
}
* 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);
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);
}
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 */
} 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__);
}
}
}
}
/* 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)
* 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);
}
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 */
* 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);
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)
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);
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();
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)
{
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);
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)
} 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';
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
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);
}
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");
}
}
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) {
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);
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);
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) {
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;
}
}
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)
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)) {
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);
{
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();
{
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);
*/
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)
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;
};
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,
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);
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)
{
#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"
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);
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);
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
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");
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;
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,
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",
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();
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
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",
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;
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));
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)));
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;
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
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;
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",
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_RT_HELP_STR
"Display Detailed Information\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
- EVPN_TYPE_4_HELP_STR
- EVPN_TYPE_4_HELP_STR
- EVPN_TYPE_5_HELP_STR
- EVPN_TYPE_5_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;
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;
*/
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_RT_DIST_HELP_STR
EVPN_ASN_IP_HELP_STR
EVPN_TYPE_HELP_STR
- EVPN_TYPE_1_HELP_STR
- EVPN_TYPE_2_HELP_STR
- EVPN_TYPE_3_HELP_STR
- EVPN_TYPE_4_HELP_STR
- EVPN_TYPE_5_HELP_STR
+ EVPN_TYPE_ALL_LIST_HELP_STR
JSON_STR)
{
struct bgp *bgp;
struct prefix_rd prd;
int type = 0;
int rd_idx = 0;
- int type_idx = 0;
bool uj = false;
json_object *json = NULL;
}
}
- /* 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);
* 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
"VNI number\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"
struct in_addr vtep_ip;
int type = 0;
int idx = 0;
+ int vtep_idx = 0;
bool uj = false;
json_object *json = NULL;
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);
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;
"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_RT_HELP_STR
"Display Detailed Information\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_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(
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_RT_HELP_STR
"VXLAN Network Identifier\n"
"VNI number\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")
{
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;
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)));
} 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",
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;
} 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;
}
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;
}
#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 */
#include "zebra.h"
+#include "lib/printfrr.h"
+
#include "prefix.h"
#include "lib_errors.h"
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;
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;
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);
}
/**
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);
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;
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;
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;
#define BGP_TIMER_OFF(T) \
do { \
- THREAD_TIMER_OFF(T); \
+ THREAD_OFF(T); \
} while (0)
#define BGP_EVENT_ADD(P, E) \
#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"
#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 */
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);
}
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);
* 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
*/
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;
}
}
#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"
if (bgp_default)
bgp_delete(bgp_default);
+ bgp_evpn_mh_finish();
+
/* reverse bgp_dump_init */
bgp_dump_finish();
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;
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 */
.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/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/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,
}
},
{
.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,
}
},
{
.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 = {
.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/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,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy,
}
},
{
.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,
}
},
{
.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,
}
},
{
.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,
}
},
{
.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,
}
},
{
.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/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/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,
}
},
{
.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,
}
},
{
.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/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,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy,
}
},
{
.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,
}
},
{
.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/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,
}
},
{
.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,
}
},
{
.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/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,
}
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy,
+ }
+ },
+ {
+ .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/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/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,
}
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy,
}
},
{
.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,
- .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_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,
}
},
{
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_external_modify(
struct nb_cb_modify_args *args);
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy(
- struct nb_cb_destroy_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_internal_destroy(
- struct nb_cb_destroy_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_admin_distance_local_destroy(
- struct nb_cb_destroy_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_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_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_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_external_destroy(
- struct nb_cb_destroy_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_internal_destroy(
- struct nb_cb_destroy_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_admin_distance_local_destroy(
- struct nb_cb_destroy_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_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_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_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_external_modify(
+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_external_destroy(
+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_internal_destroy(
- struct nb_cb_destroy_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_admin_distance_local_destroy(
- struct nb_cb_destroy_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_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_external_modify(
+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_external_destroy(
+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_admin_distance_internal_modify(
+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_admin_distance_internal_destroy(
+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_admin_distance_local_modify(
+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_admin_distance_local_destroy(
+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(
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 */
"/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
#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", },
bgp->as);
return NB_ERR_INCONSISTENCY;
}
-
break;
}
/* Cancel max-med onstartup if its on */
if (bgp->t_maxmed_onstartup) {
- THREAD_TIMER_OFF(bgp->t_maxmed_onstartup);
+ THREAD_OFF(bgp->t_maxmed_onstartup);
bgp->maxmed_onstartup_over = 1;
}
*/
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:
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:
- /* TODO: implement me. */
+ return bgp_global_afi_safis_afi_safi_network_config_destroy(
+ args);
+
break;
}
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
- /* TODO: implement me. */
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/backdoor
+ * /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_backdoor_modify(
+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:
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/network-config/label-index
+ * /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_network_config_label_index_modify(
- struct nb_cb_modify_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/network-config/rmap-policy-export
+ * /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_network_config_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route
+ * /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_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set
+ * /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_as_set_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only
+ * /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_summary_only_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
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
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ return NB_OK;
case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
+ return bgp_global_afi_safi_admin_distance_route_destroy(args);
}
return NB_OK;
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
{
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:
- /* TODO: implement me. */
break;
}
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:
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:
- /* TODO: implement me. */
- break;
+ 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/maximum-paths
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp
*/
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
- struct nb_cb_modify_args *args)
+void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish(
+ struct nb_cb_apply_finish_args *args)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
+ 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:
- /* 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_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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/metric
+ * /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_ipv4_unicast_redistribution_list_metric_modify(
- struct nb_cb_modify_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/redistribution-list/rmap-policy-import
+ * /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_ipv4_unicast_redistribution_list_rmap_policy_import_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external
+ * /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_ipv4_unicast_admin_distance_external_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal
+ * /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_ipv4_unicast_admin_distance_internal_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local
+ * /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_ipv4_unicast_admin_distance_local_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export
+ * /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_ipv4_unicast_filter_config_rmap_export_modify(
- struct nb_cb_modify_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/vpn-config/rd
+ * /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_ipv4_unicast_vpn_config_rd_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
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)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
- /* TODO: implement me. */
break;
}
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label-auto
+ * /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_ipv4_unicast_vpn_config_label_auto_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/nexthop
+ * /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_ipv4_unicast_vpn_config_nexthop_modify(
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn
+ * /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_ipv4_unicast_vpn_config_import_vpn_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
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)
+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:
/*
* 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
+ * /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_ipv4_unicast_vpn_config_import_vrf_list_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-import
+ * /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_ipv4_unicast_vpn_config_rmap_import_modify(
+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:
- /* TODO: implement me. */
- break;
+ return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+ args);
}
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-export
+ * /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_ipv4_unicast_vpn_config_rmap_export_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/redirect-rt
+ * /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_ipv4_unicast_vpn_config_redirect_rt_modify(
- struct nb_cb_modify_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy(
+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:
- /* TODO: implement me. */
+ 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;
}
/*
* 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
+ * /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_ipv4_unicast_vpn_config_import_rt_list_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_ipv4_unicast_vpn_config_export_rt_list_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rt-list
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance
*/
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create(
- struct nb_cb_create_args *args)
+void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish(
+ struct nb_cb_apply_finish_args *args)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ 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;
}
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ /* 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/network-config
+ * /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_network_config_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor
+ * /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_network_config_backdoor_modify(
+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:
- /* TODO: implement me. */
- break;
+ 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/network-config/label-index
+ * /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_network_config_label_index_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_network_config_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route
+ * /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_aggregate_route_create(
- struct nb_cb_create_args *args)
+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:
- /* TODO: implement me. */
- break;
+ return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify(
+ args);
}
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/aggregate-route/as-set
+ * /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_aggregate_route_as_set_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only
+ * /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_aggregate_route_summary_only_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_aggregate_route_rmap_policy_export_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)
{
+ 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:
- /* TODO: implement me. */
- break;
+ 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_aggregate_route_rmap_policy_export_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/admin-distance-route
+ * /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_admin_distance_route_create(
- struct nb_cb_create_args *args)
+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:
- /* TODO: implement me. */
- break;
+ 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_admin_distance_route_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/admin-distance-route/distance
+ * /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_admin_distance_route_distance_modify(
+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:
- /* TODO: implement me. */
- break;
+ 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/admin-distance-route/access-list-policy-export
+ * /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_admin_distance_route_access_list_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_use_multiple_paths_ebgp_maximum_paths_modify(
- struct nb_cb_modify_args *args)
+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:
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)
+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:
/*
* 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
+ * /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_use_multiple_paths_ibgp_cluster_length_list_modify(
- struct nb_cb_modify_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list
+ * /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_redistribution_list_create(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create(
struct nb_cb_create_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric
+ * /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_ipv6_unicast_redistribution_list_metric_modify(
+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:
- /* TODO: implement me. */
- break;
+ return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+ args);
}
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* 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
+ * /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_ipv6_unicast_redistribution_list_rmap_policy_import_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external
+ * /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_ipv6_unicast_admin_distance_external_modify(
+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:
- /* TODO: implement me. */
- break;
- }
-
- return NB_OK;
-}
-
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy(
- struct nb_cb_destroy_args *args)
-{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
break;
}
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal
+ * /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_ipv6_unicast_admin_distance_internal_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local
+ * /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_ipv6_unicast_admin_distance_local_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export
+ * /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_ipv6_unicast_filter_config_rmap_export_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rd
+ * /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_ipv6_unicast_vpn_config_rd_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label
+ * /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_unicast_vpn_config_label_modify(
+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:
- /* TODO: implement me. */
- break;
+ return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+ args);
}
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label-auto
+ * /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_unicast_vpn_config_label_auto_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/nexthop
+ * /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_unicast_vpn_config_nexthop_modify(
+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:
- /* TODO: implement me. */
- break;
- }
-
- 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:
- case NB_EV_APPLY:
- /* TODO: implement me. */
break;
}
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vpn
+ * /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_unicast_vpn_config_import_vpn_modify(
+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) {
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)
+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:
/*
* 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
+ * /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_unicast_vpn_config_import_vrf_list_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-import
+ * /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_unicast_vpn_config_rmap_import_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-export
+ * /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_unicast_vpn_config_rmap_export_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy(
+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) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/redirect-rt
+ * /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_ipv6_unicast_vpn_config_redirect_rt_modify(
- struct nb_cb_modify_args *args)
+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:
- /* TODO: implement me. */
+ return bgp_global_afi_safis_afi_safi_network_config_destroy(
+ args);
break;
}
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* 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
+ * /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_ipv6_unicast_vpn_config_import_rt_list_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_ipv6_unicast_vpn_config_export_rt_list_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rt-list
+ * /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_ipv6_unicast_vpn_config_rt_list_create(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create(
struct nb_cb_create_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* 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
+ * /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_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config
+ * /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_network_config_create(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create(
struct nb_cb_create_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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/network-config/backdoor
+ * /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_network_config_backdoor_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/label-index
+ * /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_network_config_label_index_modify(
+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) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy(
+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) {
/*
* 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
+ * /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_ipv4_multicast_network_config_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
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)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
- /* TODO: implement me. */
break;
}
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/as-set
+ * /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_ipv4_multicast_aggregate_route_as_set_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
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)
+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:
/*
* 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
+ * /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_ipv4_multicast_aggregate_route_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route
+ * /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_ipv4_multicast_admin_distance_route_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external
+ * /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_ipv4_multicast_admin_distance_external_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance
*/
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
- struct nb_cb_modify_args *args)
+void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish(
+ struct nb_cb_apply_finish_args *args)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
-
- return NB_OK;
+ bgp_global_afi_safis_admin_distance_modify(args);
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy(
- struct nb_cb_destroy_args *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)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ /* 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
+ * /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_local_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
struct nb_cb_modify_args *args)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ /* Handled in admin_distance_apply_finish callback */
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ /* Handled in admin_distance_apply_finish callback */
return NB_OK;
}
{
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:
- /* TODO: implement me. */
break;
}
int bgp_global_afi_safis_afi_safi_ipv6_multicast_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;
- }
+ /* Handled in network_config_apply_finish callback */
return NB_OK;
}
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ return NB_OK;
case NB_EV_APPLY:
- /* TODO: implement me. */
+ return bgp_global_afi_safis_afi_safi_network_config_destroy(
+ args);
+
break;
}
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route
+ * /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_admin_distance_route_create(
- struct nb_cb_create_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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:
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external
+ * /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_admin_distance_external_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal
+ * /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_internal_modify(
- struct nb_cb_modify_args *args)
+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:
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy(
+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:
- /* TODO: implement me. */
- break;
+ 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-multicast/admin-distance/local
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance
*/
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify(
+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)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ /* Handled in admin_distance_apply_finish callback */
return NB_OK;
}
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_destroy(
- struct nb_cb_destroy_args *args)
+/*
+ * 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)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ /* 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;
}
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;
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;
}
#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,
/*
* 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)
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); */
&& 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
/* 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;
|| (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);
peer->update_time = bgp_clock();
+ /* Notify BGP Conditional advertisement scanner process */
+ peer->advmap_table_change = true;
+
return Receive_UPDATE_message;
}
*/
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);
__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);
__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);
__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);
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);
__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);
#include "jhash.h"
#include "pbr.h"
+#include "lib/printfrr.h"
+
#include "bgpd/bgpd.h"
#include "bgpd/bgp_pbr.h"
#include "bgpd/bgp_debug.h"
int i = 0;
char return_string[512];
char *ptr = return_string;
- char buff[64];
int nb_items = 0;
int delta, len = sizeof(return_string);
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);
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;
}
#include "filter.h"
#include "frrstr.h"
+#include "lib/printfrr.h"
+
#include "bgpd/bgpd.h"
#include "bgpd/bgp_rd.h"
#include "bgpd/bgp_attr.h"
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
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);
}
#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"
#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"
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,
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;
*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;
}
}
safi_t safi)
{
struct bgp_filter *filter;
+ enum filter_type ret = FILTER_PERMIT;
filter = &peer->filter[afi][safi];
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;
+ }
+ }
+
+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 FILTER_PERMIT;
+ return ret;
#undef FILTER_EXIST_WARN
}
safi_t safi)
{
struct bgp_filter *filter;
+ enum filter_type ret = FILTER_PERMIT;
filter = &peer->filter[afi][safi];
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;
+ }
+ }
+
+ 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");
}
- return FILTER_PERMIT;
+done:
+ return ret;
#undef FILTER_EXIST_WARN
}
}
-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;
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;
}
/* 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
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};
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
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],
/* 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,
*/
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;
}
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)
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;
{
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)
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
if (!paf->t_announce_route)
return;
- THREAD_TIMER_OFF(paf->t_announce_route);
+ thread_cancel(&paf->t_announce_route);
}
/*
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;
}
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];
*/
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;
}
}
/* 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) {
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. */
/* 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. */
bgp_static_update(bgp, &p, bgp_static, afi, safi);
}
- return CMD_SUCCESS;
+ return 0;
}
void bgp_static_add(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);
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;
}
}
- 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)
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,
* Toggles the route suppression status for this aggregate address
* configuration.
*/
-static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
- struct bgp *bgp,
- const struct prefix *p, afi_t afi,
- safi_t safi, bool suppress)
+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];
- struct bgp_path_info_extra *pie;
const struct prefix *dest_p;
struct bgp_dest *dest, *top;
struct bgp_path_info *pi;
if (pi->sub_type == BGP_ROUTE_AGGREGATE)
continue;
- /*
- * On installation it is possible that pi->extra is
- * set to NULL, otherwise it must exists.
- */
- assert(!suppress && pi->extra != NULL);
-
/* We are toggling suppression back. */
if (suppress) {
- pie = bgp_path_info_extra_get(pi);
/* Suppress route if not suppressed already. */
- pie->suppress++;
- bgp_path_info_set_flag(dest, pi,
- BGP_PATH_ATTR_CHANGED);
- toggle_suppression = true;
+ if (aggr_suppress_path(aggregate, pi))
+ toggle_suppression = true;
continue;
}
- pie = pi->extra;
- assert(pie->suppress > 0);
- pie->suppress--;
/* Install route if there is no more suppression. */
- if (pie->suppress == 0) {
- bgp_path_info_set_flag(dest, pi,
- BGP_PATH_ATTR_CHANGED);
+ if (aggr_unsuppress_path(aggregate, pi))
toggle_suppression = true;
- }
}
if (toggle_suppression)
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
*/
if (aggregate->summary_only
&& AGGREGATE_MED_VALID(aggregate)) {
- (bgp_path_info_extra_get(pi))->suppress++;
- bgp_path_info_set_flag(dest, pi,
- BGP_PATH_ATTR_CHANGED);
- match++;
+ 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++;
if (aggregate->summary_only && pi->extra
&& AGGREGATE_MED_VALID(aggregate)) {
- pi->extra->suppress--;
+ 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)
pinew, true);
if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
- (bgp_path_info_extra_get(pinew))->suppress++;
+ 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:
if (pi->sub_type == BGP_ROUTE_AGGREGATE)
return;
- if (aggregate->summary_only && pi->extra && pi->extra->suppress > 0
- && AGGREGATE_MED_VALID(aggregate)) {
- 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` check to avoid
+ * This must be called after `summary`, `suppress-map` check to avoid
* "unsuppressing" twice.
*/
if (aggregate->match_med)
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);
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, bool match_med)
+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;
}
}
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");
}
}
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;
}
-DEFPY(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"
- "}",
- 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")
-{
- const char *prefix_s = NULL;
+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);
- uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
- int as_set = AGGREGATE_AS_UNSET;
char prefix_buf[PREFIX2STR_BUFFER];
if (addr_str) {
vty_out(vty, "%% Inconsistent address and mask\n");
return CMD_WARNING_CONFIG_FAILED;
}
- prefix_s = prefix_buf;
- } else
- prefix_s = prefix_str;
-
- if (origin_s) {
- if (strcmp(origin_s, "egp") == 0)
- origin = BGP_ORIGIN_EGP;
- else if (strcmp(origin_s, "igp") == 0)
- origin = BGP_ORIGIN_IGP;
- else if (strcmp(origin_s, "incomplete") == 0)
- origin = BGP_ORIGIN_INCOMPLETE;
+ } else {
+ strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
}
- if (as_set_s)
- as_set = AGGREGATE_AS_SET;
+ 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);
+ else
+ nb_cli_enqueue_change(vty, "./rmap-policy-export",
+ NB_OP_DESTROY, NULL);
+
+ 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);
+
+ 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);
- /* Handle configuration removal, otherwise installation. */
if (no)
- return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
-
- return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
- summary_only != NULL, as_set, origin,
- match_med != NULL);
-}
-
-DEFPY(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"
- "}",
- 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")
-{
- uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
- int as_set = AGGREGATE_AS_UNSET;
-
- if (origin_s) {
- if (strcmp(origin_s, "egp") == 0)
- origin = BGP_ORIGIN_EGP;
- else if (strcmp(origin_s, "igp") == 0)
- origin = BGP_ORIGIN_IGP;
- else if (strcmp(origin_s, "incomplete") == 0)
- origin = BGP_ORIGIN_INCOMPLETE;
- }
-
- if (as_set_s)
- as_set = AGGREGATE_AS_SET;
-
- /* Handle configuration removal, otherwise installation. */
+ 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);
+
+ 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)
- return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
- SAFI_UNICAST);
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+ else
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
- return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
- rmap_name, summary_only != NULL, as_set,
- origin, match_med != NULL);
+ return nb_cli_apply_changes(vty, base_xpath);
+}
+
+void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
+ struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+ 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. */
json_object_string_add(json, "network", buf2);
}
} else if (p->family == AF_ETHERNET) {
- prefix2str(p, buf, PREFIX_STRLEN);
len = vty_out(vty, "%pFX", p);
} else if (p->family == AF_EVPN) {
if (!json)
- len = vty_out(vty, "%s",
- prefix2str((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) {
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)
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))
}
} 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,
} 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(
}
} 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,
/* 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];
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))
|| !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];
&& ((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)))
{
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;
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,
}
if (safi == SAFI_EVPN) {
if (!json_paths) {
- prefix2str((struct prefix_evpn *)
- bgp_dest_get_prefix(bn),
- buf2, sizeof(buf2));
- vty_out(vty, " Route %s", buf2);
+ vty_out(vty, " Route %pFX",
+ (struct prefix_evpn *)
+ bgp_dest_get_prefix(bn));
if (tag_buf[0] != '\0')
vty_out(vty, " VNI %s", tag_buf);
vty_out(vty, "\n");
pdest),
buf1, sizeof(buf1));
if (is_pi_family_evpn(parent_ri)) {
- prefix2str((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);
+ vty_out(vty,
+ " Imported from %s:%pFX, VNI %s\n",
+ buf1,
+ (struct prefix_evpn *)
+ bgp_dest_get_prefix(
+ dest),
+ 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));
}
}
}
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");
} 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);
}
}
|| 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(
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(
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 */
}
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,
/* 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)) {
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);
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]);
}
}
}
}
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\" : {");
}
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
struct peer *peer;
struct listnode *node, *nnode;
char buf1[RD_ADDRSTRLEN];
- char buf3[EVPN_ROUTE_STRLEN];
char prefix_str[BUFSIZ];
int count = 0;
int best = 0;
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 ? ":" : "",
- prefix2str((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)) :
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)
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);
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
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);
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
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);
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;
}
* 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;
}
}
-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. */
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");
}
}
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);
/* 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;
#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) \
#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
/* 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 *);
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,
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);
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 */
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,
int route_update)
{
int i;
+ bool matched;
afi_t afi;
safi_t safi;
struct peer *peer;
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);
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);
}
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;
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;
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 *)
--- /dev/null
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+
+#include "bgp_trace.h"
--- /dev/null
+/* 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 */
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);
+ }
}
/**
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);
}
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,
&& 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
UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted);
THREAD_OFF(subgrp->t_merge_check);
-
- THREAD_TIMER_OFF(subgrp->t_coalesce);
+ THREAD_OFF(subgrp->t_coalesce);
bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp));
subgroup_clear_table(subgrp);
- THREAD_TIMER_OFF(subgrp->t_coalesce);
sync_delete(subgrp);
if (BGP_DEBUG(update_groups, UPDATE_GROUPS) && subgrp->update_group)
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;
}
}
}
+
+ /* Notify BGP Conditional advertisement */
+ bgp_notify_conditional_adv_scanner(subgrp);
}
return UPDWALK_CONTINUE;
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;
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 {
struct bgp *bgp;
struct attr attr;
struct attr *new_attr = &attr;
- struct aspath *aspath;
struct prefix p;
struct peer *from;
struct bgp_dest *dest;
from = bgp->peer_self;
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
- aspath = attr.aspath;
attr.local_pref = bgp->default_local_pref;
}
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
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
if (subgroup_announce_check(
dest, pi, subgrp,
bgp_dest_get_prefix(dest),
- &attr))
+ &attr, false))
bgp_adj_out_set_subgroup(
dest, subgrp, &attr,
pi);
subgroup_default_update_packet(subgrp, new_attr, from);
}
}
-
- aspath_unintern(&aspath);
}
/*
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) {
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;
/* 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
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);
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
" 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);
#include "command.h"
#include "prefix.h"
#include "lib/json.h"
+#include "lib/printfrr.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
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",
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);
"%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);
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,
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)
{
* @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;
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",
return nb_cli_apply_changes(vty, NULL);
}
-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")
+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")
{
int idx = 0;
return nb_cli_apply_changes(vty, NULL);
}
-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")
+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")
{
nb_cli_enqueue_change(vty,
"./global/med-config/max-med-onstart-up-time",
* Furthermore, the maximums used here should correspond to
* BGP_WRITE_PACKET_MAX and BGP_READ_PACKET_MAX.
*/
-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")
+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(
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")
+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(
}
-DEFUN_YANG(bgp_coalesce_time,
- bgp_coalesce_time_cmd,
- "coalesce-time (0-4294967295)",
- "Subgroup coalesce timer\n"
- "Subgroup coalesce timer value (in ms)\n")
+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;
}
/* 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,
"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,
"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,
"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,
"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,
/* BGP timers. */
-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")
+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")
{
int idx_number = 2;
int idx_number_2 = 3;
return nb_cli_apply_changes(vty, NULL);
}
-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")
+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);
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",
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);
}
}
}
"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,
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
*/
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,
"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
"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) {
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)
"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",
"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,
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");
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);
+ 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 (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;
- }
- }
-
- 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
"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");
+
+ return nb_cli_apply_changes(vty, base_xpath);
+}
- 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);
- }
+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");
+}
- return CMD_SUCCESS;
+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,
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>]",
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;
}
"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;
}
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,
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",
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)),
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)
/* 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(
: 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);
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();
"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]);
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]);
struct prefix *range;
struct peer *conf;
struct peer *peer;
- char buf[PREFIX2STR_BUFFER];
afi_t afi;
safi_t safi;
const char *peer_status;
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);
}
}
/* 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");
+
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
- bgp_redist_add(bgp, AFI_IP, type, 0);
- return bgp_redistribute_set(bgp, AFI_IP, type, 0, false);
+ return nb_cli_apply_changes(vty, base_xpath);
}
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];
- 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);
+ 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);
+
+ return nb_cli_apply_changes(vty, base_xpath);
}
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");
+
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+ 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_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(
"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(
"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");
+
+ 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);
- 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);
+ return nb_cli_apply_changes(vty, base_xpath);
}
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,
"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];
- 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);
+ 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);
+
+ return nb_cli_apply_changes(vty, base_xpath);
}
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,
"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(
"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(
"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(
"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(
"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");
- 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);
+ 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);
}
-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"
"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");
+
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+ nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+ argv[idx_number]->arg);
- 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);
+ 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");
+
+ 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);
- 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);
+ 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");
+
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, base_xpath);
+}
- return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
+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,
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;
}
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))
/* 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)
/* 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))
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);
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")
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")
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")
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 */
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;
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;
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);
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);
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);
}
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);
}
}
}
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];
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);
}
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)
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;
}
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;
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));
#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"
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
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
struct listnode *node, *nnode;
struct peer *peer;
afi_t afi;
- char buf[PREFIX2STR_BUFFER];
afi = family2afi(range->family);
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)) {
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);
}
}
}
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
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 */
struct prefix *listen_range;
int dncount;
char buf[PREFIX2STR_BUFFER];
- char buf1[PREFIX2STR_BUFFER];
sockunion2hostprefix(su, &prefix);
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;
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)
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,
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,
/* BGP thread master. */
struct thread_master *master;
- /* work queues */
- struct work_queue *process_main_queue;
-
/* Listening sockets */
struct list *listen_sockets;
/* 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)
#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. */
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,
#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];
/* 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)
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);
#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);
++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) {
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);
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) {
* 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;
}
* 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;
}
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;
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);
}
{
- 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);
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
}
}
- 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);
}
}
#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
#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
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);
}
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;
}
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);
"%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);
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);
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;
}
}
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);
"%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);
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;
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] -=
rfapiMonitorDetachImport(m);
}
- if (m->timer) {
- thread_cancel(m->timer);
- m->timer = NULL;
- }
+ thread_cancel(&m->timer);
/*
* remove from rfd list
rfapiMonitorDetachImport(m);
}
- if (m->timer) {
- thread_cancel(m->timer);
- m->timer = NULL;
- }
+ thread_cancel(&m->timer);
XFREE(MTYPE_RFAPI_MONITOR, m);
rn->info = NULL;
#endif
}
- if (mon_eth->timer) {
- thread_cancel(mon_eth->timer);
- mon_eth->timer = NULL;
- }
+ thread_cancel(&mon_eth->timer);
/*
* remove from rfd list
if (m->rfd->response_lifetime - remain < 2)
return;
- thread_cancel(m->timer);
- m->timer = NULL;
+ thread_cancel(&m->timer);
}
{
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);
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) {
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
if (m->rfd->response_lifetime - remain < 2)
return;
- thread_cancel(m->timer);
- m->timer = NULL;
+ thread_cancel(&m->timer);
}
{
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);
rfapiMonitorEthDetachImport(bgp, val);
}
- if (val->timer) {
- thread_cancel(val->timer);
- val->timer = NULL;
- }
+ thread_cancel(&val->timer);
/*
* remove from rfd list
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);
}
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));
*/
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;
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",
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);
}
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
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);
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);
afi_t afi;
uint32_t queued_flag;
int count = 0;
- char buf[PREFIX_STRLEN];
vnc_zlog_debug_verbose("%s: entry", __func__);
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);
#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
*/
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
#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(
*/
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)
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);
}
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) {
int rc;
afi_t afi;
struct rfapi_adb *adb;
- char buf[PREFIX_STRLEN];
vty_out(vty, "%-10p ", rfd);
rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
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);
}
(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 */
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:
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 */
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",
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);
}
/* 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
* 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);
}
}
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);
/*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) {
}
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) {
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",
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
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);
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
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 */
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)) {
* 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);
}
#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
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;
* 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);
}
(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(
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 ");
{
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 ");
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;
}
}
}
- 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);
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 \
bgpd/bgpd.c \
bgpd/bgp_nb.c \
bgpd/bgp_nb_config.c \
+ bgpd/bgp_trace.c \
# end
if ENABLE_BGP_VNC
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 \
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 \
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
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
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],
])
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 ------
## 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
------------------------------
packaging
process-architecture
library
+ tracing
testing
bgpd
fpm
--- /dev/null
+.. _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.
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
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
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
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
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
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/`
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] [backup]
-.. clicmd:: show isis route [level-1|level-2] [backup]
+.. 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.
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
.. _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.
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
==============
.. 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
===========================
:file:`/etc/snmp/snmpd.conf`:
::
+
# This is the default view
view all included .1 80
# Remove ipRouteTable from view
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
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);
}
/*
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));
*/
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");
}
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);
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));
}
}
/* 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 *);
#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);
#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,
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);
&& (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);
& 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);
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 */
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)
}
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;
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);
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;
}
}
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);
}
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;
}
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);
{
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));
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
|| (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;
}
*/
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;
}
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;
}
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);
&& (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);
/* 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;
}
//
* 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;
}
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);
}
/* 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 */
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 */
/* 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 */
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);
}
}
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);
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);
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);
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;
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);
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));
}
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));
/* 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));
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);
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;
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);
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;
}
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);
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);
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);
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],
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]);
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;
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) {
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");
{
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) {
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) {
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;
{
struct prefix_ipv4 *ipv4, *ip = NULL;
struct listnode *node;
- char buf[PREFIX2STR_BUFFER];
struct prefix_ipv6 *ipv6, *ip6 = NULL;
int found = 0;
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");
}
}
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,
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(
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;
} 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);
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",
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");
"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);
} 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']",
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);
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"))
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");
}
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->isis->sysid, ISIS_SYS_ID_LEN);
&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],
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;
}
}
- 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();
}
}
} 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;
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);
}
}
if (ldp_sync_info &&
ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED &&
ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) {
- THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+ 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);
}
ils_debug("ldp_sync: remove if %s", circuit->interface
? circuit->interface->name : "");
- 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) {
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) {
return false;
}
-/* Find SRGB associated to a System ID. */
-static struct isis_sr_block *tilfa_find_srgb(struct lspdb_head *lspdb,
- const uint8_t *sysid)
-{
- 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;
-}
-
struct tilfa_find_pnode_prefix_sid_args {
uint32_t sid_index;
};
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:
- srgb = tilfa_find_srgb(lspdb, sadj->id);
+ 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(sadj->id));
+ print_sys_hostname(target_node));
goto error;
}
/* Check if the SID index falls inside the SRGB. */
- if (sid->value.index >= srgb->range_size) {
+ 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);
+ __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;
+ label = srgb->lower_bound + sid->value.index.value;
break;
case TILFA_SID_ADJ:
/* Adj-SID: absolute label value can be used directly */
struct listnode *node;
bool is_pnode, is_qnode;
char buf[VID2STR_BUFFER];
- struct isis_tilfa_sid sid_qnode, sid_pnode;
+ struct isis_tilfa_sid sid_dest = {}, sid_qnode = {}, sid_pnode = {};
+ uint32_t sid_index;
mpls_label_t label_qnode;
if (IS_DEBUG_TILFA) {
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
/* Push Prefix-SID label when necessary. */
if (is_pnode) {
- uint32_t sid_index;
-
/* 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)
if (IS_DEBUG_TILFA)
zlog_debug(
- "ISIS-TI-LFA: pushing Prefix-SID to %s (index %u)",
+ "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 = sid_index;
+ sid_pnode.value.index.value = sid_index;
listnode_add_head(repair_list, &sid_pnode);
/* Apply repair list. */
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,
struct route_table *route_table;
route_table = spftree_pc->lfa.old.spftree->route_table_backup;
- if (route_node_lookup(route_table, &vertex->N.ip.dest)) {
+ 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",
struct isis_tilfa_sid {
enum isis_tilfa_sid_type type;
union {
- uint32_t index;
+ struct {
+ uint32_t value;
+ bool remote;
+ uint8_t remote_sysid[ISIS_SYS_ID_LEN];
+ } index;
mpls_label_t label;
} value;
};
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;
*/
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
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);
}
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(
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,
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,
"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)) {
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(
"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 =
.modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify,
},
},
+ {
+ .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 = {
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);
return NB_OK;
}
+/*
+ * 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
*/
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;
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);
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);
if (thread_timer_remain_msec(*threadp) < (unsigned long)delay)
return;
- thread_cancel(*threadp);
+ thread_cancel(threadp);
}
thread_add_timer_msec(master, send_hello_cb,
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.",
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)
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;
nexthop->family = family;
nexthop->ifindex = ifindex;
nexthop->ip = *ip;
- isis_sr_nexthop_reset(&nexthop->sr);
return nexthop;
}
}
void adjinfo2nexthop(int family, struct list *nexthops,
- struct isis_adjacency *adj,
+ struct isis_adjacency *adj, struct isis_sr_psid_info *sr,
struct mpls_label_stack *label_stack)
{
struct isis_nexthop *nh;
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;
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;
static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
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;
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;
/*
* 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;
}
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;
}
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)
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)",
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 */
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,
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);
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);
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;
};
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;
};
void isis_nexthop_delete(struct isis_nexthop *nexthop);
void adjinfo2nexthop(int family, struct list *nexthops,
- struct isis_adjacency *adj,
+ 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 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);
/* Walk the given table and install new routes to zebra and remove old ones.
* route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
}
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;
}
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;
/*
* 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;
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);
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
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;
/* 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)
}
}
- 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
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);
(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;
}
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)
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);
}
}
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);
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
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;
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;
}
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);
static void add_to_paths(struct isis_spftree *spftree,
struct isis_vertex *vertex)
{
- struct isis_area *area = spftree->area;
+#ifdef EXTREME_DEBUG
char buff[VID2STR_BUFFER];
+#endif /* EXTREME_DEBUG */
if (isis_find_vertex(&spftree->paths, &vertex->N, vertex->type))
return;
vid2string(vertex, buff, sizeof(buff)), vertex->depth,
vertex->d_N);
#endif /* EXTREME_DEBUG */
+}
+
+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);
+
+ 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 (VTYPE_IP(vertex->type)
&& !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ROUTES)) {
- if (listcount(vertex->Adj_N) > 0) {
+ if (vertex->depth == 1 || listcount(vertex->Adj_N) > 0) {
struct route_table *route_table;
if (spftree->type == SPF_TYPE_TI_LFA) {
} else
route_table = spftree->route_table;
- isis_route_create(&vertex->N.ip.dest, &vertex->N.ip.src,
- vertex->d_N, vertex->depth,
+ 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(
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);
-
- spftree->mtid = mtid;
}
static void isis_spf_loop(struct isis_spftree *spftree,
{
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);
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,
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;
return CMD_SUCCESS;
}
+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 backup)
+ 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)
/* 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, '-');
+ 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->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.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. */
}
static void show_isis_route_common(struct vty *vty, int levels,
- struct isis *isis, bool backup)
+ struct isis *isis, bool prefix_sid,
+ bool backup)
{
struct listnode *node;
struct isis_area *area;
isis_print_routes(
vty,
area->spftree[SPFTREE_IPV4][level - 1],
- backup);
+ prefix_sid, backup);
}
if (area->ipv6_circuits > 0) {
isis_print_routes(
vty,
area->spftree[SPFTREE_IPV6][level - 1],
- backup);
+ prefix_sid, backup);
}
if (isis_area_ipv6_dstsrc_enabled(area)) {
isis_print_routes(vty,
area->spftree[SPFTREE_DSTSRC]
[level - 1],
- backup);
+ prefix_sid, backup);
}
}
}
#ifndef FABRICD
" [<level-1|level-2>]"
#endif
- " [backup]",
+ " [<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 listnode *node;
const char *vrf_name = VRF_DEFAULT_NAME;
bool all_vrf = false;
+ bool prefix_sid = false;
bool backup = false;
int idx = 0;
}
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 (all_vrf) {
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
show_isis_route_common(vty, levels, isis,
- backup);
+ prefix_sid, backup);
return CMD_SUCCESS;
}
isis = isis_lookup_by_vrfname(vrf_name);
if (isis != NULL)
- show_isis_route_common(vty, levels, isis, backup);
+ show_isis_route_common(vty, levels, isis, prefix_sid,
+ backup);
}
return CMD_SUCCESS;
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,
- bool backup);
+ 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_vertex_adj {
struct isis_spf_adj *sadj;
+ struct isis_sr_psid_info sr;
struct mpls_label_stack *label_stack;
};
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 */
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;
}
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;
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");
}
#include "memory.h"
#include "prefix.h"
#include "table.h"
+#include "srcdest_table.h"
#include "vty.h"
#include "zclient.h"
#include "lib/lib_errors.h"
/* 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,
/* --- 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 --- */
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,
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. */
srdb->config.srlb_lower_bound = lower_bound;
srdb->config.srlb_upper_bound = upper_bound;
- if (srdb->enabled) {
- /* Initialize new SRLB */
- if (sr_local_block_init(area) != 0)
- return -1;
-
- /* Reinstall local Adjacency-SIDs with new labels. */
- for (ALL_LIST_ELEMENTS_RO(area->srdb.adj_sids, node, sra))
- sr_adj_sid_update(sra, &srdb->srlb);
-
- /* Update and Flood LSP */
- lsp_regenerate_schedule(area, area->is_type, 0);
- } else if (srdb->config.enabled) {
- /* Try to enable SR again using the new SRLB. */
- isis_sr_start(area);
- }
-
- return 0;
-}
-
-/**
- * Add new Prefix-SID configuration to the SRDB.
- *
- * @param area IS-IS area
- * @param prefix Prefix to be added
- *
- * @return Newly added Prefix-SID configuration structure
- */
-struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area,
- const struct prefix *prefix)
-{
- struct sr_prefix_cfg *pcfg;
- struct interface *ifp;
-
- sr_debug("ISIS-Sr (%s): Add local prefix %pFX", area->area_tag, prefix);
-
- pcfg = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*pcfg));
- pcfg->prefix = *prefix;
- pcfg->area = area;
-
- /* Pull defaults from the YANG module. */
- pcfg->sid_type = yang_get_default_enum(
- "%s/prefix-sid-map/prefix-sid/sid-value-type", ISIS_SR);
- pcfg->last_hop_behavior = yang_get_default_enum(
- "%s/prefix-sid-map/prefix-sid/last-hop-behavior", ISIS_SR);
-
- /* Set the N-flag when appropriate. */
- ifp = if_lookup_prefix(prefix, VRF_DEFAULT);
- if (ifp && sr_prefix_is_node_sid(ifp, prefix))
- pcfg->node_sid = true;
-
- /* Save prefix-sid configuration. */
- srdb_prefix_cfg_add(&area->srdb.config.prefix_sids, pcfg);
-
- return pcfg;
-}
-
-/**
- * Removal of locally configured Prefix-SID.
- *
- * @param pcfg Configured Prefix-SID
- */
-void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg)
-{
- struct isis_area *area = pcfg->area;
-
- sr_debug("ISIS-Sr (%s): Delete local Prefix-SID %pFX %s %u",
- area->area_tag, &pcfg->prefix,
- pcfg->sid_type == SR_SID_VALUE_TYPE_INDEX ? "index" : "label",
- pcfg->sid);
-
- srdb_prefix_cfg_del(&area->srdb.config.prefix_sids, pcfg);
- XFREE(MTYPE_ISIS_SR_INFO, pcfg);
-}
-
-/**
- * Lookup for Prefix-SID in the local configuration.
- *
- * @param area IS-IS area
- * @param prefix Prefix to lookup
- *
- * @return Configured Prefix-SID structure if found, NULL otherwise
- */
-struct sr_prefix_cfg *isis_sr_cfg_prefix_find(struct isis_area *area,
- union prefixconstptr prefix)
-{
- struct sr_prefix_cfg pcfg = {};
-
- prefix_copy(&pcfg.prefix, prefix.p);
- return srdb_prefix_cfg_find(&area->srdb.config.prefix_sids, &pcfg);
-}
-
-/**
- * Fill in Prefix-SID Sub-TLV according to the corresponding configuration.
- *
- * @param pcfg Prefix-SID configuration
- * @param external False if prefix is locally configured, true otherwise
- * @param psid Prefix-SID sub-TLV to be updated
- */
-void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, bool external,
- struct isis_prefix_sid *psid)
-{
- /* Set SID algorithm. */
- psid->algorithm = SR_ALGORITHM_SPF;
-
- /* Set SID flags. */
- psid->flags = 0;
- switch (pcfg->last_hop_behavior) {
- case SR_LAST_HOP_BEHAVIOR_EXP_NULL:
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
- break;
- case SR_LAST_HOP_BEHAVIOR_NO_PHP:
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
- UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
- break;
- case SR_LAST_HOP_BEHAVIOR_PHP:
- UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
- UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
- break;
- }
- if (external)
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_READVERTISED);
- if (pcfg->node_sid)
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_NODE);
-
- /* Set SID value. */
- psid->value = pcfg->sid;
- if (pcfg->sid_type == SR_SID_VALUE_TYPE_ABSOLUTE) {
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_VALUE);
- SET_FLAG(psid->flags, ISIS_PREFIX_SID_LOCAL);
- }
-}
-
-/* --- 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;
+ if (srdb->enabled) {
+ /* Initialize new SRLB */
+ if (sr_local_block_init(area) != 0)
+ return -1;
- /* Only SPF algorithm is supported right now */
- if (psid->algorithm != SR_ALGORITHM_SPF)
- continue;
+ /* Reinstall local Adjacency-SIDs with new labels. */
+ for (ALL_LIST_ELEMENTS_RO(area->srdb.adj_sids, node, sra))
+ sr_adj_sid_update(sra, &srdb->srlb);
- /* 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;
+ /* Update and Flood LSP */
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ } else if (srdb->config.enabled) {
+ /* Try to enable SR again using the new SRLB. */
+ isis_sr_start(area);
}
+
+ return 0;
}
/**
- * Parse all SR-related information from the given LSP.
+ * Add new Prefix-SID configuration to the SRDB.
*
- * @param area IS-IS area
- * @param level IS-IS level
- * @param srn Segment Routing Node
- * @param lsp IS-IS LSP
+ * @param area IS-IS area
+ * @param prefix Prefix to be added
+ *
+ * @return Newly added Prefix-SID configuration structure
*/
-static void parse_lsp(struct isis_area *area, int level, struct sr_node **srn,
- struct isis_lsp *lsp)
+struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area,
+ const struct prefix *prefix)
{
- 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;
- }
+ struct sr_prefix_cfg *pcfg;
+ struct interface *ifp;
- /* 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;
+ sr_debug("ISIS-Sr (%s): Add local prefix %pFX", area->area_tag, prefix);
- ir = (struct isis_extended_ip_reach *)i;
- if (!ir->subtlvs)
- continue;
+ pcfg = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*pcfg));
+ pcfg->prefix = *prefix;
+ pcfg->area = area;
- parse_prefix_sid_subtlvs(*srn, &ir->prefix, local,
- &ir->subtlvs->prefix_sids);
- }
+ /* Pull defaults from the YANG module. */
+ pcfg->sid_type = yang_get_default_enum(
+ "%s/prefix-sid-map/prefix-sid/sid-value-type", ISIS_SR);
+ pcfg->last_hop_behavior = yang_get_default_enum(
+ "%s/prefix-sid-map/prefix-sid/last-hop-behavior", ISIS_SR);
- /* 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;
+ /* Set the N-flag when appropriate. */
+ ifp = if_lookup_prefix(prefix, VRF_DEFAULT);
+ if (ifp && sr_prefix_is_node_sid(ifp, prefix) && !pcfg->n_flag_clear)
+ pcfg->node_sid = true;
- ir = (struct isis_ipv6_reach *)i;
- if (!ir->subtlvs)
- continue;
+ /* Save prefix-sid configuration. */
+ srdb_prefix_cfg_add(&area->srdb.config.prefix_sids, pcfg);
- parse_prefix_sid_subtlvs(*srn, &ir->prefix, local,
- &ir->subtlvs->prefix_sids);
- }
+ return pcfg;
}
/**
- * Parse all SR-related information from the entire LSPDB.
+ * Removal of locally configured Prefix-SID.
*
- * @param area IS-IS area
+ * @param pcfg Configured Prefix-SID
*/
-static void parse_lspdb(struct isis_area *area)
+void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg)
{
- struct isis_lsp *lsp;
+ struct isis_area *area = pcfg->area;
- 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);
- }
- }
+ sr_debug("ISIS-Sr (%s): Delete local Prefix-SID %pFX %s %u",
+ area->area_tag, &pcfg->prefix,
+ pcfg->sid_type == SR_SID_VALUE_TYPE_INDEX ? "index" : "label",
+ pcfg->sid);
+
+ srdb_prefix_cfg_del(&area->srdb.config.prefix_sids, pcfg);
+ XFREE(MTYPE_ISIS_SR_INFO, pcfg);
}
/**
- * Process any new/deleted/modified Prefix-SID in the LSPDB.
+ * Lookup for Prefix-SID in the local configuration.
*
- * @param srn Segment Routing Node
- * @param srp Segment Routing Prefix
+ * @param area IS-IS area
+ * @param prefix Prefix to lookup
+ *
+ * @return Configured Prefix-SID structure if found, NULL otherwise
*/
-static void process_prefix_changes(struct sr_node *srn, struct sr_prefix *srp)
+struct sr_prefix_cfg *isis_sr_cfg_prefix_find(struct isis_area *area,
+ union prefixconstptr prefix)
{
- 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;
- }
+ struct sr_prefix_cfg pcfg = {};
- /* Validate SRDB State for next LSPDB parsing */
- srp->state = SRDB_STATE_VALIDATED;
+ prefix_copy(&pcfg.prefix, prefix.p);
+ return srdb_prefix_cfg_find(&area->srdb.config.prefix_sids, &pcfg);
}
/**
- * Process any new/deleted/modified SRGB in the LSPDB.
+ * Fill in Prefix-SID Sub-TLV according to the corresponding configuration.
*
- * @param area IS-IS area
- * @param level IS-IS level
- * @param srn Segment Routing Node
+ * @param pcfg Prefix-SID configuration
+ * @param external False if prefix is locally configured, true otherwise
+ * @param psid Prefix-SID sub-TLV to be updated
*/
-static void process_node_changes(struct isis_area *area, int level,
- struct sr_node *srn)
+void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, bool external,
+ struct isis_prefix_sid *psid)
{
- struct sr_prefix *srp;
- uint8_t sysid[ISIS_SYS_ID_LEN];
- bool adjacent;
-
- memcpy(sysid, srn->sysid, sizeof(sysid));
+ /* Set SID algorithm. */
+ psid->algorithm = SR_ALGORITHM_SPF;
- /*
- * 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);
+ /* Set SID flags. */
+ psid->flags = 0;
+ switch (pcfg->last_hop_behavior) {
+ case SR_LAST_HOP_BEHAVIOR_EXP_NULL:
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
break;
- case SRDB_STATE_UNCHANGED:
+ case SR_LAST_HOP_BEHAVIOR_NO_PHP:
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
+ UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
+ break;
+ case SR_LAST_HOP_BEHAVIOR_PHP:
+ UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
+ UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
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;
}
+ if (external)
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_READVERTISED);
+ if (pcfg->node_sid)
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_NODE);
- /* 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);
+ /* Set SID value. */
+ psid->value = pcfg->sid;
+ if (pcfg->sid_type == SR_SID_VALUE_TYPE_ABSOLUTE) {
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_VALUE);
+ SET_FLAG(psid->flags, ISIS_PREFIX_SID_LOCAL);
+ }
}
/**
sr_adj_sid_del(sra);
}
-/**
- * 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;
- }
-
- return 0;
-}
-
/* --- Segment Routing Local Block management functions --------------------- */
/**
struct mpls_label_stack *label_stack;
label_stack = vadj->label_stack;
- adjinfo2nexthop(family, sra->backup_nexthops, adj,
+ adjinfo2nexthop(family, sra->backup_nexthops, adj, NULL,
label_stack);
}
}
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);
}
return 0;
}
-/* --- Segment Routing Show information functions --------------------------- */
-
/**
* Show LFIB operation in human readable format.
*
* @param size Size of the buffer
* @param label_in Input Label
* @param label_out Output Label
- * @param label_stack Output Label Stack (TI-LFA)
*
* @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,
- const struct mpls_label_stack *label_stack)
+char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
+ mpls_label_t label_out)
{
if (size < 24)
return NULL;
return buf;
}
- if (label_stack) {
- char buf_labels[256];
-
- mpls_label2str(label_stack->num_labels, &label_stack->label[0],
- buf_labels, sizeof(buf_labels), 1);
-
- snprintf(buf, size, "Swap(%u, %s)", label_in, buf_labels);
- return buf;
- }
-
switch (label_out) {
case MPLS_LABEL_IMPLICIT_NULL:
snprintf(buf, size, "Pop(%u)", label_in);
return buf;
}
-/**
- * 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, 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, bool backup)
-{
- 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;
- struct isis_route_info *rinfo;
-
- (void)prefix2str(&srp->prefix, buf_prefix, sizeof(buf_prefix));
-
- rinfo = srp->u.remote.rinfo;
- if (rinfo && backup)
- rinfo = rinfo->backup;
- if (!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, NULL));
- return;
- }
-
- for (ALL_LIST_ELEMENTS_RO(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, nexthop->label_stack);
-
- 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,
- bool backup)
-{
- 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, backup);
- 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 [backup]",
- SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
- "All VRFs\n"
- "Segment-Routing\n"
- "Segment-Routing Prefix-SIDs\n"
- "Show backup 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;
- bool backup = false;
- int idx = 0;
-
- ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf);
- if (argv_find(argv, argc, "backup", &idx))
- backup = true;
-
- 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, backup);
- }
- }
- 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,
- backup);
- }
- }
- }
-
- return CMD_SUCCESS;
-}
-
/**
* Show Segment Routing Node.
*
*/
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]);
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. */
return CMD_SUCCESS;
}
-
/* --- IS-IS Segment Routing Management function ---------------------------- */
/**
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,
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);
*/
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);
}
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);
}
#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;
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,
/* 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;
/* 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;
};
/* 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,
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 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 void isis_area_verify_sr(struct isis_area *area);
+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);
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");
}
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");
}
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,
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",
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,
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,
}
/* 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;
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;
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);
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;
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;
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;
/* 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
{
struct isis_tx_queue_entry *e = element;
- if (e->retry)
- thread_cancel(e->retry);
+ thread_cancel(&(e->retry));
XFREE(MTYPE_TX_QUEUE_ENTRY, e);
}
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;
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);
{
struct isis_circuit *circuit;
struct connected *c;
-#ifdef EXTREME_DEBUG
- struct prefix *p;
- char buf[PREFIX2STR_BUFFER];
-#endif /* EXTREME_DEBUG */
c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
zclient->ibuf, vrf_id);
return 0;
#ifdef EXTREME_DEBUG
- p = c->address;
- prefix2str(p, buf, sizeof(buf));
-
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)) {
{
struct isis_circuit *circuit;
struct connected *c;
-#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);
return 0;
#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(c->ifp)) {
}
enum isis_zebra_nexthop_type {
- ISIS_ROUTE_NEXTHOP_MAIN = 0,
- ISIS_ROUTE_NEXTHOP_BACKUP,
- ISIS_MPLS_NEXTHOP_MAIN,
- ISIS_MPLS_NEXTHOP_BACKUP,
+ 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,
- uint8_t backup_nhs)
+ bool mpls_lsp, uint8_t backup_nhs)
{
struct isis_nexthop *nexthop;
struct listnode *node;
/* Add MPLS label(s). */
switch (type) {
- case ISIS_ROUTE_NEXTHOP_MAIN:
- case ISIS_ROUTE_NEXTHOP_BACKUP:
- /*
- * SR/TI-LFA labels are installed using separate
- * messages.
- */
- break;
- case ISIS_MPLS_NEXTHOP_MAIN:
- if (nexthop->sr.label != MPLS_INVALID_LABEL) {
+ case ISIS_NEXTHOP_MAIN:
+ if (nexthop->sr.present) {
api_nh->label_num = 1;
api_nh->labels[0] = nexthop->sr.label;
- } else {
- api_nh->label_num = 1;
- api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
- }
+ } else if (mpls_lsp)
+ /*
+ * Do not use non-SR enabled nexthops to prevent
+ * broken LSPs from being formed.
+ */
+ continue;
break;
- case ISIS_MPLS_NEXTHOP_BACKUP:
+ case ISIS_NEXTHOP_BACKUP:
if (nexthop->label_stack) {
api_nh->label_num =
nexthop->label_stack->num_labels;
nexthop->label_stack->label,
sizeof(mpls_label_t)
* api_nh->label_num);
- } else {
+ } 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;
}
struct zapi_route api;
int count = 0;
- if (zclient->sock < 0)
+ if (zclient->sock < 0 || list_isempty(route_info->nexthops))
return;
memset(&api, 0, sizeof(api));
if (route_info->backup) {
count = isis_zebra_add_nexthops(
isis, route_info->backup->nexthops, api.backup_nexthops,
- ISIS_ROUTE_NEXTHOP_BACKUP, 0);
+ 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_ROUTE_NEXTHOP_MAIN,
+ api.nexthops, ISIS_NEXTHOP_MAIN, false,
count);
if (!count)
return;
}
/**
- * 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 isis *isis = srp->srn->area->isis;
struct zapi_labels zl;
- struct zapi_nexthop *znh;
- struct interface *ifp;
- struct isis_route_info *rinfo;
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;
}
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;
-
- rinfo = srp->u.remote.rinfo;
-
+ } else {
/* Add backup nexthops first. */
if (rinfo->backup) {
count = isis_zebra_add_nexthops(
- isis, rinfo->backup->nexthops,
- zl.backup_nexthops, ISIS_MPLS_NEXTHOP_BACKUP,
+ area->isis, rinfo->backup->nexthops,
+ zl.backup_nexthops, ISIS_NEXTHOP_BACKUP, true,
0);
if (count > 0) {
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
}
/* Add primary nexthops. */
- count = isis_zebra_add_nexthops(isis, rinfo->nexthops,
- zl.nexthops,
- ISIS_MPLS_NEXTHOP_MAIN, count);
+ count = isis_zebra_add_nexthops(area->isis, rinfo->nexthops,
+ zl.nexthops, ISIS_NEXTHOP_MAIN,
+ true, count);
if (!count)
return;
zl.nexthop_num = count;
- break;
}
/* Send message to zebra. */
}
/**
- * 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.
*
count = isis_zebra_add_nexthops(isis, sra->backup_nexthops,
zl.backup_nexthops,
- ISIS_MPLS_NEXTHOP_BACKUP, 0);
+ ISIS_NEXTHOP_BACKUP, true, 0);
if (count > 0) {
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
zl.backup_nexthop_num = count;
void isis_zebra_stop(void);
struct isis_route_info;
-struct sr_prefix;
struct sr_adjacency;
void isis_zebra_route_add_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);
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]);
}
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);
isis_vrf_unlink(isis, vrf);
}
+ list_delete(&isis->area_list);
+ list_delete(&isis->init_circ_list);
XFREE(MTYPE_ISIS, isis);
}
}
}
- 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;
}
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;
{
if (accept_queue.evt != NULL) {
log_debug(__func__);
- THREAD_TIMER_OFF(accept_queue.evt);
+ thread_cancel(&accept_queue.evt);
accept_arm();
}
}
{
struct accept_ev *av;
LIST_FOREACH(av, &accept_queue.queue, entry)
- THREAD_READ_OFF(av->ev);
+ thread_cancel(&av->ev);
}
static int
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
{
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");
}
{
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)
{
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);
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) &&
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);
void
adj_stop_itimer(struct adj *adj)
{
- THREAD_TIMER_OFF(adj->inactivity_timer);
+ thread_cancel(&adj->inactivity_timer);
}
/* targeted neighbors */
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);
static void
tnbr_stop_hello_timer(struct tnbr *tnbr)
{
- THREAD_TIMER_OFF(tnbr->hello_timer);
+ thread_cancel(&tnbr->hello_timer);
}
struct ctl_adj *
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);
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;
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;
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)) {
* 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;
}
* 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;
}
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);
* 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);
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;
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;
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;
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;
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) {
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) {
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))
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)
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;
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:
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:
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);
static void
if_stop_hello_timer(struct iface_af *ia)
{
- THREAD_TIMER_OFF(ia->hello_timer);
+ thread_cancel(&ia->hello_timer);
}
struct ctl_iface *
{
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);
{
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);
}
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);
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
}
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);
}
*/
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);
}
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++;
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);
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));
}
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();
}
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();
}
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);
void
lde_gc_stop_timer(void)
{
- THREAD_TIMER_OFF(gc_timer);
+ thread_cancel(&gc_timer);
}
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)
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);
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;
#include <zebra.h>
#include <sys/un.h>
+#include "lib/printfrr.h"
#include "ldpd.h"
#include "ldpe.h"
}
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:
{
struct ctl_ldp_sync *iface;
json_object *json_iface;
+ char buf[PREFIX_STRLEN];
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LDP_SYNC:
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;
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);
{
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",
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));
json_object *json)
{
struct ctl_adj *adj;
+ char buf[PREFIX_STRLEN];
json_object *json_array;
json_object *json_adj;
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");
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;
}
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,
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;
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));
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));
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));
json_object *json)
{
struct ctl_nbr *nbr;
+ char buf[PREFIX_STRLEN];
json_object *json_array;
json_object *json_nbr;
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",
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;
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",
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;
json_object *json)
{
struct ctl_nbr *nbr;
+ char buf[PREFIX_STRLEN];
json_object *json_nbr;
switch (imsg->hdr.type) {
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:
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");
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;
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:
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);
{
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;
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:
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;
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) {
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:
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 */
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:
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");
json_object *json)
{
struct ctl_pw *pw;
+ char buf[PREFIX_STRLEN];
json_object *json_pw;
switch (imsg->hdr.type) {
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)
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,
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();
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();
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);
}
void
evbuf_clear(struct evbuf *eb)
{
- THREAD_WRITE_OFF(eb->ev);
+ thread_cancel(&eb->ev);
msgbuf_clear(&eb->wbuf);
eb->wbuf.fd = -1;
}
#ifdef __OpenBSD__
if (sysdep.no_pfkey == 0) {
- THREAD_READ_OFF(pfkey_ev);
+ thread_cancel(&pfkey_ev);
close(global.pfkeysock);
}
#endif
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();
}
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();
}
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;
*/
#include <zebra.h>
+#include "lib/printfrr.h"
#include "mpls.h"
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:
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);
}
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) {
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__);
{
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__
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);
/* 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);
}
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 */
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);
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);
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 */
{
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);
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);
}
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 */
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);
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);
void
nbr_stop_idtimer(struct nbr *nbr)
{
- THREAD_TIMER_OFF(nbr->initdelay_timer);
+ thread_cancel(&nbr->initdelay_timer);
}
int
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);
}
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);
}
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)
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);
}
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);
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:
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);
evbuf_clear(&tcp->wbuf);
if (tcp->nbr) {
- THREAD_READ_OFF(tcp->rev);
+ thread_cancel(&tcp->rev);
free(tcp->rbuf);
tcp->nbr->tcp = NULL;
}
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);
}
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);
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;
*/
while (ln) {
struct listnode *nextln = listnextnode(ln);
- thread_cancel(listgetdata(ln));
+ thr = listgetdata(ln);
+ thread_cancel(&thr);
list_delete_node(events, ln);
ln = nextln;
}
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
.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)
{
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);
&& 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);
}
}
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--;
}
#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);
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");
}
}
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");
}
}
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");
}
}
#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")
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);
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;
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);
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);
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);
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);
#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")
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;
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;
void *hash_release(struct hash *hash, void *data)
{
- void *ret;
+ void *ret = NULL;
unsigned int key;
unsigned int index;
struct hash_bucket *bucket;
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 *),
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;
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);
}
}
}
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) {
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);
}
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;
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;
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)
{
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"
* update state
*/
if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
- THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+ THREAD_OFF(ldp_sync_info->t_holddown);
if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP)
ldp_sync_info->state =
--- /dev/null
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+
+#include "libfrr_trace.h"
--- /dev/null
+/* 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_ */
#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")
struct listnode *listnode_add(struct list *list, void *val)
{
+ frrtrace(2, frr_libfrr, list_add, list, val);
+
struct listnode *node;
assert(val != NULL);
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)
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
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;
#include "memory.h"
#include "log.h"
+#include "libfrr_trace.h"
static struct memgroup *mg_first = NULL;
struct memgroup **mg_insert = &mg_first;
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);
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 */
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");
const struct nexthop *nh,
char *altifname)
{
- char buf[100];
char *ifname;
vty_out(vty, "nexthop ");
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;
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;
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)
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;
}
}
}
-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,
__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,
*/
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.
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;
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);
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;
}
"%% 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,
continue;
nb_node = snode->priv;
+ if (!nb_node)
+ continue;
+
DEBUGD(&nb_dbg_client_confd, "%s: subscribing to '%s'",
__func__, nb_node->xpath);
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))
* 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));
{
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;
}
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);
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);
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);
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);
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)
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);
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);
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",
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);
#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")
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)
#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.
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)
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) {
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,
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
}
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);
}
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);
"____________________");
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");
"____________________");
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");
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)
{
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);
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;
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);
{
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));
{
struct spf_backoff *backoff = THREAD_ARG(thread);
- 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",
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);
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
#
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 \
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 \
lib/lib_errors.h \
lib/lib_vty.h \
lib/libfrr.h \
+ lib/libfrr_trace.h \
lib/libospf.h \
lib/linklist.h \
lib/log.h \
lib/table.h \
lib/termtable.h \
lib/thread.h \
+ lib/trace.h \
lib/typerb.h \
lib/typesafe.h \
lib/vector.h \
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 \
lib/command_py.c \
lib/defun_lex.l \
lib/graph.c \
+ lib/libfrr_trace.c \
lib/memory.c \
lib/vector.c \
# end
#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")
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);
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;
route_node_delete(node);
}
+static inline unsigned int route_node_get_lock_count(struct route_node *node)
+{
+ return node->lock;
+}
+
/*
* route_table_iter_next
*
#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")
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
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)
;
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)
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 */
{
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) {
*
* @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;
}
/**
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) {
while (!master->canceled)
pthread_cond_wait(&master->cancel_cond, &master->mtx);
}
+
+ if (thread)
+ *thread = NULL;
}
/* ------------------------------------------------------------------------- */
struct timeval zerotime = {0, 0};
struct timeval tv;
struct timeval *tw = NULL;
-
+ bool eintr_p = false;
int num = 0;
do {
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;
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);
/* 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);
+}
#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__)
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 *);
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
--- /dev/null
+/* 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_ */
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) */
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);
void work_queue_plug(struct work_queue *wq)
{
if (wq->thread)
- thread_cancel(wq->thread);
+ thread_cancel(&(wq->thread));
wq->thread = NULL;
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;
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.
* 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.
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)
{
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;
}
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__)
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;
}
/* 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;
}
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;
}
/* 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;
}
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);
}
}
* 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 {
#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")
{
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
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;
}
/* 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;
}
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);
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);
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;
}
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");
}
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)
}
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);
struct route_info *ri;
struct prefix lookup;
afi_t afi = family2afi(sockunion_family(addr));
- char buf[PREFIX_STRLEN];
sockunion2hostprefix(addr, &lookup);
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)
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;
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);
}
}
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);
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);
{
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);
{
struct nhrp_shortcut *s;
struct route_node *rn;
- char buf[PREFIX_STRLEN];
afi_t afi = family2afi(PREFIX_FAMILY(p));
if (!shortcut_rib[afi])
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);
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);
}
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])),
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 */
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;
}
}
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 {
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;
}
}
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;
}
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, area->ospf6);
return 0;
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;
}
}
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;
}
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
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, ospf6);
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
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)) {
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));
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,
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)
&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)
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);
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;
}
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) {
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;
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) {
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);
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);
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;
}
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),
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))
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
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;
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;
}
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;
}
}
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;
/* 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, oa->ospf6);
}
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;
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,
oi->area->ospf6);
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;
}
}
}
- 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.
/* 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; \
}
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);
/* send message */
if (oi->area->ospf6->fd != -1) {
- len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector,
+ len = ospf6_sendmsg(src, dst, oi->interface->ifindex, iovector,
oi->area->ospf6->fd);
if (len != ntohs(oh->length))
flog_err(EC_LIB_DEVELOPMENT,
}
int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
- ifindex_t *ifindex, struct iovec *message, int ospf6_sock)
+ ifindex_t ifindex, struct iovec *message, int ospf6_sock)
{
int retval;
struct msghdr smsghdr;
struct sockaddr_in6 dst_sin6;
assert(dst);
- assert(*ifindex);
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
scmsgp = (struct cmsghdr *)&cmsgbuf;
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
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;
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;
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 *, int ospf6_sock);
-extern int ospf6_recvmsg(struct in6_addr *, struct in6_addr *, ifindex_t *,
- struct iovec *, int ospf6_sock);
+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 */
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);
"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);
"%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),
{
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,
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;
}
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;
}
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);
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);
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);
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);
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,
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))
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)) {
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);
}
}
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)) {
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);
}
}
#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
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
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);
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);
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));
}
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));
}
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 */
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;
}
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;
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))
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;
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
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;
}
}
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;
}
/* 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;
}
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;
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;
}
&& 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,
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);
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);
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(
} 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;
}
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;
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);
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);
}
}
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;
}
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)
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);
}
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);
}
}
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)) {
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)) {
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)
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)) {
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))
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);
}
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);
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))
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. */
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
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 */
}
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. */
}
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. */
}
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. */
*/
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;
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. */
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;
}
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;
}
/* 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);
}
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;
}
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;
}
#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)
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)
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. */
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;
}
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);
}
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)
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;
}
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);
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) {
+ lsa = 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
+ lsa = 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;
+}
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
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 */
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;
}
struct prefix_ipv4 asbr, p;
struct route_node *rn;
struct ospf_route *new, * or ;
- char buf1[INET_ADDRSTRLEN];
int ret;
assert(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
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);
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)
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);
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);
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)
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);
}
}
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)
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));
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)
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++)
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);
}
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);
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));
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;
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;
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"
"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;
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;
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;
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
"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
"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;
#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
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));
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;
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)
* 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);
}
}
}
/* 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);
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);
}
(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)
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);
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);
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
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);
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));
/* Handling Max age grace LSA.*/
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, Received a maxage GRACE-LSA from router %s",
+ "%s, Received a maxage GRACE-LSA from router %pI4",
__PRETTY_FUNCTION__,
- inet_ntoa(new->data->adv_router));
+ &new->data->adv_router);
if (current) {
ospf_process_maxage_grace_lsa(ospf, new, nbr);
} else {
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, Received a GRACE-LSA from router %s",
+ "%s, Received a GRACE-LSA from router %pI4",
__PRETTY_FUNCTION__,
- inet_ntoa(new->data->adv_router));
+ &new->data->adv_router);
if (ospf_process_grace_lsa(ospf, new, nbr)
== OSPF_GR_NOT_HELPER) {
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))
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));
* 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);
}
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);
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);
* 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);
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);
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);
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, Grace LSA received from %s, grace interval:%u, restartreason :%s",
- __PRETTY_FUNCTION__, inet_ntoa(restart_addr),
+ "%s, Grace LSA received from %pI4, grace interval:%u, restartreason :%s",
+ __PRETTY_FUNCTION__, &restart_addr,
grace_interval,
ospf_restart_reason2str(restart_reason));
if (!restarter) {
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, Restarter is not a nbr(%s) for this router.",
+ "%s, Restarter is not a nbr(%pI4) for this router.",
__PRETTY_FUNCTION__,
- inet_ntoa(restart_addr));
+ &restart_addr);
return OSPF_GR_NOT_HELPER;
}
} else
if (!IS_NBR_STATE_FULL(restarter)) {
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, This Neighbour %s is not in FULL state.",
- __PRETTY_FUNCTION__, inet_ntoa(restarter->src));
+ "%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;
} else {
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, This Router becomes a HELPER for the neighbour %s",
- __PRETTY_FUNCTION__, inet_ntoa(restarter->src));
+ "%s, This Router becomes a HELPER for the neighbour %pI4",
+ __PRETTY_FUNCTION__, &restarter->src);
}
/* Became a Helper to the RESTART neighbour.
if (IS_DEBUG_OSPF_GR_HELPER)
zlog_debug(
- "%s, Topo change detected due to lsa LSID:%s type:%d",
- __PRETTY_FUNCTION__, inet_ntoa(lsa->data->id),
+ "%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;
return;
if (IS_DEBUG_OSPF_GR_HELPER)
- zlog_debug("%s, Exiting from HELPER support to %s, due to %s",
- __PRETTY_FUNCTION__, inet_ntoa(nbr->src),
+ zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s",
+ __PRETTY_FUNCTION__, &nbr->src,
ospf_exit_reason2str(reason));
/* Reset helper status*/
}
if (IS_DEBUG_OSPF_GR_HELPER)
- zlog_debug("%s, GraceLSA received for neighbour %s.",
- __PRETTY_FUNCTION__, inet_ntoa(restartAddr));
+ 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
restartAddr = (struct grace_tlv_restart_addr *)tlvh;
sum += TLV_SIZE(tlvh);
- vty_out(vty, " Restarter address:%s\n",
- inet_ntoa(restartAddr->addr));
+ vty_out(vty, " Restarter address:%pI4\n",
+ &restartAddr->addr);
break;
default:
vty_out(vty, " Unknown TLV type %d\n",
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))) {
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);
}
}
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);
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);
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) {
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();
&& !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);
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))
}
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;
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)
{
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);
}
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(
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);
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(
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);
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)) {
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);
} 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) \
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);
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;
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);
}
}
if (ldp_sync_info &&
ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED &&
ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) {
- THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+ THREAD_OFF(ldp_sync_info->t_holddown);
ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
ospf_if_recalculate_output_cost(ifp);
}
* restore cost
*/
ols_debug("ldp_sync: Removed from if %s", ifp->name);
- 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))
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");
*/
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)
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);
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;
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);
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);
}
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);
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;
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);
}
/* 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);
}
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);
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);
}
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;
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);
}
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);
}
/* 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);
}
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);
}
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);
}
== 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;
}
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;
}
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;
}
"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++;
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;
}
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;
}
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;
}
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;
}
/* 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);
}
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++) {
(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.");
}
}
}
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);
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;
}
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(
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);
+ }
}
}
}
/* 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;
}
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;
}
/* 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);
}
/* 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:
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;
}
}
*/
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);
}
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))
} 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);
}
}
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;
}
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;
}
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);
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);
&& 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);
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;
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;
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);
/* 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:
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])
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);
}
}
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);
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;
+ }
+}
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 *);
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 */
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")
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 */
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 {
/* 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;
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);
}
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;
}
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;
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;
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;
}
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;
}
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
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));
/* Dont trigger NSM_InactivityTimer event , if the current
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. */
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));
}
{
/* 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),
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),
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_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);
}
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]);
*/
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),
#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) \
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);
/* 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));
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;
}
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);
* 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);
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)
&& 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;
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:
#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 \
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,
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);
}
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;
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;
}
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));
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(
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;
}
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;
}
/* 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;
!= 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;
}
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));
* 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 */
* 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 */
&& !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
!= 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;
}
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;
}
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"
*/
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);
}
}
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;
}
&& (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;
}
&& (!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);
}
* 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 */
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);
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;
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);
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;
}
}
&& 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;
}
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 ");
&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. */
}
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;
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(
/* 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;
}
/* 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;
}
&& 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;
}
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)
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;
}
}
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;
}
&& 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;
}
* 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;
}
* 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 */
!= 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;
}
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);
}
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;
}
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;
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;
}
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;
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;
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;
/* 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;
}
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;
}
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;
}
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;
}
== 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;
}
}
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];
&& (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);
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;
}
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(
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);
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);
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);
}
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);
}
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
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;
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)
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;
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);
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);
}
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);
}
/* 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);
}
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)
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",
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",
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",
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));
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));
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);
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);
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
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;
}
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,
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,
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;
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);
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;
}
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;
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);
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;
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);
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;
}
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);
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;
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),
}
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);
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)
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;
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);
}
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);
}
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;
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;
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);
}
}
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);
}
/*
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;
}
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)
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)
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);
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");
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;
}
char pref[19];
char sid[22];
char op[32];
+ char buf[PREFIX_STRLEN];
int indent = 0;
snprintfrr(pref, 19, "%pFX", (struct prefix *)&srp->prefv4);
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;
}
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;
}
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;
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",
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);
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();
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",
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)
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;
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)) {
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) {
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);
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);
}
/* 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;
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);
}
/* 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);
}
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);
}
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);
}
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);
}
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);
}
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);
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);
}
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;
}
#include <zebra.h>
#include <string.h>
+#include "printfrr.h"
#include "monotime.h"
#include "memory.h"
#include "thread.h"
#include "zclient.h"
#include <lib/json.h>
#include "defaults.h"
+#include "lib/printfrr.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
#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 },
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)
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;
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");
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;
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;
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);
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;
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);
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)) {
}
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");
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;
/* 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 */
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? */
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
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",
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]);
: "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);
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);
}
}
}
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;
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);
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));
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),
{
struct listnode *node;
struct ospf_interface *oi;
+ char buf[PREFIX_STRLEN];
json_object *json_vrf = NULL;
json_object *json_neighbor_sub = NULL;
"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);
}
}
bool use_json, json_object *json)
{
char timebuf[OSPF_TIME_DUMP_SIZE];
+ char buf[PREFIX_STRLEN];
json_object *json_sub = NULL;
if (use_json)
/* 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) {
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 &&
&& 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);
&& 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) {
/* 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) {
}
/* 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;
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:
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:
default:
break;
}
- vty_out(vty, "\n");
+
+ if (!json_lsa)
+ vty_out(vty, "\n");
}
return 0;
"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",
"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[] = {
"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);
+
+ if (!json)
+ vty_out(vty, " Number of Links: %d\n\n",
+ ntohs(rl->links));
+ else
+ json_object_int_add(json, "numOfLinks",
+ ntohs(rl->links));
- vty_out(vty, " Number of Links: %d\n\n", ntohs(rl->links));
+ show_ip_ospf_database_router_links(vty, rl, json);
- show_ip_ospf_database_router_links(vty, rl);
- vty_out(vty, "\n");
+ 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;
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");
}
#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,
}
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);
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);
}
/* 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;
}
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:
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);
+ }
- vty_out(vty, "\n");
+ show_lsa_summary(vty, lsa, self,
+ json_lsa);
+ }
+
+ 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:
}
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"
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);
+ }
+
+ ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
- vty_out(vty, "\n OSPF Router with ID (%s)\n\n",
- inet_ntoa(ospf->router_id));
+ /* 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;
}
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;
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 {
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);
}
}
- return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_ospf_database_max,
- show_ip_ospf_database_max_cmd,
- "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
- SHOW_STR
+ 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_database_max,
+ show_ip_ospf_database_max_cmd,
+ "show ip ospf [vrf <NAME|all>] database <max-age|self-originate> [json]",
+ SHOW_STR
IP_STR
"OSPF information\n"
VRF_CMD_HELP_STR
"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;
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);
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)
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 */
}
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;
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"
"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;
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);
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");
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);
}
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 */
}
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;
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);
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;
}
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)
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"
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;
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);
}
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);
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");
}
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 */
}
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));*/
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);
* 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);
+ 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--;
+ ospf->if_ospf_cli_count -= count;
}
}
+
return CMD_NOT_MY_INSTANCE;
}
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)) {
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);
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",
struct vty *vty = (struct vty *)arg;
static unsigned int count;
- vty_out(vty, "%-6s,", inet_ntoa(rtr->advRtrAddr));
+ vty_out(vty, "%-6pI4,", &rtr->advRtrAddr);
count++;
if (count % 5 == 0)
{
struct listnode *node;
struct ospf_interface *oi;
+ char buf[PREFIX_STRLEN];
json_object *json_vrf = NULL;
if (uj) {
/* Show Router ID. */
if (uj) {
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, "\n OSPF Router with ID (%s)\n\n",
- inet_ntoa(ospf->router_id));
+ vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n",
+ &ospf->router_id);
}
if (!uj) {
if (!uj) {
vty_out(vty, " Neighbour %d :\n", cnt);
- vty_out(vty, " Address : %s\n",
- inet_ntoa(nbr->address.u
- .prefix4));
- vty_out(vty, " Routerid : %s\n",
- inet_ntoa(nbr->router_id));
+ 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
json_neigh = json_object_new_object();
json_object_string_add(
json_neigh, "srcAddr",
- inet_ntoa(nbr->src));
+ inet_ntop(AF_INET, &nbr->src,
+ buf, sizeof(buf)));
json_object_string_add(
json_neigh, "routerid",
- inet_ntoa(nbr->router_id));
+ inet_ntop(AF_INET,
+ &nbr->router_id,
+ buf, sizeof(buf)));
json_object_int_add(
json_neigh,
"recvdGraceInterval",
.gr_restart_reason));
json_object_object_add(
json_neighbors,
- inet_ntoa(nbr->src),
+ 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;
}
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 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;
"============ 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();
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) {
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:
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",
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));
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;
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)) {
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");
"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
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",
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));
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;
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);
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(
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));
struct ospf *ospf = NULL;
struct listnode *node = NULL;
int count = 0;
+ char buf[PREFIX_STRLEN];
static const char header[] = "Name Id RouterId ";
if (uj) {
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);
}
}
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;
+ }
+ ret = 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. */
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");
}
}
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");
}
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");
}
" 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");
}
}
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");
}
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");
}
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");
}
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");
}
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");
}
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");
}
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");
}
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");
}
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;
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)
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");
/* 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)
|| 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 */
->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);
}
}
struct advRtr *rtr = backet->data;
struct vty *vty = (struct vty *)arg;
- vty_out(vty, " graceful-restart helper-only %s\n",
- inet_ntoa(rtr->advRtrAddr));
+ vty_out(vty, " graceful-restart helper-only %pI4\n",
+ &rtr->advRtrAddr);
return HASHWALK_CONTINUE;
}
vty_out(vty, " graceful-restart helper-only\n");
if (!ospf->strict_lsa_check)
- vty_out(vty, " no graceful-restart helper strict-lsa-checking\n");
+ 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");
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;
}
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
: "");
}
/* 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)
/* 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");
== 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. */
/* "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. */
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);
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);
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;
}
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)
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;
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;
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);
}
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)
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,
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;
}
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);
/* 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;
}
}
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;
}
/* 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;
}
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.
*/
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
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;
}
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;
}
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:
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);
+ }
}
}
}
} 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 */);
+ }
}
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);
+ }
+ }
}
}
}
}
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;
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)) {
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,
ospf_gr_helper_init(new);
+ ospf_asbr_external_aggregator_init(new);
+
QOBJ_REG(new, ospf);
new->fd = -1;
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 */
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;
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);
}
/* 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;
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);
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);
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);
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
*/
}
/* 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)
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))
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) {
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;
}
/* 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;
#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;
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);
{
zlog_notice("Terminating on signal");
+ pbr_vrf_terminate();
+
frr_fini();
exit(0);
{
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;
#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")
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);
+ }
+}
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
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)
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);
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",
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)
{
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;
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;
}
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)) {
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)) {
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);
}
}
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
#include "checksum.h"
#include "prefix.h"
#include "mtracebis_routeget.h"
-
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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)
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)) {
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);
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);
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);
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);
}
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 */
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,
struct in_addr ifaddr;
char uptime[10];
char timer[10];
+ char buf[PREFIX_STRLEN];
ifaddr = pim_ifp->primary_address;
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)
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"
char addr_str[INET_ADDRSTRLEN];
struct pim_assert_metric am;
struct in_addr ifaddr;
+ char buf[PREFIX_STRLEN];
ifaddr = pim_ifp->primary_address;
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)
struct in_addr ifaddr;
char pref_str[16];
char metr_str[16];
+ char buf[PREFIX_STRLEN];
ifaddr = pim_ifp->primary_address;
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,
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))
{
struct interface *ifp;
time_t now;
+ char buf[PREFIX_STRLEN];
json_object *json = NULL;
json_object *json_row = NULL;
? (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",
? (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);
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;
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;
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");
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;
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)
char uptime[10];
char expire[10];
char prune[10];
+ char buf[PREFIX_STRLEN];
ifaddr = pim_ifp->primary_address;
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);
}
struct in_addr ifaddr;
struct listnode *neighnode;
struct pim_neighbor *neigh;
+ char buf[PREFIX_STRLEN];
pim_ifp = ifp->info;
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);
}
}
}
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;
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");
bool uj)
{
struct interface *ifp;
+ char buf[PREFIX_STRLEN];
json_object *json = NULL;
json_object *json_row = NULL;
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);
} 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,
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;
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__);
++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));
}
}
++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));
}
}
} 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;
}
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);
}
}
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);
}
}
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);
}
}
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));
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;
}
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;
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;
}
/*
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;
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 */
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;
}
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);
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;
}
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);
}
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;
}
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;
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;
}
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;
/* 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;
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));
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;
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;
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;
}
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));
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;
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 */
"<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) */
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);
/*
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);
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;
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);
}
#include "hash.h"
#include "jhash.h"
+#include "lib/printfrr.h"
+
#include "pimd.h"
#include "pimd/pim_nht.h"
#include "log.h"
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;
}
{
struct pim_nexthop_cache *pnc;
char hash_name[64];
- char buf1[64];
pnc = XCALLOC(MTYPE_PIM_NEXTHOP_CACHE,
sizeof(struct pim_nexthop_cache));
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);
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) {
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
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 {
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) {
/*
}
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);
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);
}
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;
}
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);
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)
}
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);
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;
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);
}
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
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) {
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))
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);
}
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
"<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);
} 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);
}
}
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))
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);
/* 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);
}
/* 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,
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);
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)) {
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++;
}
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;
.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;
}
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",
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 ",
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(
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);
}
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);
}
}
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));
}
{
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);
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");
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");
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);
}
}
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");
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))
%{!?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 }
%if %{with_pam}
BuildRequires: pam-devel
%endif
-%if %{with_rpki}
-BuildRequires: librtr-devel >= 0.5
-%endif
%if "%{initsystem}" == "systemd"
BuildRequires: systemd
BuildRequires: systemd-devel
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}
%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"
%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}
%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
%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}
%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>
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);
}
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)
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 */
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);
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++)
/* 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;
}
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;
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));
}
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++;
#include "lib_errors.h"
#include "northbound_cli.h"
#include "network.h"
+#include "lib/printfrr.h"
#include "ripd/ripd.h"
#include "ripd/rip_nb.h"
(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;
}
(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;
}
== 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;
}
}
== 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;
}
}
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;
}
/* 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;
}
}
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;
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;
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;
}
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;
}
/* 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;
}
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;
}
== 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;
}
} 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;
}
}
!= 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)
}
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);
}
}
&& ((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;
}
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));
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);
}
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)
(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);
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));
/* 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;
}
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;
}
/* 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);
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(
}
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;
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;
}
}
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;
}
}
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);
}
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;
}
(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));
" 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
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;
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:
/* 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);
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);
#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
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);
}
}
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);
{
struct connected *ifc;
struct prefix *p;
- char buf[INET6_ADDRSTRLEN];
ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
zclient->ibuf, vrf_id);
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);
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;
}
/* Update timeout thread. */
- peer->t_timeout = NULL;
thread_add_timer(master, ripng_peer_timeout, peer,
RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout);
(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;
}
(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;
}
== 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;
}
}
== 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;
}
}
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));
}
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));
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));
/* 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. */
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. */
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;
}
}
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;
}
}
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;
}
&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);
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) {
/* 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
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);
"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;
}
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",
"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);
"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);
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);
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;
}
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);
}
}
/* Print the SPT and the corresponding routing table. */
isis_print_spftree(vty, spftree);
- isis_print_routes(vty, spftree, false);
+ isis_print_routes(vty, spftree, false, false);
/* Cleanup SPF tree. */
isis_spftree_del(spftree);
/* Print the post-convergence SPT and the correspoding routing table. */
isis_print_spftree(vty, spftree_pc);
- isis_print_routes(vty, spftree_self, true);
+ isis_print_routes(vty, spftree_self, false, true);
/* Cleanup everything. */
isis_spftree_del(spftree_self);
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ - rt3 16060 \r
\r
IS-IS paths to level-1 routers that speak IPv6\r
Vertex Type Metric Next-Hop Interface Parent\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 20 - rt2 - \r
- 2001:db8::3/128 20 - rt3 - \r
- 2001:db8::4/128 30 - rt2 - \r
- 2001:db8::5/128 30 - rt3 - \r
- 2001:db8::6/128 40 - rt2 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 0 - - - \r
+ 2001:db8::2/128 20 - rt2 implicit-null \r
+ 2001:db8::3/128 20 - rt3 implicit-null \r
+ 2001:db8::4/128 30 - rt2 16041 \r
+ 2001:db8::5/128 30 - rt3 16051 \r
+ 2001:db8::6/128 40 - rt2 16061 \r
+ - rt3 16061 \r
\r
test# test isis topology 2 root rt1 spf\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 25 - rt2 - \r
- 10.0.255.3/32 40 - rt3 - \r
- 10.0.255.4/32 20 - rt4 - \r
- 10.0.255.5/32 20 - rt5 - \r
- 10.0.255.6/32 30 - rt4 - \r
- - rt5 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 25 - rt2 implicit-null \r
+ 10.0.255.3/32 40 - rt3 implicit-null \r
+ 10.0.255.4/32 20 - rt4 implicit-null \r
+ 10.0.255.5/32 20 - rt5 implicit-null \r
+ 10.0.255.6/32 30 - rt4 16060 \r
+ - rt5 16060 \r
\r
IS-IS paths to level-1 routers that speak IPv6\r
Vertex Type Metric Next-Hop Interface Parent\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 25 - rt2 - \r
- 2001:db8::3/128 40 - rt3 - \r
- 2001:db8::4/128 20 - rt4 - \r
- 2001:db8::5/128 20 - rt5 - \r
- 2001:db8::6/128 30 - rt4 - \r
- - rt5 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 0 - - - \r
+ 2001:db8::2/128 25 - rt2 implicit-null \r
+ 2001:db8::3/128 40 - rt3 implicit-null \r
+ 2001:db8::4/128 20 - rt4 implicit-null \r
+ 2001:db8::5/128 20 - rt5 implicit-null \r
+ 2001:db8::6/128 30 - rt4 16061 \r
+ - rt5 16061 \r
\r
test# test isis topology 3 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 40 - rt2 - \r
- 10.0.255.6/32 40 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 40 - rt2 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
\r
test# test isis topology 4 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- 10.0.255.7/32 40 - rt3 - \r
- 10.0.255.8/32 50 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ 10.0.255.7/32 40 - rt3 16070 \r
+ 10.0.255.8/32 50 - rt2 16080 \r
\r
test# test isis topology 5 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- 10.0.255.7/32 40 - rt3 - \r
- 10.0.255.8/32 50 - rt2 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ 10.0.255.7/32 40 - rt3 16070 \r
+ 10.0.255.8/32 50 - rt2 16080 \r
+ - rt3 16080 \r
\r
test# test isis topology 6 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- - rt3 - \r
- 10.0.255.5/32 50 - rt2 - \r
- - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- - rt3 - \r
- 10.0.255.7/32 60 - rt2 - \r
- - rt3 - \r
- 10.0.255.8/32 50 - rt2 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ - rt3 16040 \r
+ 10.0.255.5/32 50 - rt2 16050 \r
+ - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ - rt3 16060 \r
+ 10.0.255.7/32 60 - rt2 16070 \r
+ - rt3 16070 \r
+ 10.0.255.8/32 50 - rt2 16080 \r
+ - rt3 16080 \r
\r
test# test isis topology 7 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- ------------------------------------------------------\r
- 10.0.255.2/32 40 - rt4 - \r
- 10.0.255.3/32 50 - rt4 - \r
- 10.0.255.4/32 20 - rt4 - \r
- 10.0.255.5/32 30 - rt4 - \r
- 10.0.255.6/32 40 - rt4 - \r
- 10.0.255.7/32 30 - rt4 - \r
- 10.0.255.8/32 40 - rt4 - \r
- 10.0.255.9/32 50 - rt4 - \r
- 10.0.255.10/32 50 - rt4 - \r
- 10.0.255.11/32 50 - rt4 - \r
- 10.0.255.12/32 60 - rt4 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 40 - rt4 16020 \r
+ 10.0.255.3/32 50 - rt4 16030 \r
+ 10.0.255.4/32 20 - rt4 implicit-null \r
+ 10.0.255.5/32 30 - rt4 16050 \r
+ 10.0.255.6/32 40 - rt4 16060 \r
+ 10.0.255.7/32 30 - rt4 16070 \r
+ 10.0.255.8/32 40 - rt4 16080 \r
+ 10.0.255.9/32 50 - rt4 16090 \r
+ 10.0.255.10/32 50 - rt4 16100 \r
+ 10.0.255.11/32 50 - rt4 16110 \r
+ 10.0.255.12/32 60 - rt4 16120 \r
\r
test# test isis topology 8 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- ------------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 30 - rt2 - \r
- 10.0.255.4/32 20 - rt4 - \r
- 10.0.255.5/32 30 - rt2 - \r
- 10.0.255.6/32 40 - rt2 - \r
- 10.0.255.7/32 30 - rt4 - \r
- 10.0.255.8/32 40 - rt2 - \r
- 10.0.255.9/32 50 - rt2 - \r
- 10.0.255.10/32 40 - rt4 - \r
- 10.0.255.11/32 50 - rt2 - \r
- 10.0.255.12/32 60 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 30 - rt2 16030 \r
+ 10.0.255.4/32 20 - rt4 implicit-null \r
+ 10.0.255.5/32 30 - rt2 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ 10.0.255.7/32 30 - rt4 16070 \r
+ 10.0.255.8/32 40 - rt2 16080 \r
+ 10.0.255.9/32 50 - rt2 16090 \r
+ 10.0.255.10/32 40 - rt4 16100 \r
+ 10.0.255.11/32 50 - rt2 16110 \r
+ 10.0.255.12/32 60 - rt2 16120 \r
\r
test# test isis topology 9 root rt1 spf\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 40 - rt2 - \r
- 10.0.255.6/32 60 - rt2 - \r
- 10.0.255.7/32 60 - rt2 - \r
- 10.0.255.8/32 60 - rt2 - \r
- 10.0.255.9/32 50 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 40 - rt2 16050 \r
+ 10.0.255.6/32 60 - rt2 16060 \r
+ 10.0.255.7/32 60 - rt2 16070 \r
+ 10.0.255.8/32 60 - rt2 16080 \r
+ 10.0.255.9/32 50 - rt2 16090 \r
\r
IS-IS paths to level-1 routers that speak IPv6\r
Vertex Type Metric Next-Hop Interface Parent\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 20 - rt2 - \r
- 2001:db8::3/128 20 - rt3 - \r
- 2001:db8::4/128 30 - rt2 - \r
- 2001:db8::5/128 40 - rt2 - \r
- 2001:db8::6/128 60 - rt2 - \r
- 2001:db8::7/128 60 - rt2 - \r
- 2001:db8::8/128 60 - rt2 - \r
- 2001:db8::9/128 50 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 0 - - - \r
+ 2001:db8::2/128 20 - rt2 implicit-null \r
+ 2001:db8::3/128 20 - rt3 implicit-null \r
+ 2001:db8::4/128 30 - rt2 16041 \r
+ 2001:db8::5/128 40 - rt2 16051 \r
+ 2001:db8::6/128 60 - rt2 16061 \r
+ 2001:db8::7/128 60 - rt2 16071 \r
+ 2001:db8::8/128 60 - rt2 16081 \r
+ 2001:db8::9/128 50 - rt2 16091 \r
\r
test# test isis topology 10 root rt1 spf\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 30 - rt3 - \r
- 10.0.255.4/32 30 - rt4 - \r
- 10.0.255.5/32 30 - rt2 - \r
- 10.0.255.6/32 40 - rt3 - \r
- 10.0.255.7/32 40 - rt4 - \r
- 10.0.255.8/32 40 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 30 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt4 implicit-null \r
+ 10.0.255.5/32 30 - rt2 16050 \r
+ 10.0.255.6/32 40 - rt3 20060 \r
+ 10.0.255.7/32 40 - rt4 16070 \r
+ 10.0.255.8/32 40 - rt2 16080 \r
\r
IS-IS paths to level-1 routers that speak IPv6\r
Vertex Type Metric Next-Hop Interface Parent\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 20 - rt2 - \r
- 2001:db8::3/128 30 - rt3 - \r
- 2001:db8::4/128 30 - rt4 - \r
- 2001:db8::5/128 30 - rt2 - \r
- 2001:db8::6/128 40 - rt3 - \r
- 2001:db8::7/128 40 - rt4 - \r
- 2001:db8::8/128 40 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 0 - - - \r
+ 2001:db8::2/128 20 - rt2 implicit-null \r
+ 2001:db8::3/128 30 - rt3 implicit-null \r
+ 2001:db8::4/128 30 - rt4 implicit-null \r
+ 2001:db8::5/128 30 - rt2 16051 \r
+ 2001:db8::6/128 40 - rt3 20061 \r
+ 2001:db8::7/128 40 - rt4 16071 \r
+ 2001:db8::8/128 40 - rt2 16081 \r
\r
test# test isis topology 11 root rt1 spf\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ - rt3 16060 \r
\r
IS-IS paths to level-1 routers that speak IPv6\r
Vertex Type Metric Next-Hop Interface Parent\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 20 - rt2 - \r
- 2001:db8::3/128 20 - rt3 - \r
- 2001:db8::4/128 30 - rt2 - \r
- 2001:db8::5/128 30 - rt3 - \r
- 2001:db8::6/128 40 - rt2 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 0 - - - \r
+ 2001:db8::2/128 20 - rt2 implicit-null \r
+ 2001:db8::3/128 20 - rt3 implicit-null \r
+ 2001:db8::4/128 30 - rt2 16041 \r
+ 2001:db8::5/128 30 - rt3 16051 \r
+ 2001:db8::6/128 40 - rt2 16061 \r
+ - rt3 16061 \r
\r
test# test isis topology 12 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- ------------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- 10.0.255.7/32 40 - rt3 - \r
- 10.0.255.8/32 50 - rt2 - \r
- 10.0.255.9/32 50 - rt3 - \r
- 10.0.255.10/32 60 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ 10.0.255.7/32 40 - rt3 16070 \r
+ 10.0.255.8/32 50 - rt2 16080 \r
+ 10.0.255.9/32 50 - rt3 16090 \r
+ 10.0.255.10/32 60 - rt2 16100 \r
\r
test# test isis topology 13 root rt1 spf ipv4-only\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- - rt3 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 30 - rt3 - \r
- 10.0.255.7/32 40 - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ - rt3 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 30 - rt3 16060 \r
+ 10.0.255.7/32 40 - rt3 16070 \r
\r
test# \r
test# test isis topology 4 root rt1 reverse-spf ipv4-only\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 20 - rt2 - \r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.4/32 30 - rt2 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt2 - \r
- 10.0.255.7/32 40 - rt3 - \r
- 10.0.255.8/32 50 - rt2 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.2/32 20 - rt2 implicit-null \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.4/32 30 - rt2 16040 \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt2 16060 \r
+ 10.0.255.7/32 40 - rt3 16070 \r
+ 10.0.255.8/32 50 - rt2 16080 \r
\r
test# test isis topology 11 root rt1 reverse-spf\r
IS-IS paths to level-1 routers that speak IP\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.3/32 20 - rt3 - \r
- 10.0.255.5/32 30 - rt3 - \r
- 10.0.255.6/32 40 - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 0 - - - \r
+ 10.0.255.3/32 20 - rt3 implicit-null \r
+ 10.0.255.5/32 30 - rt3 16050 \r
+ 10.0.255.6/32 40 - rt3 16060 \r
\r
IS-IS paths to level-1 routers that speak IPv6\r
Vertex Type Metric Next-Hop Interface Parent\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::3/128 20 - rt3 - \r
- 2001:db8::5/128 30 - rt3 - \r
- 2001:db8::6/128 40 - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 0 - - - \r
+ 2001:db8::3/128 20 - rt3 implicit-null \r
+ 2001:db8::5/128 30 - rt3 16051 \r
+ 2001:db8::6/128 40 - rt3 16061 \r
\r
test# \r
test# test isis topology 1 root rt1 ti-lfa system-id rt2\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 60 - rt3 16060 \r
- 10.0.255.4/32 50 - rt3 16060 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ --------------------------------------------------------\r
+ 10.0.255.2/32 60 - rt3 16060/16020 \r
+ 10.0.255.4/32 50 - rt3 16060/16040 \r
\r
P-space (self):\r
rt3\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 60 - rt3 16061 \r
- 2001:db8::4/128 50 - rt3 16061 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 2001:db8::2/128 60 - rt3 16061/16021 \r
+ 2001:db8::4/128 50 - rt3 16061/16041 \r
\r
test# test isis topology 2 root rt1 ti-lfa system-id rt3\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.3/32 60 - rt5 16050/18 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.3/32 60 - rt5 16050/18/16030 \r
\r
P-space (self):\r
rt2\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::3/128 60 - rt5 16051/19 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::3/128 60 - rt5 16051/19/16031 \r
\r
test# test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.4/32 65 - rt2 16020/18 \r
- 10.0.255.5/32 75 - rt2 16020/18 \r
- 10.0.255.6/32 75 - rt2 16020/18 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.4/32 65 - rt2 16020/18/16040 \r
+ 10.0.255.5/32 75 - rt2 16020/18/16050 \r
+ 10.0.255.6/32 75 - rt2 16020/18/16060 \r
\r
P-space (self):\r
rt2\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::4/128 65 - rt2 16021/19 \r
- 2001:db8::5/128 75 - rt2 16021/19 \r
- 2001:db8::6/128 75 - rt2 16021/19 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::4/128 65 - rt2 16021/19/16041 \r
+ 2001:db8::5/128 75 - rt2 16021/19/16051 \r
+ 2001:db8::6/128 75 - rt2 16021/19/16061 \r
\r
test# test isis topology 2 root rt5 ti-lfa system-id rt1 pseudonode-id 1\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.1/32 40 - rt6 16040 \r
- 10.0.255.2/32 55 - rt6 16040 \r
- 10.0.255.4/32 30 - rt6 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ --------------------------------------------------------\r
+ 10.0.255.1/32 40 - rt6 16040/16010 \r
+ 10.0.255.2/32 55 - rt6 16040/16020 \r
+ 10.0.255.4/32 30 - rt6 16040 \r
\r
P-space (self):\r
rt6\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::1/128 40 - rt6 16041 \r
- 2001:db8::2/128 55 - rt6 16041 \r
- 2001:db8::4/128 30 - rt6 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 2001:db8::1/128 40 - rt6 16041/16011 \r
+ 2001:db8::2/128 55 - rt6 16041/16021 \r
+ 2001:db8::4/128 30 - rt6 16041 \r
\r
test# test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only\r
P-space (self):\r
\r
Prefix Metric Interface Nexthop Label(s) \r
-----------------------------------------------------\r
- 10.0.255.1/32 50 - rt3 - \r
- - rt6 - \r
- 10.0.255.2/32 40 - rt6 - \r
- 10.0.255.4/32 30 - rt6 - \r
+ 10.0.255.1/32 50 - rt3 16010 \r
+ - rt6 16010 \r
+ 10.0.255.2/32 40 - rt6 16020 \r
+ 10.0.255.4/32 30 - rt6 16040 \r
\r
test# test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 100 - rt3 16050/17 \r
- 10.0.255.4/32 90 - rt3 16050/17 \r
- 10.0.255.6/32 80 - rt3 16050/17 \r
- 10.0.255.8/32 90 - rt3 16050/17 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.2/32 100 - rt3 16050/17/16020 \r
+ 10.0.255.4/32 90 - rt3 16050/17/16040 \r
+ 10.0.255.6/32 80 - rt3 16050/17/16060 \r
+ 10.0.255.8/32 90 - rt3 16050/17/16080 \r
\r
test# test isis topology 4 root rt4 ti-lfa system-id rt6 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.6/32 100 - rt2 16050/17 \r
- 10.0.255.8/32 110 - rt2 16050/17 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.6/32 100 - rt2 16050/17/16060 \r
+ 10.0.255.8/32 110 - rt2 16050/17/16080 \r
\r
test# test isis topology 5 root rt1 ti-lfa system-id rt2 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 80 - rt3 16080 \r
- 10.0.255.4/32 70 - rt3 16080 \r
- 10.0.255.6/32 60 - rt3 16080 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ --------------------------------------------------------\r
+ 10.0.255.2/32 80 - rt3 16080/16020 \r
+ 10.0.255.4/32 70 - rt3 16080/16040 \r
+ 10.0.255.6/32 60 - rt3 16080/16060 \r
\r
test# test isis topology 6 root rt4 ti-lfa system-id rt3 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.3/32 40 - rt2 16010 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ --------------------------------------------------------\r
+ 10.0.255.3/32 40 - rt2 16010/16030 \r
\r
test# test isis topology 7 root rt11 ti-lfa system-id rt8 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.1/32 60 - rt10 - \r
- 10.0.255.2/32 60 - rt12 16090 \r
- 10.0.255.3/32 70 - rt12 16090 \r
- 10.0.255.4/32 50 - rt10 - \r
- 10.0.255.5/32 50 - rt12 16090 \r
- 10.0.255.6/32 60 - rt12 16090 \r
- 10.0.255.7/32 40 - rt10 - \r
- 10.0.255.8/32 40 - rt12 16090 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ --------------------------------------------------------\r
+ 10.0.255.1/32 60 - rt10 16010 \r
+ 10.0.255.2/32 60 - rt12 16090/16020 \r
+ 10.0.255.3/32 70 - rt12 16090/16030 \r
+ 10.0.255.4/32 50 - rt10 16040 \r
+ 10.0.255.5/32 50 - rt12 16090/16050 \r
+ 10.0.255.6/32 60 - rt12 16090/16060 \r
+ 10.0.255.7/32 40 - rt10 16070 \r
+ 10.0.255.8/32 40 - rt12 16090/16080 \r
\r
test# test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- ------------------------------------------------------\r
- 10.0.255.1/32 60 - rt3 16020 \r
- 10.0.255.4/32 50 - rt3 16020 \r
- 10.0.255.5/32 40 - rt3 16020 \r
- 10.0.255.7/32 60 - rt9 - \r
- - rt3 - \r
- 10.0.255.8/32 50 - rt9 - \r
- - rt3 - \r
- 10.0.255.10/32 70 - rt9 - \r
- - rt3 - \r
- 10.0.255.11/32 60 - rt9 - \r
- - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ---------------------------------------------------------\r
+ 10.0.255.1/32 60 - rt3 16020/16010 \r
+ 10.0.255.4/32 50 - rt3 16020/16040 \r
+ 10.0.255.5/32 40 - rt3 16020/16050 \r
+ 10.0.255.7/32 60 - rt9 16070 \r
+ - rt3 16070 \r
+ 10.0.255.8/32 50 - rt9 16080 \r
+ - rt3 16080 \r
+ 10.0.255.10/32 70 - rt9 16100 \r
+ - rt3 16100 \r
+ 10.0.255.11/32 60 - rt9 16110 \r
+ - rt3 16110 \r
\r
test# test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- ------------------------------------------------------\r
- 10.0.255.1/32 100 - rt5 16110/17 \r
- 10.0.255.4/32 90 - rt5 16110/17 \r
- 10.0.255.7/32 80 - rt5 16110/17 \r
- 10.0.255.10/32 70 - rt5 16110/17 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 10.0.255.1/32 100 - rt5 16110/17/16010 \r
+ 10.0.255.4/32 90 - rt5 16110/17/16040 \r
+ 10.0.255.7/32 80 - rt5 16110/17/16070 \r
+ 10.0.255.10/32 70 - rt5 16110/17/16100 \r
\r
test# test isis topology 8 root rt2 ti-lfa system-id rt5 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- ------------------------------------------------------\r
- 10.0.255.5/32 40 - rt3 16060 \r
- 10.0.255.8/32 50 - rt3 16060 \r
- 10.0.255.9/32 60 - rt3 16060 \r
- 10.0.255.11/32 60 - rt3 16060 \r
- 10.0.255.12/32 70 - rt3 16060 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ---------------------------------------------------------\r
+ 10.0.255.5/32 40 - rt3 16060/16050 \r
+ 10.0.255.8/32 50 - rt3 16060/16080 \r
+ 10.0.255.9/32 60 - rt3 16060/16090 \r
+ 10.0.255.11/32 60 - rt3 16060/16110 \r
+ 10.0.255.12/32 70 - rt3 16060/16120 \r
\r
test# test isis topology 9 root rt1 ti-lfa system-id rt3\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.3/32 130 - rt2 16040/18 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.3/32 130 - rt2 16040/18/16030 \r
\r
P-space (self):\r
rt2\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::3/128 130 - rt2 16041/19 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::3/128 130 - rt2 16041/19/16031 \r
\r
test# test isis topology 9 root rt1 ti-lfa system-id rt2\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 130 - rt3 16030/18 \r
- 10.0.255.4/32 120 - rt3 16030/18 \r
- 10.0.255.5/32 130 - rt3 16030/18 \r
- 10.0.255.6/32 150 - rt3 16030/18 \r
- 10.0.255.7/32 150 - rt3 16030/18 \r
- 10.0.255.8/32 150 - rt3 16030/18 \r
- 10.0.255.9/32 140 - rt3 16030/18 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.2/32 130 - rt3 16030/18/16020 \r
+ 10.0.255.4/32 120 - rt3 16030/18/16040 \r
+ 10.0.255.5/32 130 - rt3 16030/18/16050 \r
+ 10.0.255.6/32 150 - rt3 16030/18/16060 \r
+ 10.0.255.7/32 150 - rt3 16030/18/16070 \r
+ 10.0.255.8/32 150 - rt3 16030/18/16080 \r
+ 10.0.255.9/32 140 - rt3 16030/18/16090 \r
\r
P-space (self):\r
rt3\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 130 - rt3 16031/19 \r
- 2001:db8::4/128 120 - rt3 16031/19 \r
- 2001:db8::5/128 130 - rt3 16031/19 \r
- 2001:db8::6/128 150 - rt3 16031/19 \r
- 2001:db8::7/128 150 - rt3 16031/19 \r
- 2001:db8::8/128 150 - rt3 16031/19 \r
- 2001:db8::9/128 140 - rt3 16031/19 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::2/128 130 - rt3 16031/19/16021 \r
+ 2001:db8::4/128 120 - rt3 16031/19/16041 \r
+ 2001:db8::5/128 130 - rt3 16031/19/16051 \r
+ 2001:db8::6/128 150 - rt3 16031/19/16061 \r
+ 2001:db8::7/128 150 - rt3 16031/19/16071 \r
+ 2001:db8::8/128 150 - rt3 16031/19/16081 \r
+ 2001:db8::9/128 140 - rt3 16031/19/16091 \r
\r
test# test isis topology 9 root rt9 ti-lfa system-id rt5\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.1/32 70 - rt6 16060/16 \r
- - rt7 16070/16 \r
- - rt8 16080/16 \r
- 10.0.255.2/32 60 - rt6 16060/16 \r
- - rt7 16070/16 \r
- - rt8 16080/16 \r
- 10.0.255.3/32 80 - rt6 16060/16 \r
- - rt7 16070/16 \r
- - rt8 16080/16 \r
- 10.0.255.4/32 50 - rt6 16060/16 \r
- - rt7 16070/16 \r
- - rt8 16080/16 \r
- 10.0.255.5/32 60 - rt6 16060/16 \r
- - rt7 16070/16 \r
- - rt8 16080/16 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32 70 - rt6 16060/16/16010 \r
+ - rt7 16070/16/16010 \r
+ - rt8 16080/16/16010 \r
+ 10.0.255.2/32 60 - rt6 16060/16/16020 \r
+ - rt7 16070/16/16020 \r
+ - rt8 16080/16/16020 \r
+ 10.0.255.3/32 80 - rt6 16060/16/16030 \r
+ - rt7 16070/16/16030 \r
+ - rt8 16080/16/16030 \r
+ 10.0.255.4/32 50 - rt6 16060/16/16040 \r
+ - rt7 16070/16/16040 \r
+ - rt8 16080/16/16040 \r
+ 10.0.255.5/32 60 - rt6 16060/16/16050 \r
+ - rt7 16070/16/16050 \r
+ - rt8 16080/16/16050 \r
\r
P-space (self):\r
rt6\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::1/128 70 - rt6 16061/17 \r
- - rt7 16071/17 \r
- - rt8 16081/17 \r
- 2001:db8::2/128 60 - rt6 16061/17 \r
- - rt7 16071/17 \r
- - rt8 16081/17 \r
- 2001:db8::3/128 80 - rt6 16061/17 \r
- - rt7 16071/17 \r
- - rt8 16081/17 \r
- 2001:db8::4/128 50 - rt6 16061/17 \r
- - rt7 16071/17 \r
- - rt8 16081/17 \r
- 2001:db8::5/128 60 - rt6 16061/17 \r
- - rt7 16071/17 \r
- - rt8 16081/17 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::1/128 70 - rt6 16061/17/16011 \r
+ - rt7 16071/17/16011 \r
+ - rt8 16081/17/16011 \r
+ 2001:db8::2/128 60 - rt6 16061/17/16021 \r
+ - rt7 16071/17/16021 \r
+ - rt8 16081/17/16021 \r
+ 2001:db8::3/128 80 - rt6 16061/17/16031 \r
+ - rt7 16071/17/16031 \r
+ - rt8 16081/17/16031 \r
+ 2001:db8::4/128 50 - rt6 16061/17/16041 \r
+ - rt7 16071/17/16041 \r
+ - rt8 16081/17/16041 \r
+ 2001:db8::5/128 60 - rt6 16061/17/16051 \r
+ - rt7 16071/17/16051 \r
+ - rt8 16081/17/16051 \r
\r
test# test isis topology 9 root rt9 ti-lfa system-id rt8\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.8/32 60 - rt5 16040/26 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.8/32 60 - rt5 16040/26/16080 \r
\r
P-space (self):\r
rt1\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::8/128 60 - rt5 16041/27 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::8/128 60 - rt5 16041/27/16081 \r
\r
test# test isis topology 10 root rt1 ti-lfa system-id rt2\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.2/32 110 - rt3 20060/18 \r
- - rt4 16070/18 \r
- 10.0.255.5/32 100 - rt3 20060/18 \r
- - rt4 16070/18 \r
- 10.0.255.8/32 90 - rt3 20060/18 \r
- - rt4 16070/18 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.2/32 110 - rt3 20060/18/16020 \r
+ - rt4 16070/18/16020 \r
+ 10.0.255.5/32 100 - rt3 20060/18/16050 \r
+ - rt4 16070/18/16050 \r
+ 10.0.255.8/32 90 - rt3 20060/18/16080 \r
+ - rt4 16070/18/16080 \r
\r
P-space (self):\r
rt3\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::2/128 110 - rt3 20061/19 \r
- - rt4 16071/19 \r
- 2001:db8::5/128 100 - rt3 20061/19 \r
- - rt4 16071/19 \r
- 2001:db8::8/128 90 - rt3 20061/19 \r
- - rt4 16071/19 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::2/128 110 - rt3 20061/19/16021 \r
+ - rt4 16071/19/16021 \r
+ 2001:db8::5/128 100 - rt3 20061/19/16051 \r
+ - rt4 16071/19/16051 \r
+ 2001:db8::8/128 90 - rt3 20061/19/16081 \r
+ - rt4 16071/19/16081 \r
\r
test# test isis topology 10 root rt1 ti-lfa system-id rt4\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.4/32 100 - rt2 16080/20 \r
- 10.0.255.7/32 90 - rt2 16080/20 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------\r
+ 10.0.255.4/32 100 - rt2 16080/20/16040 \r
+ 10.0.255.7/32 90 - rt2 16080/20/16070 \r
\r
P-space (self):\r
rt2\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::4/128 100 - rt2 16081/21 \r
- 2001:db8::7/128 90 - rt2 16081/21 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -------------------------------------------------------------\r
+ 2001:db8::4/128 100 - rt2 16081/21/16041 \r
+ 2001:db8::7/128 90 - rt2 16081/21/16071 \r
\r
test# test isis topology 11 root rt2 ti-lfa system-id rt4\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.1/32 60 - rt1 - \r
- 10.0.255.3/32 60 - rt3 - \r
- 10.0.255.4/32 80 - rt3 16050 \r
- 10.0.255.5/32 70 - rt3 - \r
- 10.0.255.6/32 80 - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32 60 - rt1 implicit-null \r
+ 10.0.255.3/32 60 - rt3 implicit-null \r
+ 10.0.255.4/32 80 - rt3 16050/16040 \r
+ 10.0.255.5/32 70 - rt3 16050 \r
+ 10.0.255.6/32 80 - rt3 16060 \r
\r
P-space (self):\r
\r
\r
IS-IS L1 IPv6 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -------------------------------------------------------\r
- 2001:db8::1/128 60 - rt1 - \r
- 2001:db8::3/128 60 - rt3 - \r
- 2001:db8::4/128 80 - rt3 16051 \r
- 2001:db8::5/128 70 - rt3 - \r
- 2001:db8::6/128 80 - rt3 - \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128 60 - rt1 implicit-null \r
+ 2001:db8::3/128 60 - rt3 implicit-null \r
+ 2001:db8::4/128 80 - rt3 16051/16041 \r
+ 2001:db8::5/128 70 - rt3 16051 \r
+ 2001:db8::6/128 80 - rt3 16061 \r
\r
test# test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------------\r
- 10.0.255.3/32 750 - rt2 16080/17/16/16 \r
- 10.0.255.5/32 350 - rt2 16080/17/16 \r
- 10.0.255.7/32 150 - rt2 16080/17 \r
- 10.0.255.9/32 160 - rt2 16080/17/18 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ -----------------------------------------------------------------\r
+ 10.0.255.3/32 750 - rt2 16080/17/16/16/16030 \r
+ 10.0.255.5/32 350 - rt2 16080/17/16/16050 \r
+ 10.0.255.7/32 150 - rt2 16080/17/16070 \r
+ 10.0.255.9/32 160 - rt2 16080/17/18/16090 \r
\r
test# test isis topology 13 root rt1 ti-lfa system-id rt3 ipv4-only\r
P-space (self):\r
\r
IS-IS L1 IPv4 routing table:\r
\r
- Prefix Metric Interface Nexthop Label(s) \r
- -----------------------------------------------------\r
- 10.0.255.3/32 40 - rt2 16040 \r
- 10.0.255.5/32 50 - rt2 16040 \r
- 10.0.255.6/32 50 - rt2 16040 \r
- 10.0.255.7/32 60 - rt2 16040 \r
+ Prefix Metric Interface Nexthop Label(s) \r
+ --------------------------------------------------------\r
+ 10.0.255.3/32 40 - rt2 16040/16030 \r
+ 10.0.255.5/32 50 - rt2 16040/16050 \r
+ 10.0.255.6/32 50 - rt2 16040/16060 \r
+ 10.0.255.7/32 60 - rt2 16040/16070 \r
\r
test#
end.
"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;
}
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!",
!= 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);
static void print_subtree(struct route_node *rn, const char *legend,
int indent_level)
{
- char buf[PREFIX2STR_BUFFER];
int i;
/*
printf(" ");
}
- prefix2str(&rn->p, buf, sizeof(buf));
- printf("%s: %s", legend, buf);
+ printf("%s: %pFX", legend, &rn->p);
if (!rn->info) {
printf(" (internal)");
}
continue;
XFREE(MTYPE_TMP, timers[index]->arg);
- thread_cancel(timers[index]);
+ thread_cancel(&timers[index]);
timers[index] = NULL;
timers_pending--;
}
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);
int index;
index = prng_rand(prng) % SCHEDULE_TIMERS;
- if (timers[index])
- thread_cancel(timers[index]);
+ thread_cancel(&timers[index]);
timers[index] = NULL;
}
isis bfd
!
router isis 1
+ lsp-gen-interval 2
net 49.0000.0000.0000.0001.00
is-type level-1
!
isis hello-multiplier 3
!
router isis 1
+ lsp-gen-interval 2
net 49.0000.0000.0000.0002.00
is-type level-1
!
isis hello-multiplier 3
!
router isis 1
+ lsp-gen-interval 2
net 49.0000.0000.0000.0003.00
is-type level-1
!
isis hello-multiplier 3
!
router isis 1
+ lsp-gen-interval 2
net 49.0000.0000.0000.0004.00
is-type level-1
!
isis hello-multiplier 3
!
router isis 1
+ lsp-gen-interval 2
net 49.0000.0000.0000.0005.00
is-type level-1
!
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
!
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
!
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:]
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
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
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
debug bgp evpn mh route
debug bgp zebra
!
-!
router bgp 65005
bgp router-id 192.168.100.18
no bgp ebgp-requires-policy
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
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)
"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
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;
}
}
+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
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
!
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."
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()
--- /dev/null
+!
+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
+!
--- /dev/null
+!
+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
+!
--- /dev/null
+!
+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
+!
--- /dev/null
+!
+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
+!
--- /dev/null
+!
+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
+!
+
--- /dev/null
+!
+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
+!
--- /dev/null
+#!/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))
--- /dev/null
+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
+!
--- /dev/null
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
--- /dev/null
+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
+!
--- /dev/null
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
--- /dev/null
+#!/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))
+++ /dev/null
-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 route-map default
- exit-address-family
-!
-route-map default permit 10
- set metric 123
-!
+++ /dev/null
-!
-interface lo
- ip address 172.16.255.254/32
-!
-interface r1-eth0
- ip address 192.168.255.1/24
-!
-ip forwarding
-!
+++ /dev/null
-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
-!
+++ /dev/null
-!
-interface r2-eth0
- ip address 192.168.255.2/24
-!
-ip forwarding
-!
+++ /dev/null
-#!/usr/bin/env python
-
-#
-# bgp_default-originate_route-map.py
-# Part of NetDEF Topology Tests
-#
-# Copyright (c) 2019 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.
-#
-
-"""
-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
-"""
-
-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=60, 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)
-
- 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))
--- /dev/null
+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
+!
--- /dev/null
+!
+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
+!
--- /dev/null
+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
+!
--- /dev/null
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
--- /dev/null
+#!/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))
--- /dev/null
+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
+!
--- /dev/null
+!
+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
+!
--- /dev/null
+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
+!
--- /dev/null
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
--- /dev/null
+#!/usr/bin/env python
+
+# Copyright (c) 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 match operations.
+And verify if set operations work as well.
+"""
+
+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))
--- /dev/null
+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 route-map default
+ exit-address-family
+!
+route-map default permit 10
+ set metric 123
+!
--- /dev/null
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
--- /dev/null
+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
+!
--- /dev/null
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
--- /dev/null
+#!/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))
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
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
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
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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)",
},
{
"type":"SR (IS-IS)",
- "outLabel":16050,
+ "outLabel":17050,
"installed":true,
- "nexthop":"10.0.2.4"
+ "nexthop":"10.0.1.3"
}
]
},
"nexthops":[
{
"type":"SR (IS-IS)",
- "outLabel":17051,
+ "outLabel":16051,
"installed":true,
- "interface":"eth-sw1"
+ "interface":"eth-rt4-1"
},
{
"type":"SR (IS-IS)",
},
{
"type":"SR (IS-IS)",
- "outLabel":16051,
+ "outLabel":17051,
"installed":true,
- "interface":"eth-rt4-1"
+ "interface":"eth-sw1"
}
]
},
"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"
}
]
},
"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"
}
]
}
]
}
],
+ "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",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
}
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
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
}
]
},
"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"
}
]
},
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"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-rt5-1",
+ "active":true,
+ "labels":[
+ 16101
+ ]
+ },
+ {
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
+ 16101
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16061
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16061
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
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
!
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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)",
"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
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"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
+ }
+ ]
}
}
"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",
]
}
],
+ "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",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16051
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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)",
"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"
}
]
},
"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
}
]
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"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
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"installed":true
}
]
+ },
+ "16101":{
+ "inLabel":16101,
+ "installed":true,
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"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
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"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
}
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"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
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"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
+ }
+ ]
}
}
"metric":30,
"nexthops":[
{
+ "fib":true,
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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)",
"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"
}
]
},
"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
+ }
+ ]
}
}
!
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
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
!
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
]
}
],
- "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
+ ]
}
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
]
}
],
- "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
}
]
}
"installed":true
}
]
+ },
+ "16101":{
+ "inLabel":16101,
+ "installed":true,
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true
+ }
+ ]
}
}
]
}
],
+ "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",
]
}
],
- "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
+ ]
}
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
]
}
],
- "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
+ ]
}
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
]
}
],
- "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
+ ]
}
]
}
"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
+ }
+ ]
}
}
]
}
],
+ "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",
]
}
],
- "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
+ ]
}
]
}
"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
+ }
+ ]
}
}
!
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
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
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
"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
+ ]
}
]
}
"ip":"10.0.7.4",
"afi":"ipv4",
"interfaceName":"eth-rt4",
- "active":true
+ "active":true,
+ "labels":[
+ 16020
+ ]
}
]
}
"ip":"10.0.8.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
- "active":true
+ "active":true,
+ "labels":[
+ 16030
+ ]
}
]
}
"ip":"10.0.7.4",
"afi":"ipv4",
"interfaceName":"eth-rt4",
- "active":true
+ "active":true,
+ "labels":[
+ 16040
+ ]
}
]
}
"ip":"10.0.8.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
- "active":true
+ "active":true,
+ "labels":[
+ 16050
+ ]
}
]
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"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
+ ]
}
]
}
"fib":true,
"afi":"ipv6",
"interfaceName":"eth-rt4",
- "active":true
+ "active":true,
+ "labels":[
+ 16021
+ ]
}
]
}
"fib":true,
"afi":"ipv6",
"interfaceName":"eth-rt5",
- "active":true
+ "active":true,
+ "labels":[
+ 16031
+ ]
}
]
}
"fib":true,
"afi":"ipv6",
"interfaceName":"eth-rt4",
- "active":true
+ "active":true,
+ "labels":[
+ 16041
+ ]
}
]
}
"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
+ ]
}
]
}
{
+ "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"
+ }
+ ]
+ }
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true
},
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"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-rt4",
+ "active":true,
+ "labels":[
+ 16101
+ ]
+ },
+ {
+ "fib":true,
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
+ "active":true,
+ "labels":[
+ 16101
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
}
]
}
+ ],
+ "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
+ ]
+ }
+ ]
+ }
]
}
"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"
+ }
+ ]
}
}
---- rt1/step3/show_ip_route.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step4/show_ip_route.ref 2020-08-31 22:42:48.831561460 -0300
+--- 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",
---- rt1/step3/show_ipv6_route.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step4/show_ipv6_route.ref 2020-08-31 22:42:48.831561460 -0300
+--- 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",
---- rt1/step3/show_mpls_table.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step4/show_mpls_table.ref 2020-08-31 22:42:48.831561460 -0300
+--- 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 @@
}
]
---- rt1/step4/show_ip_route.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step5/show_ip_route.ref 2020-08-31 22:42:48.831561460 -0300
+--- 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",
---- rt1/step4/show_ipv6_route.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step5/show_ipv6_route.ref 2020-08-31 22:42:48.831561460 -0300
+--- 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",
---- rt1/step4/show_mpls_table.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step5/show_mpls_table.ref 2020-08-31 22:42:48.831561460 -0300
+--- 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 @@
}
]
---- rt1/step6/show_ip_route.ref 2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step7/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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",
---- rt1/step6/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step7/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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",
---- rt1/step6/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step7/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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 @@
}
]
---- rt1/step7/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step8/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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",
---- rt1/step7/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step8/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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",
---- rt1/step7/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step8/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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 @@
}
]
---- rt1/step8/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step9/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
---- rt1/step8/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step9/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
---- rt1/step8/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step9/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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 @@
}
]
"interfaceName":"eth-rt4-1",
"active":true,
"labels":[
- 16050
+ 16050,
+ 16010
]
},
{
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
- 16050
+ 16050,
+ 16010
]
}
]
"interfaceName":"eth-rt4-1",
"active":true,
"labels":[
- 16050
+ 16050,
+ 16030
]
},
{
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
- 16050
+ 16050,
+ 16030
]
}
]
"afi":"ipv4",
"interfaceName":"eth-rt4-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
"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
+ ]
+ }
]
}
],
"afi":"ipv4",
"interfaceName":"eth-rt4-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16060
]
"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
+ }
]
}
],
"ip":"10.0.2.4",
"afi":"ipv4",
"interfaceName":"eth-rt4-1",
- "active":true
+ "active":true,
+ "labels":[
+ 16050
+ ]
},
{
"ip":"10.0.3.4",
"afi":"ipv4",
"interfaceName":"eth-rt4-2",
- "active":true
+ "active":true,
+ "labels":[
+ 16050
+ ]
}
]
}
{
"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
+ ]
}
]
}
"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
+ ]
}
]
}
"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,
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "ip":"10.0.1.3",
+ "afi":"ipv4",
+ "interfaceName":"eth-sw1",
"active":true
}
]
"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
+ ]
}
]
}
"interfaceName":"eth-rt4-1",
"active":true,
"labels":[
- 16051
+ 16051,
+ 16011
]
},
{
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
- 16051
+ 16051,
+ 16011
]
}
]
"interfaceName":"eth-rt4-1",
"active":true,
"labels":[
- 16051
+ 16051,
+ 16031
]
},
{
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
- 16051
+ 16051,
+ 16031
]
}
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-1",
+ "interfaceName":"eth-rt4-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+ 16051,
+ 16041
+ ]
+ }
]
}
],
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-1",
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt4-2",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
"active":true,
"labels":[
16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-1",
+ "interfaceName":"eth-rt4-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16061
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16061
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-sw1",
+ "active":true
+ }
]
}
]
"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"
}
]
},
"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"
+ "interface":"eth-rt4-1",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16051,
+ "interface":"eth-sw1"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16060,
"installed":true,
- "nexthop":"10.0.3.4"
+ "nexthop":"10.0.3.4",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":16060,
"installed":true,
- "nexthop":"10.0.2.4"
+ "nexthop":"10.0.2.4",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "nexthop":"10.0.1.3"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16061,
"installed":true,
- "interface":"eth-rt4-2"
+ "interface":"eth-rt4-2",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":16061,
"installed":true,
- "interface":"eth-rt4-1"
+ "interface":"eth-rt4-1",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "interface":"eth-sw1"
}
]
}
---- rt2/step1/show_ip_route.ref 2020-08-31 15:36:25.999825589 -0300
-+++ rt2/step2/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -15,34 +15,10 @@
+--- 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,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16010
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16010
- ]
- }
]
}
],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16030
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16030
- ]
- }
]
}
],
-@@ -212,34 +164,12 @@
+@@ -248,40 +196,12 @@
{
"ip":"10.0.1.1",
"afi":"ipv4",
- "ip":"10.0.2.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-1",
-- "active":true
+- "active":true,
+- "labels":[
+- 16050
+- ]
- },
- {
- "ip":"10.0.3.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-2",
-- "active":true
+- "active":true,
+- "labels":[
+- 16050
+- ]
+ "interfaceName":"eth-sw1"
}
]
}
-@@ -301,24 +231,6 @@
+@@ -377,24 +297,6 @@
"ip":"10.0.1.3",
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true
}
]
-@@ -339,24 +251,6 @@
+@@ -415,24 +317,6 @@
"ip":"10.0.1.3",
"afi":"ipv4",
"interfaceName":"eth-sw1",
---- rt2/step1/show_ipv6_route.ref 2020-08-31 15:36:25.999825589 -0300
-+++ rt2/step2/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -14,32 +14,10 @@
+--- 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,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16011
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16011
- ]
- }
]
}
],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16031
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16031
- ]
- }
]
---- rt2/step1/show_mpls_table.ref 2020-08-31 15:36:25.999825589 -0300
-+++ rt2/step2/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
---- rt2/step2/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step3/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -15,10 +15,34 @@
+--- 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,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16010
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16010
+ ]
+ }
]
}
],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16030
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16030
+ ]
+ }
]
}
],
-@@ -164,12 +212,34 @@
+@@ -196,12 +248,40 @@
{
"ip":"10.0.1.1",
"afi":"ipv4",
+ "ip":"10.0.2.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4-1",
-+ "active":true
++ "active":true,
++ "labels":[
++ 16050
++ ]
+ },
+ {
+ "ip":"10.0.3.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4-2",
-+ "active":true
++ "active":true,
++ "labels":[
++ 16050
++ ]
}
]
}
-@@ -231,6 +301,24 @@
+@@ -297,6 +377,24 @@
"ip":"10.0.1.3",
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true
}
]
-@@ -251,6 +339,24 @@
+@@ -317,6 +415,24 @@
"ip":"10.0.1.3",
"afi":"ipv4",
"interfaceName":"eth-sw1",
---- rt2/step2/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step3/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -14,10 +14,32 @@
+--- 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,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16011
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16011
+ ]
+ }
]
}
],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16031
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16031
+ ]
+ }
]
---- rt2/step2/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step3/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
---- rt2/step3/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step4/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -15,34 +15,10 @@
+--- 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,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16010
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16010
- ]
- }
]
}
],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16030
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16030
- ]
- }
]
}
],
-@@ -108,20 +60,14 @@
- "ip":"10.0.2.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-1",
-- "active":true,
+@@ -115,9 +63,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
- "labels":[
- 3
-- ]
-+ "active":true
+ ]
},
{
- "fib":true,
- "ip":"10.0.3.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-2",
-- "active":true,
+@@ -128,9 +73,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
- "labels":[
- 3
-- ]
-+ "active":true
- }
- ]
- }
-@@ -153,7 +99,7 @@
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
-+ 3
]
- },
- {
-@@ -163,7 +109,7 @@
- "interfaceName":"eth-rt4-2",
+ }
+ ],
+@@ -141,8 +83,7 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
-- 16050
-+ 3
+- 16050,
+- 16040
++ 16050
]
}
]
-@@ -184,20 +130,14 @@
+@@ -173,20 +114,14 @@
"ip":"10.0.2.4",
"afi":"ipv4",
"interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16060
+- 16050
- ]
+ "active":true
},
"interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16060
+- 16050
- ]
+ "active":true
}
]
}
-@@ -212,34 +152,12 @@
+@@ -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",
- "ip":"10.0.2.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-1",
-- "active":true
+- "active":true,
+- "labels":[
+- 16050
+- ]
- },
- {
- "ip":"10.0.3.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-2",
-- "active":true
+- "active":true,
+- "labels":[
+- 16050
+- ]
+ "interfaceName":"eth-sw1"
}
]
---- rt2/step3/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step4/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -14,32 +14,10 @@
+--- 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,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16011
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16011
- ]
- }
]
}
],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16031
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16031
- ]
- }
]
}
],
-@@ -101,19 +57,13 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt4-1",
-- "active":true,
+@@ -108,9 +60,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
- "labels":[
- 3
-- ]
-+ "active":true
+ ]
},
{
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt4-2",
-- "active":true,
+@@ -120,9 +69,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
- "labels":[
- 3
-- ]
-+ "active":true
- }
- ]
- }
-@@ -134,7 +84,7 @@
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
-+ 3
]
- },
- {
-@@ -152,7 +102,7 @@
- "interfaceName":"eth-rt4-2",
+ }
+ ],
+@@ -132,8 +78,7 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
-- 16051
-+ 3
+- 16051,
+- 16041
++ 16051
]
}
]
-@@ -172,19 +122,13 @@
+@@ -162,19 +107,13 @@
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-1",
+ "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16061
+- 16051
- ]
+ "active":true
},
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16061
+- 16051
- ]
+ "active":true
}
]
}
+@@ -196,9 +135,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
+- "labels":[
+- 16061
+ ]
+ },
+ {
+@@ -208,9 +144,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
+- "labels":[
+- 16061
+ ]
+ }
+ ],
---- rt2/step3/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step4/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
}
]
},
-@@ -91,59 +43,7 @@
+@@ -91,84 +43,6 @@
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
- "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"
- }
- ]
- },
- "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"
-+ "interface":"eth-sw1"
- }
- ]
- },
-@@ -153,13 +53,13 @@
- "nexthops":[
- {
- "type":"SR (IS-IS)",
-- "outLabel":16050,
-+ "outLabel":3,
- "installed":true,
- "nexthop":"10.0.3.4"
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16050,
-+ "outLabel":3,
- "installed":true,
- "nexthop":"10.0.2.4"
- },
-@@ -177,13 +77,13 @@
- "nexthops":[
- {
- "type":"SR (IS-IS)",
-- "outLabel":16051,
-+ "outLabel":3,
- "installed":true,
- "interface":"eth-rt4-2"
- },
- {
- "type":"SR (IS-IS)",
+- "interface":"eth-rt4-1",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
- "outLabel":16051,
-+ "outLabel":3,
- "installed":true,
- "interface":"eth-rt4-1"
- },
-@@ -194,41 +94,5 @@
"interface":"eth-sw1"
}
]
-- },
-- "16060":{
-- "inLabel":16060,
-- "installed":true,
-- "nexthops":[
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":16060,
-- "installed":true,
+@@ -181,18 +55,6 @@
+ "type":"SR (IS-IS)",
+ "outLabel":16050,
+ "installed":true,
- "nexthop":"10.0.3.4"
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16060,
+- "outLabel":16050,
- "installed":true,
- "nexthop":"10.0.2.4"
-- }
-- ]
-- },
-- "16061":{
-- "inLabel":16061,
-- "installed":true,
-- "nexthops":[
+- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16061,
+- "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":16061,
+- "outLabel":16051,
- "installed":true,
- "interface":"eth-rt4-1"
-- }
-- ]
- }
- }
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16051,
+ "installed":true,
+ "interface":"eth-sw1"
+ }
---- rt2/step4/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step5/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -15,10 +15,34 @@
+--- 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,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16010
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16010
+ ]
+ }
]
}
],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16030
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16030
+ ]
+ }
]
}
],
-@@ -60,14 +108,20 @@
- "ip":"10.0.2.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-1",
-- "active":true
-+ "active":true,
+@@ -63,6 +115,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
+ "labels":[
+ 3
-+ ]
+ ]
},
{
- "fib":true,
- "ip":"10.0.3.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-2",
-- "active":true
-+ "active":true,
+@@ -73,6 +128,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
+ "labels":[
+ 3
-+ ]
- }
- ]
- }
-@@ -99,7 +153,7 @@
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 3
-+ 16050
]
- },
- {
-@@ -109,7 +163,7 @@
- "interfaceName":"eth-rt4-2",
+ }
+ ],
+@@ -83,7 +141,8 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
-- 3
-+ 16050
+- 16050
++ 16050,
++ 16040
]
}
]
-@@ -130,14 +184,20 @@
+@@ -114,14 +173,20 @@
"ip":"10.0.2.4",
"afi":"ipv4",
"interfaceName":"eth-rt4-1",
- "active":true
+ "active":true,
+ "labels":[
-+ 16060
++ 16050
+ ]
},
{
- "active":true
+ "active":true,
+ "labels":[
-+ 16060
++ 16050
+ ]
}
]
}
-@@ -152,12 +212,34 @@
+@@ -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",
+ "ip":"10.0.2.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4-1",
-+ "active":true
++ "active":true,
++ "labels":[
++ 16050
++ ]
+ },
+ {
+ "ip":"10.0.3.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4-2",
-+ "active":true
++ "active":true,
++ "labels":[
++ 16050
++ ]
}
]
}
---- rt2/step4/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step5/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -14,10 +14,32 @@
+--- 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,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16011
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16011
+ ]
+ }
]
}
],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16031
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16031
+ ]
+ }
]
}
],
-@@ -57,13 +101,19 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt4-1",
-- "active":true
-+ "active":true,
+@@ -60,6 +108,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
+ "labels":[
+ 3
-+ ]
+ ]
},
{
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt4-2",
-- "active":true
-+ "active":true,
+@@ -69,6 +120,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
+ "labels":[
+ 3
-+ ]
- }
- ]
- }
-@@ -84,7 +134,7 @@
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 3
-+ 16051
]
- },
- {
-@@ -102,7 +152,7 @@
- "interfaceName":"eth-rt4-2",
+ }
+ ],
+@@ -78,7 +132,8 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
-- 3
-+ 16051
+- 16051
++ 16051,
++ 16041
]
}
]
-@@ -122,13 +172,19 @@
+@@ -107,13 +162,19 @@
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-1",
+ "interfaceName":"eth-rt4-2",
- "active":true
+ "active":true,
+ "labels":[
-+ 16061
++ 16051
+ ]
},
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
- "active":true
+ "active":true,
+ "labels":[
-+ 16061
++ 16051
+ ]
}
]
}
+@@ -135,6 +196,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
++ "labels":[
++ 16061
+ ]
+ },
+ {
+@@ -144,6 +208,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
++ "labels":[
++ 16061
+ ]
+ }
+ ],
---- rt2/step4/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step5/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
}
]
},
-@@ -43,12 +91,28 @@
+@@ -43,6 +91,84 @@
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
-- "interface":"eth-sw1"
+ "interface":"eth-sw1",
+ "backupIndex":[
+ 0,
+ "type":"SR (IS-IS)",
+ "outLabel":16051,
+ "interface":"eth-rt4-2"
- }
- ]
- },
-- "16050":{
-- "inLabel":16050,
-+ "16040":{
-+ "inLabel":16040,
- "installed":true,
- "nexthops":[
- {
-@@ -62,6 +126,42 @@
- "outLabel":3,
- "installed":true,
- "nexthop":"10.0.2.4"
+ }
+ ]
+ },
-+ "16041":{
-+ "inLabel":16041,
++ "16040":{
++ "inLabel":16040,
+ "installed":true,
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
-+ "interface":"eth-rt4-2"
++ "nexthop":"10.0.3.4",
++ "backupIndex":[
++ 0
++ ]
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
-+ "interface":"eth-rt4-1"
++ "nexthop":"10.0.2.4",
++ "backupIndex":[
++ 0
++ ]
++ }
++ ],
++ "backupNexthops":[
++ {
++ "type":"SR (IS-IS)",
++ "outLabel":16050,
++ "nexthop":"10.0.1.3"
+ }
+ ]
+ },
-+ "16050":{
-+ "inLabel":16050,
++ "16041":{
++ "inLabel":16041,
+ "installed":true,
+ "nexthops":[
+ {
+ "type":"SR (IS-IS)",
-+ "outLabel":16050,
++ "outLabel":3,
+ "installed":true,
-+ "nexthop":"10.0.3.4"
++ "interface":"eth-rt4-2",
++ "backupIndex":[
++ 0
++ ]
+ },
+ {
+ "type":"SR (IS-IS)",
-+ "outLabel":16050,
++ "outLabel":3,
+ "installed":true,
-+ "nexthop":"10.0.2.4"
- },
- {
- "type":"SR (IS-IS)",
-@@ -77,13 +177,13 @@
- "nexthops":[
- {
- "type":"SR (IS-IS)",
-- "outLabel":3,
-+ "outLabel":16051,
- "installed":true,
- "interface":"eth-rt4-2"
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":3,
++ "interface":"eth-rt4-1",
++ "backupIndex":[
++ 0
++ ]
++ }
++ ],
++ "backupNexthops":[
++ {
++ "type":"SR (IS-IS)",
+ "outLabel":16051,
- "installed":true,
- "interface":"eth-rt4-1"
- },
-@@ -94,5 +194,41 @@
"interface":"eth-sw1"
}
]
-+ },
-+ "16060":{
-+ "inLabel":16060,
-+ "installed":true,
-+ "nexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":16060,
-+ "installed":true,
+@@ -55,6 +181,18 @@
+ "type":"SR (IS-IS)",
+ "outLabel":16050,
+ "installed":true,
+ "nexthop":"10.0.3.4"
+ },
+ {
+ "type":"SR (IS-IS)",
-+ "outLabel":16060,
++ "outLabel":16050,
+ "installed":true,
+ "nexthop":"10.0.2.4"
-+ }
-+ ]
-+ },
-+ "16061":{
-+ "inLabel":16061,
-+ "installed":true,
-+ "nexthops":[
++ },
+ {
+ "type":"SR (IS-IS)",
-+ "outLabel":16061,
++ "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":16061,
++ "outLabel":16051,
+ "installed":true,
+ "interface":"eth-rt4-1"
-+ }
-+ ]
- }
- }
++ },
++ {
++ "type":"SR (IS-IS)",
++ "outLabel":16051,
+ "installed":true,
+ "interface":"eth-sw1"
+ }
---- rt2/step6/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step7/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -15,34 +15,10 @@
+--- 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,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16010
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16010
- ]
- }
]
}
],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16030
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16050
+- 16050,
+- 16030
- ]
- }
]
}
],
-@@ -141,30 +93,21 @@
+@@ -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",
}
]
}
-@@ -212,34 +155,12 @@
+@@ -248,40 +169,12 @@
{
"ip":"10.0.1.1",
"afi":"ipv4",
- "ip":"10.0.2.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-1",
-- "active":true
+- "active":true,
+- "labels":[
+- 16050
+- ]
- },
- {
- "ip":"10.0.3.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4-2",
-- "active":true
+- "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
+ }
+ ]
+ }
---- rt2/step6/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step7/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -14,32 +14,10 @@
+--- 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,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16011
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16011
- ]
- }
]
}
],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
- "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16031
- ]
- },
- {
- "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
-- 16051
+- 16051,
+- 16031
- ]
- }
]
}
],
-@@ -132,28 +88,19 @@
- "fib":true,
+@@ -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
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt4-2",
- "active":true,
- "labels":[
- 16051
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
- "active":true,
- "labels":[
- 16051
---- rt2/step6/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step7/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
}
]
},
-@@ -147,54 +83,6 @@
+@@ -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,
- "type":"SR (IS-IS)",
- "outLabel":16051,
- "installed":true,
-- "interface":"eth-rt4-2"
-- },
-- {
-- "type":"SR (IS-IS)",
+ "interface":"eth-rt4-2"
+ },
+ {
+ "type":"SR (IS-IS)",
- "outLabel":16051,
-- "installed":true,
-- "interface":"eth-rt4-1"
++ "outLabel":3,
+ "installed":true,
+ "interface":"eth-rt4-1"
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":16051,
- "installed":true,
- "interface":"eth-sw1"
-- }
-- ]
-- },
- "16060":{
- "inLabel":16060,
- "installed":true,
+ }
+ ]
+ },
---- rt2/step7/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step8/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -15,10 +15,34 @@
+--- 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,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16010
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16010
+ ]
+ }
]
}
],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16030
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16050
++ 16050,
++ 16030
+ ]
+ }
]
}
],
-@@ -93,21 +141,30 @@
+@@ -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",
}
]
}
-@@ -155,12 +212,34 @@
+@@ -169,12 +248,40 @@
{
"ip":"10.0.1.1",
"afi":"ipv4",
+ "ip":"10.0.2.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4-1",
-+ "active":true
++ "active":true,
++ "labels":[
++ 16050
++ ]
+ },
+ {
+ "ip":"10.0.3.4",
+ "afi":"ipv4",
+ "interfaceName":"eth-rt4-2",
-+ "active":true
++ "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
++ ]
}
]
}
---- rt2/step7/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step8/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-@@ -14,10 +14,32 @@
+--- 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,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16011
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16011
+ ]
+ }
]
}
],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16031
+ ]
+ },
+ {
+ "interfaceName":"eth-rt4-2",
+ "active":true,
+ "labels":[
-+ 16051
++ 16051,
++ 16031
+ ]
+ }
]
}
],
-@@ -88,19 +132,28 @@
- "fib":true,
+@@ -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":[
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt4-2",
- "active":true
+ "active":true,
+ "labels":[
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4-2",
+ "interfaceName":"eth-rt4-1",
- "active":true
+ "active":true,
+ "labels":[
---- rt2/step7/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step8/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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,
}
]
},
-@@ -83,6 +147,54 @@
+@@ -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,
+ "type":"SR (IS-IS)",
+ "outLabel":16051,
+ "installed":true,
-+ "interface":"eth-rt4-1"
+ "interface":"eth-rt4-1"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16051,
+ "installed":true,
+ "interface":"eth-sw1"
-+ }
-+ ]
-+ },
- "16060":{
- "inLabel":16060,
- "installed":true,
+ }
+ ]
+ },
---- rt2/step8/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step9/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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
]
},
{
-@@ -40,7 +40,7 @@
+@@ -175,7 +175,7 @@
+ "interfaceName":"eth-rt4-1",
+ "active":true,
+ "labels":[
+- 16050
++ 16500
+ ]
+ },
+ {
+@@ -185,7 +185,7 @@
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
]
}
]
-@@ -78,7 +78,7 @@
+@@ -271,7 +271,7 @@
"interfaceName":"eth-rt4-1",
"active":true,
"labels":[
]
},
{
-@@ -87,7 +87,7 @@
+@@ -280,7 +280,7 @@
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
]
}
]
-@@ -143,7 +143,7 @@
+@@ -318,7 +318,7 @@
"interfaceName":"eth-sw1",
"active":true,
"labels":[
- 16050
+ 16500
]
- },
- {
-@@ -153,7 +153,7 @@
- "interfaceName":"eth-rt4-1",
+ }
+ ]
+@@ -356,7 +356,7 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
- 16050
+ 16500
]
- },
- {
-@@ -163,7 +163,7 @@
- "interfaceName":"eth-rt4-2",
+ }
+ ]
+@@ -517,7 +517,7 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
- 16050
---- rt2/step8/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step9/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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
+- 16051,
++ 16501,
+ 16011
]
},
- {
-@@ -37,7 +37,7 @@
+@@ -38,7 +38,7 @@
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
-- 16051
-+ 16501
+- 16051,
++ 16501,
+ 16011
]
}
- ]
-@@ -73,7 +73,7 @@
+@@ -75,7 +75,7 @@
"interfaceName":"eth-rt4-1",
"active":true,
"labels":[
-- 16051
-+ 16501
+- 16051,
++ 16501,
+ 16031
]
},
- {
-@@ -81,7 +81,7 @@
+@@ -84,7 +84,7 @@
"interfaceName":"eth-rt4-2",
"active":true,
"labels":[
-- 16051
-+ 16501
+- 16051,
++ 16501,
+ 16031
]
}
- ]
-@@ -134,7 +134,7 @@
- "interfaceName":"eth-rt4-1",
+@@ -132,7 +132,7 @@
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+- 16051,
++ 16501,
+ 16041
+ ]
+ }
+@@ -155,7 +155,7 @@
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
- 16051
]
},
{
-@@ -143,7 +143,7 @@
- "interfaceName":"eth-sw1",
+@@ -164,7 +164,7 @@
+ "interfaceName":"eth-rt4-2",
"active":true,
"labels":[
- 16051
]
},
{
-@@ -152,7 +152,7 @@
- "interfaceName":"eth-rt4-2",
+@@ -173,7 +173,7 @@
+ "interfaceName":"eth-rt4-1",
"active":true,
"labels":[
- 16051
---- rt2/step8/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step9/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
+--- 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":[
{
"interface":"eth-rt4-2"
}
]
-@@ -147,87 +147,87 @@
- }
- ]
- },
-- "16050":{
-- "inLabel":16050,
-+ "16060":{
-+ "inLabel":16060,
- "installed":true,
- "nexthops":[
+@@ -137,7 +137,7 @@
+ "backupNexthops":[
{
"type":"SR (IS-IS)",
- "outLabel":16050,
-+ "outLabel":16060,
- "installed":true,
- "nexthop":"10.0.3.4"
- },
++ "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,
-+ "outLabel":16060,
- "installed":true,
- "nexthop":"10.0.2.4"
+- "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,
-+ "16061":{
-+ "inLabel":16061,
- "installed":true,
- "nexthops":[
- {
- "type":"SR (IS-IS)",
+- "installed":true,
+- "nexthops":[
+- {
+- "type":"SR (IS-IS)",
- "outLabel":16051,
-+ "outLabel":16061,
- "installed":true,
- "interface":"eth-rt4-2"
- },
- {
- "type":"SR (IS-IS)",
+- "installed":true,
+- "interface":"eth-rt4-2"
+- },
+- {
+- "type":"SR (IS-IS)",
- "outLabel":16051,
-+ "outLabel":16061,
- "installed":true,
- "interface":"eth-rt4-1"
+- "installed":true,
+- "interface":"eth-rt4-1"
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":16051,
- "installed":true,
-- "interface":"eth-sw1"
++ "outLabel":16501,
+ "interface":"eth-sw1"
+ }
+ ]
+@@ -282,5 +234,53 @@
+ "interface":"eth-sw1"
}
]
- },
-- "16060":{
-- "inLabel":16060,
++ },
+ "16500":{
+ "inLabel":16500,
- "installed":true,
- "nexthops":[
- {
- "type":"SR (IS-IS)",
-- "outLabel":16060,
++ "installed":true,
++ "nexthops":[
++ {
++ "type":"SR (IS-IS)",
+ "outLabel":16500,
- "installed":true,
- "nexthop":"10.0.3.4"
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16060,
++ "installed":true,
++ "nexthop":"10.0.3.4"
++ },
++ {
++ "type":"SR (IS-IS)",
+ "outLabel":16500,
- "installed":true,
- "nexthop":"10.0.2.4"
++ "installed":true,
++ "nexthop":"10.0.2.4"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16500,
+ "installed":true,
+ "nexthop":"10.0.1.3"
- }
- ]
- },
-- "16061":{
-- "inLabel":16061,
++ }
++ ]
++ },
+ "16501":{
+ "inLabel":16501,
- "installed":true,
- "nexthops":[
- {
- "type":"SR (IS-IS)",
-- "outLabel":16061,
++ "installed":true,
++ "nexthops":[
++ {
++ "type":"SR (IS-IS)",
+ "outLabel":16501,
- "installed":true,
- "interface":"eth-rt4-2"
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16061,
++ "installed":true,
++ "interface":"eth-rt4-2"
++ },
++ {
++ "type":"SR (IS-IS)",
+ "outLabel":16501,
- "installed":true,
- "interface":"eth-rt4-1"
++ "installed":true,
++ "interface":"eth-rt4-1"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16501,
+ "installed":true,
+ "interface":"eth-sw1"
- }
- ]
++ }
++ ]
}
+ }
],
"backupNexthops":[
{
- "ip":"10.0.5.5",
+ "ip":"10.0.4.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
- 16040
+ 16040,
+ 16010
]
},
{
- "ip":"10.0.4.5",
+ "ip":"10.0.5.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
- 16040
+ 16040,
+ 16010
]
}
]
],
"backupNexthops":[
{
- "ip":"10.0.5.5",
+ "ip":"10.0.4.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
- 16040
+ 16040,
+ 16020
]
},
{
- "ip":"10.0.4.5",
+ "ip":"10.0.5.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
- 16040
+ 16040,
+ 16020
]
}
]
"afi":"ipv4",
"interfaceName":"eth-rt5-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
"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
+ ]
+ }
]
}
],
"afi":"ipv4",
"interfaceName":"eth-rt5-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16060
]
"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
+ }
]
}
],
],
"backupNexthops":[
{
- "ip":"10.0.5.5",
+ "ip":"10.0.4.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-2",
- "active":true
+ "interfaceName":"eth-rt5-1",
+ "active":true,
+ "labels":[
+ 16040
+ ]
},
{
- "ip":"10.0.4.5",
+ "ip":"10.0.5.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-1",
- "active":true
+ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
+ 16040
+ ]
}
]
}
],
"backupNexthops":[
{
- "ip":"10.0.5.5",
+ "ip":"10.0.4.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true
},
{
- "ip":"10.0.4.5",
+ "ip":"10.0.5.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true
}
]
],
"backupNexthops":[
{
- "ip":"10.0.5.5",
+ "ip":"10.0.4.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true
},
{
- "ip":"10.0.4.5",
+ "ip":"10.0.5.5",
"afi":"ipv4",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true
}
]
{
"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
+ ]
}
]
}
"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
+ ]
}
]
}
"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,
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "ip":"10.0.1.2",
+ "afi":"ipv4",
+ "interfaceName":"eth-sw1",
"active":true
}
]
"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
+ ]
}
]
}
"backupNexthops":[
{
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
- 16041
+ 16041,
+ 16011
]
},
{
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
- 16041
+ 16041,
+ 16011
]
}
]
"backupNexthops":[
{
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
- 16041
+ 16041,
+ 16021
]
},
{
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
- 16041
+ 16041,
+ 16021
]
}
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-sw1",
"active":true,
"labels":[
16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
16041
"afi":"ipv6",
"interfaceName":"eth-rt5-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
"afi":"ipv6",
"interfaceName":"eth-rt5-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+ 16041,
+ 16051
+ ]
+ }
]
}
],
"afi":"ipv6",
"interfaceName":"eth-rt5-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16061
]
"afi":"ipv6",
"interfaceName":"eth-rt5-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16061
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-sw1",
+ "active":true
+ }
]
}
]
{
"type":"SR (IS-IS)",
"outLabel":16040,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5"
},
{
"type":"SR (IS-IS)",
"outLabel":16040,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5"
}
]
},
{
"type":"SR (IS-IS)",
"outLabel":16041,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1"
},
{
"type":"SR (IS-IS)",
"outLabel":16041,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2"
}
]
},
{
"type":"SR (IS-IS)",
"outLabel":16040,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5"
},
{
"type":"SR (IS-IS)",
"outLabel":16040,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5"
}
]
},
{
"type":"SR (IS-IS)",
"outLabel":16041,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1"
},
{
"type":"SR (IS-IS)",
"outLabel":16041,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16040,
"installed":true,
- "nexthop":"10.0.1.2"
+ "nexthop":"10.0.5.5"
},
{
"type":"SR (IS-IS)",
"type":"SR (IS-IS)",
"outLabel":16040,
"installed":true,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.1.2"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16041,
"installed":true,
- "interface":"eth-sw1"
+ "interface":"eth-rt5-2"
},
{
"type":"SR (IS-IS)",
"type":"SR (IS-IS)",
"outLabel":16041,
"installed":true,
- "interface":"eth-rt5-2"
+ "interface":"eth-sw1"
}
]
},
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16040,
+ "nexthop":"10.0.1.2"
}
]
},
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
+ "interface":"eth-sw1"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16060,
"installed":true,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":16060,
"installed":true,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "nexthop":"10.0.1.2"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16061,
"installed":true,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":16061,
"installed":true,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "interface":"eth-sw1"
}
]
}
---- rt3/step3/show_ip_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt3/step4/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -15,34 +15,10 @@
+--- 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,
- ],
- "backupNexthops":[
- {
-- "ip":"10.0.5.5",
+- "ip":"10.0.4.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt5-2",
+- "interfaceName":"eth-rt5-1",
- "active":true,
- "labels":[
-- 16040
+- 16040,
+- 16010
- ]
- },
- {
-- "ip":"10.0.4.5",
+- "ip":"10.0.5.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt5-1",
+- "interfaceName":"eth-rt5-2",
- "active":true,
- "labels":[
-- 16040
+- 16040,
+- 16010
- ]
- }
]
}
],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
- ],
- "backupNexthops":[
- {
-- "ip":"10.0.5.5",
+- "ip":"10.0.4.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt5-2",
+- "interfaceName":"eth-rt5-1",
- "active":true,
- "labels":[
-- 16040
+- 16040,
+- 16020
- ]
- },
- {
-- "ip":"10.0.4.5",
+- "ip":"10.0.5.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt5-1",
+- "interfaceName":"eth-rt5-2",
- "active":true,
- "labels":[
-- 16040
+- 16040,
+- 16020
- ]
- }
]
}
],
-@@ -108,30 +60,21 @@
+@@ -112,30 +60,21 @@
"ip":"10.0.1.2",
"afi":"ipv4",
"interfaceName":"eth-sw1",
}
]
}
-@@ -212,34 +155,12 @@
+@@ -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",
- ],
- "backupNexthops":[
- {
-- "ip":"10.0.5.5",
+- "ip":"10.0.4.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt5-2",
-- "active":true
+- "interfaceName":"eth-rt5-1",
+- "active":true,
+- "labels":[
+- 16040
+- ]
- },
- {
-- "ip":"10.0.4.5",
+- "ip":"10.0.5.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt5-1",
-- "active":true
+- "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
+ }
+ ]
+ }
---- rt3/step3/show_ipv6_route.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt3/step4/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -14,32 +14,10 @@
+--- 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,
- "backupNexthops":[
- {
- "afi":"ipv6",
-- "interfaceName":"eth-rt5-2",
+- "interfaceName":"eth-rt5-1",
- "active":true,
- "labels":[
-- 16041
+- 16041,
+- 16011
- ]
- },
- {
- "afi":"ipv6",
-- "interfaceName":"eth-rt5-1",
+- "interfaceName":"eth-rt5-2",
- "active":true,
- "labels":[
-- 16041
+- 16041,
+- 16011
- ]
- }
]
}
],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
- "backupNexthops":[
- {
- "afi":"ipv6",
-- "interfaceName":"eth-rt5-2",
+- "interfaceName":"eth-rt5-1",
- "active":true,
- "labels":[
-- 16041
+- 16041,
+- 16021
- ]
- },
- {
- "afi":"ipv6",
-- "interfaceName":"eth-rt5-1",
+- "interfaceName":"eth-rt5-2",
- "active":true,
- "labels":[
-- 16041
+- 16041,
+- 16021
- ]
- }
]
}
],
-@@ -101,28 +57,19 @@
+@@ -105,28 +57,19 @@
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-sw1",
- "active":true,
- "labels":[
- 16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
- "active":true,
- "labels":[
- 16041
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt5-1",
- "active":true,
- "labels":[
- 16041
}
]
}
+@@ -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
+- ]
+- }
+ ]
+ }
+ ],
---- rt3/step3/show_mpls_table.ref 2020-08-31 22:42:48.835561429 -0300
-+++ rt3/step4/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
+--- 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,
- {
- "type":"SR (IS-IS)",
- "outLabel":16040,
-- "nexthop":"10.0.5.5"
+- "nexthop":"10.0.4.5"
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":16040,
-- "nexthop":"10.0.4.5"
+- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.1.1"
}
]
- {
- "type":"SR (IS-IS)",
- "outLabel":16041,
-- "interface":"eth-rt5-2"
+- "interface":"eth-rt5-1"
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":16041,
-- "interface":"eth-rt5-1"
+- "interface":"eth-rt5-2"
+ "interface":"eth-sw1"
}
]
- {
- "type":"SR (IS-IS)",
- "outLabel":16040,
-- "nexthop":"10.0.5.5"
+- "nexthop":"10.0.4.5"
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":16040,
-- "nexthop":"10.0.4.5"
+- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.1.2"
}
]
},
-@@ -91,71 +43,7 @@
+@@ -91,70 +43,6 @@
"type":"SR (IS-IS)",
"outLabel":3,
"installed":true,
- {
- "type":"SR (IS-IS)",
- "outLabel":16041,
-- "interface":"eth-rt5-2"
+- "interface":"eth-rt5-1"
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":16041,
-- "interface":"eth-rt5-1"
+- "interface":"eth-rt5-2"
- }
- ]
- },
- "type":"SR (IS-IS)",
- "outLabel":16040,
- "installed":true,
-- "nexthop":"10.0.1.2"
+- "nexthop":"10.0.5.5"
- },
- {
- "type":"SR (IS-IS)",
- "type":"SR (IS-IS)",
- "outLabel":16040,
- "installed":true,
-- "nexthop":"10.0.5.5"
+- "nexthop":"10.0.1.2"
- }
- ]
- },
- "type":"SR (IS-IS)",
- "outLabel":16041,
- "installed":true,
- "interface":"eth-sw1"
+- "interface":"eth-rt5-2"
- },
- {
- "type":"SR (IS-IS)",
- "type":"SR (IS-IS)",
- "outLabel":16041,
- "installed":true,
-- "interface":"eth-rt5-2"
+ "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"
}
]
},
---- rt3/step4/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step5/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -15,10 +15,34 @@
+--- 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,
+ ],
+ "backupNexthops":[
+ {
-+ "ip":"10.0.5.5",
++ "ip":"10.0.4.5",
+ "afi":"ipv4",
-+ "interfaceName":"eth-rt5-2",
++ "interfaceName":"eth-rt5-1",
+ "active":true,
+ "labels":[
-+ 16040
++ 16040,
++ 16010
+ ]
+ },
+ {
-+ "ip":"10.0.4.5",
++ "ip":"10.0.5.5",
+ "afi":"ipv4",
-+ "interfaceName":"eth-rt5-1",
++ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
-+ 16040
++ 16040,
++ 16010
+ ]
+ }
]
}
],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
"afi":"ipv4",
"interfaceName":"eth-sw1",
"active":true,
+ ],
+ "backupNexthops":[
+ {
-+ "ip":"10.0.5.5",
++ "ip":"10.0.4.5",
+ "afi":"ipv4",
-+ "interfaceName":"eth-rt5-2",
++ "interfaceName":"eth-rt5-1",
+ "active":true,
+ "labels":[
-+ 16040
++ 16040,
++ 16020
+ ]
+ },
+ {
-+ "ip":"10.0.4.5",
++ "ip":"10.0.5.5",
+ "afi":"ipv4",
-+ "interfaceName":"eth-rt5-1",
++ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
-+ 16040
++ 16040,
++ 16020
+ ]
+ }
]
}
],
-@@ -60,21 +108,30 @@
+@@ -60,21 +112,30 @@
"ip":"10.0.1.2",
"afi":"ipv4",
"interfaceName":"eth-sw1",
}
]
}
-@@ -155,12 +212,34 @@
+@@ -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",
+ ],
+ "backupNexthops":[
+ {
-+ "ip":"10.0.5.5",
++ "ip":"10.0.4.5",
+ "afi":"ipv4",
-+ "interfaceName":"eth-rt5-2",
-+ "active":true
++ "interfaceName":"eth-rt5-1",
++ "active":true,
++ "labels":[
++ 16040
++ ]
+ },
+ {
-+ "ip":"10.0.4.5",
++ "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",
-+ "active":true
++ "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
++ ]
}
]
}
---- rt3/step4/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step5/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -14,10 +14,32 @@
+--- 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,
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
-+ "interfaceName":"eth-rt5-2",
++ "interfaceName":"eth-rt5-1",
+ "active":true,
+ "labels":[
-+ 16041
++ 16041,
++ 16011
+ ]
+ },
+ {
+ "afi":"ipv6",
-+ "interfaceName":"eth-rt5-1",
++ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
-+ 16041
++ 16041,
++ 16011
+ ]
+ }
]
}
],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
"afi":"ipv6",
"interfaceName":"eth-sw1",
"active":true,
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
-+ "interfaceName":"eth-rt5-2",
++ "interfaceName":"eth-rt5-1",
+ "active":true,
+ "labels":[
-+ 16041
++ 16041,
++ 16021
+ ]
+ },
+ {
+ "afi":"ipv6",
-+ "interfaceName":"eth-rt5-1",
++ "interfaceName":"eth-rt5-2",
+ "active":true,
+ "labels":[
-+ 16041
++ 16041,
++ 16021
+ ]
+ }
]
}
],
-@@ -57,19 +101,28 @@
+@@ -57,19 +105,28 @@
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-2",
+ "interfaceName":"eth-sw1",
- "active":true
+ "active":true,
+ "labels":[
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5-1",
+ "interfaceName":"eth-rt5-2",
- "active":true
+ "active":true,
+ "labels":[
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-sw1",
+ "interfaceName":"eth-rt5-1",
- "active":true
+ "active":true,
+ "labels":[
}
]
}
+@@ -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
++ ]
++ }
+ ]
+ }
+ ],
---- rt3/step4/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step5/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
+--- 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,
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16040,
-+ "nexthop":"10.0.5.5"
++ "nexthop":"10.0.4.5"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16040,
-+ "nexthop":"10.0.4.5"
++ "nexthop":"10.0.5.5"
}
]
},
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
-+ "interface":"eth-rt5-2"
++ "interface":"eth-rt5-1"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
-+ "interface":"eth-rt5-1"
++ "interface":"eth-rt5-2"
}
]
},
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16040,
-+ "nexthop":"10.0.5.5"
++ "nexthop":"10.0.4.5"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16040,
-+ "nexthop":"10.0.4.5"
++ "nexthop":"10.0.5.5"
}
]
},
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
-+ "interface":"eth-rt5-2"
++ "interface":"eth-rt5-1"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
-+ "interface":"eth-rt5-1"
++ "interface":"eth-rt5-2"
+ }
+ ]
+ },
+ "type":"SR (IS-IS)",
+ "outLabel":16040,
+ "installed":true,
-+ "nexthop":"10.0.4.5"
++ "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)",
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
+ "installed":true,
-+ "interface":"eth-rt5-1"
++ "interface":"eth-rt5-2"
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16041,
+ "installed":true,
-+ "interface":"eth-rt5-2"
++ "interface":"eth-rt5-1"
+ },
+ {
+ "type":"SR (IS-IS)",
"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"
+ }
+ ]
+ },
---- rt3/step5/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step6/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
+--- 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-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
-- 16040
-+ 30040
+- 16040,
++ 30040,
+ 16010
]
},
- {
-@@ -40,7 +40,7 @@
- "interfaceName":"eth-rt5-1",
+@@ -41,7 +41,7 @@
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
-- 16040
-+ 30040
+- 16040,
++ 30040,
+ 16010
]
}
- ]
-@@ -78,7 +78,7 @@
- "interfaceName":"eth-rt5-2",
+@@ -80,7 +80,7 @@
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
-- 16040
-+ 30040
+- 16040,
++ 30040,
+ 16020
]
},
- {
-@@ -87,7 +87,7 @@
- "interfaceName":"eth-rt5-1",
+@@ -90,7 +90,7 @@
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
-- 16040
-+ 30040
+- 16040,
++ 30040,
+ 16020
]
}
- ]
-@@ -120,7 +120,7 @@
+@@ -124,7 +124,7 @@
"interfaceName":"eth-rt5-1",
"active":true,
"labels":[
]
},
{
-@@ -130,7 +130,7 @@
+@@ -134,7 +134,7 @@
"interfaceName":"eth-rt5-2",
"active":true,
"labels":[
]
}
]
-@@ -186,7 +186,7 @@
- "interfaceName":"eth-rt5-1",
+@@ -185,7 +185,7 @@
"active":true,
"labels":[
+ 16040,
+- 16050
++ 30050
+ ]
+ }
+ ]
+@@ -211,7 +211,7 @@
+ 0
+ ],
+ "labels":[
- 16060
+ 30060
]
},
{
-@@ -196,7 +196,7 @@
- "interfaceName":"eth-rt5-2",
- "active":true,
+@@ -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
+ ]
+ }
]
---- rt3/step5/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step6/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
+--- 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-2",
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
-- 16041
-+ 30041
+- 16041,
++ 30041,
+ 16011
]
},
- {
-@@ -37,7 +37,7 @@
- "interfaceName":"eth-rt5-1",
+@@ -38,7 +38,7 @@
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
-- 16041
-+ 30041
+- 16041,
++ 30041,
+ 16011
]
}
- ]
-@@ -73,7 +73,7 @@
- "interfaceName":"eth-rt5-2",
+@@ -75,7 +75,7 @@
+ "interfaceName":"eth-rt5-1",
"active":true,
"labels":[
-- 16041
-+ 30041
+- 16041,
++ 30041,
+ 16021
]
},
- {
-@@ -81,7 +81,7 @@
- "interfaceName":"eth-rt5-1",
+@@ -84,7 +84,7 @@
+ "interfaceName":"eth-rt5-2",
"active":true,
"labels":[
-- 16041
-+ 30041
+- 16041,
++ 30041,
+ 16021
]
}
- ]
-@@ -103,7 +103,7 @@
+@@ -116,7 +116,7 @@
"interfaceName":"eth-rt5-2",
"active":true,
"labels":[
]
},
{
-@@ -112,7 +112,7 @@
+@@ -125,7 +125,7 @@
"interfaceName":"eth-rt5-1",
"active":true,
"labels":[
- 16041
+ 30041
]
- },
- {
-@@ -174,7 +174,7 @@
- "interfaceName":"eth-rt5-2",
+ }
+ ]
+@@ -173,7 +173,7 @@
"active":true,
"labels":[
+ 16041,
+- 16051
++ 30051
+ ]
+ }
+ ]
+@@ -198,7 +198,7 @@
+ 0
+ ],
+ "labels":[
- 16061
+ 30061
]
},
{
-@@ -183,7 +183,7 @@
- "interfaceName":"eth-rt5-1",
- "active":true,
+@@ -210,7 +210,7 @@
+ 0
+ ],
"labels":[
- 16061
+ 30061
]
}
- ]
+ ],
---- rt3/step5/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step6/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
+--- 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.5.5"
+ "nexthop":"10.0.4.5"
},
{
"type":"SR (IS-IS)",
- "outLabel":16040,
+ "outLabel":30040,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5"
}
]
@@ -45,12 +45,12 @@
"type":"SR (IS-IS)",
- "outLabel":16041,
+ "outLabel":30041,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1"
},
{
"type":"SR (IS-IS)",
- "outLabel":16041,
+ "outLabel":30041,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2"
}
]
@@ -73,12 +73,12 @@
"type":"SR (IS-IS)",
- "outLabel":16040,
+ "outLabel":30040,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5"
},
{
"type":"SR (IS-IS)",
- "outLabel":16040,
+ "outLabel":30040,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5"
}
]
@@ -101,12 +101,12 @@
"type":"SR (IS-IS)",
- "outLabel":16041,
+ "outLabel":30041,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1"
},
{
"type":"SR (IS-IS)",
- "outLabel":16041,
+ "outLabel":30041,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2"
}
]
@@ -117,13 +117,13 @@
- "outLabel":16040,
+ "outLabel":30040,
"installed":true,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5"
},
{
"type":"SR (IS-IS)",
- "outLabel":16040,
+ "outLabel":30040,
"installed":true,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5"
},
@@ -141,13 +141,13 @@
"nexthops":[
- "outLabel":16041,
+ "outLabel":30041,
"installed":true,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2"
},
{
"type":"SR (IS-IS)",
- "outLabel":16041,
+ "outLabel":30041,
"installed":true,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1"
},
-@@ -201,13 +201,13 @@
+@@ -227,7 +227,7 @@
"nexthops":[
{
"type":"SR (IS-IS)",
- "outLabel":16060,
+ "outLabel":30060,
"installed":true,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5",
+ "backupIndex":[
+@@ -236,7 +236,7 @@
},
{
"type":"SR (IS-IS)",
- "outLabel":16060,
+ "outLabel":30060,
"installed":true,
- "nexthop":"10.0.5.5"
- }
-@@ -219,13 +219,13 @@
+ "nexthop":"10.0.4.5",
+ "backupIndex":[
+@@ -258,7 +258,7 @@
"nexthops":[
{
"type":"SR (IS-IS)",
- "outLabel":16061,
+ "outLabel":30061,
"installed":true,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2",
+ "backupIndex":[
+@@ -267,7 +267,7 @@
},
{
"type":"SR (IS-IS)",
- "outLabel":16061,
+ "outLabel":30061,
"installed":true,
- "interface":"eth-rt5-2"
- }
+ "interface":"eth-rt5-1",
+ "backupIndex":[
---- rt3/step6/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step7/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -151,20 +151,14 @@
- "ip":"10.0.4.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5-1",
-- "active":true,
+--- 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
-- ]
-+ "active":true
+ ]
},
{
- "fib":true,
- "ip":"10.0.5.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5-2",
-- "active":true,
+@@ -171,9 +168,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
- "labels":[
- 3
-- ]
-+ "active":true
+ ]
+ }
+ ],
+@@ -184,8 +178,7 @@
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+- 16040,
+- 30050
++ 16040
+ ]
}
]
- }
---- rt3/step6/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step7/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -141,19 +141,13 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt5-2",
-- "active":true,
+--- 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
-- ]
-+ "active":true
+ ]
},
{
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt5-1",
-- "active":true,
+@@ -160,9 +157,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
- "labels":[
- 3
-- ]
-+ "active":true
+ ]
+ }
+ ],
+@@ -172,8 +166,7 @@
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+- 16041,
+- 30051
++ 16041
+ ]
}
]
- }
---- rt3/step6/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step7/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -159,42 +159,6 @@
+--- 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 @@
}
]
},
- "type":"SR (IS-IS)",
- "outLabel":3,
- "installed":true,
-- "nexthop":"10.0.4.5"
+- "nexthop":"10.0.5.5",
+- "backupIndex":[
+- 0
+- ]
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":3,
- "installed":true,
-- "nexthop":"10.0.5.5"
+- "nexthop":"10.0.4.5",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16040,
+- "nexthop":"10.0.1.2"
- }
- ]
- },
- "type":"SR (IS-IS)",
- "outLabel":3,
- "installed":true,
-- "interface":"eth-rt5-1"
+- "interface":"eth-rt5-2",
+- "backupIndex":[
+- 0
+- ]
- },
- {
- "type":"SR (IS-IS)",
- "outLabel":3,
- "installed":true,
-- "interface":"eth-rt5-2"
+- "interface":"eth-rt5-1",
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16041,
+- "interface":"eth-sw1"
- }
- ]
- },
---- rt3/step7/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step8/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -151,14 +151,20 @@
- "ip":"10.0.4.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5-1",
-- "active":true
-+ "active":true,
+--- 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
-+ ]
+ ]
},
{
- "fib":true,
- "ip":"10.0.5.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5-2",
-- "active":true
-+ "active":true,
+@@ -168,6 +171,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
+ "labels":[
+ 3
-+ ]
+ ]
+ }
+ ],
+@@ -178,7 +184,8 @@
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+- 16040
++ 16040,
++ 30050
+ ]
}
]
- }
---- rt3/step7/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step8/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -141,13 +141,19 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt5-2",
-- "active":true
-+ "active":true,
+--- 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
-+ ]
+ ]
},
{
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt5-1",
-- "active":true
-+ "active":true,
+@@ -157,6 +160,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
+ "labels":[
+ 3
-+ ]
+ ]
+ }
+ ],
+@@ -166,7 +172,8 @@
+ "interfaceName":"eth-sw1",
+ "active":true,
+ "labels":[
+- 16041
++ 16041,
++ 30051
+ ]
}
]
- }
---- rt3/step7/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step8/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -159,6 +159,42 @@
+--- 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 @@
}
]
},
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
-+ "nexthop":"10.0.4.5"
++ "nexthop":"10.0.5.5",
++ "backupIndex":[
++ 0
++ ]
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
-+ "nexthop":"10.0.5.5"
++ "nexthop":"10.0.4.5",
++ "backupIndex":[
++ 0
++ ]
++ }
++ ],
++ "backupNexthops":[
++ {
++ "type":"SR (IS-IS)",
++ "outLabel":16040,
++ "nexthop":"10.0.1.2"
+ }
+ ]
+ },
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
-+ "interface":"eth-rt5-1"
++ "interface":"eth-rt5-2",
++ "backupIndex":[
++ 0
++ ]
+ },
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
-+ "interface":"eth-rt5-2"
++ "interface":"eth-rt5-1",
++ "backupIndex":[
++ 0
++ ]
++ }
++ ],
++ "backupNexthops":[
++ {
++ "type":"SR (IS-IS)",
++ "outLabel":16041,
++ "interface":"eth-sw1"
+ }
+ ]
+ },
+--- 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
+ ]
+ }
+ ]
+--- 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
+ ]
+ }
+ ]
---- rt3/step8/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step9/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -159,73 +159,73 @@
+--- 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 @@
}
]
},
- "outLabel":3,
+ "outLabel":30060,
"installed":true,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5",
+ "backupIndex":[
+@@ -174,7 +174,7 @@
},
{
"type":"SR (IS-IS)",
- "outLabel":3,
+ "outLabel":30060,
"installed":true,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5",
+ "backupIndex":[
+@@ -185,18 +185,18 @@
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":16040,
++ "outLabel":3,
+ "nexthop":"10.0.1.2"
}
]
},
- "outLabel":3,
+ "outLabel":30061,
"installed":true,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2",
+ "backupIndex":[
+@@ -205,7 +205,7 @@
},
{
"type":"SR (IS-IS)",
- "outLabel":3,
+ "outLabel":30061,
"installed":true,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1",
+ "backupIndex":[
+@@ -216,18 +216,18 @@
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":16041,
++ "outLabel":3,
+ "interface":"eth-sw1"
}
]
},
- "outLabel":30060,
+ "outLabel":3,
"installed":true,
- "nexthop":"10.0.4.5"
+ "nexthop":"10.0.5.5",
+ "backupIndex":[
+@@ -236,7 +236,7 @@
},
{
"type":"SR (IS-IS)",
- "outLabel":30060,
+ "outLabel":3,
"installed":true,
- "nexthop":"10.0.5.5"
+ "nexthop":"10.0.4.5",
+ "backupIndex":[
+@@ -247,18 +247,18 @@
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":3,
++ "outLabel":16040,
+ "nexthop":"10.0.1.2"
}
]
},
- "outLabel":30061,
+ "outLabel":3,
"installed":true,
- "interface":"eth-rt5-1"
+ "interface":"eth-rt5-2",
+ "backupIndex":[
+@@ -267,7 +267,7 @@
},
{
"type":"SR (IS-IS)",
- "outLabel":30061,
+ "outLabel":3,
"installed":true,
- "interface":"eth-rt5-2"
+ "interface":"eth-rt5-1",
+ "backupIndex":[
+@@ -278,7 +278,7 @@
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+- "outLabel":3,
++ "outLabel":16041,
+ "interface":"eth-sw1"
}
+ ]
"afi":"ipv4",
"interfaceName":"eth-rt2-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16010
]
"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
+ }
]
}
],
"afi":"ipv4",
"interfaceName":"eth-rt2-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
"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
+ ]
+ }
]
}
],
"ip":"10.0.7.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"ip":"10.0.6.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"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
}
]
{
"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
+ ]
}
]
}
"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
+ ]
}
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16011
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16011
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
+ "active":true
+ }
]
}
],
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
+ "active":true,
+ "labels":[
+ 16031,
+ 16021
+ ]
+ }
]
}
],
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-2",
+ "interfaceName":"eth-rt2-1",
"active":true,
"labels":[
16031
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt2-1",
+ "interfaceName":"eth-rt2-2",
"active":true,
"labels":[
16031
{
"afi":"ipv6",
"interfaceName":"eth-rt6",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
{
"afi":"ipv6",
"interfaceName":"eth-rt5",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
---- rt4/step3/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step4/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -14,20 +14,14 @@
- "ip":"10.0.2.2",
+--- 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,
-- "labels":[
-- 16010
-- ]
-+ "active":true
- },
- {
- "fib":true,
- "ip":"10.0.3.2",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 16010
+ ]
+@@ -28,21 +25,10 @@
"afi":"ipv4",
"interfaceName":"eth-rt2-2",
-- "active":true,
-- "labels":[
-- 16010
-- ]
-+ "active":true
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 16010
+ ]
}
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.6.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+- "active":true
+- }
]
}
-@@ -47,20 +41,14 @@
- "ip":"10.0.2.2",
+ ],
+@@ -62,9 +48,6 @@
"afi":"ipv4",
"interfaceName":"eth-rt2-1",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- },
- {
- "fib":true,
- "ip":"10.0.3.2",
+ "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":[
-- 3
+- 16030,
+- 16020
- ]
-+ "active":true
+- }
+ ]
+ }
+ ],
+@@ -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
+- }
]
}
-@@ -80,30 +68,21 @@
+ ],
+@@ -223,27 +169,13 @@
"ip":"10.0.2.2",
"afi":"ipv4",
"interfaceName":"eth-rt2-1",
- "active":true,
-- "labels":[
-- 16030
+- "backupIndex":[
+- 0
- ]
+ "active":true
},
"afi":"ipv4",
"interfaceName":"eth-rt2-2",
- "active":true,
-- "labels":[
-- 16030
+- "backupIndex":[
+- 0
- ]
-+ "active":true
- },
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.6.5",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt5",
+ "active":true
+ }
+ ]
+@@ -259,30 +191,13 @@
{
- "fib":true,
- "ip":"10.0.6.5",
+ "ip":"10.0.2.2",
"afi":"ipv4",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 16030
+- "interfaceName":"eth-rt2-1",
+- "backupIndex":[
+- 0
- ]
-+ "active":true
- }
- ]
- }
-@@ -123,24 +102,7 @@
- "ip":"10.0.6.5",
++ "interfaceName":"eth-rt2-1"
+ },
+ {
+ "ip":"10.0.3.2",
"afi":"ipv4",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt2-2",
- "active":true,
- "backupIndex":[
- 0
-- ],
-- "labels":[
-- 3
- ]
- }
- ],
- "backupNexthops":[
- {
-- "ip":"10.0.7.6",
+- "ip":"10.0.6.5",
- "afi":"ipv4",
-- "interfaceName":"eth-rt6",
+- "interfaceName":"eth-rt5",
- "active":true,
- "labels":[
-- 3
+- 16030
- ]
+ "active":true
}
]
}
-@@ -160,24 +122,7 @@
- "ip":"10.0.7.6",
+@@ -298,29 +213,12 @@
+ "ip":"10.0.2.2",
"afi":"ipv4",
- "interfaceName":"eth-rt6",
+ "interfaceName":"eth-rt2-1",
- "active":true,
- "backupIndex":[
- 0
-- ],
-- "labels":[
-- 3
+- ]
++ "active":true
+ },
+ {
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+- "interfaceName":"eth-rt2-2",
+- "backupIndex":[
+- 0
- ]
- }
- ],
- "interfaceName":"eth-rt5",
- "active":true,
- "labels":[
-- 3
+- 16030
- ]
-+ "active":true
++ "interfaceName":"eth-rt2-2"
}
]
}
-@@ -266,31 +211,6 @@
+@@ -340,31 +238,6 @@
"ip":"10.0.6.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
"active":true
}
]
-@@ -311,31 +231,6 @@
+@@ -385,31 +258,6 @@
"ip":"10.0.6.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
"active":true
}
]
-@@ -351,18 +246,7 @@
+@@ -425,18 +273,7 @@
{
"ip":"10.0.6.5",
"afi":"ipv4",
}
]
}
-@@ -377,18 +261,7 @@
+@@ -451,18 +288,7 @@
{
"ip":"10.0.7.6",
"afi":"ipv4",
---- rt4/step3/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step4/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -13,19 +13,13 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt2-2",
-- "active":true,
-- "labels":[
-- 16011
-- ]
-+ "active":true
- },
- {
- "fib":true,
+--- 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,
-- "labels":[
-- 16011
-- ]
-+ "active":true
- }
- ]
- }
-@@ -44,19 +38,13 @@
- "fib":true,
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 16011
+ ]
+@@ -26,20 +23,10 @@
"afi":"ipv6",
"interfaceName":"eth-rt2-2",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- },
- {
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt2-1",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 16011
+ ]
}
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt5",
+- "active":true
+- }
]
}
-@@ -75,28 +63,19 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt2-2",
-- "active":true,
-- "labels":[
-- 16031
-- ]
-+ "active":true
- },
- {
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 16031
-- ]
-+ "active":true
- },
- {
- "fib":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
+- 16031,
+- 16021
- ]
-+ "active":true
- }
+- }
]
}
-@@ -115,23 +94,7 @@
- "fib":true,
+ ],
+@@ -146,20 +116,10 @@
"afi":"ipv6",
"interfaceName":"eth-rt5",
-- "active":true,
+ "active":true,
- "backupIndex":[
- 0
- ],
-- "labels":[
-- 3
-- ]
-- }
+ "labels":[
+ 3
+ ]
+ }
- ],
- "backupNexthops":[
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt6",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
+- "active":true
+- }
]
}
-@@ -150,23 +113,7 @@
- "fib":true,
+ ],
+@@ -178,20 +138,10 @@
"afi":"ipv6",
"interfaceName":"eth-rt6",
-- "active":true,
+ "active":true,
- "backupIndex":[
- 0
- ],
-- "labels":[
-- 3
-- ]
-- }
+ "labels":[
+ 3
+ ]
+ }
- ],
- "backupNexthops":[
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
+- "active":true
+- }
]
}
+ ]
---- rt4/step3/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step4/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -1,210 +1,2 @@
- {
-- "16010":{
-- "inLabel":16010,
-- "installed":true,
-- "nexthops":[
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":16010,
-- "installed":true,
-- "nexthop":"10.0.3.2"
-- },
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":16010,
-- "installed":true,
-- "nexthop":"10.0.2.2"
-- }
-- ]
-- },
-- "16011":{
-- "inLabel":16011,
-- "installed":true,
-- "nexthops":[
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":16011,
-- "installed":true,
-- "interface":"eth-rt2-2"
-- },
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":16011,
-- "installed":true,
-- "interface":"eth-rt2-1"
+--- 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
+- ]
- }
-- ]
-- },
-- "16020":{
-- "inLabel":16020,
-- "installed":true,
-- "nexthops":[
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":3,
-- "installed":true,
-- "nexthop":"10.0.3.2"
-- },
+- ],
+- "backupNexthops":[
- {
- "type":"SR (IS-IS)",
- "outLabel":3,
-- "installed":true,
-- "nexthop":"10.0.2.2"
+- "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
+- ]
- }
-- ]
-- },
-- "16021":{
-- "inLabel":16021,
-- "installed":true,
-- "nexthops":[
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":3,
-- "installed":true,
-- "interface":"eth-rt2-2"
-- },
+- ],
+- "backupNexthops":[
- {
- "type":"SR (IS-IS)",
- "outLabel":3,
-- "installed":true,
-- "interface":"eth-rt2-1"
+- "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
+- ]
- }
-- ]
-- },
-- "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"
-- },
+- ],
+- "backupNexthops":[
- {
- "type":"SR (IS-IS)",
- "outLabel":16030,
-- "installed":true,
- "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
+- ]
- }
-- ]
-- },
-- "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"
-- },
+- ],
+- "backupNexthops":[
- {
- "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,
++ "interface":"eth-rt2-1"
+ }
+ ]
+ },
+@@ -179,17 +127,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
- "nexthop":"10.0.6.5",
- "backupIndex":[
- 0
- "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,
++ "nexthop":"10.0.6.5"
+ }
+ ]
+ },
+@@ -201,17 +139,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
- "interface":"eth-rt5",
- "backupIndex":[
- 0
- "type":"SR (IS-IS)",
- "outLabel":3,
- "interface":"eth-rt6"
-- }
-- ]
-- },
-- "16060":{
-- "inLabel":16060,
-- "installed":true,
-- "nexthops":[
-- {
-- "type":"SR (IS-IS)",
-- "outLabel":3,
-- "installed":true,
++ "interface":"eth-rt5"
+ }
+ ]
+ },
+@@ -223,17 +151,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
- "nexthop":"10.0.7.6",
- "backupIndex":[
- 0
- "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,
++ "nexthop":"10.0.7.6"
+ }
+ ]
+ },
+@@ -245,17 +163,7 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
- "interface":"eth-rt6",
- "backupIndex":[
- 0
- "type":"SR (IS-IS)",
- "outLabel":3,
- "interface":"eth-rt5"
-- }
-- ]
-- }
- }
++ "interface":"eth-rt6"
+ }
+ ]
+ }
---- rt4/step4/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step5/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -14,14 +14,20 @@
- "ip":"10.0.2.2",
+--- 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
-+ "active":true,
-+ "labels":[
-+ 16010
-+ ]
- },
- {
- "fib":true,
- "ip":"10.0.3.2",
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 16010
+ ]
+@@ -25,10 +28,21 @@
"afi":"ipv4",
"interfaceName":"eth-rt2-2",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 16010
-+ ]
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 16010
+ ]
}
++ ],
++ "backupNexthops":[
++ {
++ "ip":"10.0.6.5",
++ "afi":"ipv4",
++ "interfaceName":"eth-rt5",
++ "active":true
++ }
]
}
-@@ -41,14 +47,20 @@
- "ip":"10.0.2.2",
+ ],
+@@ -48,6 +62,9 @@
"afi":"ipv4",
"interfaceName":"eth-rt2-1",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- },
- {
- "fib":true,
- "ip":"10.0.3.2",
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 3
+ ]
+@@ -58,10 +75,25 @@
"afi":"ipv4",
"interfaceName":"eth-rt2-2",
-- "active":true
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 3
+ ]
+ }
++ ],
++ "backupNexthops":[
++ {
++ "ip":"10.0.6.5",
++ "afi":"ipv4",
++ "interfaceName":"eth-rt5",
+ "active":true,
+ "labels":[
-+ 3
++ 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
++ }
]
}
-@@ -68,21 +80,30 @@
+ ],
+@@ -169,13 +223,27 @@
"ip":"10.0.2.2",
"afi":"ipv4",
"interfaceName":"eth-rt2-1",
- "active":true
+ "active":true,
-+ "labels":[
-+ 16030
++ "backupIndex":[
++ 0
+ ]
},
{
"ip":"10.0.3.2",
"afi":"ipv4",
"interfaceName":"eth-rt2-2",
-- "active":true
+ "active":true,
-+ "labels":[
-+ 16030
++ "backupIndex":[
++ 0
+ ]
- },
++ }
++ ],
++ "backupNexthops":[
++ {
++ "ip":"10.0.6.5",
++ "afi":"ipv4",
++ "interfaceName":"eth-rt5",
+ "active":true
+ }
+ ]
+@@ -191,13 +259,30 @@
{
- "fib":true,
- "ip":"10.0.6.5",
+ "ip":"10.0.2.2",
"afi":"ipv4",
- "interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 16030
+- "interfaceName":"eth-rt2-1"
++ "interfaceName":"eth-rt2-1",
++ "backupIndex":[
++ 0
+ ]
- }
- ]
- }
-@@ -102,7 +123,24 @@
- "ip":"10.0.6.5",
+ },
+ {
+ "ip":"10.0.3.2",
"afi":"ipv4",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt2-2",
- "active":true
+ "active":true,
+ "backupIndex":[
+ 0
-+ ],
-+ "labels":[
-+ 3
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
-+ "ip":"10.0.7.6",
++ "ip":"10.0.6.5",
+ "afi":"ipv4",
-+ "interfaceName":"eth-rt6",
++ "interfaceName":"eth-rt5",
+ "active":true,
+ "labels":[
-+ 3
++ 16030
+ ]
}
]
}
-@@ -122,7 +160,24 @@
- "ip":"10.0.7.6",
+@@ -213,12 +298,29 @@
+ "ip":"10.0.2.2",
"afi":"ipv4",
- "interfaceName":"eth-rt6",
+ "interfaceName":"eth-rt2-1",
- "active":true
+ "active":true,
+ "backupIndex":[
+ 0
-+ ],
-+ "labels":[
-+ 3
++ ]
+ },
+ {
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+- "interfaceName":"eth-rt2-2"
++ "interfaceName":"eth-rt2-2",
++ "backupIndex":[
++ 0
+ ]
+ }
+ ],
+ "interfaceName":"eth-rt5",
+ "active":true,
+ "labels":[
-+ 3
++ 16030
+ ]
}
]
}
-@@ -211,6 +266,31 @@
+@@ -238,6 +340,31 @@
"ip":"10.0.6.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
"active":true
}
]
-@@ -231,6 +311,31 @@
+@@ -258,6 +385,31 @@
"ip":"10.0.6.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
"active":true
}
]
-@@ -246,7 +351,18 @@
+@@ -273,7 +425,18 @@
{
"ip":"10.0.6.5",
"afi":"ipv4",
}
]
}
-@@ -261,7 +377,18 @@
+@@ -288,7 +451,18 @@
{
"ip":"10.0.7.6",
"afi":"ipv4",
---- rt4/step4/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step5/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -13,13 +13,19 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt2-2",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 16011
-+ ]
- },
- {
- "fib":true,
+--- 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
-+ "active":true,
-+ "labels":[
-+ 16011
-+ ]
- }
- ]
- }
-@@ -38,13 +44,19 @@
- "fib":true,
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 16011
+ ]
+@@ -23,10 +26,20 @@
"afi":"ipv6",
"interfaceName":"eth-rt2-2",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- },
- {
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt2-1",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 16011
+ ]
}
++ ],
++ "backupNexthops":[
++ {
++ "afi":"ipv6",
++ "interfaceName":"eth-rt5",
++ "active":true
++ }
]
}
-@@ -63,19 +75,28 @@
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt2-2",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 16031
-+ ]
- },
- {
- "fib":true,
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 16031
-+ ]
- },
- {
- "fib":true,
+ ],
+@@ -45,6 +58,9 @@
"afi":"ipv6",
"interfaceName":"eth-rt2-1",
-- "active":true
+ "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
++ 16031,
++ 16021
+ ]
- }
++ }
]
}
-@@ -94,7 +115,23 @@
- "fib":true,
+ ],
+@@ -116,10 +146,20 @@
"afi":"ipv6",
"interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
+ "active":true,
+ "backupIndex":[
+ 0
+ ],
-+ "labels":[
-+ 3
-+ ]
-+ }
+ "labels":[
+ 3
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
++ "active":true
++ }
]
}
-@@ -113,7 +150,23 @@
- "fib":true,
+ ],
+@@ -138,10 +178,20 @@
"afi":"ipv6",
"interfaceName":"eth-rt6",
-- "active":true
-+ "active":true,
+ "active":true,
+ "backupIndex":[
+ 0
+ ],
-+ "labels":[
-+ 3
-+ ]
-+ }
+ "labels":[
+ 3
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
++ "active":true
++ }
]
}
+ ]
---- rt4/step4/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step5/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -1,2 +1,210 @@
- {
-+ "16010":{
-+ "inLabel":16010,
-+ "installed":true,
-+ "nexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":16010,
-+ "installed":true,
-+ "nexthop":"10.0.3.2"
-+ },
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":16010,
-+ "installed":true,
-+ "nexthop":"10.0.2.2"
-+ }
-+ ]
-+ },
-+ "16011":{
-+ "inLabel":16011,
-+ "installed":true,
-+ "nexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":16011,
-+ "installed":true,
-+ "interface":"eth-rt2-2"
-+ },
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":16011,
-+ "installed":true,
-+ "interface":"eth-rt2-1"
+--- 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
++ ]
+ }
-+ ]
-+ },
-+ "16020":{
-+ "inLabel":16020,
-+ "installed":true,
-+ "nexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":3,
-+ "installed":true,
-+ "nexthop":"10.0.3.2"
-+ },
++ ],
++ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
-+ "installed":true,
-+ "nexthop":"10.0.2.2"
++ "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
++ ]
+ }
-+ ]
-+ },
-+ "16021":{
-+ "inLabel":16021,
-+ "installed":true,
-+ "nexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":3,
-+ "installed":true,
-+ "interface":"eth-rt2-2"
-+ },
++ ],
++ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
-+ "installed":true,
-+ "interface":"eth-rt2-1"
++ "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
++ ]
+ }
-+ ]
-+ },
-+ "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"
-+ },
++ ],
++ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":16030,
-+ "installed":true,
+ "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
++ ]
+ }
-+ ]
-+ },
-+ "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"
-+ },
++ ],
++ "backupNexthops":[
+ {
+ "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,
+ }
+ ]
+ },
+@@ -127,7 +179,17 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "nexthop":"10.0.6.5"
+ "nexthop":"10.0.6.5",
+ "backupIndex":[
+ 0
+ "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,
+ }
+ ]
+ },
+@@ -139,7 +201,17 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "interface":"eth-rt5"
+ "interface":"eth-rt5",
+ "backupIndex":[
+ 0
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "interface":"eth-rt6"
-+ }
-+ ]
-+ },
-+ "16060":{
-+ "inLabel":16060,
-+ "installed":true,
-+ "nexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":3,
-+ "installed":true,
+ }
+ ]
+ },
+@@ -151,7 +223,17 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "nexthop":"10.0.7.6"
+ "nexthop":"10.0.7.6",
+ "backupIndex":[
+ 0
+ "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,
+ }
+ ]
+ },
+@@ -163,7 +245,17 @@
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "installed":true,
+- "interface":"eth-rt6"
+ "interface":"eth-rt6",
+ "backupIndex":[
+ 0
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "interface":"eth-rt5"
-+ }
-+ ]
-+ }
- }
+ }
+ ]
+ }
---- rt4/step5/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step6/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -102,7 +102,7 @@
+--- 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":[
---- rt4/step5/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step6/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -86,7 +86,7 @@
+--- 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":[
---- rt4/step5/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step6/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -89,7 +89,7 @@
+--- 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)",
"installed":true,
"nexthop":"10.0.6.5"
}
-@@ -113,7 +113,7 @@
+@@ -165,7 +165,7 @@
},
{
"type":"SR (IS-IS)",
---- rt4/step6/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step7/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -126,9 +126,6 @@
+--- 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
]
}
],
-@@ -137,10 +134,7 @@
- "ip":"10.0.7.6",
- "afi":"ipv4",
- "interfaceName":"eth-rt6",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
---- rt4/step6/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step7/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -118,9 +118,6 @@
+--- 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
]
}
],
-@@ -128,10 +125,7 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt6",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
---- rt4/step6/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step7/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -119,50 +119,6 @@
+--- 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 @@
}
]
},
---- rt4/step7/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step8/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -126,6 +126,9 @@
+--- 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
]
}
],
-@@ -134,7 +137,10 @@
- "ip":"10.0.7.6",
- "afi":"ipv4",
- "interfaceName":"eth-rt6",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
---- rt4/step7/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step8/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -118,6 +118,9 @@
+--- 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
]
}
],
-@@ -125,7 +128,10 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt6",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
---- rt4/step7/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step8/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -119,6 +119,50 @@
+--- 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 @@
}
]
},
---- rt4/step8/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step9/show_mpls_table.ref 2020-08-31 22:42:48.839561398 -0300
-@@ -119,15 +119,15 @@
+--- 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 @@
}
]
},
"backupIndex":[
0
]
-@@ -137,19 +137,19 @@
+@@ -189,19 +189,19 @@
{
"type":"SR (IS-IS)",
"outLabel":3,
"backupIndex":[
0
]
-@@ -159,19 +159,19 @@
+@@ -211,19 +211,19 @@
{
"type":"SR (IS-IS)",
"outLabel":3,
"backupIndex":[
0
]
-@@ -181,19 +181,19 @@
+@@ -233,19 +233,19 @@
{
"type":"SR (IS-IS)",
"outLabel":3,
"backupIndex":[
0
]
-@@ -203,7 +203,7 @@
+@@ -255,7 +255,7 @@
{
"type":"SR (IS-IS)",
"outLabel":3,
"afi":"ipv4",
"interfaceName":"eth-rt3-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16010
]
"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
+ }
]
}
],
"afi":"ipv4",
"interfaceName":"eth-rt3-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
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
+ ]
+ }
]
}
],
"ip":"10.0.8.6",
"afi":"ipv4",
"interfaceName":"eth-rt6",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"ip":"10.0.6.4",
"afi":"ipv4",
"interfaceName":"eth-rt4",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"ip":"10.0.4.3",
"afi":"ipv4",
"interfaceName":"eth-rt3-1",
- "active":true
+ "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
}
]
{
"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
+ ]
}
]
}
"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
+ ]
}
]
}
"afi":"ipv6",
"interfaceName":"eth-rt3-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16011
]
"afi":"ipv6",
"interfaceName":"eth-rt3-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
16011
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
]
}
],
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt3-1",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16021
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt3-1",
"active":true,
"labels":[
16021
"afi":"ipv6",
"interfaceName":"eth-rt3-1",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
"afi":"ipv6",
"interfaceName":"eth-rt3-2",
"active":true,
+ "backupIndex":[
+ 0
+ ],
"labels":[
3
]
}
+ ],
+ "backupNexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true,
+ "labels":[
+ 16021,
+ 16031
+ ]
+ }
]
}
],
{
"afi":"ipv6",
"interfaceName":"eth-rt6",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
{
"afi":"ipv6",
"interfaceName":"eth-rt4",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"type":"SR (IS-IS)",
"outLabel":16010,
"installed":true,
- "nexthop":"10.0.5.3"
+ "nexthop":"10.0.5.3",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":16010,
"installed":true,
- "nexthop":"10.0.4.3"
+ "nexthop":"10.0.4.3",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "nexthop":"10.0.6.4"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16011,
"installed":true,
- "interface":"eth-rt3-2"
+ "interface":"eth-rt3-2",
+ "backupIndex":[
+ 0
+ ]
},
{
"type":"SR (IS-IS)",
"outLabel":16011,
"installed":true,
- "interface":"eth-rt3-1"
+ "interface":"eth-rt3-1",
+ "backupIndex":[
+ 0
+ ]
+ }
+ ],
+ "backupNexthops":[
+ {
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "interface":"eth-rt4"
}
]
},
"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"
}
]
},
"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"
}
]
},
---- rt5/step3/show_ip_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt5/step4/show_ip_route.ref 2020-08-31 22:42:48.843561366 -0300
-@@ -69,7 +69,7 @@
+--- 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":[
-- 16020
-+ 3
+ 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
+- ]
+- }
]
-@@ -126,9 +126,6 @@
+ }
+ ],
+@@ -158,9 +137,6 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -137,10 +134,7 @@
- "ip":"10.0.8.6",
+@@ -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-rt6",
+ "interfaceName":"eth-rt3-2",
+- "active":true,
+- "backupIndex":[
+- 0
+- ]
+- }
+- ],
+- "backupNexthops":[
+- {
+- "ip":"10.0.6.4",
+- "afi":"ipv4",
+- "interfaceName":"eth-rt4",
- "active":true,
- "labels":[
-- 3
+- 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"
}
]
}
---- rt5/step3/show_ipv6_route.ref 2020-08-31 22:42:48.839561398 -0300
-+++ rt5/step4/show_ipv6_route.ref 2020-08-31 22:42:48.843561366 -0300
-@@ -55,7 +55,7 @@
+--- 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":[
+- "active":true,
+- "labels":[
- 16021
-+ 3
- ]
+- ]
++ "active":true
},
{
-@@ -118,9 +118,6 @@
+ "fib":true,
+@@ -98,9 +95,6 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3-1",
"active":true,
- "backupIndex":[
- 0
+- "backupIndex":[
+- 0
- ],
-- "labels":[
-- 3
+ "labels":[
+ 3
]
- }
- ],
-@@ -128,10 +125,7 @@
- {
+@@ -110,24 +104,10 @@
"afi":"ipv6",
- "interfaceName":"eth-rt6",
+ "interfaceName":"eth-rt3-2",
+ "active":true,
+- "backupIndex":[
+- 0
+- ],
+ "labels":[
+ 3
+ ]
+ }
+- ],
+- "backupNexthops":[
+- {
+- "afi":"ipv6",
+- "interfaceName":"eth-rt4",
- "active":true,
- "labels":[
-- 3
+- 16021,
+- 16031
- ]
-+ "active":true
- }
+- }
]
}
+ ],
+@@ -148,9 +128,6 @@
+ "active":true,
+ "backupIndex":[
+ 0
+- ],
+- "labels":[
+- 3
+ ]
+ }
+ ],
---- rt5/step3/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step4/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
-@@ -53,7 +53,7 @@
- },
- {
- "type":"SR (IS-IS)",
+--- 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,
-+ "outLabel":3,
+- "installed":true,
+- "nexthop":"10.0.6.4"
+ }
+ ]
+ },
+@@ -100,12 +94,6 @@
+ "outLabel":16021,
"installed":true,
- "nexthop":"10.0.6.4"
+ "interface":"eth-rt3-1"
+- },
+- {
+- "type":"SR (IS-IS)",
+- "outLabel":16021,
+- "installed":true,
+- "interface":"eth-rt4"
}
-@@ -77,7 +77,7 @@
+ ]
+ },
+@@ -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":16021,
-+ "outLabel":3,
+ "outLabel":3,
"installed":true,
- "interface":"eth-rt4"
- }
-@@ -119,50 +119,6 @@
+- "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,
- "type":"SR (IS-IS)",
- "outLabel":3,
- "interface":"eth-rt6"
-- }
-- ]
-- },
- "16060":{
- "inLabel":16060,
- "installed":true,
++ "interface":"eth-rt3-1"
+ }
+ ]
+ },
---- rt5/step4/show_ip_route.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step5/show_ip_route.ref 2020-08-31 22:42:48.843561366 -0300
-@@ -69,7 +69,7 @@
+--- 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
-+ 16020
+ 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
++ ]
++ }
]
-@@ -126,6 +126,9 @@
+ }
+ ],
+@@ -137,6 +158,9 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -134,7 +137,10 @@
- "ip":"10.0.8.6",
+@@ -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-rt6",
+ "interfaceName":"eth-rt3-2",
- "active":true
+ "active":true,
++ "backupIndex":[
++ 0
++ ]
++ }
++ ],
++ "backupNexthops":[
++ {
++ "ip":"10.0.6.4",
++ "afi":"ipv4",
++ "interfaceName":"eth-rt4",
++ "active":true,
+ "labels":[
-+ 3
++ 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
+ ]
}
]
---- rt5/step4/show_ipv6_route.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step5/show_ipv6_route.ref 2020-08-31 22:42:48.843561366 -0300
-@@ -55,7 +55,7 @@
+--- 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,
- "labels":[
-- 3
+- "active":true
++ "active":true,
++ "labels":[
+ 16021
- ]
++ ]
},
{
-@@ -118,6 +118,9 @@
+ "fib":true,
+@@ -95,6 +98,9 @@
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3-1",
"active":true,
- "backupIndex":[
- 0
++ "backupIndex":[
++ 0
+ ],
-+ "labels":[
-+ 3
+ "labels":[
+ 3
]
- }
- ],
-@@ -125,7 +128,10 @@
- {
+@@ -104,10 +110,24 @@
"afi":"ipv6",
- "interfaceName":"eth-rt6",
-- "active":true
+ "interfaceName":"eth-rt3-2",
+ "active":true,
++ "backupIndex":[
++ 0
++ ],
+ "labels":[
+ 3
+ ]
+ }
++ ],
++ "backupNexthops":[
++ {
++ "afi":"ipv6",
++ "interfaceName":"eth-rt4",
+ "active":true,
+ "labels":[
-+ 3
++ 16021,
++ 16031
+ ]
- }
++ }
]
}
+ ],
+@@ -128,6 +148,9 @@
+ "active":true,
+ "backupIndex":[
+ 0
++ ],
++ "labels":[
++ 3
+ ]
+ }
+ ],
---- rt5/step4/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step5/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
-@@ -53,7 +53,7 @@
+--- 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":3,
-+ "outLabel":16020,
+ "outLabel":16021,
"installed":true,
- "nexthop":"10.0.6.4"
- }
-@@ -77,7 +77,7 @@
++ "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,
-+ "outLabel":16021,
+ "outLabel":3,
"installed":true,
- "interface":"eth-rt4"
- }
-@@ -119,6 +119,50 @@
+- "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,
+ "type":"SR (IS-IS)",
+ "outLabel":3,
+ "interface":"eth-rt6"
-+ }
-+ ]
-+ },
- "16060":{
- "inLabel":16060,
- "installed":true,
+ }
+ ]
+ },
---- rt5/step5/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step6/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
+--- 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":{
"installed":true,
"nexthops":[
{
-@@ -17,8 +17,8 @@
+@@ -30,8 +30,8 @@
}
]
},
"installed":true,
"nexthops":[
{
-@@ -35,8 +35,8 @@
+@@ -61,56 +61,56 @@
}
]
},
"installed":true,
"nexthops":[
{
-@@ -59,8 +59,8 @@
+ "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"
}
]
},
"installed":true,
"nexthops":[
{
-@@ -83,8 +83,8 @@
+ "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"
}
]
},
"installed":true,
"nexthops":[
{
-@@ -101,8 +101,8 @@
+@@ -140,8 +140,8 @@
}
]
},
"installed":true,
"nexthops":[
{
-@@ -119,8 +119,8 @@
+@@ -171,8 +171,8 @@
}
]
},
"installed":true,
"nexthops":[
{
-@@ -141,8 +141,8 @@
+@@ -193,8 +193,8 @@
}
]
},
"installed":true,
"nexthops":[
{
-@@ -163,8 +163,8 @@
+@@ -215,8 +215,8 @@
}
]
},
"installed":true,
"nexthops":[
{
-@@ -185,8 +185,8 @@
+@@ -237,8 +237,8 @@
}
]
},
"ip":"10.0.8.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"ip":"10.0.7.4",
"afi":"ipv4",
"interfaceName":"eth-rt4",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"ip":"10.0.8.5",
"afi":"ipv4",
"interfaceName":"eth-rt5",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"ip":"10.0.7.4",
"afi":"ipv4",
"interfaceName":"eth-rt4",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt4",
+ "interfaceName":"eth-rt5",
"active":true,
"labels":[
16011
{
"fib":true,
"afi":"ipv6",
- "interfaceName":"eth-rt5",
+ "interfaceName":"eth-rt4",
"active":true,
"labels":[
16011
{
"afi":"ipv6",
"interfaceName":"eth-rt5",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
{
"afi":"ipv6",
"interfaceName":"eth-rt4",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
{
"afi":"ipv6",
"interfaceName":"eth-rt5",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
{
"afi":"ipv6",
"interfaceName":"eth-rt4",
- "active":true,
- "labels":[
- 3
- ]
+ "active":true
}
]
}
"type":"SR (IS-IS)",
"outLabel":16010,
"installed":true,
- "nexthop":"10.0.8.5"
+ "nexthop":"10.0.7.4"
},
{
"type":"SR (IS-IS)",
"outLabel":16010,
"installed":true,
- "nexthop":"10.0.7.4"
+ "nexthop":"10.0.8.5"
}
]
},
"type":"SR (IS-IS)",
"outLabel":16011,
"installed":true,
- "interface":"eth-rt5"
+ "interface":"eth-rt4"
},
{
"type":"SR (IS-IS)",
"outLabel":16011,
"installed":true,
- "interface":"eth-rt4"
+ "interface":"eth-rt5"
}
]
},
---- rt6/step3/show_ip_route.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt6/step4/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -16,7 +16,7 @@
+--- 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":[
+- "active":true,
+- "labels":[
- 16010
-+ 3
- ]
+- ]
++ "active":true
},
{
-@@ -50,9 +50,6 @@
+ "fib":true,
+@@ -50,9 +47,6 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -61,10 +58,7 @@
- "ip":"10.0.8.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
-@@ -124,9 +118,6 @@
+@@ -118,9 +112,6 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -135,10 +126,7 @@
- "ip":"10.0.8.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
---- rt6/step3/show_ipv6_route.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt6/step4/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -15,7 +15,7 @@
+--- 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":[
+- "active":true,
+- "labels":[
- 16011
-+ 3
- ]
- },
- {
-@@ -47,9 +47,6 @@
+- ]
++ "active":true
+ }
+ ]
+ }
+@@ -47,9 +44,6 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -57,10 +54,7 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
-@@ -117,9 +111,6 @@
+@@ -111,9 +105,6 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -127,10 +118,7 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
---- rt6/step3/show_mpls_table.ref 2020-08-31 22:42:48.843561366 -0300
-+++ rt6/step4/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -11,7 +11,7 @@
- },
- {
+--- 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,
-+ "outLabel":3,
+ "outLabel":16010,
"installed":true,
- "nexthop":"10.0.7.4"
- }
-@@ -29,53 +29,9 @@
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16011,
-- "installed":true,
-- "interface":"eth-rt4"
-- }
-- ]
-- },
-- "16020":{
-- "inLabel":16020,
-- "installed":true,
-- "nexthops":[
+- "nexthop":"10.0.7.4"
+- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":16020,
+- "outLabel":16010,
- "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,
+ "nexthop":"10.0.8.5"
+ }
+ ]
+@@ -25,12 +19,6 @@
+ "type":"SR (IS-IS)",
+ "outLabel":16011,
"installed":true,
-- "interface":"eth-rt4",
-- "backupIndex":[
-- 0
-- ]
-- }
-- ],
-- "backupNexthops":[
+- "interface":"eth-rt4"
+- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":3,
-- "interface":"eth-rt5"
-+ "interface":"eth-rt4"
+- "outLabel":16011,
+- "installed":true,
+ "interface":"eth-rt5"
}
]
- },
-@@ -123,50 +79,6 @@
+@@ -123,50 +111,6 @@
}
]
},
---- rt6/step4/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step5/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -16,7 +16,7 @@
+--- 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,
- "labels":[
-- 3
+- "active":true
++ "active":true,
++ "labels":[
+ 16010
- ]
++ ]
},
{
-@@ -50,6 +50,9 @@
+ "fib":true,
+@@ -47,6 +50,9 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -58,7 +61,10 @@
- "ip":"10.0.8.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
-@@ -118,6 +124,9 @@
+@@ -112,6 +118,9 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -126,7 +135,10 @@
- "ip":"10.0.8.5",
- "afi":"ipv4",
- "interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
---- rt6/step4/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step5/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -15,7 +15,7 @@
+--- 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,
- "labels":[
-- 3
+- "active":true
++ "active":true,
++ "labels":[
+ 16011
- ]
- },
- {
-@@ -47,6 +47,9 @@
++ ]
+ }
+ ]
+ }
+@@ -44,6 +47,9 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -54,7 +57,10 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
-@@ -111,6 +117,9 @@
+@@ -105,6 +111,9 @@
"active":true,
"backupIndex":[
0
]
}
],
-@@ -118,7 +127,10 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt5",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
---- rt6/step4/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step5/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -11,7 +11,7 @@
- },
- {
+--- 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":3,
-+ "outLabel":16010,
+ "outLabel":16010,
"installed":true,
- "nexthop":"10.0.7.4"
- }
-@@ -29,12 +29,56 @@
- },
- {
- "type":"SR (IS-IS)",
-- "outLabel":3,
-+ "outLabel":16011,
- "installed":true,
- "interface":"eth-rt4"
- }
- ]
- },
-+ "16020":{
-+ "inLabel":16020,
-+ "installed":true,
-+ "nexthops":[
++ "nexthop":"10.0.7.4"
++ },
+ {
+ "type":"SR (IS-IS)",
-+ "outLabel":16020,
++ "outLabel":16010,
+ "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":[
+ "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":16021,
++ "outLabel":16011,
+ "installed":true,
-+ "interface":"eth-rt4",
-+ "backupIndex":[
-+ 0
-+ ]
-+ }
-+ ],
-+ "backupNexthops":[
-+ {
-+ "type":"SR (IS-IS)",
-+ "outLabel":3,
-+ "interface":"eth-rt5"
-+ }
-+ ]
-+ },
- "16030":{
- "inLabel":16030,
- "installed":true,
-@@ -79,6 +123,50 @@
+ "interface":"eth-rt5"
+ }
+ ]
+@@ -111,6 +123,50 @@
}
]
},
---- rt6/step5/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step6/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
+--- 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,
]
}
]
-@@ -89,7 +89,7 @@
+@@ -86,7 +86,7 @@
0
],
"labels":[
---- rt6/step5/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step6/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -24,7 +24,7 @@
+--- 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
]
- }
- ]
-@@ -84,7 +84,7 @@
+ },
+ {
+@@ -81,7 +81,7 @@
0
],
"labels":[
---- rt6/step5/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step6/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -5,7 +5,7 @@
- "nexthops":[
+--- 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 @@
},
-@@ -23,7 +23,7 @@
- "nexthops":[
{
"type":"SR (IS-IS)",
- "outLabel":16011,
+ "outLabel":30011,
"installed":true,
"interface":"eth-rt5"
- },
+ }
@@ -85,7 +85,7 @@
"nexthops":[
{
---- rt6/step6/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step7/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -161,9 +161,6 @@
+--- 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
]
}
],
-@@ -172,10 +169,7 @@
- "ip":"10.0.7.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
---- rt6/step6/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step7/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -152,9 +152,6 @@
+--- 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
]
}
],
-@@ -162,10 +159,7 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt4",
-- "active":true,
-- "labels":[
-- 3
-- ]
-+ "active":true
- }
- ]
- }
---- rt6/step6/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step7/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
+--- 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"
}
---- rt6/step7/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step8/show_ip_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -161,6 +161,9 @@
+--- 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
]
}
],
-@@ -169,7 +172,10 @@
- "ip":"10.0.7.4",
- "afi":"ipv4",
- "interfaceName":"eth-rt4",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
---- rt6/step7/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step8/show_ipv6_route.ref 2020-08-31 22:42:48.847561334 -0300
-@@ -152,6 +152,9 @@
+--- 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
]
}
],
-@@ -159,7 +162,10 @@
- {
- "afi":"ipv6",
- "interfaceName":"eth-rt4",
-- "active":true
-+ "active":true,
-+ "labels":[
-+ 3
-+ ]
- }
- ]
- }
---- rt6/step7/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step8/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
+--- 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"
}
---- rt6/step8/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step9/show_mpls_table.ref 2020-08-31 22:42:48.847561334 -0300
+--- 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 @@
}
]
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
}
],
"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": [
{
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
}
],
"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": [
{
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
}
],
"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": [
{
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
}
],
"10.0.21.0/24": [
- {
- "nexthops": [
- {
- "afi": "ipv4",
- "interfaceName": "r4-eth0",
- "ip": "10.0.21.2"
- }
- ],
- "prefix": "10.0.21.0/24",
- "protocol": "isis",
- "vrfName": "r4-cust1"
- },
{
"nexthops": [
{
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
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
}
],
"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": [
{
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
}
],
"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": [
{
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
!
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
}
],
"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": [
{
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
!
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
}
],
"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": [
{
debug isis update-packets
interface r5-eth0
ip router isis 1
+ isis hello-interval 2
ipv6 router isis 1
isis circuit-type level-1
!
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
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
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
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
--- /dev/null
+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
--- /dev/null
+@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
# 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
/* 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));
"\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");
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();
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);
return;
}
THREAD_OFF(dmn->t_wakeup);
+
if (try_connect(dmn) < 0)
SET_WAKEUP_DOWN(dmn);
}
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;
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);
}
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 {
type uint8 {
range "1..255";
}
+ default "20";
description
"Administrative distance for routes learned from
external BGP (EBGP).";
type uint8 {
range "1..255";
}
+ default "200";
description
"Administrative distance for routes learned from
internal BGP (IBGP).";
type uint8 {
range "1..255";
}
+ default "200";
description
"Administrative distance for routes learned from
local.";
case import-export {
uses rt-list;
}
+
case both {
leaf-list rt-list {
type rt-types:route-target;
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;
uses distance-per-route-config;
}
+ uses route-flap-dampening;
+
uses mp-afi-unicast-common;
uses global-filter-config;
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" {
description
"IPv4 multicast destination prefix.";
}
+
+ uses distance-per-route-config;
}
uses admin-distance;
description
"IPv6 multicast destination prefix.";
}
+
+ uses distance-per-route-config;
}
+ uses route-flap-dampening;
+
uses admin-distance;
}
description
"Configure last hop behavior.";
}
+ leaf n-flag-clear {
+ type boolean;
+ default "false";
+ description
+ "Not a node SID";
+ }
}
}
}
description
"List of nexthop groups, each contains group of nexthops";
leaf name {
- type nexthop-group-ref;
+ type string;
description
"The nexthop-group name.";
}
enum vnc {
value 17;
}
+ enum vnc-direct {
+ value 18;
+ }
enum babel {
value 22;
}
enum vnc {
value 17;
}
+ enum vnc-direct {
+ value 18;
+ }
enum babel {
value 22;
}
/* 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);
}
}
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",
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)
/* 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);
}
}
/* 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);
}
}
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.
*/
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;
}
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);
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;
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) {
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)
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]) {
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;
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);
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
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);
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);
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) {
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;
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;
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)
{
struct route_node *rn;
struct zebra_if *zebra_if;
struct vrf *vrf;
+ char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
zebra_if = ifp->info;
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;
}
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)
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);
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;
#include "zebra/zebra_l2.h"
#include "zebra/zebra_nhg_private.h"
+#include "zebra/zebra_router.h"
#ifdef __cplusplus
extern "C" {
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;
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;
/* 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;
#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)
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);
{
struct zebra_if *zi = ifp->info;
struct irdp_interface *irdp = zi->irdp;
- char buf[PREFIX_STRLEN];
uint32_t dst;
uint32_t ttl = 1;
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);
}
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)) {
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;
struct zebra_if *zi;
struct irdp_interface *irdp;
uint16_t saved_chksum;
+ char buf[PREFIX_STRLEN];
zi = ifp->info;
if (!zi)
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;
}
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;
}
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;
}
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;
}
&& !(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;
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;
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);
}
}
{
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;
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:
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);
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;
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);
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));
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) {
}
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;
}
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);
}
struct listnode *node, *nnode;
struct zserv *client;
int afi;
- char buf[PREFIX_STRLEN];
vrf_id_t vrfid;
if (old_re)
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. */
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;
}
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))
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);
* 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);
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,
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);
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);
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;
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;
}
}
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))
: "",
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;
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];
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;
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(
*/
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:
__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(
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])
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,
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;
}
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:
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;
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;
}
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;
}
struct rtadv_prefix *rprefix;
struct rtadv_rdnss *rdnss;
struct rtadv_dnssl *dnssl;
- char buf[PREFIX_STRLEN];
int interval;
zif = ifp->info;
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)) {
} *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;
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);
}
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. */
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);
}
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);
}
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);
}
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);
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));
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,
#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 */
uint8_t nh_grp_count;
};
+/*
+ * 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 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;
};
/*
union pw_protocol_fields fields;
};
+/*
+ * 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_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;
_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;
*/
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.
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:
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;
}
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;
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.
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;
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 */
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;
return result;
}
+/*
+ * 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.
*/
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();
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;
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;
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;
}
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:
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:
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;
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:
return zdplane_info.dg_is_shutdown;
}
+/*
+ * 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
/* Link layer address discovery */
DPLANE_OP_NEIGH_DISCOVER,
+
+ /* bridge port update */
+ DPLANE_OP_BR_PORT_UPDATE,
};
/*
#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);
*/
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);
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);
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);
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;
/* 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.
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];
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);
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);
}
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];
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);
}
{
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. */
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));
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));
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);
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)
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();
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");
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);
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 ");
}
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",
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];
"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);
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];
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);
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;
}
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;
}
* ZEBRA_MAC_ES_PEER_ACTIVE or ZEBRA_NEIGH_ES_PEER_PROXY
*/
uint32_t sync_neigh_cnt;
+
+ time_t uptime;
};
/*
#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"
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;
}
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)
}
}
-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)
}
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);
}
}
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");
}
return;
}
- zebra_evpn_es_evi_show_one_evpn(zevpn, vty, json, detail);
+
+ 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);
+ }
}
/* Initialize the ES tables maintained per-L2_VNI */
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)
{
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",
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)
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
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;
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);
}
/*****************************************************************************
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);
}
}
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 */
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;
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);
}
}
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);
}
}
+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)
{
/* 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
*/
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
*/
*/
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);
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;
}
/* 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) {
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) {
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) {
}
}
- 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;
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)
}
}
+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)
{
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)
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);
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));
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)
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");
}
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)
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)
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,
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
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
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;
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();
/* 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)
#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;
/* 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);
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 */
};
#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)
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 */
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);
n->ifindex = ifindex;
inform_dataplane = true;
}
+
+ n->uptime = monotime(NULL);
}
/* update the neigh seq. we don't bother with the mac seq as
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);
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;
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";
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:");
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);
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)) {
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];
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");
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");
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;
}
time_t dad_dup_detect_time;
+ time_t uptime;
+
/* used for ageing out the PEER_ACTIVE flag */
struct thread *hold_timer;
};
*/
static inline void zfpm_read_off(void)
{
- THREAD_READ_OFF(zfpm_g->t_read);
+ thread_cancel(&zfpm_g->t_read);
}
/*
*/
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);
}
/*
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
}
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);
return;
zfpm_debug("Stopping existing stats timer");
- THREAD_TIMER_OFF(zfpm_g->t_stats);
+ thread_cancel(&zfpm_g->t_stats);
}
/*
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;
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)
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");
}
}
#include "zebra/zebra_fpm_private.h"
#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
*
{
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)
);
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;
}
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);
}
}
#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"
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);
+ }
}
/*
/* 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.
*/
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);
}
}
/* 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,
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? */
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);
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
}
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)
|| 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 =
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);
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);
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:
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,
{
struct route_table *table;
zebra_fec_t *fec;
- char buf[BUFSIZ];
bool new_client;
bool label_change = false;
uint32_t old_label;
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;
}
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;
}
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",
{
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
{
struct route_table *table;
zebra_fec_t *fec;
- char buf[BUFSIZ];
mpls_label_t old_label;
int ret = 0;
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)
/* 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);
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)
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);
}
struct route_node *rn;
int af;
zebra_fec_t *fec;
- char buf[BUFSIZ];
int write = 0;
for (af = AFI_IP; af < AFI_MAX; af++) {
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));
}
}
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;
* 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);
}
}
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);
}
}
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);
}
}
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);
#include "lib/log.h"
#include "lib/northbound.h"
+#include "lib/printfrr.h"
#include "libfrr.h"
#include "lib/command.h"
#include "lib/routemap.h"
{
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");
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;
}
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;
}
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)
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);
/* 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,
nhe->nhg.nexthop->vrf_id, nhe->id);
}
-
return nhe;
}
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;
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);
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.
*
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.
*/
* 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;
"(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)
"(R)" : "");
depends_find_add(&backup_nhe->nhg_depends, nh, afi,
- backup_nhe->type);
+ backup_nhe->type, from_dplane);
}
}
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;
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 {
}
}
- 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 = {};
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)",
}
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(
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);
}
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 = {};
*/
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);
}
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;
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) {
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",
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)",
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)",
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);
}
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;
}
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
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);
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);
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);
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);
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,
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);
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);
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);
}
struct route_node *rn,
struct zebra_dplane_ctx *ctx)
{
- char dest_str[PREFIX_STRLEN] = "";
struct nexthop *nexthop;
bool matched;
const struct nexthop_group *ctxnhg;
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.
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)) {
*/
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;
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);
}
/*
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;
}
*/
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)");
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) {
*/
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;
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);
}
/*
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);
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;
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;
}
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));
/*
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);
}
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);
}
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 */
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:
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);
}
/*
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;
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;
}
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
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;
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)));
}
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);
}
/*
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,
} 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.
} 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.
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
/* 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;
}
struct route_node *rn;
struct route_entry *re;
struct vrf *vrf;
- char prefix_buf[INET_ADDRSTRLEN];
vrf = vrf_lookup_by_id(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;
}
*/
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);
/* 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))
: "");
}
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)
/* 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);
}
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)
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);
{
int state_changed = 0;
struct zserv *client;
- char bufn[INET6_ADDRSTRLEN];
struct listnode *node;
zebra_rnh_remove_from_routing_table(rnh);
}
if (state_changed || force) {
- if (IS_ZEBRA_DEBUG_NHT) {
- prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
+ 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,
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));
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);
}
}
/* 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();
}
/* 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;
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;
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(
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,
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");
struct vty *vty;
vrf_id_t vrf_id;
afi_t afi;
+ int type;
};
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:
}
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);
}
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"
"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);
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");
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;
return CMD_WARNING;
}
- show_nexthop_group_cmd_helper(vty, zvrf, afi);
+ show_nexthop_group_cmd_helper(vty, zvrf, afi, type);
return CMD_SUCCESS;
}
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\
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]",
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"
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;
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;
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);
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);
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(
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);
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;
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);
/* 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;
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));
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",
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);
{
char buf[ETHER_ADDR_STRLEN];
char buf1[INET6_ADDRSTRLEN];
- char buf2[PREFIX_STRLEN];
zebra_mac_t *zrmac = NULL;
zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
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));
&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;
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. */
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;
}
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 */
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",
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);
vty_out(vty, " Detection freeze %s\n",
"permanent");
}
+ zebra_evpn_mh_print(vty);
}
if (uj) {
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);
}
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,
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));
}
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;
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. */
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. */
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 */
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 */
/* 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 */
}
}
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");