summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_open.c129
-rw-r--r--bgpd/bgp_route.c30
-rw-r--r--bgpd/bgp_route.h5
-rw-r--r--bgpd/bgp_vty.c1
-rw-r--r--bgpd/bgp_zebra.c5
-rw-r--r--bgpd/bgpd.c10
-rw-r--r--doc/user/bgp.rst9
-rw-r--r--include/linux/nexthop.h59
-rw-r--r--lib/route_opaque.h6
-rw-r--r--lib/zclient.c2
-rw-r--r--tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py2
-rw-r--r--zebra/debug_nl.c1
-rw-r--r--zebra/kernel_netlink.h4
-rw-r--r--zebra/zapi_msg.c1
-rw-r--r--zebra/zebra_vty.c5
15 files changed, 168 insertions, 101 deletions
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index f1dfebdc1b..ca8b1e398b 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -42,6 +42,63 @@
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_memory.h"
+static const struct message capcode_str[] = {
+ {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
+ {CAPABILITY_CODE_REFRESH, "Route Refresh"},
+ {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
+ {CAPABILITY_CODE_RESTART, "Graceful Restart"},
+ {CAPABILITY_CODE_AS4, "4-octet AS number"},
+ {CAPABILITY_CODE_ADDPATH, "AddPath"},
+ {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
+ {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
+ {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
+ {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
+ {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
+ {CAPABILITY_CODE_FQDN, "FQDN"},
+ {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"},
+ {CAPABILITY_CODE_EXT_MESSAGE, "BGP Extended Message"},
+ {0}};
+
+/* Minimum sizes for length field of each cap (so not inc. the header) */
+static const size_t cap_minsizes[] = {
+ [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
+ [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
+ [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
+ [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
+ [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
+ [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
+ [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
+ [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
+ [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
+ [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
+ [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
+ [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
+ [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN,
+ [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN,
+};
+
+/* value the capability must be a multiple of.
+ * 0-data capabilities won't be checked against this.
+ * Other capabilities whose data doesn't fall on convenient boundaries for this
+ * table should be set to 1.
+ */
+static const size_t cap_modsizes[] = {
+ [CAPABILITY_CODE_MP] = 4,
+ [CAPABILITY_CODE_REFRESH] = 1,
+ [CAPABILITY_CODE_ORF] = 1,
+ [CAPABILITY_CODE_RESTART] = 1,
+ [CAPABILITY_CODE_AS4] = 4,
+ [CAPABILITY_CODE_ADDPATH] = 4,
+ [CAPABILITY_CODE_DYNAMIC] = 1,
+ [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
+ [CAPABILITY_CODE_ENHE] = 6,
+ [CAPABILITY_CODE_REFRESH_OLD] = 1,
+ [CAPABILITY_CODE_ORF_OLD] = 1,
+ [CAPABILITY_CODE_FQDN] = 1,
+ [CAPABILITY_CODE_ENHANCED_RR] = 1,
+ [CAPABILITY_CODE_EXT_MESSAGE] = 1,
+};
+
/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
negotiate remote peer supports extentions or not. But if
remote-peer doesn't supports negotiation process itself. We would
@@ -264,9 +321,9 @@ static int bgp_capability_mp(struct peer *peer, struct capability_header *hdr)
bgp_capability_mp_data(s, &mpc);
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %s/%s",
- peer->host, iana_afi2str(mpc.afi),
- iana_safi2str(mpc.safi));
+ zlog_debug("%s OPEN has %s capability for afi/safi: %s/%s",
+ peer->host, lookup_msg(capcode_str, hdr->code, NULL),
+ iana_afi2str(mpc.afi), iana_safi2str(mpc.safi));
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_iana2int(mpc.afi, mpc.safi, &afi, &safi))
@@ -466,8 +523,6 @@ static int bgp_capability_restart(struct peer *peer,
peer->v_gr_restart = restart_flag_time;
if (bgp_debug_neighbor_events(peer)) {
- zlog_debug("%s OPEN has Graceful Restart capability",
- peer->host);
zlog_debug("%s Peer has%srestarted. Restart Time : %d",
peer->host,
CHECK_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV)
@@ -580,9 +635,10 @@ static int bgp_capability_addpath(struct peer *peer,
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s OPEN has AddPath CAP for afi/safi: %s/%s%s%s",
- peer->host, iana_afi2str(pkt_afi),
- iana_safi2str(pkt_safi),
+ "%s OPEN has %s capability for afi/safi: %s/%s%s%s",
+ peer->host,
+ lookup_msg(capcode_str, hdr->code, NULL),
+ iana_afi2str(pkt_afi), iana_safi2str(pkt_safi),
(send_receive & BGP_ADDPATH_RX) ? ", receive"
: "",
(send_receive & BGP_ADDPATH_TX) ? ", transmit"
@@ -763,63 +819,6 @@ static int bgp_capability_hostname(struct peer *peer,
return 0;
}
-static const struct message capcode_str[] = {
- {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
- {CAPABILITY_CODE_REFRESH, "Route Refresh"},
- {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
- {CAPABILITY_CODE_RESTART, "Graceful Restart"},
- {CAPABILITY_CODE_AS4, "4-octet AS number"},
- {CAPABILITY_CODE_ADDPATH, "AddPath"},
- {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
- {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
- {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
- {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
- {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
- {CAPABILITY_CODE_FQDN, "FQDN"},
- {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"},
- {CAPABILITY_CODE_EXT_MESSAGE, "BGP Extended Message"},
- {0}};
-
-/* Minimum sizes for length field of each cap (so not inc. the header) */
-static const size_t cap_minsizes[] = {
- [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
- [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
- [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
- [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
- [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
- [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
- [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
- [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
- [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
- [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
- [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
- [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
- [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN,
- [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN,
-};
-
-/* value the capability must be a multiple of.
- * 0-data capabilities won't be checked against this.
- * Other capabilities whose data doesn't fall on convenient boundaries for this
- * table should be set to 1.
- */
-static const size_t cap_modsizes[] = {
- [CAPABILITY_CODE_MP] = 4,
- [CAPABILITY_CODE_REFRESH] = 1,
- [CAPABILITY_CODE_ORF] = 1,
- [CAPABILITY_CODE_RESTART] = 1,
- [CAPABILITY_CODE_AS4] = 4,
- [CAPABILITY_CODE_ADDPATH] = 4,
- [CAPABILITY_CODE_DYNAMIC] = 1,
- [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
- [CAPABILITY_CODE_ENHE] = 6,
- [CAPABILITY_CODE_REFRESH_OLD] = 1,
- [CAPABILITY_CODE_ORF_OLD] = 1,
- [CAPABILITY_CODE_FQDN] = 1,
- [CAPABILITY_CODE_ENHANCED_RR] = 1,
- [CAPABILITY_CODE_EXT_MESSAGE] = 1,
-};
-
/**
* Parse given capability.
* XXX: This is reading into a stream, but not using stream API
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 2a84f548f8..4b798cc264 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -8433,8 +8433,7 @@ enum bgp_display_type {
normal_list,
};
-static const char *
-bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
+const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
{
switch (reason) {
case bgp_path_selection_none:
@@ -13451,16 +13450,6 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
bgp = peer->bgp;
- if (!bgp) {
- if (use_json) {
- json_object_string_add(json, "alert", "no BGP");
- vty_out(vty, "%s\n", json_object_to_json_string(json));
- json_object_free(json);
- } else
- vty_out(vty, "%% No bgp\n");
- return;
- }
-
subgrp = peer_subgroup(peer, afi, safi);
if (type == bgp_show_adj_route_advertised && subgrp
@@ -13701,6 +13690,9 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
"No such neighbor or address family");
vty_out(vty, "%s\n", json_object_to_json_string(json));
json_object_free(json);
+ json_object_free(json_ar);
+ json_object_free(json_scode);
+ json_object_free(json_ocode);
} else
vty_out(vty, "%% No such neighbor or address family\n");
@@ -13717,6 +13709,9 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
"Inbound soft reconfiguration not enabled");
vty_out(vty, "%s\n", json_object_to_json_string(json));
json_object_free(json);
+ json_object_free(json_ar);
+ json_object_free(json_scode);
+ json_object_free(json_ocode);
} else
vty_out(vty,
"%% Inbound soft reconfiguration not enabled\n");
@@ -13785,14 +13780,17 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
- if (!output_count && !filtered_count) {
+ /*
+ * These fields only give up ownership to `json` when `header1`
+ * is used (set to zero). See code in `show_adj_route` and
+ * `show_adj_route_header`.
+ */
+ if (header1 == 1) {
json_object_free(json_scode);
json_object_free(json_ocode);
}
- if (json)
- json_object_free(json);
-
+ json_object_free(json);
} else if (output_count > 0) {
if (filtered_count > 0)
vty_out(vty,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 37bf675b67..46802d0d14 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -90,6 +90,9 @@ enum bgp_show_adj_route_type {
/* Maximum number of sids we can process or send with a prefix. */
#define BGP_MAX_SIDS 6
+/* Maximum buffer length for storing BGP best path selection reason */
+#define BGP_MAX_SELECTION_REASON_STR_BUF 32
+
/* Error codes for handling NLRI */
#define BGP_NLRI_PARSE_OK 0
#define BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW -1
@@ -803,4 +806,6 @@ extern void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
const struct prefix *p, afi_t afi,
safi_t safi, bool suppress);
extern void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr);
+const char *
+bgp_path_selection_reason2str(enum bgp_path_selection_reason reason);
#endif /* _QUAGGA_BGP_ROUTE_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 158a5f30b7..772e20dc85 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -10241,6 +10241,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
count = 0; /* Reset the value as its used again */
filtered_count = 0;
+ dn_count = 0;
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 6161f56fe6..5fc6bb2a1a 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1490,6 +1490,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
struct bgp_zebra_opaque bzo = {};
+ const char *reason =
+ bgp_path_selection_reason2str(dest->reason);
strlcpy(bzo.aspath, info->attr->aspath->str,
sizeof(bzo.aspath));
@@ -1503,6 +1505,9 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
strlcpy(bzo.lcommunity, info->attr->lcommunity->str,
sizeof(bzo.lcommunity));
+ strlcpy(bzo.selection_reason, reason,
+ sizeof(bzo.selection_reason));
+
SET_FLAG(api.message, ZAPI_MESSAGE_OPAQUE);
api.opaque.length = MIN(sizeof(struct bgp_zebra_opaque),
ZAPI_MESSAGE_OPAQUE_LENGTH);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index b191029d2f..c5a5e49a48 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4775,6 +4775,7 @@ int peer_ebgp_multihop_unset(struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
+ int ttl;
if (peer->sort == BGP_PEER_IBGP)
return 0;
@@ -4783,9 +4784,14 @@ int peer_ebgp_multihop_unset(struct peer *peer)
return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
if (peer_group_active(peer))
- peer->ttl = peer->group->conf->ttl;
+ ttl = peer->group->conf->ttl;
else
- peer->ttl = BGP_DEFAULT_TTL;
+ ttl = BGP_DEFAULT_TTL;
+
+ if (ttl == peer->ttl)
+ return 0;
+
+ peer->ttl = ttl;
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 5fcddafaaa..1793ae3d27 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1425,15 +1425,6 @@ Configuring Peers
Set description of the peer.
-.. clicmd:: neighbor PEER version VERSION
-
- Set up the neighbor's BGP version. `version` can be `4`, `4+` or `4-`. BGP
- version `4` is the default value used for BGP peering. BGP version `4+`
- means that the neighbor supports Multiprotocol Extensions for BGP-4. BGP
- version `4-` is similar but the neighbor speaks the old Internet-Draft
- revision 00's Multiprotocol Extensions for BGP-4. Some routing software is
- still using this version.
-
.. clicmd:: neighbor PEER interface IFNAME
When you connect to a BGP peer over an IPv6 link-local address, you have to
diff --git a/include/linux/nexthop.h b/include/linux/nexthop.h
index ee2a15b9c7..d8ffa8c9ca 100644
--- a/include/linux/nexthop.h
+++ b/include/linux/nexthop.h
@@ -1,12 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _LINUX_NEXTHOP_H
-#define _LINUX_NEXTHOP_H
+#ifndef _UAPI_LINUX_NEXTHOP_H
+#define _UAPI_LINUX_NEXTHOP_H
#include <linux/types.h>
-#define RTM_NHA(h) ((struct rtattr *)(((char *)(h)) + \
- NLMSG_ALIGN(sizeof(struct nhmsg))))
-
struct nhmsg {
unsigned char nh_family;
unsigned char nh_scope; /* return only */
@@ -15,6 +12,7 @@ struct nhmsg {
unsigned int nh_flags; /* RTNH_F flags */
};
+/* entry in a nexthop group */
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
@@ -23,7 +21,10 @@ struct nexthop_grp {
};
enum {
- NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
+ NEXTHOP_GRP_TYPE_MPATH, /* hash-threshold nexthop group
+ * default type if not specified
+ */
+ NEXTHOP_GRP_TYPE_RES, /* resilient nexthop group */
__NEXTHOP_GRP_TYPE_MAX,
};
@@ -50,10 +51,54 @@ enum {
*/
NHA_GROUPS, /* flag; only return nexthop groups in dump */
NHA_MASTER, /* u32; only return nexthops with given master dev */
- NHA_FDB, /* nexthop belongs to a bridge fdb */
+
+ NHA_FDB, /* flag; nexthop belongs to a bridge fdb */
+ /* if NHA_FDB is added, OIF, BLACKHOLE, ENCAP cannot be set */
+
+ /* nested; resilient nexthop group attributes */
+ NHA_RES_GROUP,
+ /* nested; nexthop bucket attributes */
+ NHA_RES_BUCKET,
__NHA_MAX,
};
#define NHA_MAX (__NHA_MAX - 1)
+
+enum {
+ NHA_RES_GROUP_UNSPEC,
+ /* Pad attribute for 64-bit alignment. */
+ NHA_RES_GROUP_PAD = NHA_RES_GROUP_UNSPEC,
+
+ /* u16; number of nexthop buckets in a resilient nexthop group */
+ NHA_RES_GROUP_BUCKETS,
+ /* clock_t as u32; nexthop bucket idle timer (per-group) */
+ NHA_RES_GROUP_IDLE_TIMER,
+ /* clock_t as u32; nexthop unbalanced timer */
+ NHA_RES_GROUP_UNBALANCED_TIMER,
+ /* clock_t as u64; nexthop unbalanced time */
+ NHA_RES_GROUP_UNBALANCED_TIME,
+
+ __NHA_RES_GROUP_MAX,
+};
+
+#define NHA_RES_GROUP_MAX (__NHA_RES_GROUP_MAX - 1)
+
+enum {
+ NHA_RES_BUCKET_UNSPEC,
+ /* Pad attribute for 64-bit alignment. */
+ NHA_RES_BUCKET_PAD = NHA_RES_BUCKET_UNSPEC,
+
+ /* u16; nexthop bucket index */
+ NHA_RES_BUCKET_INDEX,
+ /* clock_t as u64; nexthop bucket idle time */
+ NHA_RES_BUCKET_IDLE_TIME,
+ /* u32; nexthop id assigned to the nexthop bucket */
+ NHA_RES_BUCKET_NH_ID,
+
+ __NHA_RES_BUCKET_MAX,
+};
+
+#define NHA_RES_BUCKET_MAX (__NHA_RES_BUCKET_MAX - 1)
+
#endif
diff --git a/lib/route_opaque.h b/lib/route_opaque.h
index 7c4e9a16e1..c5e7d6a327 100644
--- a/lib/route_opaque.h
+++ b/lib/route_opaque.h
@@ -36,6 +36,12 @@ struct bgp_zebra_opaque {
/* Show at least 10 large-communities AA:BB:CC */
char lcommunity[LCOMMUNITY_SIZE * 30];
+
+ /* 32 bytes seems enough because of
+ * bgp_path_selection_confed_as_path which is
+ * `Confederation based AS Path`.
+ */
+ char selection_reason[BGP_MAX_SELECTION_REASON_STR_BUF];
};
static_assert(sizeof(struct bgp_zebra_opaque) <= ZAPI_MESSAGE_OPAQUE_LENGTH,
diff --git a/lib/zclient.c b/lib/zclient.c
index 90439d5e17..e9a020df13 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -450,7 +450,7 @@ enum zclient_send_status zclient_send_localsid(struct zclient *zclient,
p.prefix = *sid;
api.vrf_id = VRF_DEFAULT;
- api.type = ZEBRA_ROUTE_BGP;
+ api.type = zclient->redist_default;
api.instance = 0;
api.safi = SAFI_UNICAST;
memcpy(&api.prefix, &p, sizeof(p));
diff --git a/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py b/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py
index 863c296927..27a4419329 100644
--- a/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py
+++ b/tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py
@@ -193,7 +193,7 @@ def test_bfd_isis_interface_failure_rt2_step3():
# initial 2 seconds to let the CI not suffer.
# TODO: add check for array size
router_compare_json_output(
- "rt1", "show ip route isis json", "step3/show_ip_route_rt2_down.ref", 20, 10
+ "rt1", "show ip route isis json", "step3/show_ip_route_rt2_down.ref", 20, 1
)
router_compare_json_output(
"rt1", "show ipv6 route isis json", "step3/show_ipv6_route_rt2_down.ref", 20, 1
diff --git a/zebra/debug_nl.c b/zebra/debug_nl.c
index 842579f89e..2175aaff60 100644
--- a/zebra/debug_nl.c
+++ b/zebra/debug_nl.c
@@ -29,6 +29,7 @@
#include <stdint.h>
#include "zebra/rt_netlink.h"
+#include "zebra/kernel_netlink.h"
const char *nlmsg_type2str(uint16_t type)
{
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index 37c76b9e59..cf8b8c785e 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -27,6 +27,10 @@ extern "C" {
#ifdef HAVE_NETLINK
+#define RTM_NHA(h) \
+ ((struct rtattr *)(((char *)(h)) + NLMSG_ALIGN(sizeof(struct nhmsg))))
+
+
#define NL_RCV_PKT_BUF_SIZE 32768
#define NL_PKT_BUF_SIZE 8192
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 6cb4cf5ca1..61bd1417d1 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -3440,6 +3440,7 @@ static inline void zebra_gre_get(ZAPI_HANDLER_ARGS)
stream_putl(s, IFINDEX_INTERNAL);
stream_putl(s, VRF_UNKNOWN);
stream_putl(s, 0);
+ stream_putl(s, 0);
}
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 5b79de9697..2cb2b5118b 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -449,6 +449,8 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
bzo.community);
json_object_string_add(json, "largeCommunities",
bzo.lcommunity);
+ json_object_string_add(json, "selectionReason",
+ bzo.selection_reason);
} else {
vty_out(vty, " AS-Path : %s\n", bzo.aspath);
@@ -459,6 +461,9 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
if (bzo.lcommunity[0] != '\0')
vty_out(vty, " Large-Communities: %s\n",
bzo.lcommunity);
+
+ vty_out(vty, " Selection reason : %s\n",
+ bzo.selection_reason);
}
}
default: