diff options
| -rw-r--r-- | bgpd/bgp_open.c | 129 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 30 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 5 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 1 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 5 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 10 | ||||
| -rw-r--r-- | doc/user/bgp.rst | 9 | ||||
| -rw-r--r-- | include/linux/nexthop.h | 59 | ||||
| -rw-r--r-- | lib/route_opaque.h | 6 | ||||
| -rw-r--r-- | lib/zclient.c | 2 | ||||
| -rw-r--r-- | tests/topotests/bfd_isis_topo1/test_bfd_isis_topo1.py | 2 | ||||
| -rw-r--r-- | zebra/debug_nl.c | 1 | ||||
| -rw-r--r-- | zebra/kernel_netlink.h | 4 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 1 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 5 |
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: |
