Merge branch 'master' into docuser

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2018-03-13 12:08:38 -04:00
commit 1f35b46a2f
No known key found for this signature in database
GPG Key ID: DAF48E0F57E0834F
335 changed files with 10243 additions and 8493 deletions

3
.gitignore vendored
View File

@ -82,3 +82,6 @@ GPATH
*.lo *.lo
compile_commands.json compile_commands.json
.dirstamp .dirstamp
# clippy generated source
*_clippy.c

View File

@ -114,3 +114,6 @@ EXTRA_DIST += \
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
noinst_HEADERS += defaults.h noinst_HEADERS += defaults.h
indent:
tools/indent.py `find sharpd bgpd eigrpd include isisd lib nhrpd ospf6d ospfd pimd qpb ripd vtysh zebra -name '*.[ch]' | grep -v include/linux`

36
alpine/APKBUILD.in Normal file
View File

@ -0,0 +1,36 @@
# Maintainer: Arthur Jones <arthur.jones@riverbed.com>
pkgname=frr
pkgver=@VERSION@
pkgrel=0
pkgdesc="Free Range Routing is a fork of quagga"
url="https://frrouting.org/"
arch="all"
license="GPL-2.0"
depends="iproute2 json-c c-ares ipsec-tools iproute2"
makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
acct autoconf automake bash
binutils binutils-libs bison bsd-compat-headers build-base
c-ares c-ares-dev ca-certificates cryptsetup-libs curl
device-mapper-libs expat fakeroot flex fortify-headers gdbm
git gmp isl json-c-dev kmod lddtree libacl libatomic libattr
libblkid libburn libbz2 libc-dev libcap libcurl libedit libffi libgcc
libgomp libisoburn libisofs libltdl libressl libssh2
libstdc++ libtool libuuid linux-headers lzip lzo m4 make mkinitfs mpc1
mpfr3 mtools musl-dev ncurses-libs ncurses-terminfo ncurses-terminfo-base
patch pax-utils pcre perl pkgconf python2 python2-dev readline
readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs"
subpackages="$pkgname-dev $pkgname-doc $pkgname-dbg"
source="$pkgname-$pkgver.tar.gz"
builddir="$srcdir"/$pkgname-$pkgver
build() {
cd "$builddir"
./configure --prefix=/usr || return 1
make || return 1
}
package() {
cd "$builddir"
make DESTDIR="$pkgdir" install || return 1
}

1
bgpd/.gitignore vendored
View File

@ -16,4 +16,3 @@ TAGS
.arch-ids .arch-ids
*~ *~
*.loT *.loT
*clippy.c

View File

@ -498,7 +498,8 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
if (!as->segments) { if (!as->segments) {
if (make_json) { if (make_json) {
json_object_string_add(as->json, "string", "Local"); json_object_string_add(as->json, "string", "Local");
json_object_object_add(as->json, "segments", jaspath_segments); json_object_object_add(as->json, "segments",
jaspath_segments);
json_object_int_add(as->json, "length", 0); json_object_int_add(as->json, "length", 0);
} }
as->str = XMALLOC(MTYPE_AS_STR, 1); as->str = XMALLOC(MTYPE_AS_STR, 1);
@ -575,8 +576,9 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
/* write out the ASNs, with their seperators, bar the last one*/ /* write out the ASNs, with their seperators, bar the last one*/
for (i = 0; i < seg->length; i++) { for (i = 0; i < seg->length; i++) {
if (make_json) if (make_json)
json_object_array_add(jseg_list, json_object_array_add(
json_object_new_int(seg->as[i])); jseg_list,
json_object_new_int(seg->as[i]));
len += snprintf(str_buf + len, str_size - len, "%u", len += snprintf(str_buf + len, str_size - len, "%u",
seg->as[i]); seg->as[i]);
@ -588,8 +590,9 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
if (make_json) { if (make_json) {
jseg = json_object_new_object(); jseg = json_object_new_object();
json_object_string_add(jseg, "type", json_object_string_add(
aspath_segment_type_str[seg->type]); jseg, "type",
aspath_segment_type_str[seg->type]);
json_object_object_add(jseg, "list", jseg_list); json_object_object_add(jseg, "list", jseg_list);
json_object_array_add(jaspath_segments, jseg); json_object_array_add(jaspath_segments, jseg);
} }
@ -904,7 +907,8 @@ size_t aspath_put(struct stream *s, struct aspath *as, int use32bit)
assegment_data_put(s, seg->as, AS_SEGMENT_MAX, assegment_data_put(s, seg->as, AS_SEGMENT_MAX,
use32bit); use32bit);
written += AS_SEGMENT_MAX; written += AS_SEGMENT_MAX;
bytes += ASSEGMENT_SIZE(AS_SEGMENT_MAX, use32bit); bytes += ASSEGMENT_SIZE(AS_SEGMENT_MAX,
use32bit);
} }
/* write the final segment, probably is also the first /* write the final segment, probably is also the first
@ -2032,9 +2036,7 @@ int aspath_cmp(const void *arg1, const void *arg2)
/* AS path hash initialize. */ /* AS path hash initialize. */
void aspath_init(void) void aspath_init(void)
{ {
ashash = hash_create_size(32768, ashash = hash_create_size(32768, aspath_key_make, aspath_cmp,
aspath_key_make,
aspath_cmp,
"BGP AS Path"); "BGP AS Path");
} }

View File

@ -83,15 +83,14 @@ static const struct message attr_str[] = {
{BGP_ATTR_PREFIX_SID, "PREFIX_SID"}, {BGP_ATTR_PREFIX_SID, "PREFIX_SID"},
{0}}; {0}};
static const struct message attr_flag_str[] = static const struct message attr_flag_str[] = {
{ {BGP_ATTR_FLAG_OPTIONAL, "Optional"},
{BGP_ATTR_FLAG_OPTIONAL, "Optional"}, {BGP_ATTR_FLAG_TRANS, "Transitive"},
{BGP_ATTR_FLAG_TRANS, "Transitive"}, {BGP_ATTR_FLAG_PARTIAL, "Partial"},
{BGP_ATTR_FLAG_PARTIAL, "Partial"}, /* bgp_attr_flags_diagnose() relies on this bit being last in
/* bgp_attr_flags_diagnose() relies on this bit being last in this list */
this list */ {BGP_ATTR_FLAG_EXTLEN, "Extended Length"},
{BGP_ATTR_FLAG_EXTLEN, "Extended Length"}, {0}};
{0}};
static struct hash *cluster_hash; static struct hash *cluster_hash;
@ -185,8 +184,7 @@ void cluster_unintern(struct cluster_list *cluster)
static void cluster_init(void) static void cluster_init(void)
{ {
cluster_hash = hash_create(cluster_hash_key_make, cluster_hash = hash_create(cluster_hash_key_make, cluster_hash_cmp,
cluster_hash_cmp,
"BGP Cluster"); "BGP Cluster");
} }
@ -363,12 +361,10 @@ static int encap_hash_cmp(const void *p1, const void *p2)
static void encap_init(void) static void encap_init(void)
{ {
encap_hash = hash_create(encap_hash_key_make, encap_hash = hash_create(encap_hash_key_make, encap_hash_cmp,
encap_hash_cmp,
"BGP Encap Hash"); "BGP Encap Hash");
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
vnc_hash = hash_create(encap_hash_key_make, vnc_hash = hash_create(encap_hash_key_make, encap_hash_cmp,
encap_hash_cmp,
"BGP VNC Hash"); "BGP VNC Hash");
#endif #endif
} }
@ -454,8 +450,7 @@ static int transit_hash_cmp(const void *p1, const void *p2)
static void transit_init(void) static void transit_init(void)
{ {
transit_hash = hash_create(transit_hash_key_make, transit_hash = hash_create(transit_hash_key_make, transit_hash_cmp,
transit_hash_cmp,
"BGP Transit Hash"); "BGP Transit Hash");
} }
@ -496,7 +491,8 @@ unsigned int attrhash_key_make(void *p)
#define MIX3(a, b, c) key = jhash_3words((a), (b), (c), key) #define MIX3(a, b, c) key = jhash_3words((a), (b), (c), key)
MIX3(attr->origin, attr->nexthop.s_addr, attr->med); MIX3(attr->origin, attr->nexthop.s_addr, attr->med);
MIX3(attr->local_pref, attr->aggregator_as, attr->aggregator_addr.s_addr); MIX3(attr->local_pref, attr->aggregator_as,
attr->aggregator_addr.s_addr);
MIX3(attr->weight, attr->mp_nexthop_global_in.s_addr, MIX3(attr->weight, attr->mp_nexthop_global_in.s_addr,
attr->originator_id.s_addr); attr->originator_id.s_addr);
MIX3(attr->tag, attr->label, attr->label_index); MIX3(attr->tag, attr->label, attr->label_index);
@ -571,9 +567,8 @@ int attrhash_cmp(const void *p1, const void *p2)
static void attrhash_init(void) static void attrhash_init(void)
{ {
attrhash = hash_create(attrhash_key_make, attrhash =
attrhash_cmp, hash_create(attrhash_key_make, attrhash_cmp, "BGP Attributes");
"BGP Attributes");
} }
/* /*
@ -747,8 +742,8 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, u_char origin,
/* If we are not shutting down ourselves and we are /* If we are not shutting down ourselves and we are
* aggregating a route that contains the GSHUT community we * aggregating a route that contains the GSHUT community we
* need to remove that community when creating the aggregate */ * need to remove that community when creating the aggregate */
if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN) && if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)
community_include(community, gshut)) { && community_include(community, gshut)) {
community_del_val(community, &gshut); community_del_val(community, &gshut);
} }
@ -840,7 +835,6 @@ void bgp_attr_undup(struct attr *new, struct attr *old)
if (new->lcommunity != old->lcommunity) if (new->lcommunity != old->lcommunity)
lcommunity_free(&new->lcommunity); lcommunity_free(&new->lcommunity);
} }
/* Free bgp attribute and aspath. */ /* Free bgp attribute and aspath. */
@ -1661,14 +1655,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
case BGP_ATTR_NHLEN_VPNV4: case BGP_ATTR_NHLEN_VPNV4:
stream_getl(s); /* RD high */ stream_getl(s); /* RD high */
stream_getl(s); /* RD low */ stream_getl(s); /* RD low */
/* /*
* NOTE: intentional fall through * NOTE: intentional fall through
* - for consistency in rx processing * - for consistency in rx processing
* *
* The following comment is to signal GCC this intention * The following comment is to signal GCC this intention
* and supress the warning * and supress the warning
*/ */
/* FALLTHRU */ /* FALLTHRU */
case BGP_ATTR_NHLEN_IPV4: case BGP_ATTR_NHLEN_IPV4:
stream_get(&attr->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN); stream_get(&attr->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
/* Probably needed for RFC 2283 */ /* Probably needed for RFC 2283 */
@ -1960,8 +1954,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
/* alloc and copy sub-tlv */ /* alloc and copy sub-tlv */
/* TBD make sure these are freed when attributes are released */ /* TBD make sure these are freed when attributes are released */
tlv = XCALLOC(MTYPE_ENCAP_TLV, tlv = XCALLOC(MTYPE_ENCAP_TLV,
sizeof(struct bgp_attr_encap_subtlv) sizeof(struct bgp_attr_encap_subtlv) + sublength);
+ sublength);
tlv->type = subtype; tlv->type = subtype;
tlv->length = sublength; tlv->length = sublength;
stream_get(tlv->value, peer->curr, sublength); stream_get(tlv->value, peer->curr, sublength);
@ -2715,8 +2708,8 @@ void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
stream_put(s, &p->u.prefix, PSIZE(p->prefixlen)); stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
} else if (afi == AFI_L2VPN && safi == SAFI_EVPN) { } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
/* EVPN prefix - contents depend on type */ /* EVPN prefix - contents depend on type */
bgp_evpn_encode_prefix(s, p, prd, label, num_labels, bgp_evpn_encode_prefix(s, p, prd, label, num_labels, attr,
attr, addpath_encode, addpath_tx_id); addpath_encode, addpath_tx_id);
} else if (safi == SAFI_LABELED_UNICAST) { } else if (safi == SAFI_LABELED_UNICAST) {
/* Prefix write with label. */ /* Prefix write with label. */
stream_put_labeled_prefix(s, p, label); stream_put_labeled_prefix(s, p, label);
@ -2799,8 +2792,9 @@ static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
if (attrlenfield > 0xff) { if (attrlenfield > 0xff) {
/* 2-octet length field */ /* 2-octet length field */
stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_EXTLEN); BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, attrtype); stream_putc(s, attrtype);
stream_putw(s, attrlenfield & 0xffff); stream_putw(s, attrlenfield & 0xffff);
} else { } else {
@ -2867,9 +2861,9 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
vecarr, attr); vecarr, attr);
bgp_packet_mpattr_prefix(s, afi, safi, p, prd, bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
label, num_labels, num_labels, addpath_encode,
addpath_encode, addpath_tx_id, attr); addpath_tx_id, attr);
bgp_packet_mpattr_end(s, mpattrlen_pos); bgp_packet_mpattr_end(s, mpattrlen_pos);
} }
@ -3039,14 +3033,15 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) { && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
if (attr->community->size * 4 > 255) { if (attr->community->size * 4 > 255) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN); | BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_COMMUNITIES); stream_putc(s, BGP_ATTR_COMMUNITIES);
stream_putw(s, attr->community->size * 4); stream_putw(s, attr->community->size * 4);
} else { } else {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_COMMUNITIES); stream_putc(s, BGP_ATTR_COMMUNITIES);
stream_putc(s, attr->community->size * 4); stream_putc(s, attr->community->size * 4);
} }
@ -3060,14 +3055,15 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
PEER_FLAG_SEND_LARGE_COMMUNITY) PEER_FLAG_SEND_LARGE_COMMUNITY)
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) { && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
if (lcom_length(attr->lcommunity) > 255) { if (lcom_length(attr->lcommunity) > 255) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN); | BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES); stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
stream_putw(s, lcom_length(attr->lcommunity)); stream_putw(s, lcom_length(attr->lcommunity));
} else { } else {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES); stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
stream_putc(s, lcom_length(attr->lcommunity)); stream_putc(s, lcom_length(attr->lcommunity));
} }
@ -3119,14 +3115,16 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
if (peer->sort == BGP_PEER_IBGP if (peer->sort == BGP_PEER_IBGP
|| peer->sort == BGP_PEER_CONFED) { || peer->sort == BGP_PEER_CONFED) {
if (attr->ecommunity->size * 8 > 255) { if (attr->ecommunity->size * 8 > 255) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_EXTLEN); | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_EXT_COMMUNITIES); stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
stream_putw(s, attr->ecommunity->size * 8); stream_putw(s, attr->ecommunity->size * 8);
} else { } else {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_EXT_COMMUNITIES); stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
stream_putc(s, attr->ecommunity->size * 8); stream_putc(s, attr->ecommunity->size * 8);
} }
@ -3192,8 +3190,9 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
label_index = attr->label_index; label_index = attr->label_index;
if (label_index != BGP_INVALID_LABEL_INDEX) { if (label_index != BGP_INVALID_LABEL_INDEX) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_PREFIX_SID); stream_putc(s, BGP_ATTR_PREFIX_SID);
stream_putc(s, 10); stream_putc(s, 10);
stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX); stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
@ -3221,8 +3220,9 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
*/ */
aspath = aspath_delete_confed_seq(aspath); aspath = aspath_delete_confed_seq(aspath);
stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_EXTLEN); BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_AS4_PATH); stream_putc(s, BGP_ATTR_AS4_PATH);
aspath_sizep = stream_get_endp(s); aspath_sizep = stream_get_endp(s);
stream_putw(s, 0); stream_putw(s, 0);
@ -3264,8 +3264,10 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
stream_putc(s, 9); // Length stream_putc(s, 9); // Length
stream_putc(s, 0); // Flags stream_putc(s, 0); // Flags
stream_putc(s, 6); // Tunnel type: Ingress Replication (6) stream_putc(s, 6); // Tunnel type: Ingress Replication (6)
stream_put(s, &(attr->label), BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI stream_put(s, &(attr->label),
stream_put_ipv4(s, attr->nexthop.s_addr); // Unicast tunnel endpoint IP address BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI
stream_put_ipv4(s, attr->nexthop.s_addr);
// Unicast tunnel endpoint IP address
} }
/* Unknown transit attribute. */ /* Unknown transit attribute. */
@ -3311,8 +3313,7 @@ void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, afi_t afi,
num_labels = 1; num_labels = 1;
} }
return bgp_packet_mpattr_prefix(s, afi, safi, p, prd, return bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
label, num_labels,
addpath_encode, addpath_tx_id, attr); addpath_encode, addpath_tx_id, attr);
} }
@ -3422,14 +3423,15 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
/* Community attribute. */ /* Community attribute. */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) { if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
if (attr->community->size * 4 > 255) { if (attr->community->size * 4 > 255) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN); | BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_COMMUNITIES); stream_putc(s, BGP_ATTR_COMMUNITIES);
stream_putw(s, attr->community->size * 4); stream_putw(s, attr->community->size * 4);
} else { } else {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_COMMUNITIES); stream_putc(s, BGP_ATTR_COMMUNITIES);
stream_putc(s, attr->community->size * 4); stream_putc(s, attr->community->size * 4);
} }
@ -3439,19 +3441,21 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
/* Large Community attribute. */ /* Large Community attribute. */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) { if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
if (lcom_length(attr->lcommunity) > 255) { if (lcom_length(attr->lcommunity) > 255) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN); | BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES); stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
stream_putw(s, lcom_length(attr->lcommunity)); stream_putw(s, lcom_length(attr->lcommunity));
} else { } else {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES); stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
stream_putc(s, lcom_length(attr->lcommunity)); stream_putc(s, lcom_length(attr->lcommunity));
} }
stream_put(s, attr->lcommunity->val, lcom_length(attr->lcommunity)); stream_put(s, attr->lcommunity->val,
lcom_length(attr->lcommunity));
} }
/* Add a MP_NLRI attribute to dump the IPv6 next hop */ /* Add a MP_NLRI attribute to dump the IPv6 next hop */
@ -3490,8 +3494,9 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
/* Prefix SID */ /* Prefix SID */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) { if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
if (attr->label_index != BGP_INVALID_LABEL_INDEX) { if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL stream_putc(s,
| BGP_ATTR_FLAG_TRANS); BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_PREFIX_SID); stream_putc(s, BGP_ATTR_PREFIX_SID);
stream_putc(s, 10); stream_putc(s, 10);
stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX); stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);

View File

@ -215,10 +215,8 @@ struct transit {
/* "(void) 0" will generate a compiler error. this is a safety check to /* "(void) 0" will generate a compiler error. this is a safety check to
* ensure we're not using a value that exceeds the bit size of attr->flag. */ * ensure we're not using a value that exceeds the bit size of attr->flag. */
#define ATTR_FLAG_BIT(X) \ #define ATTR_FLAG_BIT(X) \
__builtin_choose_expr((X) >= 1 && (X) <= 64, \ __builtin_choose_expr((X) >= 1 && (X) <= 64, 1ULL << ((X)-1), (void)0)
1ULL << ((X) - 1), \
(void) 0)
#define BGP_CLUSTER_LIST_LENGTH(attr) \ #define BGP_CLUSTER_LIST_LENGTH(attr) \
(((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \ (((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \
@ -260,8 +258,8 @@ extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
struct bpacket_attr_vec_arr *vecarr, struct bpacket_attr_vec_arr *vecarr,
struct prefix *, afi_t, safi_t, struct prefix *, afi_t, safi_t,
struct peer *, struct prefix_rd *, struct peer *, struct prefix_rd *,
mpls_label_t *, u_int32_t, mpls_label_t *, u_int32_t, int,
int, u_int32_t); u_int32_t);
extern void bgp_dump_routes_attr(struct stream *, struct attr *, extern void bgp_dump_routes_attr(struct stream *, struct attr *,
struct prefix *); struct prefix *);
extern int attrhash_cmp(const void *, const void *); extern int attrhash_cmp(const void *, const void *);
@ -320,9 +318,9 @@ extern size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi,
safi_t safi); safi_t safi);
extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p,
afi_t afi, safi_t safi, afi_t afi, safi_t safi,
struct prefix_rd *prd, struct prefix_rd *prd, mpls_label_t *,
mpls_label_t *, u_int32_t, u_int32_t, int, u_int32_t,
int, u_int32_t, struct attr *); struct attr *);
extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt); extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt);
static inline int bgp_rmap_nhop_changed(u_int32_t out_rmap_flags, static inline int bgp_rmap_nhop_changed(u_int32_t out_rmap_flags,

View File

@ -106,8 +106,7 @@ char *ecom_mac2str(char *ecom_mac)
} }
/* Fetch router-mac from extended community */ /* Fetch router-mac from extended community */
void bgp_attr_rmac(struct attr *attr, void bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac)
struct ethaddr *rmac)
{ {
int i = 0; int i = 0;
struct ecommunity *ecom; struct ecommunity *ecom;
@ -126,8 +125,8 @@ void bgp_attr_rmac(struct attr *attr,
type = *pnt++; type = *pnt++;
sub_type = *pnt++; sub_type = *pnt++;
if (!(type == ECOMMUNITY_ENCODE_EVPN && if (!(type == ECOMMUNITY_ENCODE_EVPN
sub_type == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC)) && sub_type == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC))
continue; continue;
memcpy(rmac, pnt, ETH_ALEN); memcpy(rmac, pnt, ETH_ALEN);
@ -139,8 +138,8 @@ void bgp_attr_rmac(struct attr *attr,
*/ */
uint8_t bgp_attr_default_gw(struct attr *attr) uint8_t bgp_attr_default_gw(struct attr *attr)
{ {
struct ecommunity *ecom; struct ecommunity *ecom;
int i; int i;
ecom = attr->ecommunity; ecom = attr->ecommunity;
if (!ecom || !ecom->size) if (!ecom || !ecom->size)
@ -149,15 +148,15 @@ uint8_t bgp_attr_default_gw(struct attr *attr)
/* If there is a default gw extendd community return true otherwise /* If there is a default gw extendd community return true otherwise
* return 0 */ * return 0 */
for (i = 0; i < ecom->size; i++) { for (i = 0; i < ecom->size; i++) {
u_char *pnt; u_char *pnt;
u_char type, sub_type; u_char type, sub_type;
pnt = (ecom->val + (i * ECOMMUNITY_SIZE)); pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
type = *pnt++; type = *pnt++;
sub_type = *pnt++; sub_type = *pnt++;
if ((type == ECOMMUNITY_ENCODE_OPAQUE if ((type == ECOMMUNITY_ENCODE_OPAQUE
&& sub_type == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW)) && sub_type == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW))
return 1; return 1;
} }

View File

@ -222,7 +222,8 @@ static void set_community_string(struct community *com, bool make_json)
if (make_json) { if (make_json) {
json_object_string_add(com->json, "string", ""); json_object_string_add(com->json, "string", "");
json_object_object_add(com->json, "list", json_community_list); json_object_object_add(com->json, "list",
json_community_list);
} }
com->str = str; com->str = str;
return; return;
@ -277,24 +278,30 @@ static void set_community_string(struct community *com, bool make_json)
strcpy(pnt, "internet"); strcpy(pnt, "internet");
pnt += strlen("internet"); pnt += strlen("internet");
if (make_json) { if (make_json) {
json_string = json_object_new_string("internet"); json_string =
json_object_array_add(json_community_list, json_string); json_object_new_string("internet");
json_object_array_add(json_community_list,
json_string);
} }
break; break;
case COMMUNITY_NO_EXPORT: case COMMUNITY_NO_EXPORT:
strcpy(pnt, "no-export"); strcpy(pnt, "no-export");
pnt += strlen("no-export"); pnt += strlen("no-export");
if (make_json) { if (make_json) {
json_string = json_object_new_string("noExport"); json_string =
json_object_array_add(json_community_list, json_string); json_object_new_string("noExport");
json_object_array_add(json_community_list,
json_string);
} }
break; break;
case COMMUNITY_NO_ADVERTISE: case COMMUNITY_NO_ADVERTISE:
strcpy(pnt, "no-advertise"); strcpy(pnt, "no-advertise");
pnt += strlen("no-advertise"); pnt += strlen("no-advertise");
if (make_json) { if (make_json) {
json_string = json_object_new_string("noAdvertise"); json_string =
json_object_array_add(json_community_list, json_string); json_object_new_string("noAdvertise");
json_object_array_add(json_community_list,
json_string);
} }
break; break;
case COMMUNITY_LOCAL_AS: case COMMUNITY_LOCAL_AS:
@ -302,15 +309,18 @@ static void set_community_string(struct community *com, bool make_json)
pnt += strlen("local-AS"); pnt += strlen("local-AS");
if (make_json) { if (make_json) {
json_string = json_object_new_string("localAs"); json_string = json_object_new_string("localAs");
json_object_array_add(json_community_list, json_string); json_object_array_add(json_community_list,
json_string);
} }
break; break;
case COMMUNITY_GSHUT: case COMMUNITY_GSHUT:
strcpy(pnt, "graceful-shutdown"); strcpy(pnt, "graceful-shutdown");
pnt += strlen("graceful-shutdown"); pnt += strlen("graceful-shutdown");
if (make_json) { if (make_json) {
json_string = json_object_new_string("gracefulShutdown"); json_string = json_object_new_string(
json_object_array_add(json_community_list, json_string); "gracefulShutdown");
json_object_array_add(json_community_list,
json_string);
} }
break; break;
default: default:
@ -319,7 +329,8 @@ static void set_community_string(struct community *com, bool make_json)
sprintf(pnt, "%u:%d", as, val); sprintf(pnt, "%u:%d", as, val);
if (make_json) { if (make_json) {
json_string = json_object_new_string(pnt); json_string = json_object_new_string(pnt);
json_object_array_add(json_community_list, json_string); json_object_array_add(json_community_list,
json_string);
} }
pnt += strlen(pnt); pnt += strlen(pnt);
break; break;
@ -545,7 +556,8 @@ community_gettoken(const char *buf, enum community_token *token, u_int32_t *val)
p += strlen("local-AS"); p += strlen("local-AS");
return p; return p;
} }
if (strncmp(p, "graceful-shutdown", strlen("graceful-shutdown")) == 0) { if (strncmp(p, "graceful-shutdown", strlen("graceful-shutdown"))
== 0) {
*val = COMMUNITY_GSHUT; *val = COMMUNITY_GSHUT;
*token = community_token_gshut; *token = community_token_gshut;
p += strlen("graceful-shutdown"); p += strlen("graceful-shutdown");
@ -662,10 +674,10 @@ struct hash *community_hash(void)
/* Initialize comminity related hash. */ /* Initialize comminity related hash. */
void community_init(void) void community_init(void)
{ {
comhash = hash_create( comhash =
(unsigned int (*)(void *))community_hash_make, hash_create((unsigned int (*)(void *))community_hash_make,
(int (*)(const void *, const void *))community_cmp, (int (*)(const void *, const void *))community_cmp,
"BGP Community Hash"); "BGP Community Hash");
} }
void community_finish(void) void community_finish(void)

View File

@ -542,7 +542,7 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf,
} else } else
reuse_time = 0; reuse_time = 0;
/* Making formatted timer strings. */ /* Making formatted timer strings. */
if (reuse_time == 0) { if (reuse_time == 0) {
if (use_json) if (use_json)
json_object_int_add(json, "reuseTimerMsecs", 0); json_object_int_add(json, "reuseTimerMsecs", 0);

View File

@ -260,8 +260,7 @@ int ecommunity_cmp(const void *arg1, const void *arg2)
/* Initialize Extended Comminities related hash. */ /* Initialize Extended Comminities related hash. */
void ecommunity_init(void) void ecommunity_init(void)
{ {
ecomhash = hash_create(ecommunity_hash_make, ecomhash = hash_create(ecommunity_hash_make, ecommunity_cmp,
ecommunity_cmp,
"BGP ecommunity hash"); "BGP ecommunity hash");
} }
@ -690,7 +689,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
tunneltype = ntohs(tunneltype); tunneltype = ntohs(tunneltype);
len = sprintf(str_buf + str_pnt, "ET:%d", len = sprintf(str_buf + str_pnt, "ET:%d",
tunneltype); tunneltype);
} else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW) { } else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW) {
len = sprintf(str_buf + str_pnt, len = sprintf(str_buf + str_pnt,
"Default Gateway"); "Default Gateway");
} else } else

File diff suppressed because it is too large Load Diff

View File

@ -55,12 +55,30 @@ static inline vni_t label2vni(mpls_label_t *label)
return vni; return vni;
} }
static inline int advertise_type5_routes(struct bgp *bgp_vrf,
afi_t afi)
{
if (!bgp_vrf->l3vni)
return 0;
if (afi == AFI_IP &&
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
return 1;
if (afi == AFI_IP6 &&
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
return 1;
return 0;
}
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
struct prefix *p, struct prefix *p,
struct attr *src_attr, struct attr *src_attr, afi_t afi,
afi_t afi, safi_t safi); safi_t safi);
extern void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, extern void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,
struct prefix *p,
afi_t afi, safi_t safi); afi_t afi, safi_t safi);
extern void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, extern void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi,
safi_t safi); safi_t safi);
@ -73,10 +91,9 @@ extern char *bgp_evpn_label2str(mpls_label_t *label, u_int32_t num_labels,
extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len); extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len);
extern void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json); extern void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json);
extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p, extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
struct prefix_rd *prd, struct prefix_rd *prd, mpls_label_t *label,
mpls_label_t *label, u_int32_t num_labels, u_int32_t num_labels, struct attr *attr,
struct attr *attr, int addpath_encode, int addpath_encode, u_int32_t addpath_tx_id);
u_int32_t addpath_tx_id);
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
struct bgp_nlri *packet, int withdraw); struct bgp_nlri *packet, int withdraw);
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi, extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
@ -91,8 +108,7 @@ extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
u_char flags); u_char flags);
extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id, extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id,
struct ethaddr *rmac, struct ethaddr *rmac,
struct in_addr originator_ip, struct in_addr originator_ip, int filter);
int filter);
extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id); extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id);
extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni); extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,

View File

@ -66,29 +66,34 @@ struct bgpevpn {
struct bgp *bgp_vrf; /* back pointer to the vrf instance */ struct bgp *bgp_vrf; /* back pointer to the vrf instance */
/* Flag to indicate if we are advertising the g/w mac ip for this VNI*/ /* Flag to indicate if we are
u_int8_t advertise_gw_macip; * advertising the g/w mac ip for
* this VNI*/
u_int8_t advertise_gw_macip;
/* Flag to indicate if we are advertising subnet for this VNI */ /* Flag to indicate if we are
u_int8_t advertise_subnet; * advertising subnet for this VNI */
u_int8_t advertise_subnet;
/* Id for deriving the RD automatically for this VNI */ /* Id for deriving the RD
u_int16_t rd_id; * automatically for this VNI */
u_int16_t rd_id;
/* RD for this VNI. */ /* RD for this VNI. */
struct prefix_rd prd; struct prefix_rd prd;
/* Route type 3 field */ /* Route type 3 field */
struct in_addr originator_ip; struct in_addr originator_ip;
/* Import and Export RTs. */ /* Import and Export RTs. */
struct list *import_rtl; struct list *import_rtl;
struct list *export_rtl; struct list *export_rtl;
/* Route table for EVPN routes for this VNI. */ /* Route table for EVPN routes for
struct bgp_table *route_table; * this VNI. */
struct bgp_table *route_table;
QOBJ_FIELDS QOBJ_FIELDS
}; };
DECLARE_QOBJ_TYPE(bgpevpn) DECLARE_QOBJ_TYPE(bgpevpn)
@ -124,8 +129,7 @@ struct vrf_irt_node {
static inline int is_vrf_rd_configured(struct bgp *bgp_vrf) static inline int is_vrf_rd_configured(struct bgp *bgp_vrf)
{ {
return (CHECK_FLAG(bgp_vrf->vrf_flags, return (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD));
BGP_VRF_RD_CFGD));
} }
static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf, static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf,
@ -168,10 +172,10 @@ static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn)
/* bail if vpn is not associated to bgp_vrf */ /* bail if vpn is not associated to bgp_vrf */
if (!vpn->bgp_vrf) if (!vpn->bgp_vrf)
return; return;
UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
listnode_delete(vpn->bgp_vrf->l2vnis, vpn); listnode_delete(vpn->bgp_vrf->l2vnis, vpn);
/* remove the backpointer to the vrf instance */ /* remove the backpointer to the vrf instance */
vpn->bgp_vrf = NULL; vpn->bgp_vrf = NULL;
} }
@ -193,8 +197,7 @@ static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn)
listnode_add_sort(bgp_vrf->l2vnis, vpn); listnode_add_sort(bgp_vrf->l2vnis, vpn);
/* check if we are advertising two labels for this vpn */ /* check if we are advertising two labels for this vpn */
if (!CHECK_FLAG(bgp_vrf->vrf_flags, if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY))
BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY))
SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
} }
@ -272,18 +275,24 @@ static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
if (IS_EVPN_PREFIX_IPADDR_V4(evp)) { if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
ip->family = AF_INET; ip->family = AF_INET;
ip->prefixlen = evp->prefix.ip_prefix_length; ip->prefixlen = evp->prefix.ip_prefix_length;
memcpy(&(ip->u.prefix4), memcpy(&(ip->u.prefix4), &(evp->prefix.ip.ip),
&(evp->prefix.ip.ip),
IPV4_MAX_BYTELEN); IPV4_MAX_BYTELEN);
} else if (IS_EVPN_PREFIX_IPADDR_V6(evp)) { } else if (IS_EVPN_PREFIX_IPADDR_V6(evp)) {
ip->family = AF_INET6; ip->family = AF_INET6;
ip->prefixlen = evp->prefix.ip_prefix_length; ip->prefixlen = evp->prefix.ip_prefix_length;
memcpy(&(ip->u.prefix6), memcpy(&(ip->u.prefix6), &(evp->prefix.ip.ip),
&(evp->prefix.ip.ip),
IPV6_MAX_BYTELEN); IPV6_MAX_BYTELEN);
} }
} }
static inline int is_evpn_prefix_default(struct prefix *evp)
{
if (evp->family != AF_EVPN)
return 0;
return ((evp->u.prefix_evpn.ip_prefix_length == 0) ? 1 : 0);
}
static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp, static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,
struct prefix *ip) struct prefix *ip)
{ {
@ -291,14 +300,12 @@ static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,
if (IS_EVPN_PREFIX_IPADDR_V4(evp)) { if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
ip->family = AF_INET; ip->family = AF_INET;
ip->prefixlen = IPV4_MAX_BITLEN; ip->prefixlen = IPV4_MAX_BITLEN;
memcpy(&(ip->u.prefix4), memcpy(&(ip->u.prefix4), &(evp->prefix.ip.ip),
&(evp->prefix.ip.ip),
IPV4_MAX_BYTELEN); IPV4_MAX_BYTELEN);
} else if (IS_EVPN_PREFIX_IPADDR_V6(evp)) { } else if (IS_EVPN_PREFIX_IPADDR_V6(evp)) {
ip->family = AF_INET6; ip->family = AF_INET6;
ip->prefixlen = IPV6_MAX_BITLEN; ip->prefixlen = IPV6_MAX_BITLEN;
memcpy(&(ip->u.prefix6), memcpy(&(ip->u.prefix6), &(evp->prefix.ip.ip),
&(evp->prefix.ip.ip),
IPV6_MAX_BYTELEN); IPV6_MAX_BYTELEN);
} }
} }
@ -353,24 +360,21 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
p->prefix.ip.ipaddr_v4 = originator_ip; p->prefix.ip.ipaddr_v4 = originator_ip;
} }
static inline int advertise_type5_routes(struct bgp *bgp_vrf, static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi,
afi_t afi) safi_t safi)
{ {
if (!bgp_vrf->l3vni)
return 0;
if (afi == AFI_IP && if (afi == AFI_IP &&
CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
return 1; return 1;
else if (afi == AFI_IP6 &&
if (afi == AFI_IP6 && CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
return 1; return 1;
return 0; return 0;
} }
extern void evpn_rt_delete_auto(struct bgp*, vni_t, struct list*); extern void evpn_rt_delete_auto(struct bgp *, vni_t, struct list *);
extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf, extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
struct ecommunity *ecomadd); struct ecommunity *ecomadd);
extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf, extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,

View File

@ -53,8 +53,7 @@ struct vni_walk_ctx {
}; };
#if defined(HAVE_CUMULUS) #if defined(HAVE_CUMULUS)
static void display_vrf_import_rt(struct vty *vty, static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt,
struct vrf_irt_node *irt,
json_object *json) json_object *json)
{ {
u_char *pnt; u_char *pnt;
@ -138,8 +137,7 @@ static void display_vrf_import_rt(struct vty *vty,
json_object_array_add( json_object_array_add(
json_vrfs, json_vrfs,
json_object_new_string( json_object_new_string(
vrf_id_to_name( vrf_id_to_name(tmp_bgp_vrf->vrf_id)));
tmp_bgp_vrf->vrf_id)));
else else
vty_out(vty, " %s\n", vty_out(vty, " %s\n",
vrf_id_to_name(tmp_bgp_vrf->vrf_id)); vrf_id_to_name(tmp_bgp_vrf->vrf_id));
@ -151,8 +149,7 @@ static void display_vrf_import_rt(struct vty *vty,
} }
} }
static void show_vrf_import_rt_entry(struct hash_backet *backet, static void show_vrf_import_rt_entry(struct hash_backet *backet, void *args[])
void *args[])
{ {
json_object *json = NULL; json_object *json = NULL;
struct vty *vty = NULL; struct vty *vty = NULL;
@ -604,7 +601,7 @@ static void show_vni_routes_hash(struct hash_backet *backet, void *arg)
} }
static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
json_object *json) json_object *json)
{ {
json_object *json_vni; json_object *json_vni;
json_object *json_import_rtl; json_object *json_import_rtl;
@ -639,8 +636,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
json_vni, "rd", json_vni, "rd",
prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN)); prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
} else { } else {
vty_out(vty, "%-1s %-10u %-4s %-21s", vty_out(vty, "%-1s %-10u %-4s %-21s", buf1, bgp->l3vni, "L3",
buf1, bgp->l3vni, "L3",
prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN)); prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
} }
@ -748,8 +744,7 @@ static void show_vni_entry(struct hash_backet *backet, void *args[])
json_vni, "rd", json_vni, "rd",
prefix_rd2str(&vpn->prd, buf2, sizeof(buf2))); prefix_rd2str(&vpn->prd, buf2, sizeof(buf2)));
} else { } else {
vty_out(vty, "%-1s %-10u %-4s %-21s", vty_out(vty, "%-1s %-10u %-4s %-21s", buf1, vpn->vni, "L2",
buf1, vpn->vni, "L2",
prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN)); prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN));
} }
@ -1430,8 +1425,7 @@ DEFUN(evpnrt5_network,
return bgp_static_set_safi( return bgp_static_set_safi(
AFI_L2VPN, SAFI_EVPN, vty, argv[idx_ipv4_prefixlen]->arg, AFI_L2VPN, SAFI_EVPN, vty, argv[idx_ipv4_prefixlen]->arg,
argv[idx_route_distinguisher]->arg, argv[idx_label]->arg, argv[idx_route_distinguisher]->arg, argv[idx_label]->arg, NULL,
NULL,
BGP_EVPN_IP_PREFIX_ROUTE, argv[idx_esi]->arg, BGP_EVPN_IP_PREFIX_ROUTE, argv[idx_esi]->arg,
argv[idx_gwip]->arg, argv[idx_ethtag]->arg, argv[idx_gwip]->arg, argv[idx_ethtag]->arg,
argv[idx_routermac]->arg); argv[idx_routermac]->arg);
@ -1632,8 +1626,7 @@ static void evpn_unconfigure_export_rt(struct bgp *bgp, struct bgpevpn *vpn,
/* /*
* Configure RD for VRF * Configure RD for VRF
*/ */
static void evpn_configure_vrf_rd(struct bgp *bgp_vrf, static void evpn_configure_vrf_rd(struct bgp *bgp_vrf, struct prefix_rd *rd)
struct prefix_rd *rd)
{ {
/* If we have already advertise type-5 routes with a diffrent RD, we /* If we have already advertise type-5 routes with a diffrent RD, we
* have to delete and withdraw them firs * have to delete and withdraw them firs
@ -1777,8 +1770,7 @@ static int evpn_delete_vni(struct bgp *bgp, struct bgpevpn *vpn)
* Display import RT mapping to VRFs (vty handler) * Display import RT mapping to VRFs (vty handler)
* bgp_def: default bgp instance * bgp_def: default bgp instance
*/ */
static void evpn_show_vrf_import_rts(struct vty *vty, static void evpn_show_vrf_import_rts(struct vty *vty, struct bgp *bgp_def,
struct bgp *bgp_def,
json_object *json) json_object *json)
{ {
void *args[2]; void *args[2];
@ -1787,8 +1779,8 @@ static void evpn_show_vrf_import_rts(struct vty *vty,
args[1] = json; args[1] = json;
hash_iterate(bgp_def->vrf_import_rt_hash, hash_iterate(bgp_def->vrf_import_rt_hash,
(void (*)(struct hash_backet *, void *)) (void (*)(struct hash_backet *,
show_vrf_import_rt_entry, void *))show_vrf_import_rt_entry,
args); args);
} }
@ -2364,8 +2356,7 @@ static void evpn_show_all_vnis(struct vty *vty, struct bgp *bgp,
if (!json) { if (!json) {
vty_out(vty, "Flags: * - Kernel\n"); vty_out(vty, "Flags: * - Kernel\n");
vty_out(vty, " %-10s %-4s %-21s %-25s %-25s %-37s\n", "VNI", vty_out(vty, " %-10s %-4s %-21s %-25s %-25s %-37s\n", "VNI",
"Type", "RD", "Import RT", "Type", "RD", "Import RT", "Export RT", "Tenant VRF");
"Export RT", "Tenant VRF");
} }
/* print all L2 VNIS */ /* print all L2 VNIS */
@ -2378,7 +2369,6 @@ static void evpn_show_all_vnis(struct vty *vty, struct bgp *bgp,
/* print all L3 VNIs */ /* print all L3 VNIs */
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_temp)) for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_temp))
show_l3vni_entry(vty, bgp_temp, json); show_l3vni_entry(vty, bgp_temp, json);
} }
/* /*
@ -2426,6 +2416,48 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,
return; return;
} }
/*
* evpn - enable advertisement of default g/w
*/
static void evpn_process_default_originate_cmd(struct bgp *bgp_vrf,
afi_t afi, int add)
{
struct prefix ip_prefix;
safi_t safi = SAFI_UNICAST; /* ipv4/ipv6 unicast */
/* form the default prefix 0.0.0.0/0 */
memset(&ip_prefix, 0, sizeof(struct prefix));
ip_prefix.family = afi2family(afi);
ip_prefix.prefixlen = 0;
if (add) {
/* bail if we are already advertising default route */
if (evpn_default_originate_set(bgp_vrf, afi, safi))
return;
if (afi == AFI_IP)
SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
else if (afi == AFI_IP6)
SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
bgp_evpn_advertise_type5_route(bgp_vrf, &ip_prefix,
NULL, afi, safi);
} else {
/* bail out if we havent advertised the default route */
if (!evpn_default_originate_set(bgp_vrf, afi, safi))
return;
if (afi == AFI_IP)
UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
else if (afi == AFI_IP6)
UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
bgp_evpn_withdraw_type5_route(bgp_vrf, &ip_prefix,
afi, safi);
}
}
/* /*
* evpn - enable advertisement of default g/w * evpn - enable advertisement of default g/w
*/ */
@ -2442,8 +2474,7 @@ static void evpn_set_advertise_subnet(struct bgp *bgp,
/* /*
* evpn - disable advertisement of default g/w * evpn - disable advertisement of default g/w
*/ */
static void evpn_unset_advertise_subnet(struct bgp *bgp, static void evpn_unset_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn)
struct bgpevpn *vpn)
{ {
if (!vpn->advertise_subnet) if (!vpn->advertise_subnet)
return; return;
@ -2624,6 +2655,43 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (bgp_evpn_default_originate,
bgp_evpn_default_originate_cmd,
"default-originate <ipv4 | ipv6>",
"originate a default route\n"
"ipv4 address family\n"
"ipv6 address family\n")
{
afi_t afi = 0;
int idx_afi = 0;
struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
if (!bgp_vrf)
return CMD_WARNING;
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
evpn_process_default_originate_cmd(bgp_vrf, afi, 1);
return CMD_SUCCESS;
}
DEFUN (no_bgp_evpn_default_originate,
no_bgp_evpn_default_originate_cmd,
"no default-originate <ipv4 | ipv6>",
NO_STR
"withdraw a default route\n"
"ipv4 address family\n"
"ipv6 address family\n")
{
afi_t afi = 0;
int idx_afi = 0;
struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
if (!bgp_vrf)
return CMD_WARNING;
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
evpn_process_default_originate_cmd(bgp_vrf, afi, 0);
return CMD_SUCCESS;
}
DEFUN (bgp_evpn_advertise_vni_subnet, DEFUN (bgp_evpn_advertise_vni_subnet,
bgp_evpn_advertise_vni_subnet_cmd, bgp_evpn_advertise_vni_subnet_cmd,
"advertise-subnet", "advertise-subnet",
@ -2643,14 +2711,6 @@ DEFUN (bgp_evpn_advertise_vni_subnet,
if (!bgp_vrf) if (!bgp_vrf)
return CMD_WARNING; return CMD_WARNING;
if (!(advertise_type5_routes(bgp_vrf, AFI_IP) ||
advertise_type5_routes(bgp_vrf, AFI_IP6))) {
vty_out(vty,
"%%Please enable ip prefix advertisement under l2vpn evpn in %s",
vrf_id_to_name(bgp_vrf->vrf_id));
return CMD_WARNING;
}
evpn_set_advertise_subnet(bgp, vpn); evpn_set_advertise_subnet(bgp, vpn);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -2699,7 +2759,8 @@ DEFUN (bgp_evpn_advertise_type5,
if (!bgp_vrf->adv_cmd_rmap[afi][safi].name) if (!bgp_vrf->adv_cmd_rmap[afi][safi].name)
rmap_changed = 1; rmap_changed = 1;
else if (strcmp(argv[idx_rmap + 1]->arg, else if (strcmp(argv[idx_rmap + 1]->arg,
bgp_vrf->adv_cmd_rmap[afi][safi].name) != 0) bgp_vrf->adv_cmd_rmap[afi][safi].name)
!= 0)
rmap_changed = 1; rmap_changed = 1;
} else if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { } else if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
rmap_changed = 1; rmap_changed = 1;
@ -2722,21 +2783,23 @@ DEFUN (bgp_evpn_advertise_type5,
/* if we are already advertising ipv4 prefix as type-5 /* if we are already advertising ipv4 prefix as type-5
* nothing to do * nothing to do
*/ */
if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, if (!rmap_changed &&
BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
return CMD_WARNING; return CMD_WARNING;
SET_FLAG(bgp_vrf->vrf_flags, SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_VRF_ADVERTISE_IPV4_IN_EVPN); BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
} else { } else {
/* if we are already advertising ipv6 prefix as type-5 /* if we are already advertising ipv6 prefix as type-5
* nothing to do * nothing to do
*/ */
if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, if (!rmap_changed &&
BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
return CMD_WARNING; return CMD_WARNING;
SET_FLAG(bgp_vrf->vrf_flags, SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_VRF_ADVERTISE_IPV6_IN_EVPN); BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
} }
if (rmap_changed) { if (rmap_changed) {
@ -2752,8 +2815,7 @@ DEFUN (bgp_evpn_advertise_type5,
/* set the route-map for advertise command */ /* set the route-map for advertise command */
if (ret && argv[idx_rmap + 1]->arg) { if (ret && argv[idx_rmap + 1]->arg) {
bgp_vrf->adv_cmd_rmap[afi][safi].name = bgp_vrf->adv_cmd_rmap[afi][safi].name =
XSTRDUP(MTYPE_ROUTE_MAP_NAME, XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[idx_rmap + 1]->arg);
argv[idx_rmap + 1]->arg);
bgp_vrf->adv_cmd_rmap[afi][safi].map = bgp_vrf->adv_cmd_rmap[afi][safi].map =
route_map_lookup_by_name(argv[idx_rmap + 1]->arg); route_map_lookup_by_name(argv[idx_rmap + 1]->arg);
} }
@ -2780,7 +2842,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi); argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi); argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
if (!(afi == AFI_IP) || (afi == AFI_IP6)) { if (!(afi == AFI_IP || afi == AFI_IP6)) {
vty_out(vty, vty_out(vty,
"%%only ipv4 or ipv6 address families are supported"); "%%only ipv4 or ipv6 address families are supported");
return CMD_WARNING; return CMD_WARNING;
@ -2794,25 +2856,25 @@ DEFUN (no_bgp_evpn_advertise_type5,
if (afi == AFI_IP) { if (afi == AFI_IP) {
/* if we are already advertising ipv4 prefix as type-5 /* if we are not advertising ipv4 prefix as type-5
* nothing to do * nothing to do
*/ */
if (CHECK_FLAG(bgp_vrf->vrf_flags, if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) { BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi); bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
UNSET_FLAG(bgp_vrf->vrf_flags, UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_VRF_ADVERTISE_IPV4_IN_EVPN); BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
} }
} else { } else {
/* if we are already advertising ipv6 prefix as type-5 /* if we are not advertising ipv6 prefix as type-5
* nothing to do * nothing to do
*/ */
if (CHECK_FLAG(bgp_vrf->vrf_flags, if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) { BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi); bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
UNSET_FLAG(bgp_vrf->vrf_flags, UNSET_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV6_IN_EVPN); BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
} }
} }
@ -2879,16 +2941,15 @@ DEFUN(show_bgp_l2vpn_evpn_vni,
? "Enabled" ? "Enabled"
: "Disabled"); : "Disabled");
json_object_string_add(json, "advertiseAllVnis", json_object_string_add(json, "advertiseAllVnis",
is_evpn_enabled() is_evpn_enabled() ? "Enabled"
? "Enabled" : "Disabled");
: "Disabled");
json_object_int_add(json, "numVnis", num_vnis); json_object_int_add(json, "numVnis", num_vnis);
json_object_int_add(json, "numL2Vnis", num_l2vnis); json_object_int_add(json, "numL2Vnis", num_l2vnis);
json_object_int_add(json, "numL3Vnis", num_l3vnis); json_object_int_add(json, "numL3Vnis", num_l3vnis);
} else { } else {
vty_out(vty, "Advertise Gateway Macip: %s\n", vty_out(vty, "Advertise Gateway Macip: %s\n",
bgp_def->advertise_gw_macip ? "Enabled" bgp_def->advertise_gw_macip ? "Enabled"
: "Disabled"); : "Disabled");
vty_out(vty, "Advertise All VNI flag: %s\n", vty_out(vty, "Advertise All VNI flag: %s\n",
is_evpn_enabled() ? "Enabled" : "Disabled"); is_evpn_enabled() ? "Enabled" : "Disabled");
vty_out(vty, "Number of L2 VNIs: %u\n", num_l2vnis); vty_out(vty, "Number of L2 VNIs: %u\n", num_l2vnis);
@ -3478,8 +3539,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni, show_bgp_evpn_vni_cmd,
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary, show_bgp_evpn_summary_cmd, ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary, show_bgp_evpn_summary_cmd,
"show bgp evpn summary [json]", SHOW_STR BGP_STR EVPN_HELP_STR "show bgp evpn summary [json]", SHOW_STR BGP_STR EVPN_HELP_STR
"Summary of BGP neighbor status\n" "Summary of BGP neighbor status\n" JSON_STR)
JSON_STR)
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd, ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd,
"show bgp evpn route [type <macip|multicast>]", "show bgp evpn route [type <macip|multicast>]",
@ -3855,13 +3915,11 @@ DEFUN (show_bgp_vrf_l3vni_info,
bgp = bgp_lookup_by_name(name); bgp = bgp_lookup_by_name(name);
if (!bgp) { if (!bgp) {
if (!uj) if (!uj)
vty_out(vty, "BGP instance for VRF %s not found", vty_out(vty, "BGP instance for VRF %s not found", name);
name);
else { else {
json_object_string_add(json, "warning", json_object_string_add(json, "warning",
"BGP instance not found"); "BGP instance not found");
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string(json));
json_object_to_json_string(json));
json_object_free(json); json_object_free(json);
} }
return CMD_WARNING; return CMD_WARNING;
@ -3869,15 +3927,15 @@ DEFUN (show_bgp_vrf_l3vni_info,
if (!json) { if (!json) {
vty_out(vty, "BGP VRF: %s\n", name); vty_out(vty, "BGP VRF: %s\n", name);
vty_out(vty, " Local-Ip: %s\n", vty_out(vty, " Local-Ip: %s\n", inet_ntoa(bgp->originator_ip));
inet_ntoa(bgp->originator_ip));
vty_out(vty, " L3-VNI: %u\n", bgp->l3vni); vty_out(vty, " L3-VNI: %u\n", bgp->l3vni);
vty_out(vty, " Rmac: %s\n", vty_out(vty, " Rmac: %s\n",
prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
vty_out(vty, " VNI Filter: %s\n", vty_out(vty, " VNI Filter: %s\n",
CHECK_FLAG(bgp->vrf_flags, CHECK_FLAG(bgp->vrf_flags,
BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY) ? BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)
"prefix-routes-only" : "none"); ? "prefix-routes-only"
: "none");
vty_out(vty, " L2-VNI List:\n"); vty_out(vty, " L2-VNI List:\n");
vty_out(vty, " "); vty_out(vty, " ");
for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn)) for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn))
@ -3900,13 +3958,15 @@ DEFUN (show_bgp_vrf_l3vni_info,
json_object_string_add(json, "local-ip", json_object_string_add(json, "local-ip",
inet_ntoa(bgp->originator_ip)); inet_ntoa(bgp->originator_ip));
json_object_int_add(json, "l3vni", bgp->l3vni); json_object_int_add(json, "l3vni", bgp->l3vni);
json_object_string_add(json, "rmac", json_object_string_add(
prefix_mac2str(&bgp->rmac, buf, json, "rmac",
sizeof(buf))); prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
json_object_string_add(json, "vniFilter", json_object_string_add(
CHECK_FLAG(bgp->vrf_flags, json, "vniFilter",
BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY) CHECK_FLAG(bgp->vrf_flags,
? "prefix-routes-only" : "none"); BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)
? "prefix-routes-only"
: "none");
/* list of l2vnis */ /* list of l2vnis */
for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn)) for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn))
json_object_array_add(json_vnis, json_object_array_add(json_vnis,
@ -3915,21 +3975,20 @@ DEFUN (show_bgp_vrf_l3vni_info,
/* export rts */ /* export rts */
for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom)) for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom))
json_object_array_add(json_export_rts, json_object_array_add(
json_object_new_string( json_export_rts,
ecommunity_str(ecom))); json_object_new_string(ecommunity_str(ecom)));
json_object_object_add(json, "export-rts", json_export_rts); json_object_object_add(json, "export-rts", json_export_rts);
/* import rts */ /* import rts */
for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom)) for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom))
json_object_array_add(json_import_rts, json_object_array_add(
json_object_new_string( json_import_rts,
ecommunity_str(ecom))); json_object_new_string(ecommunity_str(ecom)));
json_object_object_add(json, "import-rts", json_import_rts); json_object_object_add(json, "import-rts", json_import_rts);
json_object_string_add( json_object_string_add(
json, "rd", json, "rd",
prefix_rd2str(&bgp->vrf_prd, buf1, RD_ADDRSTRLEN)); prefix_rd2str(&bgp->vrf_prd, buf1, RD_ADDRSTRLEN));
} }
if (uj) { if (uj) {
@ -3979,8 +4038,7 @@ DEFUN (bgp_evpn_vrf_rt,
ecommunity_str(ecomadd); ecommunity_str(ecomadd);
/* Do nothing if we already have this import route-target */ /* Do nothing if we already have this import route-target */
if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl, if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl, ecomadd))
ecomadd))
bgp_evpn_configure_import_rt_for_vrf(bgp, ecomadd); bgp_evpn_configure_import_rt_for_vrf(bgp, ecomadd);
} }
@ -3995,8 +4053,7 @@ DEFUN (bgp_evpn_vrf_rt,
ecommunity_str(ecomadd); ecommunity_str(ecomadd);
/* Do nothing if we already have this export route-target */ /* Do nothing if we already have this export route-target */
if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl, if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl, ecomadd))
ecomadd))
bgp_evpn_configure_export_rt_for_vrf(bgp, ecomadd); bgp_evpn_configure_export_rt_for_vrf(bgp, ecomadd);
} }
@ -4324,12 +4381,22 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (bgp->advertise_gw_macip) if (bgp->advertise_gw_macip)
vty_out(vty, " advertise-default-gw\n"); vty_out(vty, " advertise-default-gw\n");
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
vty_out(vty, " advertise ipv4 unicast\n"); vty_out(vty, " advertise ipv4 unicast\n");
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
vty_out(vty, " advertise ipv6 unicast\n"); vty_out(vty, " advertise ipv6 unicast\n");
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
vty_out(vty, " default-originate ipv4\n");
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
vty_out(vty, " default-originate ipv6\n");
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD)) if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
vty_out(vty, " rd %s\n", vty_out(vty, " rd %s\n",
prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1))); prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
@ -4344,8 +4411,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
ecom)) { ecom)) {
ecom_str = ecommunity_ecom2str( ecom_str = ecommunity_ecom2str(
ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
vty_out(vty, " route-target import %s\n", vty_out(vty, " route-target import %s\n", ecom_str);
ecom_str);
XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
} }
} }
@ -4360,8 +4426,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
ecom)) { ecom)) {
ecom_str = ecommunity_ecom2str( ecom_str = ecommunity_ecom2str(
ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
vty_out(vty, " route-target export %s\n", vty_out(vty, " route-target export %s\n", ecom_str);
ecom_str);
XFREE(MTYPE_ECOMMUNITY_STR, ecom_str); XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
} }
} }
@ -4394,6 +4459,8 @@ void bgp_ethernetvpn_init(void)
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd); install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd); install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd); install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
/* "show bgp l2vpn evpn" commands. */ /* "show bgp l2vpn evpn" commands. */
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd); install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);

View File

@ -1056,8 +1056,8 @@ int bgp_stop(struct peer *peer)
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
for (afi = AFI_IP; afi < AFI_MAX; afi++) for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN;
safi <= SAFI_MPLS_VPN; safi++) safi++)
peer->nsf[afi][safi] = 0; peer->nsf[afi][safi] = 0;
} }
@ -1377,12 +1377,11 @@ int bgp_start(struct peer *peer)
return 0; return 0;
} }
if (peer->bgp && if (peer->bgp && peer->bgp->vrf_id == VRF_UNKNOWN) {
peer->bgp->vrf_id == VRF_UNKNOWN) {
if (bgp_debug_neighbor_events(peer)) if (bgp_debug_neighbor_events(peer))
zlog_err( zlog_err(
"%s [FSM] In a VRF that is not initialised yet", "%s [FSM] In a VRF that is not initialised yet",
peer->host); peer->host);
return -1; return -1;
} }
@ -1518,9 +1517,8 @@ static int bgp_establish(struct peer *peer)
} }
if (other == peer) if (other == peer)
ret = ret = 1; /* bgp_establish specific code when xfer_conn
1; /* bgp_establish specific code when xfer_conn happens. */
happens. */
/* Reset capability open status flag. */ /* Reset capability open status flag. */
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)) if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN))

View File

@ -290,8 +290,8 @@ static uint16_t bgp_write(struct peer *peer)
uint16_t status = 0; uint16_t status = 0;
uint32_t wpkt_quanta_old; uint32_t wpkt_quanta_old;
wpkt_quanta_old = wpkt_quanta_old = atomic_load_explicit(&peer->bgp->wpkt_quanta,
atomic_load_explicit(&peer->bgp->wpkt_quanta, memory_order_relaxed); memory_order_relaxed);
while (count < wpkt_quanta_old && (s = stream_fifo_head(peer->obuf))) { while (count < wpkt_quanta_old && (s = stream_fifo_head(peer->obuf))) {
int writenum; int writenum;
@ -402,7 +402,7 @@ static uint16_t bgp_read(struct peer *peer)
/* EAGAIN or EWOULDBLOCK; come back later */ /* EAGAIN or EWOULDBLOCK; come back later */
if (nbytes < 0 && ERRNO_IO_RETRY(errno)) { if (nbytes < 0 && ERRNO_IO_RETRY(errno)) {
SET_FLAG(status, BGP_IO_TRANS_ERR); SET_FLAG(status, BGP_IO_TRANS_ERR);
/* Fatal error; tear down session */ /* Fatal error; tear down session */
} else if (nbytes < 0) { } else if (nbytes < 0) {
zlog_err("%s [Error] bgp_read_packet error: %s", peer->host, zlog_err("%s [Error] bgp_read_packet error: %s", peer->host,
safe_strerror(errno)); safe_strerror(errno));
@ -417,7 +417,7 @@ static uint16_t bgp_read(struct peer *peer)
BGP_EVENT_ADD(peer, TCP_fatal_error); BGP_EVENT_ADD(peer, TCP_fatal_error);
SET_FLAG(status, BGP_IO_FATAL_ERR); SET_FLAG(status, BGP_IO_FATAL_ERR);
/* Received EOF / TCP session closed */ /* Received EOF / TCP session closed */
} else if (nbytes == 0) { } else if (nbytes == 0) {
if (bgp_debug_neighbor_events(peer)) if (bgp_debug_neighbor_events(peer))
zlog_debug("%s [Event] BGP connection closed fd %d", zlog_debug("%s [Event] BGP connection closed fd %d",
@ -485,8 +485,8 @@ static bool validate_header(struct peer *peer)
type); type);
bgp_notify_send_with_data(peer, BGP_NOTIFY_HEADER_ERR, bgp_notify_send_with_data(peer, BGP_NOTIFY_HEADER_ERR,
BGP_NOTIFY_HEADER_BAD_MESTYPE, BGP_NOTIFY_HEADER_BAD_MESTYPE, &type,
&type, 1); 1);
return false; return false;
} }
@ -506,14 +506,14 @@ static bool validate_header(struct peer *peer)
zlog_debug("%s bad message length - %d for %s", zlog_debug("%s bad message length - %d for %s",
peer->host, size, peer->host, size,
type == 128 ? "ROUTE-REFRESH" type == 128 ? "ROUTE-REFRESH"
: bgp_type_str[(int) type]); : bgp_type_str[(int)type]);
} }
uint16_t nsize = htons(size); uint16_t nsize = htons(size);
bgp_notify_send_with_data(peer, BGP_NOTIFY_HEADER_ERR, bgp_notify_send_with_data(peer, BGP_NOTIFY_HEADER_ERR,
BGP_NOTIFY_HEADER_BAD_MESLEN, BGP_NOTIFY_HEADER_BAD_MESLEN,
(unsigned char *) &nsize, 2); (unsigned char *)&nsize, 2);
return false; return false;
} }

View File

@ -174,13 +174,11 @@ struct lcommunity *lcommunity_merge(struct lcommunity *lcom1,
struct lcommunity *lcom2) struct lcommunity *lcom2)
{ {
if (lcom1->val) if (lcom1->val)
lcom1->val = lcom1->val = XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom1->val,
XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom1->val, lcom_length(lcom1) + lcom_length(lcom2));
lcom_length(lcom1) + lcom_length(lcom2));
else else
lcom1->val = lcom1->val = XMALLOC(MTYPE_LCOMMUNITY_VAL,
XMALLOC(MTYPE_LCOMMUNITY_VAL, lcom_length(lcom1) + lcom_length(lcom2));
lcom_length(lcom1) + lcom_length(lcom2));
memcpy(lcom1->val + lcom_length(lcom1), lcom2->val, lcom_length(lcom2)); memcpy(lcom1->val + lcom_length(lcom1), lcom2->val, lcom_length(lcom2));
lcom1->size += lcom2->size; lcom1->size += lcom2->size;
@ -243,8 +241,7 @@ int lcommunity_cmp(const void *arg1, const void *arg2)
const struct lcommunity *lcom2 = arg2; const struct lcommunity *lcom2 = arg2;
return (lcom1->size == lcom2->size return (lcom1->size == lcom2->size
&& memcmp(lcom1->val, lcom2->val, lcom_length(lcom1)) && memcmp(lcom1->val, lcom2->val, lcom_length(lcom1)) == 0);
== 0);
} }
/* Return communities hash. */ /* Return communities hash. */
@ -256,8 +253,7 @@ struct hash *lcommunity_hash(void)
/* Initialize Large Comminities related hash. */ /* Initialize Large Comminities related hash. */
void lcommunity_init(void) void lcommunity_init(void)
{ {
lcomhash = hash_create(lcommunity_hash_make, lcomhash = hash_create(lcommunity_hash_make, lcommunity_cmp,
lcommunity_cmp,
"BGP lcommunity hash"); "BGP lcommunity hash");
} }
@ -462,8 +458,8 @@ int lcommunity_match(const struct lcommunity *lcom1,
/* Every community on com2 needs to be on com1 for this to match */ /* Every community on com2 needs to be on com1 for this to match */
while (i < lcom1->size && j < lcom2->size) { while (i < lcom1->size && j < lcom2->size) {
if (memcmp(lcom1->val + (i * LCOMMUNITY_SIZE), lcom2->val + (j * LCOMMUNITY_SIZE), if (memcmp(lcom1->val + (i * LCOMMUNITY_SIZE),
LCOMMUNITY_SIZE) lcom2->val + (j * LCOMMUNITY_SIZE), LCOMMUNITY_SIZE)
== 0) == 0)
j++; j++;
i++; i++;
@ -499,8 +495,8 @@ void lcommunity_del_val(struct lcommunity *lcom, u_char *ptr)
if (lcom->size > 0) if (lcom->size > 0)
lcom->val = lcom->val =
XREALLOC(MTYPE_LCOMMUNITY_VAL, lcom->val, XREALLOC(MTYPE_LCOMMUNITY_VAL,
lcom_length(lcom)); lcom->val, lcom_length(lcom));
else { else {
XFREE(MTYPE_LCOMMUNITY_VAL, lcom->val); XFREE(MTYPE_LCOMMUNITY_VAL, lcom->val);
lcom->val = NULL; lcom->val = NULL;

View File

@ -105,9 +105,8 @@ static struct quagga_signal_t bgp_signals[] = {
static int retain_mode = 0; static int retain_mode = 0;
/* privileges */ /* privileges */
static zebra_capabilities_t _caps_p[] = { static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
};
struct zebra_privs_t bgpd_privs = { struct zebra_privs_t bgpd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP) #if defined(FRR_USER) && defined(FRR_GROUP)

View File

@ -141,16 +141,17 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
&bi2->attr->mp_nexthop_global); &bi2->attr->mp_nexthop_global);
break; break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
addr1 = (bi1->attr->mp_nexthop_prefer_global) ? addr1 = (bi1->attr->mp_nexthop_prefer_global)
bi1->attr->mp_nexthop_global ? bi1->attr->mp_nexthop_global
: bi1->attr->mp_nexthop_local; : bi1->attr->mp_nexthop_local;
addr2 = (bi2->attr->mp_nexthop_prefer_global) ? addr2 = (bi2->attr->mp_nexthop_prefer_global)
bi2->attr->mp_nexthop_global ? bi2->attr->mp_nexthop_global
: bi2->attr->mp_nexthop_local; : bi2->attr->mp_nexthop_local;
if (!bi1->attr->mp_nexthop_prefer_global && if (!bi1->attr->mp_nexthop_prefer_global
!bi2->attr->mp_nexthop_prefer_global) && !bi2->attr->mp_nexthop_prefer_global)
compare = !bgp_interface_same(bi1->peer->ifp, bi2->peer->ifp); compare = !bgp_interface_same(
bi1->peer->ifp, bi2->peer->ifp);
if (!compare) if (!compare)
compare = IPV6_ADDR_CMP(&addr1, &addr2); compare = IPV6_ADDR_CMP(&addr1, &addr2);

View File

@ -447,8 +447,8 @@ static char *bgp_get_bound_name(struct peer *peer)
{ {
char *name = NULL; char *name = NULL;
if ((peer->bgp->vrf_id == VRF_DEFAULT) && if ((peer->bgp->vrf_id == VRF_DEFAULT) && !peer->ifname
!peer->ifname && !peer->conf_if) && !peer->conf_if)
return NULL; return NULL;
if (peer->su.sa.sa_family != AF_INET if (peer->su.sa.sa_family != AF_INET
@ -673,8 +673,7 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
listener->fd = sock; listener->fd = sock;
/* this socket needs a change of ns. record bgp back pointer */ /* this socket needs a change of ns. record bgp back pointer */
if (bgp->vrf_id != VRF_DEFAULT && if (bgp->vrf_id != VRF_DEFAULT && vrf_is_mapped_on_netns(bgp->vrf_id))
vrf_is_mapped_on_netns(bgp->vrf_id))
listener->bgp = bgp; listener->bgp = bgp;
memcpy(&listener->su, sa, salen); memcpy(&listener->su, sa, salen);
@ -704,8 +703,8 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
if (bgpd_privs.change(ZPRIVS_RAISE)) if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("Can't raise privileges"); zlog_err("Can't raise privileges");
ret = vrf_getaddrinfo(address, port_str, &req, ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save,
&ainfo_save, bgp->vrf_id); bgp->vrf_id);
if (bgpd_privs.change(ZPRIVS_LOWER)) if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("Can't lower privileges"); zlog_err("Can't lower privileges");
if (ret != 0) { if (ret != 0) {
@ -723,8 +722,7 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
if (bgpd_privs.change(ZPRIVS_RAISE)) if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("Can't raise privileges"); zlog_err("Can't raise privileges");
sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype, sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype,
ainfo->ai_protocol, bgp->vrf_id, ainfo->ai_protocol, bgp->vrf_id, NULL);
NULL);
if (bgpd_privs.change(ZPRIVS_LOWER)) if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("Can't lower privileges"); zlog_err("Can't lower privileges");
if (sock < 0) { if (sock < 0) {
@ -736,8 +734,8 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
* ttl=255 */ * ttl=255 */
sockopt_ttl(ainfo->ai_family, sock, MAXTTL); sockopt_ttl(ainfo->ai_family, sock, MAXTTL);
ret = bgp_listener(sock, ainfo->ai_addr, ret = bgp_listener(sock, ainfo->ai_addr, ainfo->ai_addrlen,
ainfo->ai_addrlen, bgp); bgp);
if (ret == 0) if (ret == 0)
++count; ++count;
else else
@ -745,8 +743,9 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
} }
freeaddrinfo(ainfo_save); freeaddrinfo(ainfo_save);
if (count == 0) { if (count == 0) {
zlog_err("%s: no usable addresses please check other programs usage of specified port %d", zlog_err(
__func__, port); "%s: no usable addresses please check other programs usage of specified port %d",
__func__, port);
zlog_err("%s: Program cannot continue", __func__); zlog_err("%s: Program cannot continue", __func__);
exit(-1); exit(-1);
} }

View File

@ -122,8 +122,7 @@ static int bgp_tip_hash_cmp(const void *p1, const void *p2)
void bgp_tip_hash_init(struct bgp *bgp) void bgp_tip_hash_init(struct bgp *bgp)
{ {
bgp->tip_hash = hash_create(bgp_tip_hash_key_make, bgp->tip_hash = hash_create(bgp_tip_hash_key_make, bgp_tip_hash_cmp,
bgp_tip_hash_cmp,
"BGP TIP hash"); "BGP TIP hash");
} }
@ -204,9 +203,9 @@ static int bgp_address_hash_cmp(const void *p1, const void *p2)
void bgp_address_init(struct bgp *bgp) void bgp_address_init(struct bgp *bgp)
{ {
bgp->address_hash = hash_create(bgp_address_hash_key_make, bgp->address_hash =
bgp_address_hash_cmp, hash_create(bgp_address_hash_key_make, bgp_address_hash_cmp,
"BGP Address Hash"); "BGP Address Hash");
} }
void bgp_address_destroy(struct bgp *bgp) void bgp_address_destroy(struct bgp *bgp)
@ -448,16 +447,14 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
rn1 = rn2 = NULL; rn1 = rn2 = NULL;
bgp = SUBGRP_INST(subgrp); bgp = SUBGRP_INST(subgrp);
rn1 = bgp_node_match(bgp->connected_table[AFI_IP], rn1 = bgp_node_match(bgp->connected_table[AFI_IP], &np);
&np);
if (!rn1) if (!rn1)
return 0; return 0;
SUBGRP_FOREACH_PEER(subgrp, paf) { SUBGRP_FOREACH_PEER (subgrp, paf) {
p.u.prefix4 = paf->peer->su.sin.sin_addr; p.u.prefix4 = paf->peer->su.sin.sin_addr;
rn2 = bgp_node_match(bgp->connected_table[AFI_IP], rn2 = bgp_node_match(bgp->connected_table[AFI_IP], &p);
&p);
if (rn1 == rn2) { if (rn1 == rn2) {
bgp_unlock_node(rn1); bgp_unlock_node(rn1);
bgp_unlock_node(rn2); bgp_unlock_node(rn2);
@ -472,8 +469,7 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
return 0; return 0;
} }
static void bgp_show_nexthops_detail(struct vty *vty, static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
struct bgp *bgp,
struct bgp_nexthop_cache *bnc) struct bgp_nexthop_cache *bnc)
{ {
char buf[PREFIX2STR_BUFFER]; char buf[PREFIX2STR_BUFFER];
@ -483,39 +479,35 @@ static void bgp_show_nexthops_detail(struct vty *vty,
switch (nexthop->type) { switch (nexthop->type) {
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
vty_out(vty, " gate %s\n", vty_out(vty, " gate %s\n",
inet_ntop(AF_INET6, &nexthop->gate.ipv6, inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
buf, sizeof(buf))); sizeof(buf)));
break; break;
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
vty_out(vty, " gate %s, if %s\n", vty_out(vty, " gate %s, if %s\n",
inet_ntop(AF_INET6, &nexthop->gate.ipv6, inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
buf, sizeof(buf)), sizeof(buf)),
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
bgp->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
vty_out(vty, " gate %s\n", vty_out(vty, " gate %s\n",
inet_ntop(AF_INET, &nexthop->gate.ipv4, inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
buf, sizeof(buf))); sizeof(buf)));
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " if %s\n", vty_out(vty, " if %s\n",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
bgp->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out(vty, " gate %s, if %s\n", vty_out(vty, " gate %s, if %s\n",
inet_ntop(AF_INET, &nexthop->gate.ipv4, inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
buf, sizeof(buf)), sizeof(buf)),
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex, bgp->vrf_id));
bgp->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " blackhole\n"); vty_out(vty, " blackhole\n");
break; break;
default: default:
vty_out(vty, vty_out(vty, " invalid nexthop type %u\n",
" invalid nexthop type %u\n",
nexthop->type); nexthop->type);
} }
} }
@ -549,7 +541,7 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
bgp_show_nexthops_detail(vty, bgp, bnc); bgp_show_nexthops_detail(vty, bgp, bnc);
} else{ } else {
vty_out(vty, " %s invalid\n", vty_out(vty, " %s invalid\n",
inet_ntop(rn->p.family, inet_ntop(rn->p.family,
&rn->p.u.prefix, buf, &rn->p.u.prefix, buf,

View File

@ -546,14 +546,14 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
return; return;
p = &(bnc->node->p); p = &(bnc->node->p);
if ((command == ZEBRA_NEXTHOP_REGISTER || if ((command == ZEBRA_NEXTHOP_REGISTER
command == ZEBRA_IMPORT_ROUTE_REGISTER) && || command == ZEBRA_IMPORT_ROUTE_REGISTER)
(CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) && (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
|| CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))) || CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)))
exact_match = true; exact_match = true;
ret = zclient_send_rnh(zclient, command, p, ret = zclient_send_rnh(zclient, command, p, exact_match,
exact_match, bnc->bgp->vrf_id); bnc->bgp->vrf_id);
/* TBD: handle the failure */ /* TBD: handle the failure */
if (ret < 0) if (ret < 0)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed"); zlog_warn("sendmsg_nexthop: zclient_send_message() failed");

View File

@ -1573,9 +1573,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
* Non-MP IPv4/Unicast EoR is a completely empty UPDATE * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
* and MP EoR should have only an empty MP_UNREACH * and MP EoR should have only an empty MP_UNREACH
*/ */
if ((!update_len && !withdraw_len && if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0)
nlris[NLRI_MP_UPDATE].length == 0) || || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
(attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
afi_t afi = 0; afi_t afi = 0;
safi_t safi; safi_t safi;

View File

@ -1967,9 +1967,8 @@ int subgroup_process_announce_selected(struct update_subgroup *subgrp,
: NULL); : NULL);
/* First update is deferred until ORF or ROUTE-REFRESH is received */ /* First update is deferred until ORF or ROUTE-REFRESH is received */
if (onlypeer if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
&& CHECK_FLAG(onlypeer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
PEER_STATUS_ORF_WAIT_REFRESH))
return 0; return 0;
memset(&attr, 0, sizeof(struct attr)); memset(&attr, 0, sizeof(struct attr));
@ -2228,10 +2227,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
/* advertise/withdraw type-5 routes */ /* advertise/withdraw type-5 routes */
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
if (new_select) if (advertise_type5_routes(bgp, afi) && new_select &&
bgp_evpn_advertise_type5_route( (!new_select->extra || !new_select->extra->parent))
bgp, &rn->p, new_select->attr, afi, safi); bgp_evpn_advertise_type5_route(bgp, &rn->p,
else if (old_select) new_select->attr,
afi, safi);
else if (advertise_type5_routes(bgp, afi) && old_select &&
(!old_select->extra || !old_select->extra->parent))
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi); bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
} }
@ -6839,10 +6841,9 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p,
bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN, bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
use_json, json); use_json, json);
else else
vty_out(vty, "%s ", vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf,
bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
BGP_UPTIME_LEN, use_json, use_json, json));
json));
/* Print attribute */ /* Print attribute */
attr = binfo->attr; attr = binfo->attr;
@ -6921,9 +6922,8 @@ static void flap_route_vty_out(struct vty *vty, struct prefix *p,
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
json); json);
else else
vty_out(vty, "%s ", vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, BGP_UPTIME_LEN, 0, NULL));
NULL));
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED) if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) { && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
@ -8029,9 +8029,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
} }
if (!use_json && header) { if (!use_json && header) {
vty_out(vty, vty_out(vty, "BGP table version is %" PRIu64
"BGP table version is %" PRIu64 ", local router ID is %s\n",
", local router ID is %s\n",
table->version, table->version,
inet_ntoa(bgp->router_id)); inet_ntoa(bgp->router_id));
vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_SCODE_HEADER);
@ -8513,9 +8512,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
if (display) if (display)
json_object_object_add(json, "paths", json_paths); json_object_object_add(json, "paths", json_paths);
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string_ext(
json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY));
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
if (!display) { if (!display) {
@ -9590,9 +9588,8 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
json, "recommended", json, "recommended",
"Please report this bug, with the above command output"); "Please report this bug, with the above command output");
} }
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string_ext(
json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY));
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
@ -9826,9 +9823,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
"bgpOriginatingDefaultNetwork", "bgpOriginatingDefaultNetwork",
"0.0.0.0"); "0.0.0.0");
} else { } else {
vty_out(vty, vty_out(vty, "BGP table version is %" PRIu64
"BGP table version is %" PRIu64 ", local router ID is %s\n",
", local router ID is %s\n",
table->version, inet_ntoa(bgp->router_id)); table->version, inet_ntoa(bgp->router_id));
vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_SCODE_HEADER);
vty_out(vty, BGP_SHOW_OCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER);
@ -9971,9 +9967,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
output_count); output_count);
} }
if (use_json) { if (use_json) {
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string_ext(
json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY));
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} }
} }

View File

@ -104,10 +104,8 @@ struct bgp_info_extra {
struct in6_addr addr6; struct in6_addr addr6;
} un; /* cached un address */ } un; /* cached un address */
time_t create_time; time_t create_time;
struct struct prefix aux_prefix; /* AFI_L2VPN: the IP addr,
prefix if family set */
aux_prefix; /* AFI_L2VPN: the IP addr,
if family set */
} import; } import;
} vnc; } vnc;

View File

@ -594,6 +594,24 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
route_match_ip_route_source_prefix_list_compile, route_match_ip_route_source_prefix_list_compile,
route_match_ip_route_source_prefix_list_free}; route_match_ip_route_source_prefix_list_free};
/* `match evpn default-route' */
/* Match function should return 1 if match is success else 0 */
static route_map_result_t route_match_evpn_default_route(void *rule,
struct prefix *p,
route_map_object_t
type, void *object)
{
if (type == RMAP_BGP && is_evpn_prefix_default(p))
return RMAP_MATCH;
return RMAP_NOMATCH;
}
/* Route map commands for default-route matching. */
struct route_map_rule_cmd route_match_evpn_default_route_cmd = {
"evpn default-route", route_match_evpn_default_route, NULL, NULL};
/* `match mac address MAC_ACCESS_LIST' */ /* `match mac address MAC_ACCESS_LIST' */
/* Match function should return 1 if match is success else return /* Match function should return 1 if match is success else return
@ -742,8 +760,7 @@ static void route_match_evpn_route_type_free(void *rule)
/* Route map commands for evpn route-type matching. */ /* Route map commands for evpn route-type matching. */
struct route_map_rule_cmd route_match_evpn_route_type_cmd = { struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
"evpn route-type", route_match_evpn_route_type, "evpn route-type", route_match_evpn_route_type,
route_match_evpn_route_type_compile, route_match_evpn_route_type_compile, route_match_evpn_route_type_free};
route_match_evpn_route_type_free};
/* `match local-preference LOCAL-PREF' */ /* `match local-preference LOCAL-PREF' */
@ -3079,12 +3096,13 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
/* for type5 command route-maps */ /* for type5 command route-maps */
FOREACH_AFI_SAFI (afi, safi) { FOREACH_AFI_SAFI (afi, safi) {
if (bgp->adv_cmd_rmap[afi][safi].name && if (bgp->adv_cmd_rmap[afi][safi].name
strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name) == 0) { && strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name)
== 0) {
if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug( zlog_debug(
"Processing route_map %s update on advertise type5 route command", "Processing route_map %s update on advertise type5 route command",
rmap_name); rmap_name);
bgp_evpn_withdraw_type5_routes(bgp, afi, safi); bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
bgp_evpn_advertise_type5_routes(bgp, afi, safi); bgp_evpn_advertise_type5_routes(bgp, afi, safi);
} }
@ -3249,6 +3267,29 @@ DEFUN (no_match_evpn_vni,
RMAP_EVENT_MATCH_DELETED); RMAP_EVENT_MATCH_DELETED);
} }
DEFUN (match_evpn_default_route,
match_evpn_default_route_cmd,
"match evpn default-route",
MATCH_STR
EVPN_HELP_STR
"default EVPN type-5 route\n")
{
return bgp_route_match_add(vty, "evpn default-route", NULL,
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_evpn_default_route,
no_match_evpn_default_route_cmd,
"no match evpn default-route",
NO_STR
MATCH_STR
EVPN_HELP_STR
"default EVPN type-5 route\n")
{
return bgp_route_match_delete(vty, "evpn default-route", NULL,
RMAP_EVENT_MATCH_DELETED);
}
DEFUN (match_peer, DEFUN (match_peer,
match_peer_cmd, match_peer_cmd,
"match peer <A.B.C.D|X:X::X:X|WORD>", "match peer <A.B.C.D|X:X::X:X|WORD>",
@ -4628,6 +4669,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_mac_address_cmd); route_map_install_match(&route_match_mac_address_cmd);
route_map_install_match(&route_match_evpn_vni_cmd); route_map_install_match(&route_match_evpn_vni_cmd);
route_map_install_match(&route_match_evpn_route_type_cmd); route_map_install_match(&route_match_evpn_route_type_cmd);
route_map_install_match(&route_match_evpn_default_route_cmd);
route_map_install_set(&route_set_ip_nexthop_cmd); route_map_install_set(&route_set_ip_nexthop_cmd);
route_map_install_set(&route_set_local_pref_cmd); route_map_install_set(&route_set_local_pref_cmd);
@ -4664,6 +4706,8 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &no_match_evpn_vni_cmd); install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
install_element(RMAP_NODE, &match_evpn_route_type_cmd); install_element(RMAP_NODE, &match_evpn_route_type_cmd);
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd); install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
install_element(RMAP_NODE, &match_evpn_default_route_cmd);
install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
install_element(RMAP_NODE, &match_aspath_cmd); install_element(RMAP_NODE, &match_aspath_cmd);
install_element(RMAP_NODE, &no_match_aspath_cmd); install_element(RMAP_NODE, &no_match_aspath_cmd);

View File

@ -1,9 +1,12 @@
/* /*
* BGP RPKI * BGP RPKI
* Copyright (C) 2013 Michael Mester (m.mester@fu-berlin.de), for FU Berlin * Copyright (C) 2013 Michael Mester (m.mester@fu-berlin.de), for FU Berlin
* Copyright (C) 2014-2017 Andreas Reuter (andreas.reuter@fu-berlin.de), for FU Berlin * Copyright (C) 2014-2017 Andreas Reuter (andreas.reuter@fu-berlin.de), for FU
* Copyright (C) 2016-2017 Colin Sames (colin.sames@haw-hamburg.de), for HAW Hamburg * Berlin
* Copyright (C) 2017 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW Hamburg * Copyright (C) 2016-2017 Colin Sames (colin.sames@haw-hamburg.de), for HAW
* Hamburg
* Copyright (C) 2017 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW
* Hamburg
* *
* This file is part of FRRouting. * This file is part of FRRouting.
* *
@ -77,14 +80,14 @@ DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group")
#define RPKI_OUTPUT_STRING "Control rpki specific settings\n" #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
struct cache { struct cache {
enum { TCP, SSH } type; enum { TCP, SSH } type;
struct tr_socket *tr_socket; struct tr_socket *tr_socket;
union { union {
struct tr_tcp_config *tcp_config; struct tr_tcp_config *tcp_config;
struct tr_ssh_config *ssh_config; struct tr_ssh_config *ssh_config;
} tr_config; } tr_config;
struct rtr_socket *rtr_socket; struct rtr_socket *rtr_socket;
uint8_t preference; uint8_t preference;
}; };
enum return_values { SUCCESS = 0, ERROR = -1 }; enum return_values { SUCCESS = 0, ERROR = -1 };
@ -105,27 +108,22 @@ static void overwrite_exit_commands(void);
static void free_cache(struct cache *cache); static void free_cache(struct cache *cache);
static struct rtr_mgr_group *get_groups(void); static struct rtr_mgr_group *get_groups(void);
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
static int add_ssh_cache(const char *host, static int add_ssh_cache(const char *host, const unsigned int port,
const unsigned int port, const char *username, const char *client_privkey_path,
const char *username,
const char *client_privkey_path,
const char *client_pubkey_path, const char *client_pubkey_path,
const char *server_pubkey_path, const char *server_pubkey_path,
const uint8_t preference); const uint8_t preference);
#endif #endif
static struct rtr_socket *create_rtr_socket(struct tr_socket *tr_socket); static struct rtr_socket *create_rtr_socket(struct tr_socket *tr_socket);
static struct cache *find_cache(const uint8_t preference); static struct cache *find_cache(const uint8_t preference);
static int add_tcp_cache(const char *host, static int add_tcp_cache(const char *host, const char *port,
const char *port,
const uint8_t preference); const uint8_t preference);
static void print_record(const struct pfx_record *record, void *data); static void print_record(const struct pfx_record *record, void *data);
static int is_synchronized(void); static int is_synchronized(void);
static int is_running(void); static int is_running(void);
static void route_match_free(void *rule); static void route_match_free(void *rule);
static route_map_result_t route_match(void *rule, static route_map_result_t route_match(void *rule, struct prefix *prefix,
struct prefix *prefix, route_map_object_t type, void *object);
route_map_object_t type,
void *object);
static void *route_match_compile(const char *arg); static void *route_match_compile(const char *arg);
static struct rtr_mgr_config *rtr_config; static struct rtr_mgr_config *rtr_config;
@ -139,9 +137,8 @@ static unsigned int timeout;
static unsigned int initial_synchronisation_timeout; static unsigned int initial_synchronisation_timeout;
static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1}; static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1};
static struct route_map_rule_cmd route_match_rpki_cmd = {"rpki", route_match, static struct route_map_rule_cmd route_match_rpki_cmd = {
route_match_compile, "rpki", route_match, route_match_compile, route_match_free};
route_match_free};
static void *malloc_wrapper(size_t size) static void *malloc_wrapper(size_t size)
{ {
@ -162,8 +159,7 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
struct prefix *prefix); struct prefix *prefix);
static route_map_result_t route_match(void *rule, struct prefix *prefix, static route_map_result_t route_match(void *rule, struct prefix *prefix,
route_map_object_t type, route_map_object_t type, void *object)
void *object)
{ {
int *rpki_status = rule; int *rpki_status = rule;
struct bgp_info *bgp_info; struct bgp_info *bgp_info;
@ -285,7 +281,7 @@ static int bgp_rpki_init(struct thread_master *master)
rtr_is_running = 0; rtr_is_running = 0;
cache_list = list_new(); cache_list = list_new();
cache_list->del = (void (*)(void *)) &free_cache; cache_list->del = (void (*)(void *)) & free_cache;
polling_period = POLLING_PERIOD_DEFAULT; polling_period = POLLING_PERIOD_DEFAULT;
expire_interval = EXPIRE_INTERVAL_DEFAULT; expire_interval = EXPIRE_INTERVAL_DEFAULT;
@ -307,9 +303,7 @@ static int bgp_rpki_fini(void)
static int bgp_rpki_module_init(void) static int bgp_rpki_module_init(void)
{ {
lrtr_set_alloc_functions(malloc_wrapper, lrtr_set_alloc_functions(malloc_wrapper, realloc_wrapper, free_wrapper);
realloc_wrapper,
free_wrapper);
hook_register(frr_late_init, bgp_rpki_init); hook_register(frr_late_init, bgp_rpki_init);
hook_register(frr_early_fini, &bgp_rpki_fini); hook_register(frr_early_fini, &bgp_rpki_fini);
@ -332,8 +326,8 @@ static int start(void)
struct rtr_mgr_group *groups = get_groups(); struct rtr_mgr_group *groups = get_groups();
ret = rtr_mgr_init(&rtr_config, groups, groups_len, polling_period, ret = rtr_mgr_init(&rtr_config, groups, groups_len, polling_period,
expire_interval, retry_interval, expire_interval, retry_interval, NULL, NULL, NULL,
NULL, NULL, NULL, NULL); NULL);
if (ret == RTR_ERROR) { if (ret == RTR_ERROR) {
RPKI_DEBUG("Init rtr_mgr failed."); RPKI_DEBUG("Init rtr_mgr failed.");
return ERROR; return ERROR;
@ -447,8 +441,8 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
if (as_segment->type == AS_SEQUENCE) { if (as_segment->type == AS_SEQUENCE) {
// Get rightmost asn // Get rightmost asn
as_number = as_segment->as[as_segment->length - 1]; as_number = as_segment->as[as_segment->length - 1];
} else if (as_segment->type == AS_CONFED_SEQUENCE || } else if (as_segment->type == AS_CONFED_SEQUENCE
as_segment->type == AS_CONFED_SET) { || as_segment->type == AS_CONFED_SET) {
// Set own as number // Set own as number
as_number = peer->bgp->as; as_number = peer->bgp->as;
} else { } else {
@ -520,16 +514,15 @@ static int add_cache(struct cache *cache)
listnode_add(cache_list, cache); listnode_add(cache_list, cache);
if (rtr_is_running && if (rtr_is_running
rtr_mgr_add_group(rtr_config, &group) != RTR_SUCCESS) { && rtr_mgr_add_group(rtr_config, &group) != RTR_SUCCESS) {
return ERROR; return ERROR;
} }
return SUCCESS; return SUCCESS;
} }
static int add_tcp_cache(const char *host, static int add_tcp_cache(const char *host, const char *port,
const char *port,
const uint8_t preference) const uint8_t preference)
{ {
struct rtr_socket *rtr_socket; struct rtr_socket *rtr_socket;
@ -556,10 +549,8 @@ static int add_tcp_cache(const char *host,
} }
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
static int add_ssh_cache(const char *host, static int add_ssh_cache(const char *host, const unsigned int port,
const unsigned int port, const char *username, const char *client_privkey_path,
const char *username,
const char *client_privkey_path,
const char *client_pubkey_path, const char *client_pubkey_path,
const char *server_pubkey_path, const char *server_pubkey_path,
const uint8_t preference) const uint8_t preference)
@ -577,8 +568,8 @@ static int add_ssh_cache(const char *host,
ssh_config->bindaddr = NULL; ssh_config->bindaddr = NULL;
ssh_config->username = XSTRDUP(MTYPE_BGP_RPKI_CACHE, username); ssh_config->username = XSTRDUP(MTYPE_BGP_RPKI_CACHE, username);
ssh_config->client_privkey_path = XSTRDUP( ssh_config->client_privkey_path =
MTYPE_BGP_RPKI_CACHE, client_privkey_path); XSTRDUP(MTYPE_BGP_RPKI_CACHE, client_privkey_path);
ssh_config->server_hostkey_path = ssh_config->server_hostkey_path =
XSTRDUP(MTYPE_BGP_RPKI_CACHE, server_pubkey_path); XSTRDUP(MTYPE_BGP_RPKI_CACHE, server_pubkey_path);
@ -597,16 +588,13 @@ static int add_ssh_cache(const char *host,
static void free_cache(struct cache *cache) static void free_cache(struct cache *cache)
{ {
if (cache->type == TCP) { if (cache->type == TCP) {
XFREE(MTYPE_BGP_RPKI_CACHE, XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->host);
cache->tr_config.tcp_config->host); XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->port);
XFREE(MTYPE_BGP_RPKI_CACHE,
cache->tr_config.tcp_config->port);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config); XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config);
} }
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
else { else {
XFREE(MTYPE_BGP_RPKI_CACHE, XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config->host);
cache->tr_config.ssh_config->host);
XFREE(MTYPE_BGP_RPKI_CACHE, XFREE(MTYPE_BGP_RPKI_CACHE,
cache->tr_config.ssh_config->username); cache->tr_config.ssh_config->username);
XFREE(MTYPE_BGP_RPKI_CACHE, XFREE(MTYPE_BGP_RPKI_CACHE,
@ -644,22 +632,17 @@ static int config_write(struct vty *vty)
#endif #endif
case TCP: case TCP:
tcp_config = cache->tr_config.tcp_config; tcp_config = cache->tr_config.tcp_config;
vty_out(vty, vty_out(vty, " rpki cache %s %s ",
" rpki cache %s %s ", tcp_config->host, tcp_config->port);
tcp_config->host,
tcp_config->port);
break; break;
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
case SSH: case SSH:
ssh_config = cache->tr_config.ssh_config; ssh_config = cache->tr_config.ssh_config;
vty_out(vty, vty_out(vty, " rpki cache %s %u %s %s %s ",
" rpki cache %s %u %s %s %s ", ssh_config->host, ssh_config->port,
ssh_config->host,
ssh_config->port,
ssh_config->username, ssh_config->username,
ssh_config->client_privkey_path, ssh_config->client_privkey_path,
ssh_config->server_hostkey_path ssh_config->server_hostkey_path != NULL
!= NULL
? ssh_config ? ssh_config
->server_hostkey_path ->server_hostkey_path
: " "); : " ");
@ -694,7 +677,8 @@ DEFUN (bgp_rpki_start,
"start rpki support\n") "start rpki support\n")
{ {
if (listcount(cache_list) == 0) if (listcount(cache_list) == 0)
vty_out(vty, "Could not start rpki because no caches are configured\n"); vty_out(vty,
"Could not start rpki because no caches are configured\n");
if (!is_running()) { if (!is_running()) {
if (start() == ERROR) { if (start() == ERROR) {
@ -855,9 +839,9 @@ DEFPY (rpki_cache,
// use ssh connection // use ssh connection
if (ssh_uname) { if (ssh_uname) {
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
return_value = add_ssh_cache( return_value =
cache, sshport, ssh_uname, ssh_privkey, ssh_pubkey, add_ssh_cache(cache, sshport, ssh_uname, ssh_privkey,
server_pubkey, preference); ssh_pubkey, server_pubkey, preference);
#else #else
vty_out(vty, vty_out(vty,
"ssh sockets are not supported. " "ssh sockets are not supported. "
@ -923,8 +907,7 @@ DEFUN (show_rpki_prefix_table,
struct cache *cache; struct cache *cache;
for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) { for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
vty_out(vty, vty_out(vty, "host: %s port: %s\n",
"host: %s port: %s\n",
cache->tr_config.tcp_config->host, cache->tr_config.tcp_config->host,
cache->tr_config.tcp_config->port); cache->tr_config.tcp_config->port);
} }
@ -947,8 +930,7 @@ DEFUN (show_rpki_cache_server,
struct cache *cache; struct cache *cache;
for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) { for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
vty_out(vty, vty_out(vty, "host: %s port: %s\n",
"host: %s port: %s\n",
cache->tr_config.tcp_config->host, cache->tr_config.tcp_config->host,
cache->tr_config.tcp_config->port); cache->tr_config.tcp_config->port);
} }
@ -973,8 +955,7 @@ DEFUN (show_rpki_cache_connection,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
vty_out(vty, "Connected to group %d\n", group->preference); vty_out(vty, "Connected to group %d\n", group->preference);
for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
cache)) {
if (cache->preference == group->preference) { if (cache->preference == group->preference) {
struct tr_tcp_config *tcp_config; struct tr_tcp_config *tcp_config;
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
@ -984,8 +965,7 @@ DEFUN (show_rpki_cache_connection,
switch (cache->type) { switch (cache->type) {
case TCP: case TCP:
tcp_config = tcp_config =
cache->tr_config cache->tr_config.tcp_config;
.tcp_config;
vty_out(vty, vty_out(vty,
"rpki tcp cache %s %s pref %hhu\n", "rpki tcp cache %s %s pref %hhu\n",
tcp_config->host, tcp_config->host,
@ -996,8 +976,7 @@ DEFUN (show_rpki_cache_connection,
#if defined(FOUND_SSH) #if defined(FOUND_SSH)
case SSH: case SSH:
ssh_config = ssh_config =
cache->tr_config cache->tr_config.ssh_config;
.ssh_config;
vty_out(vty, vty_out(vty,
"rpki ssh cache %s %u pref %hhu\n", "rpki ssh cache %s %u pref %hhu\n",
ssh_config->host, ssh_config->host,
@ -1142,9 +1121,9 @@ static void overwrite_exit_commands(void)
for (i = 0; i < cmd_vector->active; ++i) { for (i = 0; i < cmd_vector->active; ++i) {
struct cmd_element *cmd = vector_lookup(cmd_vector, i); struct cmd_element *cmd = vector_lookup(cmd_vector, i);
if (strcmp(cmd->string, "exit") == 0 || if (strcmp(cmd->string, "exit") == 0
strcmp(cmd->string, "quit") == 0 || || strcmp(cmd->string, "quit") == 0
strcmp(cmd->string, "end") == 0) { || strcmp(cmd->string, "end") == 0) {
uninstall_element(RPKI_NODE, cmd); uninstall_element(RPKI_NODE, cmd);
} }
} }
@ -1156,7 +1135,7 @@ static void overwrite_exit_commands(void)
static void install_cli_commands(void) static void install_cli_commands(void)
{ {
//TODO: make config write work // TODO: make config write work
install_node(&rpki_node, &config_write); install_node(&rpki_node, &config_write);
install_default(RPKI_NODE); install_default(RPKI_NODE);
overwrite_exit_commands(); overwrite_exit_commands();
@ -1212,4 +1191,4 @@ static void install_cli_commands(void)
FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6", FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6",
.description = "Enable RPKI support for FRR.", .description = "Enable RPKI support for FRR.",
.init = bgp_rpki_module_init) .init = bgp_rpki_module_init)

View File

@ -864,8 +864,6 @@ static u_char *bgp4PathAttrTable(struct variable *v, oid name[], size_t *length,
return SNMP_INTEGER(-1); return SNMP_INTEGER(-1);
break; break;
case BGP4PATHATTRBEST: /* 13 */ case BGP4PATHATTRBEST: /* 13 */
/* $FRR indent$ */
/* clang-format off */
#define BGP4_PathAttrBest_false 1 #define BGP4_PathAttrBest_false 1
#define BGP4_PathAttrBest_true 2 #define BGP4_PathAttrBest_true 2
if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)) if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))

View File

@ -85,9 +85,8 @@ static void sync_init(struct update_subgroup *subgrp)
BGP_ADV_FIFO_INIT(&subgrp->sync->update); BGP_ADV_FIFO_INIT(&subgrp->sync->update);
BGP_ADV_FIFO_INIT(&subgrp->sync->withdraw); BGP_ADV_FIFO_INIT(&subgrp->sync->withdraw);
BGP_ADV_FIFO_INIT(&subgrp->sync->withdraw_low); BGP_ADV_FIFO_INIT(&subgrp->sync->withdraw_low);
subgrp->hash = hash_create(baa_hash_key, subgrp->hash =
baa_hash_cmp, hash_create(baa_hash_key, baa_hash_cmp, "BGP SubGroup Hash");
"BGP SubGroup Hash");
/* We use a larger buffer for subgrp->work in the event that: /* We use a larger buffer for subgrp->work in the event that:
* - We RX a BGP_UPDATE where the attributes alone are just * - We RX a BGP_UPDATE where the attributes alone are just
@ -1545,8 +1544,7 @@ void update_bgp_group_init(struct bgp *bgp)
AF_FOREACH (afid) AF_FOREACH (afid)
bgp->update_groups[afid] = bgp->update_groups[afid] =
hash_create(updgrp_hash_key_make, hash_create(updgrp_hash_key_make, updgrp_hash_cmp,
updgrp_hash_cmp,
"BGP Update Group Hash"); "BGP Update Group Hash");
} }
@ -1877,11 +1875,12 @@ void subgroup_trigger_write(struct update_subgroup *subgrp)
* the subgroup output queue into their own output queue. This action * the subgroup output queue into their own output queue. This action
* will trigger a write job on the I/O thread. * will trigger a write job on the I/O thread.
*/ */
SUBGRP_FOREACH_PEER(subgrp, paf) SUBGRP_FOREACH_PEER (subgrp, paf)
if (paf->peer->status == Established) if (paf->peer->status == Established)
thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets, thread_add_timer_msec(
paf->peer, 0, bm->master, bgp_generate_updgrp_packets,
&paf->peer->t_generate_updgrp_packets); paf->peer, 0,
&paf->peer->t_generate_updgrp_packets);
} }
int update_group_clear_update_dbg(struct update_group *updgrp, void *arg) int update_group_clear_update_dbg(struct update_group *updgrp, void *arg)

View File

@ -287,7 +287,6 @@ struct update_subgroup {
*/ */
#define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1) #define SUBGRP_DECR_STAT(subgrp, stat) SUBGRP_INCR_STAT_BY(subgrp, stat, -1)
typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx); typedef int (*updgrp_walkcb)(struct update_group *updgrp, void *ctx);
/* really a private structure */ /* really a private structure */
@ -341,23 +340,23 @@ struct updwalk_context {
* Walk all subgroups in an update group. * Walk all subgroups in an update group.
*/ */
#define UPDGRP_FOREACH_SUBGRP(updgrp, subgrp) \ #define UPDGRP_FOREACH_SUBGRP(updgrp, subgrp) \
LIST_FOREACH(subgrp, &((updgrp)->subgrps), updgrp_train) LIST_FOREACH (subgrp, &((updgrp)->subgrps), updgrp_train)
#define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp) \ #define UPDGRP_FOREACH_SUBGRP_SAFE(updgrp, subgrp, tmp_subgrp) \
LIST_FOREACH_SAFE(subgrp, &((updgrp)->subgrps), updgrp_train, \ LIST_FOREACH_SAFE (subgrp, &((updgrp)->subgrps), updgrp_train, \
tmp_subgrp) tmp_subgrp)
#define SUBGRP_FOREACH_PEER(subgrp, paf) \ #define SUBGRP_FOREACH_PEER(subgrp, paf) \
LIST_FOREACH(paf, &(subgrp->peers), subgrp_train) LIST_FOREACH (paf, &(subgrp->peers), subgrp_train)
#define SUBGRP_FOREACH_PEER_SAFE(subgrp, paf, temp_paf) \ #define SUBGRP_FOREACH_PEER_SAFE(subgrp, paf, temp_paf) \
LIST_FOREACH_SAFE(paf, &(subgrp->peers), subgrp_train, temp_paf) LIST_FOREACH_SAFE (paf, &(subgrp->peers), subgrp_train, temp_paf)
#define SUBGRP_FOREACH_ADJ(subgrp, adj) \ #define SUBGRP_FOREACH_ADJ(subgrp, adj) \
TAILQ_FOREACH(adj, &(subgrp->adjq), subgrp_adj_train) TAILQ_FOREACH (adj, &(subgrp->adjq), subgrp_adj_train)
#define SUBGRP_FOREACH_ADJ_SAFE(subgrp, adj, adj_temp) \ #define SUBGRP_FOREACH_ADJ_SAFE(subgrp, adj, adj_temp) \
TAILQ_FOREACH_SAFE(adj, &(subgrp->adjq), subgrp_adj_train, adj_temp) TAILQ_FOREACH_SAFE (adj, &(subgrp->adjq), subgrp_adj_train, adj_temp)
/* Prototypes. */ /* Prototypes. */
/* bgp_updgrp.c */ /* bgp_updgrp.c */

View File

@ -733,8 +733,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s)) space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
- BGP_MAX_PACKET_SIZE_OVERFLOW; - BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed = BGP_NLRI_LENGTH + addpath_overhead + space_needed =
bgp_packet_mpattr_prefix_size(afi, safi, &rn->p); BGP_NLRI_LENGTH + addpath_overhead
+ bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
/* When remaining space can't include NLRI and it's length. */ /* When remaining space can't include NLRI and it's length. */
if (space_remaining < space_needed) if (space_remaining < space_needed)
@ -778,9 +779,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
space_remaining = space_remaining =
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s)) STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
- BGP_MAX_PACKET_SIZE_OVERFLOW; - BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed = BGP_NLRI_LENGTH + addpath_overhead + space_needed = BGP_NLRI_LENGTH + addpath_overhead
bgp_packet_mpattr_prefix_size(afi, safi, + bgp_packet_mpattr_prefix_size(
&rn->p); afi, safi, &rn->p);
/* If the attributes alone do not leave any room for /* If the attributes alone do not leave any room for
* NLRI then * NLRI then

View File

@ -832,8 +832,7 @@ DEFUN_NOSH (router_bgp,
} }
if (listcount(bm->bgp) > 1) { if (listcount(bm->bgp) > 1) {
vty_out(vty, vty_out(vty, "%% Please specify ASN and VRF\n");
"%% Multiple BGP processes are configured\n");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
} }
@ -908,8 +907,7 @@ DEFUN (no_router_bgp,
} }
if (listcount(bm->bgp) > 1) { if (listcount(bm->bgp) > 1) {
vty_out(vty, vty_out(vty, "%% Please specify ASN and VRF\n");
"%% Multiple BGP processes are configured\n");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
@ -1540,8 +1538,7 @@ DEFUN (no_bgp_maxpaths,
} }
ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd,
"no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", NO_STR
NO_STR
"Forward packets over multiple paths\n" "Forward packets over multiple paths\n"
"Number of paths\n") "Number of paths\n")
@ -6413,11 +6410,16 @@ DEFUN (clear_bgp_ipv6_safi_prefix,
"Clear bestpath and re-advertise\n" "Clear bestpath and re-advertise\n"
"IPv6 prefix\n") "IPv6 prefix\n")
{ {
int idx_safi = 3; int idx_safi = 0;
int idx_ipv6_prefixlen = 5; int idx_ipv6_prefix = 0;
safi_t safi = SAFI_UNICAST;
char *prefix = argv_find(argv, argc, "X:X::X:X/M", &idx_ipv6_prefix) ?
argv[idx_ipv6_prefix]->arg : NULL;
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
return bgp_clear_prefix( return bgp_clear_prefix(
vty, NULL, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, vty, NULL, prefix, AFI_IP6,
bgp_vty_safi_from_str(argv[idx_safi]->text), NULL); safi, NULL);
} }
DEFUN (clear_bgp_instance_ipv6_safi_prefix, DEFUN (clear_bgp_instance_ipv6_safi_prefix,
@ -6433,11 +6435,20 @@ DEFUN (clear_bgp_instance_ipv6_safi_prefix,
"IPv6 prefix\n") "IPv6 prefix\n")
{ {
int idx_word = 3; int idx_word = 3;
int idx_safi = 5; int idx_safi = 0;
int idx_ipv6_prefixlen = 7; int idx_ipv6_prefix = 0;
safi_t safi = SAFI_UNICAST;
char *prefix = argv_find(argv, argc, "X:X::X:X/M", &idx_ipv6_prefix) ?
argv[idx_ipv6_prefix]->arg : NULL;
/* [<view|vrf> VIEWVRFNAME] */
char *vrfview = argv_find(argv, argc, "VIEWVRFNAME", &idx_word) ?
argv[idx_word]->arg : NULL;
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
return bgp_clear_prefix( return bgp_clear_prefix(
vty, argv[idx_word]->arg, argv[idx_ipv6_prefixlen]->arg, vty, vrfview, prefix,
AFI_IP6, bgp_vty_safi_from_str(argv[idx_safi]->text), NULL); AFI_IP6, safi, NULL);
} }
DEFUN (show_bgp_views, DEFUN (show_bgp_views,
@ -6571,9 +6582,8 @@ DEFUN (show_bgp_vrfs,
json_object_int_add(json, "totalVrfs", count); json_object_int_add(json, "totalVrfs", count);
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string_ext(
json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY));
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
if (count) if (count)
@ -6722,20 +6732,17 @@ DEFUN (show_bgp_memory,
/* Other attributes */ /* Other attributes */
if ((count = community_count())) if ((count = community_count()))
vty_out(vty, "%ld BGP community entries, using %s of memory\n", vty_out(vty, "%ld BGP community entries, using %s of memory\n",
count, count, mtype_memstr(memstrbuf, sizeof(memstrbuf),
mtype_memstr(memstrbuf, sizeof(memstrbuf), count * sizeof(struct community)));
count * sizeof(struct community)));
if ((count = mtype_stats_alloc(MTYPE_ECOMMUNITY))) if ((count = mtype_stats_alloc(MTYPE_ECOMMUNITY)))
vty_out(vty, "%ld BGP community entries, using %s of memory\n", vty_out(vty, "%ld BGP community entries, using %s of memory\n",
count, count, mtype_memstr(memstrbuf, sizeof(memstrbuf),
mtype_memstr(memstrbuf, sizeof(memstrbuf), count * sizeof(struct ecommunity)));
count * sizeof(struct ecommunity)));
if ((count = mtype_stats_alloc(MTYPE_LCOMMUNITY))) if ((count = mtype_stats_alloc(MTYPE_LCOMMUNITY)))
vty_out(vty, vty_out(vty,
"%ld BGP large-community entries, using %s of memory\n", "%ld BGP large-community entries, using %s of memory\n",
count, count, mtype_memstr(memstrbuf, sizeof(memstrbuf),
mtype_memstr(memstrbuf, sizeof(memstrbuf), count * sizeof(struct lcommunity)));
count * sizeof(struct lcommunity)));
if ((count = mtype_stats_alloc(MTYPE_CLUSTER))) if ((count = mtype_stats_alloc(MTYPE_CLUSTER)))
vty_out(vty, "%ld Cluster lists, using %s of memory\n", count, vty_out(vty, "%ld Cluster lists, using %s of memory\n", count,
@ -6764,9 +6771,8 @@ DEFUN (show_bgp_memory,
count * sizeof(struct hash_backet))); count * sizeof(struct hash_backet)));
if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP))) if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP)))
vty_out(vty, "%ld compiled regexes, using %s of memory\n", vty_out(vty, "%ld compiled regexes, using %s of memory\n",
count, count, mtype_memstr(memstrbuf, sizeof(memstrbuf),
mtype_memstr(memstrbuf, sizeof(memstrbuf), count * sizeof(regex_t)));
count * sizeof(regex_t)));
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -7018,9 +7024,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
json, "peerGroupCount", ents); json, "peerGroupCount", ents);
json_object_int_add( json_object_int_add(
json, "peerGroupMemory", json, "peerGroupMemory",
ents ents * sizeof(struct
* sizeof(struct peer_group));
peer_group));
} }
if (CHECK_FLAG(bgp->af_flags[afi][safi], if (CHECK_FLAG(bgp->af_flags[afi][safi],
@ -7043,11 +7048,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
vty_out(vty, vty_out(vty,
"RIB entries %ld, using %s of memory\n", "RIB entries %ld, using %s of memory\n",
ents, ents,
mtype_memstr( mtype_memstr(memstrbuf,
memstrbuf, sizeof(memstrbuf), sizeof(memstrbuf),
ents ents * sizeof(struct
* sizeof(struct bgp_node)));
bgp_node)));
/* Peer related usage */ /* Peer related usage */
ents = listcount(bgp->peer); ents = listcount(bgp->peer);
@ -7064,9 +7068,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
mtype_memstr( mtype_memstr(
memstrbuf, memstrbuf,
sizeof(memstrbuf), sizeof(memstrbuf),
ents ents * sizeof(struct
* sizeof(struct peer_group)));
peer_group)));
if (CHECK_FLAG(bgp->af_flags[afi][safi], if (CHECK_FLAG(bgp->af_flags[afi][safi],
BGP_CONFIG_DAMPENING)) BGP_CONFIG_DAMPENING))
@ -7199,9 +7202,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
bgp_show_bestpath_json(bgp, json); bgp_show_bestpath_json(bgp, json);
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string_ext(
json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY));
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
if (count) if (count)
@ -7836,9 +7838,8 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
paf = peer_af_find(p, afi, safi); paf = peer_af_find(p, afi, safi);
if (paf && PAF_SUBGRP(paf)) { if (paf && PAF_SUBGRP(paf)) {
vty_out(vty, vty_out(vty, " Update group %" PRIu64
" Update group %" PRIu64 ", subgroup %" PRIu64 ", subgroup %" PRIu64 "\n",
"\n",
PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id); PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id);
vty_out(vty, " Packet Queue length %d\n", vty_out(vty, " Packet Queue length %d\n",
bpacket_queue_virtual_length(paf)); bpacket_queue_virtual_length(paf));
@ -9638,9 +9639,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
} else } else
vty_out(vty, vty_out(vty,
" Reduce the no. of prefix from %s, will restart in %ld seconds\n", " Reduce the no. of prefix from %s, will restart in %ld seconds\n",
p->host, p->host, thread_timer_remain_second(
thread_timer_remain_second( p->t_pmax_restart));
p->t_pmax_restart));
} else { } else {
if (use_json) if (use_json)
json_object_boolean_true_add( json_object_boolean_true_add(
@ -9884,9 +9884,8 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
} }
if (use_json) { if (use_json) {
vty_out(vty, "%s\n", vty_out(vty, "%s\n", json_object_to_json_string_ext(
json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY));
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
vty_out(vty, "\n"); vty_out(vty, "\n");
@ -10300,227 +10299,43 @@ static void show_bgp_updgrps_adj_info_aux(struct vty *vty, const char *name,
} }
} }
DEFUN (show_ip_bgp_updgrps_adj, DEFPY(show_ip_bgp_instance_updgrps_adj_s,
show_ip_bgp_updgrps_adj_cmd, show_ip_bgp_instance_updgrps_adj_s_cmd,
"show [ip] bgp update-groups <advertise-queue|advertised-routes|packet-queue>", "show [ip]$ip bgp [<view|vrf> VIEWVRFNAME$vrf] [<ipv4|ipv6>$afi <unicast|multicast|vpn>$safi] update-groups [SUBGROUP-ID]$sgid <advertise-queue|advertised-routes|packet-queue>$rtq",
SHOW_STR SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
IP_STR BGP_SAFI_HELP_STR
BGP_STR "Detailed info about dynamic update groups\n"
"Detailed info about dynamic update groups\n" "Specific subgroup to display info for\n"
"Advertisement queue\n" "Advertisement queue\n"
"Announced routes\n" "Announced routes\n"
"Packet queue\n") "Packet queue\n")
{ {
int idx_type = 4; uint64_t subgrp_id = 0;
show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP, SAFI_UNICAST, afi_t afiz;
argv[idx_type]->arg, 0); safi_t safiz;
if (sgid)
subgrp_id = strtoull(sgid, NULL, 10);
if (!ip && !afi)
afiz = AFI_IP6;
if (!ip && afi)
afiz = bgp_vty_afi_from_str(afi);
if (ip && !afi)
afiz = AFI_IP;
if (ip && afi) {
afiz = bgp_vty_afi_from_str(afi);
if (afiz != AFI_IP)
vty_out(vty,
"%% Cannot specify both 'ip' and 'ipv6'\n");
return CMD_WARNING;
}
safiz = safi ? bgp_vty_safi_from_str(safi) : SAFI_UNICAST;
show_bgp_updgrps_adj_info_aux(vty, vrf, afiz, safiz, rtq, subgrp_id);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFUN (show_ip_bgp_instance_updgrps_adj,
show_ip_bgp_instance_updgrps_adj_cmd,
"show [ip] bgp <view|vrf> VIEWVRFNAME update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_word = 4;
int idx_type = 6;
show_bgp_updgrps_adj_info_aux(vty, argv[idx_word]->arg, AFI_IP,
SAFI_UNICAST, argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_afi_adj,
show_bgp_updgrps_afi_adj_cmd,
"show [ip] bgp "BGP_AFI_SAFI_CMD_STR" update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_AFI_SAFI_HELP_STR
"Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_afi = 2;
int idx_safi = 3;
int idx_type = 5;
show_bgp_updgrps_adj_info_aux(
vty, NULL, bgp_vty_afi_from_str(argv[idx_afi]->text),
bgp_vty_safi_from_str(argv[idx_safi]->text),
argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_adj,
show_bgp_updgrps_adj_cmd,
"show [ip] bgp update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
"Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_type = 3;
show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP6, SAFI_UNICAST,
argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_bgp_instance_updgrps_adj,
show_bgp_instance_updgrps_adj_cmd,
"show [ip] bgp <view|vrf> VIEWVRFNAME update-groups <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"Detailed info about dynamic update groups\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_word = 3;
int idx_type = 5;
show_bgp_updgrps_adj_info_aux(vty, argv[idx_word]->arg, AFI_IP6,
SAFI_UNICAST, argv[idx_type]->arg, 0);
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_updgrps_adj_s,
show_ip_bgp_updgrps_adj_s_cmd,
"show [ip] bgp update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
"Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_subgroup_id = 4;
int idx_type = 5;
uint64_t subgrp_id;
subgrp_id = strtoull(argv[idx_subgroup_id]->arg, NULL, 10);
show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP, SAFI_UNICAST,
argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_instance_updgrps_adj_s,
show_ip_bgp_instance_updgrps_adj_s_cmd,
"show [ip] bgp <view|vrf> VIEWVRFNAME update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_vrf = 4;
int idx_subgroup_id = 6;
int idx_type = 7;
uint64_t subgrp_id;
subgrp_id = strtoull(argv[idx_subgroup_id]->arg, NULL, 10);
show_bgp_updgrps_adj_info_aux(vty, argv[idx_vrf]->arg, AFI_IP,
SAFI_UNICAST, argv[idx_type]->arg,
subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_afi_adj_s,
show_bgp_updgrps_afi_adj_s_cmd,
"show [ip] bgp "BGP_AFI_SAFI_CMD_STR" update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_AFI_SAFI_HELP_STR
"Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_afi = 2;
int idx_safi = 3;
int idx_subgroup_id = 5;
int idx_type = 6;
uint64_t subgrp_id;
subgrp_id = strtoull(argv[idx_subgroup_id]->arg, NULL, 10);
show_bgp_updgrps_adj_info_aux(
vty, NULL, bgp_vty_afi_from_str(argv[idx_afi]->text),
bgp_vty_safi_from_str(argv[idx_safi]->text),
argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_bgp_updgrps_adj_s,
show_bgp_updgrps_adj_s_cmd,
"show [ip] bgp update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
"Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_subgroup_id = 3;
int idx_type = 4;
uint64_t subgrp_id;
subgrp_id = strtoull(argv[idx_subgroup_id]->arg, NULL, 10);
show_bgp_updgrps_adj_info_aux(vty, NULL, AFI_IP6, SAFI_UNICAST,
argv[idx_type]->arg, subgrp_id);
return CMD_SUCCESS;
}
DEFUN (show_bgp_instance_updgrps_adj_s,
show_bgp_instance_updgrps_adj_s_cmd,
"show [ip] bgp <view|vrf> VIEWVRFNAME update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"Detailed info about dynamic update groups\n"
"Specific subgroup to display info for\n"
"Advertisement queue\n"
"Announced routes\n"
"Packet queue\n")
{
int idx_vrf = 3;
int idx_subgroup_id = 5;
int idx_type = 6;
uint64_t subgrp_id;
subgrp_id = strtoull(argv[idx_subgroup_id]->arg, NULL, 10);
show_bgp_updgrps_adj_info_aux(vty, argv[idx_vrf]->arg, AFI_IP6,
SAFI_UNICAST, argv[idx_type]->arg,
subgrp_id);
return CMD_SUCCESS;
}
static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group) static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group)
{ {
struct listnode *node, *nnode; struct listnode *node, *nnode;
@ -12435,19 +12250,10 @@ void bgp_vty_init(void)
/* "show [ip] bgp summary" commands. */ /* "show [ip] bgp summary" commands. */
install_element(VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd); install_element(VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
install_element(VIEW_NODE, &show_bgp_instance_updgrps_adj_cmd);
install_element(VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd);
install_element(VIEW_NODE, &show_bgp_instance_updgrps_stats_cmd); install_element(VIEW_NODE, &show_bgp_instance_updgrps_stats_cmd);
install_element(VIEW_NODE, &show_bgp_updgrps_adj_cmd);
install_element(VIEW_NODE, &show_bgp_updgrps_adj_s_cmd);
install_element(VIEW_NODE, &show_bgp_updgrps_afi_adj_cmd);
install_element(VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd);
install_element(VIEW_NODE, &show_bgp_updgrps_stats_cmd); install_element(VIEW_NODE, &show_bgp_updgrps_stats_cmd);
install_element(VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_cmd);
install_element(VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd); install_element(VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
install_element(VIEW_NODE, &show_ip_bgp_summary_cmd); install_element(VIEW_NODE, &show_ip_bgp_summary_cmd);
install_element(VIEW_NODE, &show_ip_bgp_updgrps_adj_cmd);
install_element(VIEW_NODE, &show_ip_bgp_updgrps_adj_s_cmd);
install_element(VIEW_NODE, &show_ip_bgp_updgrps_cmd); install_element(VIEW_NODE, &show_ip_bgp_updgrps_cmd);
/* "show [ip] bgp neighbors" commands. */ /* "show [ip] bgp neighbors" commands. */

View File

@ -1746,8 +1746,7 @@ static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient,
if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s filter %s", zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s filter %s",
(cmd == ZEBRA_L3VNI_ADD) ? "add" : "del", (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del",
vrf_id_to_name(vrf_id), vrf_id_to_name(vrf_id), l3vni,
l3vni,
prefix_mac2str(&rmac, buf, sizeof(buf)), prefix_mac2str(&rmac, buf, sizeof(buf)),
filter ? "prefix-routes-only" : "none"); filter ? "prefix-routes-only" : "none");

View File

@ -108,7 +108,8 @@ static int bgp_check_main_socket(bool create, struct bgp *bgp)
struct listnode *bgpnode, *nbgpnode; struct listnode *bgpnode, *nbgpnode;
struct bgp *bgp_temp; struct bgp *bgp_temp;
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF &&
vrf_is_mapped_on_netns(bgp->vrf_id))
return 0; return 0;
if (create == true) { if (create == true) {
if (bgp_server_main_created) if (bgp_server_main_created)
@ -1078,10 +1079,8 @@ static void peer_free(struct peer *peer)
XFREE(MTYPE_TMP, peer->notify.data); XFREE(MTYPE_TMP, peer->notify.data);
memset(&peer->notify, 0, sizeof(struct bgp_notify)); memset(&peer->notify, 0, sizeof(struct bgp_notify));
if (peer->clear_node_queue) { if (peer->clear_node_queue)
work_queue_free(peer->clear_node_queue); work_queue_free_and_null(&peer->clear_node_queue);
peer->clear_node_queue = NULL;
}
bgp_sync_delete(peer); bgp_sync_delete(peer);
@ -3019,17 +3018,15 @@ struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
/* handle socket creation or deletion, if necessary /* handle socket creation or deletion, if necessary
* this is called for all new BGP instances * this is called for all new BGP instances
*/ */
int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
vrf_id_t old_vrf_id, bool create) bool create)
{ {
int ret = 0; int ret = 0;
/* Create BGP server socket, if listen mode not disabled */ /* Create BGP server socket, if listen mode not disabled */
if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN)) if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
return 0; return 0;
if (bgp->name if (bgp->name && bgp->inst_type == BGP_INSTANCE_TYPE_VRF && vrf) {
&& bgp->inst_type == BGP_INSTANCE_TYPE_VRF
&& vrf) {
/* /*
* suppress vrf socket * suppress vrf socket
*/ */
@ -3425,8 +3422,8 @@ struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
* invoked without an instance * invoked without an instance
* when examining VRFs. * when examining VRFs.
*/ */
if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF) && if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
!vrf_is_mapped_on_netns(bgp->vrf_id)) && !vrf_is_mapped_on_netns(bgp->vrf_id))
continue; continue;
peer = hash_lookup(bgp->peerhash, &tmp_peer); peer = hash_lookup(bgp->peerhash, &tmp_peer);
@ -4070,9 +4067,8 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
} }
/* Track if addpath TX is in use */ /* Track if addpath TX is in use */
if (flag if (flag & (PEER_FLAG_ADDPATH_TX_ALL_PATHS
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
| PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
bgp = peer->bgp; bgp = peer->bgp;
addpath_tx_used = 0; addpath_tx_used = 0;
@ -6885,9 +6881,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
} else { } else {
if (!peer_af_flag_check(peer, afi, safi, if (!peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_COMMUNITY) PEER_FLAG_SEND_COMMUNITY)
&& (!g_peer && (!g_peer || peer_af_flag_check(g_peer, afi, safi,
|| peer_af_flag_check(g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
PEER_FLAG_SEND_COMMUNITY))
&& !peer_af_flag_check(peer, afi, safi, && !peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY) PEER_FLAG_SEND_EXT_COMMUNITY)
&& (!g_peer && (!g_peer
@ -6895,10 +6890,9 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
PEER_FLAG_SEND_EXT_COMMUNITY)) PEER_FLAG_SEND_EXT_COMMUNITY))
&& !peer_af_flag_check(peer, afi, safi, && !peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY) PEER_FLAG_SEND_LARGE_COMMUNITY)
&& (!g_peer && (!g_peer || peer_af_flag_check(
|| peer_af_flag_check( g_peer, afi, safi,
g_peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))) {
PEER_FLAG_SEND_LARGE_COMMUNITY))) {
vty_out(vty, " no neighbor %s send-community all\n", vty_out(vty, " no neighbor %s send-community all\n",
addr); addr);
} else { } else {
@ -6926,10 +6920,9 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
if (!peer_af_flag_check(peer, afi, safi, if (!peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_COMMUNITY) PEER_FLAG_SEND_COMMUNITY)
&& (!g_peer && (!g_peer || peer_af_flag_check(
|| peer_af_flag_check( g_peer, afi, safi,
g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))) {
PEER_FLAG_SEND_COMMUNITY))) {
vty_out(vty, vty_out(vty,
" no neighbor %s send-community\n", " no neighbor %s send-community\n",
addr); addr);
@ -7644,10 +7637,8 @@ void bgp_terminate(void)
bgp_notify_send(peer, BGP_NOTIFY_CEASE, bgp_notify_send(peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_PEER_UNCONFIG); BGP_NOTIFY_CEASE_PEER_UNCONFIG);
if (bm->process_main_queue) { if (bm->process_main_queue)
work_queue_free(bm->process_main_queue); work_queue_free_and_null(&bm->process_main_queue);
bm->process_main_queue = NULL;
}
if (bm->t_rmap_update) if (bm->t_rmap_update)
BGP_TIMER_OFF(bm->t_rmap_update); BGP_TIMER_OFF(bm->t_rmap_update);

View File

@ -133,8 +133,6 @@ struct bgp_master {
/* timer to dampen route map changes */ /* timer to dampen route map changes */
struct thread *t_rmap_update; /* Handle route map updates */ struct thread *t_rmap_update; /* Handle route map updates */
u_int32_t rmap_update_timer; /* Route map update timer */ u_int32_t rmap_update_timer; /* Route map update timer */
/* $FRR indent$ */
/* clang-format off */
#define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */ #define RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */
/* Id space for automatic RD derivation for an EVI/VRF */ /* Id space for automatic RD derivation for an EVI/VRF */
@ -249,8 +247,6 @@ struct bgp {
*t_startup; /* start-up timer on only once at the beginning */ *t_startup; /* start-up timer on only once at the beginning */
u_int32_t v_maxmed_onstartup; /* Duration of max-med on start-up */ u_int32_t v_maxmed_onstartup; /* Duration of max-med on start-up */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_ONSTARTUP_UNCONFIGURED 0 /* 0 means off, its the default */ #define BGP_MAXMED_ONSTARTUP_UNCONFIGURED 0 /* 0 means off, its the default */
u_int32_t maxmed_onstartup_value; /* Max-med value when active on u_int32_t maxmed_onstartup_value; /* Max-med value when active on
start-up */ start-up */
@ -259,17 +255,13 @@ struct bgp {
u_char maxmed_onstartup_over; /* Flag to make it effective only once */ u_char maxmed_onstartup_over; /* Flag to make it effective only once */
u_char v_maxmed_admin; /* 1/0 if max-med administrative is on/off */ u_char v_maxmed_admin; /* 1/0 if max-med administrative is on/off */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */ #define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */
u_int32_t maxmed_admin_value; /* Max-med value when administrative in on u_int32_t maxmed_admin_value; /* Max-med value when administrative in on
*/ */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */ #define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */
u_char maxmed_active; /* 1/0 if max-med is active or not */ u_char maxmed_active; /* 1/0 if max-med is active or not */
u_int32_t maxmed_value; /* Max-med value when its active */ u_int32_t maxmed_value; /* Max-med value when its active */
/* BGP update delay on startup */ /* BGP update delay on startup */
struct thread *t_update_delay; struct thread *t_update_delay;
@ -320,6 +312,13 @@ struct bgp {
u_int16_t af_flags[AFI_MAX][SAFI_MAX]; u_int16_t af_flags[AFI_MAX][SAFI_MAX];
#define BGP_CONFIG_DAMPENING (1 << 0) #define BGP_CONFIG_DAMPENING (1 << 0)
/* l2vpn evpn flags - 1 << 0 is used for DAMPENNG */
#define BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST (1 << 1)
#define BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST (1 << 2)
#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4 (1 << 3)
#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6 (1 << 4)
/* Route table for next-hop lookup cache. */ /* Route table for next-hop lookup cache. */
struct bgp_table *nexthop_cache_table[AFI_MAX]; struct bgp_table *nexthop_cache_table[AFI_MAX];
@ -431,12 +430,11 @@ struct bgp {
/* vrf flags */ /* vrf flags */
uint32_t vrf_flags; uint32_t vrf_flags;
#define BGP_VRF_AUTO (1 << 0) #define BGP_VRF_AUTO (1 << 0)
#define BGP_VRF_ADVERTISE_IPV4_IN_EVPN (1 << 1) #define BGP_VRF_IMPORT_RT_CFGD (1 << 1)
#define BGP_VRF_ADVERTISE_IPV6_IN_EVPN (1 << 2) #define BGP_VRF_EXPORT_RT_CFGD (1 << 2)
#define BGP_VRF_IMPORT_RT_CFGD (1 << 3) #define BGP_VRF_RD_CFGD (1 << 3)
#define BGP_VRF_EXPORT_RT_CFGD (1 << 4) #define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 4)
#define BGP_VRF_RD_CFGD (1 << 5)
#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 6)
/* unique ID for auto derivation of RD for this vrf */ /* unique ID for auto derivation of RD for this vrf */
uint16_t vrf_rd_id; uint16_t vrf_rd_id;
@ -680,8 +678,6 @@ struct peer {
unsigned short port; /* Destination port for peer */ unsigned short port; /* Destination port for peer */
char *host; /* Printable address of the peer. */ char *host; /* Printable address of the peer. */
union sockunion su; /* Sockunion address of the peer. */ union sockunion su; /* Sockunion address of the peer. */
/* $FRR indent$ */
/* clang-format off */
#define BGP_PEER_SU_UNSPEC(peer) (peer->su.sa.sa_family == AF_UNSPEC) #define BGP_PEER_SU_UNSPEC(peer) (peer->su.sa.sa_family == AF_UNSPEC)
time_t uptime; /* Last Up/Down time */ time_t uptime; /* Last Up/Down time */
time_t readtime; /* Last read time */ time_t readtime; /* Last read time */
@ -898,8 +894,8 @@ struct peer {
memory_order_relaxed) memory_order_relaxed)
/* Statistics field */ /* Statistics field */
_Atomic uint32_t open_in; /* Open message input count */ _Atomic uint32_t open_in; /* Open message input count */
_Atomic uint32_t open_out; /* Open message output count */ _Atomic uint32_t open_out; /* Open message output count */
_Atomic uint32_t update_in; /* Update message input count */ _Atomic uint32_t update_in; /* Update message input count */
_Atomic uint32_t update_out; /* Update message ouput count */ _Atomic uint32_t update_out; /* Update message ouput count */
_Atomic time_t update_time; /* Update message received time. */ _Atomic time_t update_time; /* Update message received time. */

View File

@ -1636,9 +1636,8 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
idx += 2; /* skip afi and keyword */ idx += 2; /* skip afi and keyword */
if (is_bgp) { if (is_bgp) {
if (idx == argc if (idx == argc || strmatch(argv[idx]->arg,
|| strmatch(argv[idx]->arg, rfg->plist_export_bgp_name[afi])) {
rfg->plist_export_bgp_name[afi])) {
if (rfg->plist_export_bgp_name[afi]) if (rfg->plist_export_bgp_name[afi])
free(rfg->plist_export_bgp_name[afi]); free(rfg->plist_export_bgp_name[afi]);
rfg->plist_export_bgp_name[afi] = NULL; rfg->plist_export_bgp_name[afi] = NULL;
@ -1768,9 +1767,8 @@ DEFUN (vnc_nve_group_export_no_routemap,
} }
if (is_bgp) { if (is_bgp) {
if (idx == argc if (idx == argc || strmatch(argv[idx]->arg,
|| strmatch(argv[idx]->arg, rfg->routemap_export_bgp_name)) {
rfg->routemap_export_bgp_name)) {
if (rfg->routemap_export_bgp_name) if (rfg->routemap_export_bgp_name)
free(rfg->routemap_export_bgp_name); free(rfg->routemap_export_bgp_name);
rfg->routemap_export_bgp_name = NULL; rfg->routemap_export_bgp_name = NULL;
@ -1780,9 +1778,8 @@ DEFUN (vnc_nve_group_export_no_routemap,
vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
} }
} else { } else {
if (idx == argc if (idx == argc || strmatch(argv[idx]->arg,
|| strmatch(argv[idx]->arg, rfg->routemap_export_zebra_name)) {
rfg->routemap_export_zebra_name)) {
if (rfg->routemap_export_zebra_name) if (rfg->routemap_export_zebra_name)
free(rfg->routemap_export_zebra_name); free(rfg->routemap_export_zebra_name);
rfg->routemap_export_zebra_name = NULL; rfg->routemap_export_zebra_name = NULL;
@ -2978,7 +2975,8 @@ DEFUN_NOSH (vnc_vrf_policy,
VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT(bgp, bgp);
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) { if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
vty_out(vty, "Can't configure vrf-policy within a BGP VRF instance\n"); vty_out(vty,
"Can't configure vrf-policy within a BGP VRF instance\n");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }

View File

@ -383,9 +383,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
vnc_zlog_debug_verbose( vnc_zlog_debug_verbose(
"%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", "%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
__func__, peer, buf, __func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
prefix_rd2str(prd, buf2, sizeof(buf2)), afi, safi, bn, afi, safi, bn, (bn ? bn->info : NULL));
(bn ? bn->info : NULL));
for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) { for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
@ -749,9 +748,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) { if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) {
uint32_t lt; uint32_t lt;
encaptlv = encaptlv = XCALLOC(MTYPE_ENCAP_TLV,
XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) + 4);
sizeof(struct bgp_attr_encap_subtlv) + 4);
assert(encaptlv); assert(encaptlv);
encaptlv->type = encaptlv->type =
BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */ BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */
@ -795,8 +793,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
*/ */
encaptlv = XCALLOC( encaptlv = XCALLOC(
MTYPE_ENCAP_TLV, MTYPE_ENCAP_TLV,
sizeof(struct bgp_attr_encap_subtlv) sizeof(struct bgp_attr_encap_subtlv) + 2
+ 2 + hop->length); + hop->length);
assert(encaptlv); assert(encaptlv);
encaptlv->type = encaptlv->type =
BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP

View File

@ -1083,9 +1083,8 @@ int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom, uint16_t *tag_id)
} else if (encode == ECOMMUNITY_ENCODE_AS) { } else if (encode == ECOMMUNITY_ENCODE_AS) {
as = (*p++ << 8); as = (*p++ << 8);
as |= (*p++); as |= (*p++);
p += p += 2; /* skip next two, tag/vid
2; /* skip next two, tag/vid always in lowest bytes */
always in lowest bytes */
} }
if (as == bgp->as) { if (as == bgp->as) {
*tag_id = *p++ << 8; *tag_id = *p++ << 8;
@ -1221,8 +1220,7 @@ static int rfapiVpnBiSamePtUn(struct bgp_info *bi1, struct bgp_info *bi2)
switch (pfx_un1.family) { switch (pfx_un1.family) {
case AF_INET: case AF_INET:
if (!IPV4_ADDR_SAME(&pfx_un1.u.prefix4, if (!IPV4_ADDR_SAME(&pfx_un1.u.prefix4, &pfx_un2.u.prefix4))
&pfx_un2.u.prefix4))
return 0; return 0;
break; break;
case AF_INET6: case AF_INET6:
@ -2235,9 +2233,9 @@ static struct bgp_info *rfapiItBiIndexSearch(
vnc_zlog_debug_verbose( vnc_zlog_debug_verbose(
"%s: bi has prd=%s, peer=%p", __func__, "%s: bi has prd=%s, peer=%p", __func__,
prefix_rd2str(&bi_result->extra->vnc.import.rd, prefix_rd2str(&bi_result->extra->vnc
buf, .import.rd,
sizeof(buf)), buf, sizeof(buf)),
bi_result->peer); bi_result->peer);
} }
#endif #endif
@ -4338,7 +4336,7 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
h->import_mac = NULL; h->import_mac = NULL;
} }
work_queue_free(h->deferred_close_q); work_queue_free_and_null(&h->deferred_close_q);
if (h->rfp != NULL) if (h->rfp != NULL)
rfp_stop(h->rfp); rfp_stop(h->rfp);

View File

@ -929,17 +929,14 @@ void rfapiMonitorItNodeChanged(
char buf_attach_pfx[PREFIX_STRLEN]; char buf_attach_pfx[PREFIX_STRLEN];
char buf_target_pfx[PREFIX_STRLEN]; char buf_target_pfx[PREFIX_STRLEN];
prefix2str(&m->node->p, prefix2str(&m->node->p, buf_attach_pfx,
buf_attach_pfx,
sizeof(buf_attach_pfx)); sizeof(buf_attach_pfx));
prefix2str(&m->p, prefix2str(&m->p, buf_target_pfx,
buf_target_pfx,
sizeof(buf_target_pfx)); sizeof(buf_target_pfx));
vnc_zlog_debug_verbose( vnc_zlog_debug_verbose(
"%s: update rfd %p attached to pfx %s (targ=%s)", "%s: update rfd %p attached to pfx %s (targ=%s)",
__func__, m->rfd, __func__, m->rfd,
buf_attach_pfx, buf_attach_pfx, buf_target_pfx);
buf_target_pfx);
/* /*
* update its RIB * update its RIB

View File

@ -345,7 +345,8 @@ extern void rfapi_un_options_free(struct rfapi_un_option *goner);
extern void rfapi_vn_options_free(struct rfapi_vn_option *goner); extern void rfapi_vn_options_free(struct rfapi_vn_option *goner);
extern void vnc_add_vrf_opener(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); extern void vnc_add_vrf_opener(struct bgp *bgp,
struct rfapi_nve_group_cfg *rfg);
extern void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg); extern void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg);
/*------------------------------------------ /*------------------------------------------
* rfapi_extract_l2o * rfapi_extract_l2o

View File

@ -511,7 +511,8 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
if (pn->info) { if (pn->info) {
if (pn->info != (void *)1) { if (pn->info != (void *)1) {
list_delete_and_null( list_delete_and_null(
(struct list **)(&pn->info)); (struct list *
*)(&pn->info));
} }
pn->info = NULL; pn->info = NULL;
/* linklist or 1 deleted */ /* linklist or 1 deleted */
@ -570,10 +571,8 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
} }
} }
} }
if (rfd->updated_responses_queue) { if (rfd->updated_responses_queue)
work_queue_free(rfd->updated_responses_queue); work_queue_free_and_null(&rfd->updated_responses_queue);
rfd->updated_responses_queue = NULL;
}
} }
/* /*
@ -1407,9 +1406,10 @@ callback:
vnc_zlog_debug_verbose( vnc_zlog_debug_verbose(
"%s: move route to recently deleted list, rd=%s", "%s: move route to recently deleted list, rd=%s",
__func__, __func__,
prefix_rd2str(&ri->rk.rd, prefix_rd2str(
buf_rd, &ri->rk.rd,
sizeof(buf_rd))); buf_rd,
sizeof(buf_rd)));
} }
#endif #endif

View File

@ -1163,8 +1163,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
* print that on the next line * print that on the next line
*/ */
if (bi->extra if (bi->extra && bi->extra->vnc.import.aux_prefix.family) {
&& bi->extra->vnc.import.aux_prefix.family) {
const char *sp; const char *sp;
sp = rfapi_ntop( sp = rfapi_ntop(
@ -4630,7 +4629,7 @@ notcfg:
************************************************************************/ ************************************************************************/
void vnc_add_vrf_opener(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) void vnc_add_vrf_opener(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)
{ {
if (rfg->rfd == NULL) { /* need new rfapi_handle */ if (rfg->rfd == NULL) { /* need new rfapi_handle */
/* based on rfapi_open */ /* based on rfapi_open */
struct rfapi_descriptor *rfd; struct rfapi_descriptor *rfd;

View File

@ -53,8 +53,7 @@
static void vnc_direct_add_rn_group_rd(struct bgp *bgp, static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
struct rfapi_nve_group_cfg *rfg, struct rfapi_nve_group_cfg *rfg,
struct route_node *rn, struct route_node *rn, struct attr *attr,
struct attr *attr,
afi_t afi, afi_t afi,
struct rfapi_descriptor *irfd); struct rfapi_descriptor *irfd);
@ -879,8 +878,9 @@ void vnc_direct_bgp_del_prefix(struct bgp *bgp,
NULL, /* attr, ignored */ NULL, /* attr, ignored */
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for unicast */ NULL, /* RD not used for unicast */
NULL, 0, NULL); /* tag not used for unicast */ NULL, 0,
NULL); /* tag not used for unicast */
/* /*
* yuck! * yuck!
* - but consistent with rest of function * - but consistent with rest of function
@ -908,8 +908,9 @@ void vnc_direct_bgp_del_prefix(struct bgp *bgp,
NULL, /* attr, ignored */ NULL, /* attr, ignored */
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for unicast */ NULL, /* RD not used for unicast */
NULL, 0, NULL); /* tag not used for unicast */ NULL, 0,
NULL); /* tag not used for unicast */
} }
} }
} }
@ -1035,20 +1036,18 @@ void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
iattr = bgp_attr_intern(&hattr); iattr = bgp_attr_intern(&hattr);
bgp_attr_flush(&hattr); bgp_attr_flush(&hattr);
bgp_update(
bgp_update(irfd->peer, irfd->peer, &rn->p, /* prefix */
&rn->p, /* prefix */ 0, /* addpath_id */
0, /* addpath_id */ iattr, /* bgp_update copies
iattr, /* bgp_update copies it */
it */ afi, SAFI_UNICAST,
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,
BGP_ROUTE_REDISTRIBUTE, /* RD not used for unicast */
NULL, /* RD not used for NULL,
unicast */ /* tag not used for unicast */
NULL, /* tag not used for 0, 0, NULL); /* EVPN not used */
unicast */
0, 0, NULL); /* EVPN not used */
bgp_attr_unintern(&iattr); bgp_attr_unintern(&iattr);
} }
@ -1153,10 +1152,8 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
static void vnc_direct_add_rn_group_rd(struct bgp *bgp, static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
struct rfapi_nve_group_cfg *rfg, struct rfapi_nve_group_cfg *rfg,
struct route_node *rn, struct route_node *rn, struct attr *attr,
struct attr *attr, afi_t afi, struct rfapi_descriptor *irfd)
afi_t afi,
struct rfapi_descriptor *irfd)
{ {
struct prefix nhp; struct prefix nhp;
struct bgp_info info; struct bgp_info info;
@ -1169,23 +1166,26 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
assert(rfg->rfd == NULL); assert(rfg->rfd == NULL);
if (!rfg->rt_export_list || !rfg->rfapi_import_table) { if (!rfg->rt_export_list || !rfg->rfapi_import_table) {
vnc_zlog_debug_verbose("%s: VRF \"%s\" is missing RT import/export configuration.\n", vnc_zlog_debug_verbose(
__func__, rfg->name); "%s: VRF \"%s\" is missing RT import/export configuration.\n",
__func__, rfg->name);
return; return;
} }
if (!rfg->rd.prefixlen) { if (!rfg->rd.prefixlen) {
vnc_zlog_debug_verbose("%s: VRF \"%s\" is missing RD configuration.\n", vnc_zlog_debug_verbose(
__func__, rfg->name); "%s: VRF \"%s\" is missing RD configuration.\n",
__func__, rfg->name);
return; return;
} }
if (rfg->label > MPLS_LABEL_MAX) { if (rfg->label > MPLS_LABEL_MAX) {
vnc_zlog_debug_verbose("%s: VRF \"%s\" is missing defaul label configuration.\n", vnc_zlog_debug_verbose(
__func__, rfg->name); "%s: VRF \"%s\" is missing defaul label configuration.\n",
__func__, rfg->name);
return; return;
} }
irfd = XCALLOC(MTYPE_RFAPI_DESC, irfd = XCALLOC(MTYPE_RFAPI_DESC,
sizeof(struct rfapi_descriptor)); sizeof(struct rfapi_descriptor));
irfd->bgp = bgp; irfd->bgp = bgp;
rfg->rfd = irfd; rfg->rfd = irfd;
/* /*
@ -1221,11 +1221,9 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
return; return;
if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) { if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) {
vnc_zlog_debug_any("%s: attr follows", vnc_zlog_debug_any("%s: attr follows", __func__);
__func__);
rfapiPrintAttrPtrs(NULL, attr); rfapiPrintAttrPtrs(NULL, attr);
vnc_zlog_debug_any("%s: hattr follows", vnc_zlog_debug_any("%s: hattr follows", __func__);
__func__);
rfapiPrintAttrPtrs(NULL, &hattr); rfapiPrintAttrPtrs(NULL, &hattr);
} }
@ -1234,12 +1232,13 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
info.peer = irfd->peer; info.peer = irfd->peer;
info.attr = &hattr; info.attr = &hattr;
ret = route_map_apply(rfg->routemap_export_bgp, ret = route_map_apply(rfg->routemap_export_bgp, &rn->p,
&rn->p, RMAP_BGP, &info); RMAP_BGP, &info);
if (ret == RMAP_DENYMATCH) { if (ret == RMAP_DENYMATCH) {
bgp_attr_flush(&hattr); bgp_attr_flush(&hattr);
vnc_zlog_debug_verbose("%s: route map says DENY, so not calling bgp_update", vnc_zlog_debug_verbose(
__func__); "%s: route map says DENY, so not calling bgp_update",
__func__);
return; return;
} }
} }
@ -1254,13 +1253,11 @@ static void vnc_direct_add_rn_group_rd(struct bgp *bgp,
bgp_update(irfd->peer, &rn->p, /* prefix */ bgp_update(irfd->peer, &rn->p, /* prefix */
0, /* addpath_id */ 0, /* addpath_id */
iattr, /* bgp_update copies it */ iattr, /* bgp_update copies it */
afi, SAFI_UNICAST, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
BGP_ROUTE_REDISTRIBUTE, NULL, /* tag not used for unicast */
NULL, /* RD not used for unicast */ 0, 0, NULL); /* EVPN not used */
NULL, /* tag not used for unicast */
0, 0, NULL); /* EVPN not used */
bgp_attr_unintern(&iattr); bgp_attr_unintern(&iattr);
@ -1340,7 +1337,8 @@ static void vnc_direct_bgp_add_group_afi(struct bgp *bgp,
for (ln = listhead(rfg->nves); ln; for (ln = listhead(rfg->nves); ln;
ln = listnextnode(ln)) { ln = listnextnode(ln)) {
vnc_direct_add_rn_group_rd(bgp, rfg, rn, &attr, vnc_direct_add_rn_group_rd(bgp, rfg, rn, &attr,
afi, listgetdata(ln)); afi,
listgetdata(ln));
} }
} }
} }
@ -1361,21 +1359,17 @@ void vnc_direct_bgp_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)
static void vnc_direct_del_rn_group_rd(struct bgp *bgp, static void vnc_direct_del_rn_group_rd(struct bgp *bgp,
struct rfapi_nve_group_cfg *rfg, struct rfapi_nve_group_cfg *rfg,
struct route_node *rn, struct route_node *rn, afi_t afi,
afi_t afi,
struct rfapi_descriptor *irfd) struct rfapi_descriptor *irfd)
{ {
if (irfd == NULL) if (irfd == NULL)
return; return;
bgp_withdraw(irfd->peer, &rn->p, /* prefix */ bgp_withdraw(irfd->peer, &rn->p, /* prefix */
0, /* addpath_id */ 0, /* addpath_id */
NULL, /* attr, ignored */ NULL, /* attr, ignored */
afi, SAFI_UNICAST, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
BGP_ROUTE_REDISTRIBUTE, NULL, 0, NULL); /* tag not used for unicast */
NULL, /* RD not used for unicast */
NULL, 0,
NULL); /* tag not used for unicast */
return; return;
} }
@ -1414,20 +1408,22 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp,
for (rn = route_top(rt); rn; rn = route_next(rn)) for (rn = route_top(rt); rn; rn = route_next(rn))
if (rn->info) { if (rn->info) {
if (rfg->type == RFAPI_GROUP_CFG_VRF) if (rfg->type == RFAPI_GROUP_CFG_VRF)
vnc_direct_del_rn_group_rd(bgp, rfg, rn, vnc_direct_del_rn_group_rd(bgp, rfg, rn, afi,
afi, rfg->rfd); rfg->rfd);
else { else {
struct listnode *ln; struct listnode *ln;
/* /*
* For each NVE that is assigned to the export nve * For each NVE that is assigned to the export
* nve
* group, generate * group, generate
* a route with that NVE as its next hop * a route with that NVE as its next hop
*/ */
for (ln = listhead(rfg->nves); ln; for (ln = listhead(rfg->nves); ln;
ln = listnextnode(ln)) ln = listnextnode(ln))
vnc_direct_del_rn_group_rd(bgp, rfg, rn, vnc_direct_del_rn_group_rd(
afi, listgetdata(ln)); bgp, rfg, rn, afi,
listgetdata(ln));
} }
} }
} }
@ -1531,8 +1527,8 @@ static void import_table_to_nve_list_direct_bgp(struct bgp *bgp,
if (rfgn->rfg && rfgn->rfg->rfapi_import_table == it) { if (rfgn->rfg && rfgn->rfg->rfapi_import_table == it) {
if (rfgn->rfg->nves) if (rfgn->rfg->nves)
nve_group_to_nve_list(rfgn->rfg, nves, family); nve_group_to_nve_list(rfgn->rfg, nves, family);
else if (rfgn->rfg->rfd && else if (rfgn->rfg->rfd
rfgn->rfg->type == RFAPI_GROUP_CFG_VRF) { && rfgn->rfg->type == RFAPI_GROUP_CFG_VRF) {
if (!*nves) if (!*nves)
*nves = list_new(); *nves = list_new();
listnode_add(*nves, rfgn->rfg->rfd); listnode_add(*nves, rfgn->rfg->rfd);
@ -1718,7 +1714,7 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
iattr, /* bgp_update copies this attr */ iattr, /* bgp_update copies this attr */
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH,
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
NULL, /* tag not used for unicast, EVPN neither */ NULL, /* tag not used for unicast, EVPN neither */
0, 0, NULL); /* EVPN not used */ 0, 0, NULL); /* EVPN not used */
bgp_attr_unintern(&iattr); bgp_attr_unintern(&iattr);
} }
@ -1734,7 +1730,8 @@ static int vncExportWithdrawTimer(struct thread *t)
NULL, /* attr, ignored */ NULL, /* attr, ignored */
family2afi(eti->node->p.family), SAFI_UNICAST, eti->type, family2afi(eti->node->p.family), SAFI_UNICAST, eti->type,
eti->subtype, NULL, /* RD not used for unicast */ eti->subtype, NULL, /* RD not used for unicast */
NULL, 0, NULL); /* tag not used for unicast, EVPN neither */ NULL, 0,
NULL); /* tag not used for unicast, EVPN neither */
/* /*
* Free the eti * Free the eti
@ -1857,9 +1854,8 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
prefix2str(&rn->p, prefixstr, prefix2str(&rn->p, prefixstr,
sizeof(prefixstr)); sizeof(prefixstr));
vnc_zlog_debug_verbose( vnc_zlog_debug_verbose("%s: checking prefix %s",
"%s: checking prefix %s", __func__, __func__, prefixstr);
prefixstr);
} }
/* /*
@ -1952,20 +1948,20 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
"%s: calling bgp_update", "%s: calling bgp_update",
__func__); __func__);
bgp_update(ri->peer, bgp_update(
&rn->p, /* prefix */ ri->peer, &rn->p, /* prefix */
0, /* addpath_id */ 0, /* addpath_id */
iattr, /* bgp_update copies iattr, /* bgp_update copies
it */ it */
AFI_IP, SAFI_UNICAST, AFI_IP, SAFI_UNICAST,
ZEBRA_ROUTE_VNC_DIRECT_RH, ZEBRA_ROUTE_VNC_DIRECT_RH,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE, NULL,
NULL, /* RD not used for /* RD not used for unicast */
unicast */ NULL,
NULL, /* tag not used for /* tag not used for unicast,
unicast, EVPN or EVPN */
neither */ 0, 0, NULL); /* EVPN not used */
0, 0, NULL); /* EVPN not used */
bgp_attr_unintern(&iattr); bgp_attr_unintern(&iattr);
} }
} }

View File

@ -2557,7 +2557,7 @@ void vnc_import_bgp_exterior_del_route_interior(
if (bi->extra) { if (bi->extra) {
prd = &bi->extra->vnc.import.rd; prd = &bi->extra->vnc.import.rd;
label = decode_label( label = decode_label(
&bi->extra->label[0]); &bi->extra->label[0]);
} else } else
prd = NULL; prd = NULL;

View File

@ -396,6 +396,8 @@ AC_ARG_ENABLE(rpki,
AS_HELP_STRING([--enable-rpki], [enable RPKI prefix validation support])) AS_HELP_STRING([--enable-rpki], [enable RPKI prefix validation support]))
AC_ARG_ENABLE([clippy-only], AC_ARG_ENABLE([clippy-only],
AS_HELP_STRING([--enable-clippy-only], [Only build clippy])) AS_HELP_STRING([--enable-clippy-only], [Only build clippy]))
AC_ARG_ENABLE([numeric_version],
AS_HELP_STRING([--enable-numeric-version], [Only numeric digits allowed in version (for Alpine)]))
AS_IF([test "${enable_clippy_only}" != "yes"], [ AS_IF([test "${enable_clippy_only}" != "yes"], [
AC_CHECK_HEADERS(json-c/json.h) AC_CHECK_HEADERS(json-c/json.h)
@ -647,6 +649,14 @@ AC_DEFINE_UNQUOTED(MULTIPATH_NUM, $MPATH_NUM, Maximum number of paths for a rout
AC_DEFINE_UNQUOTED(VTYSH_PAGER, "$VTYSH_PAGER", [What pager to use]) AC_DEFINE_UNQUOTED(VTYSH_PAGER, "$VTYSH_PAGER", [What pager to use])
dnl ------------------------------------
dnl Alpine only accepts numeric versions
dnl ------------------------------------
if test "x${enable_numeric_version}" != "x" ; then
VERSION="`echo ${VERSION} | tr -c -d '[[.0-9]]'`"
PACKAGE_VERSION="`echo ${PACKAGE_VERSION} | tr -c -d '[[.0-9]]'`"
fi
dnl ----------------------------------- dnl -----------------------------------
dnl Add extra version string to package dnl Add extra version string to package
dnl name, string and version fields. dnl name, string and version fields.
@ -1872,6 +1882,7 @@ AC_CONFIG_FILES([Makefile
redhat/frr.spec redhat/frr.spec
debianpkg/Makefile debianpkg/Makefile
debianpkg/changelog debianpkg/changelog
alpine/APKBUILD
snapcraft/snapcraft.yaml snapcraft/snapcraft.yaml
lib/version.h lib/version.h
tests/lib/cli/test_cli.refout tests/lib/cli/test_cli.refout

View File

@ -170,6 +170,12 @@ customize the build to include or exclude specific features and dependencies.
Build with FPM module support. Build with FPM module support.
.. option:: --enable-numeric-version
Alpine Linux does not allow non-numeric characters in the version string.
With this option, we provide a way to strip out these characters for apk dev
package builds.
You may specify any combination of the above options to the configure You may specify any combination of the above options to the configure
script. By default, the executables are placed in :file:`/usr/local/sbin` 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/` and the configuration files in :file:`/usr/local/etc`. The :file:`/usr/local/`

View File

@ -94,11 +94,7 @@
#define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/ #define EIGRP_MULTICAST_ADDRESS 0xe000000A /*224.0.0.10*/
#define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/ #define EIGRP_MAX_METRIC 0xffffffffU /*4294967295*/
enum metric_change { enum metric_change { METRIC_DECREASE, METRIC_SAME, METRIC_INCREASE };
METRIC_DECREASE,
METRIC_SAME,
METRIC_INCREASE
};
#define DEFAULT_ROUTE ZEBRA_ROUTE_MAX #define DEFAULT_ROUTE ZEBRA_ROUTE_MAX
#define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE) #define DEFAULT_ROUTE_TYPE(T) ((T) == DEFAULT_ROUTE)
@ -182,7 +178,7 @@ enum eigrp_fsm_events {
* state not changed * state not changed
* usually by receiving not last reply * usually by receiving not last reply
*/ */
EIGRP_FSM_KEEP_STATE, EIGRP_FSM_KEEP_STATE,
}; };
/** /**

View File

@ -216,8 +216,7 @@ void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp,
vty_out(vty, "%u %c %-10u", 0, '/', vty_out(vty, "%u %c %-10u", 0, '/',
eigrp_neighbor_packet_queue_sum(ei)); eigrp_neighbor_packet_queue_sum(ei));
vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0); vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0);
vty_out(vty, "%-8u %-8u \n", ei->params.v_hello, vty_out(vty, "%-8u %-8u \n", ei->params.v_hello, ei->params.v_wait);
ei->params.v_wait);
} }
void show_ip_eigrp_interface_detail(struct vty *vty, struct eigrp *eigrp, void show_ip_eigrp_interface_detail(struct vty *vty, struct eigrp *eigrp,
@ -253,7 +252,8 @@ void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr,
vty_out(vty, "%-3u %-17s %-21s", 0, eigrp_neigh_ip_string(nbr), vty_out(vty, "%-3u %-17s %-21s", 0, eigrp_neigh_ip_string(nbr),
eigrp_if_name_string(nbr->ei)); eigrp_if_name_string(nbr->ei));
if (nbr->t_holddown) if (nbr->t_holddown)
vty_out(vty, "%-7lu", thread_timer_remain_second(nbr->t_holddown)); vty_out(vty, "%-7lu",
thread_timer_remain_second(nbr->t_holddown));
else else
vty_out(vty, "- "); vty_out(vty, "- ");
vty_out(vty, "%-8u %-6u %-5u", 0, 0, EIGRP_PACKET_RETRANS_TIME); vty_out(vty, "%-8u %-6u %-5u", 0, 0, EIGRP_PACKET_RETRANS_TIME);
@ -295,8 +295,7 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
vty_out(vty, "%s, ", vty_out(vty, "%s, ",
prefix2str(tn->destination, buffer, PREFIX_STRLEN)); prefix2str(tn->destination, buffer, PREFIX_STRLEN));
vty_out(vty, "%u successors, ", vty_out(vty, "%u successors, ", (successors) ? successors->count : 0);
(successors) ? successors->count : 0);
vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance, vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance,
tn->serno); tn->serno);
@ -305,7 +304,7 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
} }
void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
struct eigrp_nexthop_entry *te, int *first) struct eigrp_nexthop_entry *te, int *first)
{ {
if (te->reported_distance == EIGRP_MAX_METRIC) if (te->reported_distance == EIGRP_MAX_METRIC)
return; return;

View File

@ -157,7 +157,7 @@ extern void show_ip_eigrp_neighbor_sub(struct vty *, struct eigrp_neighbor *,
extern void show_ip_eigrp_prefix_entry(struct vty *, extern void show_ip_eigrp_prefix_entry(struct vty *,
struct eigrp_prefix_entry *); struct eigrp_prefix_entry *);
extern void show_ip_eigrp_nexthop_entry(struct vty *, struct eigrp *, extern void show_ip_eigrp_nexthop_entry(struct vty *, struct eigrp *,
struct eigrp_nexthop_entry *, int *); struct eigrp_nexthop_entry *, int *);
extern void eigrp_debug_init(void); extern void eigrp_debug_init(void);

View File

@ -257,8 +257,8 @@ static const char *change2str(enum metric_change change)
* Return number of occurred event (arrow in diagram). * Return number of occurred event (arrow in diagram).
* *
*/ */
static enum eigrp_fsm_events eigrp_get_fsm_event( static enum eigrp_fsm_events
struct eigrp_fsm_action_message *msg) eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg)
{ {
// Loading base information from message // Loading base information from message
// struct eigrp *eigrp = msg->eigrp; // struct eigrp *eigrp = msg->eigrp;
@ -315,8 +315,7 @@ static enum eigrp_fsm_events eigrp_get_fsm_event(
return EIGRP_FSM_KEEP_STATE; return EIGRP_FSM_KEEP_STATE;
zlog_info("All reply received\n"); zlog_info("All reply received\n");
if (head->reported_distance if (head->reported_distance < prefix->fdistance) {
< prefix->fdistance) {
return EIGRP_FSM_EVENT_LR_FCS; return EIGRP_FSM_EVENT_LR_FCS;
} }
@ -417,13 +416,12 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
{ {
enum eigrp_fsm_events event = eigrp_get_fsm_event(msg); enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
zlog_info("EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s", zlog_info(
msg->eigrp->AS, prefix_state2str(msg->prefix->state), "EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s",
fsm_state2str(event), msg->eigrp->AS, prefix_state2str(msg->prefix->state),
eigrp_topology_ip_string(msg->prefix), fsm_state2str(event), eigrp_topology_ip_string(msg->prefix),
packet_type2str(msg->packet_type), packet_type2str(msg->packet_type), msg->prefix->rij->count,
msg->prefix->rij->count, change2str(msg->change));
change2str(msg->change));
(*(NSM[msg->prefix->state][event].func))(msg); (*(NSM[msg->prefix->state][event].func))(msg);
return 1; return 1;
@ -444,8 +442,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
ne = listnode_head(successors); ne = listnode_head(successors);
prefix->state = EIGRP_FSM_STATE_ACTIVE_1; prefix->state = EIGRP_FSM_STATE_ACTIVE_1;
prefix->rdistance = prefix->distance = prefix->fdistance = prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
ne->distance;
prefix->reported_metric = ne->total_metric; prefix->reported_metric = ne->total_metric;
if (eigrp_nbr_count_get()) { if (eigrp_nbr_count_get()) {
@ -472,8 +469,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
ne = listnode_head(successors); ne = listnode_head(successors);
prefix->state = EIGRP_FSM_STATE_ACTIVE_3; prefix->state = EIGRP_FSM_STATE_ACTIVE_3;
prefix->rdistance = prefix->distance = prefix->fdistance = prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
ne->distance;
prefix->reported_metric = ne->total_metric; prefix->reported_metric = ne->total_metric;
if (eigrp_nbr_count_get()) { if (eigrp_nbr_count_get()) {
prefix->req_action |= EIGRP_FSM_NEED_QUERY; prefix->req_action |= EIGRP_FSM_NEED_QUERY;
@ -498,8 +494,7 @@ int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
ne->total_metric)) { ne->total_metric)) {
prefix->rdistance = prefix->fdistance = prefix->rdistance = prefix->fdistance =
prefix->distance = ne->distance; prefix->distance = ne->distance;
prefix->reported_metric = prefix->reported_metric = ne->total_metric;
ne->total_metric;
if (msg->packet_type == EIGRP_OPC_QUERY) if (msg->packet_type == EIGRP_OPC_QUERY)
eigrp_send_reply(msg->adv_router, prefix); eigrp_send_reply(msg->adv_router, prefix);
prefix->req_action |= EIGRP_FSM_NEED_UPDATE; prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
@ -523,8 +518,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
struct eigrp_prefix_entry *prefix = msg->prefix; struct eigrp_prefix_entry *prefix = msg->prefix;
struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries); struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
prefix->fdistance = prefix->distance = prefix->rdistance = prefix->fdistance = prefix->distance = prefix->rdistance = ne->distance;
ne->distance;
prefix->reported_metric = ne->total_metric; prefix->reported_metric = ne->total_metric;
if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) { if (prefix->state == EIGRP_FSM_STATE_ACTIVE_3) {
@ -533,8 +527,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
assert(successors); // It's like Napolean and Waterloo assert(successors); // It's like Napolean and Waterloo
ne = listnode_head(successors); ne = listnode_head(successors);
eigrp_send_reply(ne->adv_router, eigrp_send_reply(ne->adv_router, prefix);
prefix);
list_delete_and_null(&successors); list_delete_and_null(&successors);
} }
@ -587,8 +580,7 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
assert(successors); // Having a spoon and all you need is a assert(successors); // Having a spoon and all you need is a
// knife // knife
ne = listnode_head(successors); ne = listnode_head(successors);
eigrp_send_reply(ne->adv_router, eigrp_send_reply(ne->adv_router, prefix);
prefix);
list_delete_and_null(&successors); list_delete_and_null(&successors);
} }

View File

@ -96,8 +96,8 @@ int eigrp_hello_timer(struct thread *thread)
/* Hello timer set. */ /* Hello timer set. */
ei->t_hello = NULL; ei->t_hello = NULL;
thread_add_timer(master, eigrp_hello_timer, ei, thread_add_timer(master, eigrp_hello_timer, ei, ei->params.v_hello,
ei->params.v_hello, &ei->t_hello); &ei->t_hello);
return 0; return 0;
} }
@ -443,7 +443,7 @@ static u_int16_t eigrp_sw_version_encode(struct stream *s)
stream_putw(s, EIGRP_TLV_SW_VERSION); stream_putw(s, EIGRP_TLV_SW_VERSION);
stream_putw(s, length); stream_putw(s, length);
stream_putc(s, FRR_MAJOR); //!< major os version stream_putc(s, FRR_MAJOR); //!< major os version
stream_putc(s, FRR_MINOR); //!< minor os version stream_putc(s, FRR_MINOR); //!< minor os version
/* and the core eigrp version */ /* and the core eigrp version */
@ -634,14 +634,14 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei,
if (ep) { if (ep) {
// encode common header feilds // encode common header feilds
eigrp_packet_header_init(EIGRP_OPC_HELLO, ei->eigrp, ep->s, 0, 0, ack); eigrp_packet_header_init(EIGRP_OPC_HELLO, ei->eigrp, ep->s, 0,
0, ack);
// encode Authentication TLV // encode Authentication TLV
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
} else if ((ei->params.auth_type } else if ((ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256)
== EIGRP_AUTH_TYPE_SHA256)
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_SHA256_to_stream(ep->s, ei); length += eigrp_add_authTLV_SHA256_to_stream(ep->s, ei);
} }
@ -680,8 +680,7 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei,
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s, eigrp_make_md5_digest(ei, ep->s,
EIGRP_AUTH_BASIC_HELLO_FLAG); EIGRP_AUTH_BASIC_HELLO_FLAG);
} else if ((ei->params.auth_type } else if ((ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256)
== EIGRP_AUTH_TYPE_SHA256)
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
eigrp_make_sha256_digest(ei, ep->s, eigrp_make_sha256_digest(ei, ep->s,
EIGRP_AUTH_BASIC_HELLO_FLAG); EIGRP_AUTH_BASIC_HELLO_FLAG);

View File

@ -125,12 +125,11 @@ struct list *eigrp_iflist;
void eigrp_if_init() void eigrp_if_init()
{ {
/* Initialize Zebra interface data structure. */ /* Initialize Zebra interface data structure. */
//hook_register_prio(if_add, 0, eigrp_if_new); // hook_register_prio(if_add, 0, eigrp_if_new);
hook_register_prio(if_del, 0, eigrp_if_delete_hook); hook_register_prio(if_del, 0, eigrp_if_delete_hook);
} }
void eigrp_del_if_params(struct eigrp_if_params *eip) void eigrp_del_if_params(struct eigrp_if_params *eip)
{ {
if (eip->auth_keychain) if (eip->auth_keychain)
@ -160,8 +159,7 @@ int eigrp_if_up(struct eigrp_interface *ei)
thread_add_event(master, eigrp_hello_timer, ei, (1), NULL); thread_add_event(master, eigrp_hello_timer, ei, (1), NULL);
/*Prepare metrics*/ /*Prepare metrics*/
metric.bandwidth = metric.bandwidth = eigrp_bandwidth_to_scaled(ei->params.bandwidth);
eigrp_bandwidth_to_scaled(ei->params.bandwidth);
metric.delay = eigrp_delay_to_scaled(ei->params.delay); metric.delay = eigrp_delay_to_scaled(ei->params.delay);
metric.load = ei->params.load; metric.load = ei->params.load;
metric.reliability = ei->params.reliability; metric.reliability = ei->params.reliability;
@ -310,8 +308,7 @@ void eigrp_if_set_multicast(struct eigrp_interface *ei)
* group. */ * group. */
if (ei->member_allrouters) { if (ei->member_allrouters) {
/* Only actually drop if this is the last reference */ /* Only actually drop if this is the last reference */
eigrp_if_drop_allspfrouters(ei->eigrp, eigrp_if_drop_allspfrouters(ei->eigrp, ei->address,
ei->address,
ei->ifp->ifindex); ei->ifp->ifindex);
/* Unset the flag regardless of whether the system call /* Unset the flag regardless of whether the system call
to leave to leave
@ -333,8 +330,7 @@ u_char eigrp_default_iftype(struct interface *ifp)
return EIGRP_IFTYPE_BROADCAST; return EIGRP_IFTYPE_BROADCAST;
} }
void eigrp_if_free(struct eigrp_interface *ei, void eigrp_if_free(struct eigrp_interface *ei, int source)
int source)
{ {
struct prefix dest_addr; struct prefix dest_addr;
struct eigrp_prefix_entry *pe; struct eigrp_prefix_entry *pe;

View File

@ -28,7 +28,6 @@
#ifndef _ZEBRA_EIGRP_MACROS_H_ #ifndef _ZEBRA_EIGRP_MACROS_H_
#define _ZEBRA_EIGRP_MACROS_H_ #define _ZEBRA_EIGRP_MACROS_H_
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
#define EIGRP_IF_STRING_MAXLEN 40 #define EIGRP_IF_STRING_MAXLEN 40

View File

@ -358,7 +358,8 @@ void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty)
eigrp_nbr_delete(nbr); eigrp_nbr_delete(nbr);
} }
int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne, struct eigrp_interface *ei) int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne,
struct eigrp_interface *ei)
{ {
if (ne->distance == EIGRP_MAX_METRIC) if (ne->distance == EIGRP_MAX_METRIC)
return 0; return 0;

View File

@ -280,8 +280,7 @@ static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p,
if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY)) if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY))
continue; continue;
if (p->family == co->address->family if (p->family == co->address->family && !ifp->info
&& !ifp->info
&& eigrp_network_match_iface(co, p)) { && eigrp_network_match_iface(co, p)) {
ei = eigrp_if_new(eigrp, ifp, co->address); ei = eigrp_if_new(eigrp, ifp, co->address);
@ -408,17 +407,17 @@ u_int32_t eigrp_calculate_total_metrics(struct eigrp *eigrp,
struct eigrp_interface *ei = entry->ei; struct eigrp_interface *ei = entry->ei;
entry->total_metric = entry->reported_metric; entry->total_metric = entry->reported_metric;
uint64_t temp_delay = (uint64_t)entry->total_metric.delay uint64_t temp_delay =
+ (uint64_t)eigrp_delay_to_scaled(ei->params.delay); (uint64_t)entry->total_metric.delay
+ (uint64_t)eigrp_delay_to_scaled(ei->params.delay);
entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC
? EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC
: (u_int32_t)temp_delay; : (u_int32_t)temp_delay;
u_int32_t bw = u_int32_t bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth);
eigrp_bandwidth_to_scaled(ei->params.bandwidth);
entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw
? bw ? bw
: entry->total_metric.bandwidth; : entry->total_metric.bandwidth;
return eigrp_calculate_metrics(eigrp, entry->total_metric); return eigrp_calculate_metrics(eigrp, entry->total_metric);
} }

View File

@ -194,8 +194,9 @@ int eigrp_check_md5_digest(struct stream *s,
key = key_lookup_for_send(keychain); key = key_lookup_for_send(keychain);
if (!key) { if (!key) {
zlog_warn("Interface %s: Expected key value not found in config", zlog_warn(
nbr->ei->ifp->name); "Interface %s: Expected key value not found in config",
nbr->ei->ifp->name);
return 0; return 0;
} }
@ -270,8 +271,9 @@ int eigrp_make_sha256_digest(struct eigrp_interface *ei, struct stream *s,
key = key_lookup_for_send(keychain); key = key_lookup_for_send(keychain);
if (!key) { if (!key) {
zlog_warn("Interface %s: Expected key value not found in config", zlog_warn(
ei->ifp->name); "Interface %s: Expected key value not found in config",
ei->ifp->name);
eigrp_authTLV_SHA256_free(auth_TLV); eigrp_authTLV_SHA256_free(auth_TLV);
return 0; return 0;
} }
@ -325,8 +327,6 @@ int eigrp_write(struct thread *thread)
#ifdef WANT_EIGRP_WRITE_FRAGMENT #ifdef WANT_EIGRP_WRITE_FRAGMENT
static u_int16_t ipid = 0; static u_int16_t ipid = 0;
#endif /* WANT_EIGRP_WRITE_FRAGMENT */ #endif /* WANT_EIGRP_WRITE_FRAGMENT */
/* $FRR indent$ */
/* clang-format off */
#define EIGRP_WRITE_IPHL_SHIFT 2 #define EIGRP_WRITE_IPHL_SHIFT 2
eigrp->t_write = NULL; eigrp->t_write = NULL;
@ -350,8 +350,7 @@ int eigrp_write(struct thread *thread)
goto out; goto out;
} }
if (ep->length < EIGRP_HEADER_LEN) { if (ep->length < EIGRP_HEADER_LEN) {
zlog_err("%s: Packet just has a header?", zlog_err("%s: Packet just has a header?", __PRETTY_FUNCTION__);
__PRETTY_FUNCTION__);
eigrp_header_dump((struct eigrp_header *)ep->s->data); eigrp_header_dump((struct eigrp_header *)ep->s->data);
eigrp_packet_delete(ei); eigrp_packet_delete(ei);
goto out; goto out;
@ -435,10 +434,10 @@ int eigrp_write(struct thread *thread)
if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND)) { if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND)) {
eigrph = (struct eigrp_header *)STREAM_DATA(ep->s); eigrph = (struct eigrp_header *)STREAM_DATA(ep->s);
zlog_debug("Sending [%s][%d/%d] to [%s] via [%s] ret [%d].", zlog_debug(
lookup_msg(eigrp_packet_type_str, eigrph->opcode, NULL), "Sending [%s][%d/%d] to [%s] via [%s] ret [%d].",
seqno, ack, lookup_msg(eigrp_packet_type_str, eigrph->opcode, NULL),
inet_ntoa(ep->dst), IF_NAME(ei), ret); seqno, ack, inet_ntoa(ep->dst), IF_NAME(ei), ret);
} }
if (ret < 0) if (ret < 0)
@ -615,10 +614,11 @@ int eigrp_read(struct thread *thread)
strlcpy(src, inet_ntoa(iph->ip_src), sizeof(src)); strlcpy(src, inet_ntoa(iph->ip_src), sizeof(src));
strlcpy(dst, inet_ntoa(iph->ip_dst), sizeof(dst)); strlcpy(dst, inet_ntoa(iph->ip_dst), sizeof(dst));
zlog_debug("Received [%s][%d/%d] length [%u] via [%s] src [%s] dst [%s]", zlog_debug(
lookup_msg(eigrp_packet_type_str, opcode, NULL), "Received [%s][%d/%d] length [%u] via [%s] src [%s] dst [%s]",
ntohl(eigrph->sequence), ntohl(eigrph->ack), length, lookup_msg(eigrp_packet_type_str, opcode, NULL),
IF_NAME(ei), src, dst); ntohl(eigrph->sequence), ntohl(eigrph->ack), length,
IF_NAME(ei), src, dst);
} }
/* Read rest of the packet and call each sort of packet routine. */ /* Read rest of the packet and call each sort of packet routine. */
@ -639,7 +639,8 @@ int eigrp_read(struct thread *thread)
eigrp_packet_free(ep); eigrp_packet_free(ep);
if ((nbr->state == EIGRP_NEIGHBOR_PENDING) if ((nbr->state == EIGRP_NEIGHBOR_PENDING)
&& (ntohl(eigrph->ack) == nbr->init_sequence_number)) { && (ntohl(eigrph->ack)
== nbr->init_sequence_number)) {
eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_UP); eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_UP);
zlog_info("Neighbor(%s) adjacency became full", zlog_info("Neighbor(%s) adjacency became full",
inet_ntoa(nbr->src)); inet_ntoa(nbr->src));
@ -647,8 +648,7 @@ int eigrp_read(struct thread *thread)
nbr->recv_sequence_number = nbr->recv_sequence_number =
ntohl(eigrph->sequence); ntohl(eigrph->sequence);
eigrp_update_send_EOT(nbr); eigrp_update_send_EOT(nbr);
} } else
else
eigrp_send_packet_reliably(nbr); eigrp_send_packet_reliably(nbr);
} }
ep = eigrp_fifo_next(nbr->multicast_queue); ep = eigrp_fifo_next(nbr->multicast_queue);
@ -875,9 +875,9 @@ void eigrp_packet_checksum(struct eigrp_interface *ei, struct stream *s,
} }
/* Make EIGRP header. */ /* Make EIGRP header. */
void eigrp_packet_header_init(int type, struct eigrp *eigrp, void eigrp_packet_header_init(int type, struct eigrp *eigrp, struct stream *s,
struct stream *s, u_int32_t flags, u_int32_t flags, u_int32_t sequence,
u_int32_t sequence, u_int32_t ack) u_int32_t ack)
{ {
struct eigrp_header *eigrph; struct eigrp_header *eigrph;
@ -1234,8 +1234,7 @@ u_int16_t eigrp_add_internalTLV_to_stream(struct stream *s,
stream_putc(s, pe->destination->u.prefix4.s_addr & 0xFF); stream_putc(s, pe->destination->u.prefix4.s_addr & 0xFF);
if (pe->destination->prefixlen > 8) if (pe->destination->prefixlen > 8)
stream_putc(s, stream_putc(s, (pe->destination->u.prefix4.s_addr >> 8) & 0xFF);
(pe->destination->u.prefix4.s_addr >> 8) & 0xFF);
if (pe->destination->prefixlen > 16) if (pe->destination->prefixlen > 16)
stream_putc(s, stream_putc(s,
(pe->destination->u.prefix4.s_addr >> 16) & 0xFF); (pe->destination->u.prefix4.s_addr >> 16) & 0xFF);

View File

@ -41,9 +41,8 @@ extern struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *,
struct eigrp_neighbor *); struct eigrp_neighbor *);
extern void eigrp_packet_free(struct eigrp_packet *); extern void eigrp_packet_free(struct eigrp_packet *);
extern void eigrp_packet_delete(struct eigrp_interface *); extern void eigrp_packet_delete(struct eigrp_interface *);
extern void eigrp_packet_header_init(int, struct eigrp *, extern void eigrp_packet_header_init(int, struct eigrp *, struct stream *,
struct stream *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
u_int32_t);
extern void eigrp_packet_checksum(struct eigrp_interface *, struct stream *, extern void eigrp_packet_checksum(struct eigrp_interface *, struct stream *,
u_int16_t); u_int16_t);
@ -84,8 +83,7 @@ extern int eigrp_hello_timer(struct thread *);
* These externs are found in eigrp_update.c * These externs are found in eigrp_update.c
*/ */
extern bool eigrp_update_prefix_apply(struct eigrp *eigrp, extern bool eigrp_update_prefix_apply(struct eigrp *eigrp,
struct eigrp_interface *ei, struct eigrp_interface *ei, int in,
int in,
struct prefix *prefix); struct prefix *prefix);
extern void eigrp_update_send(struct eigrp_interface *); extern void eigrp_update_send(struct eigrp_interface *);
extern void eigrp_update_receive(struct eigrp *, struct ip *, extern void eigrp_update_receive(struct eigrp *, struct ip *,

View File

@ -142,13 +142,13 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph,
break; break;
case EIGRP_TLV_IPv4_EXT: case EIGRP_TLV_IPv4_EXT:
/* DVS: processing of external routes needs packet and fsm work. /* DVS: processing of external routes needs packet and fsm work.
* for now, lets just not creash the box * for now, lets just not creash the box
*/ */
default: default:
length = stream_getw(s); length = stream_getw(s);
// -2 for type, -2 for len // -2 for type, -2 for len
for (length-=4; length ; length--) { for (length -= 4; length; length--) {
(void)stream_getc(s); (void)stream_getc(s);
} }
} }
@ -177,16 +177,15 @@ void eigrp_send_query(struct eigrp_interface *ei)
ep = eigrp_packet_new(ei->ifp->mtu, NULL); ep = eigrp_packet_new(ei->ifp->mtu, NULL);
/* Prepare EIGRP INIT UPDATE header */ /* Prepare EIGRP INIT UPDATE header */
eigrp_packet_header_init(EIGRP_OPC_QUERY, eigrp_packet_header_init(EIGRP_OPC_QUERY, ei->eigrp,
ei->eigrp, ep->s, 0, ep->s, 0,
ei->eigrp->sequence_number, 0); ei->eigrp->sequence_number, 0);
// encode Authentication TLV, if needed // encode Authentication TLV, if needed
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
length += length += eigrp_add_authTLV_MD5_to_stream(ep->s,
eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
ei);
} }
new_packet = false; new_packet = false;
} }

View File

@ -75,12 +75,10 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
sizeof(struct eigrp_prefix_entry)); sizeof(struct eigrp_prefix_entry));
memcpy(pe2, pe, sizeof(struct eigrp_prefix_entry)); memcpy(pe2, pe, sizeof(struct eigrp_prefix_entry));
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
EIGRP_FILTER_OUT,
pe2->destination)) { pe2->destination)) {
zlog_info("REPLY SEND: Setting Metric to max"); zlog_info("REPLY SEND: Setting Metric to max");
pe2->reported_metric.delay = EIGRP_MAX_METRIC; pe2->reported_metric.delay = EIGRP_MAX_METRIC;
} }
/* /*
@ -163,17 +161,18 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
dest_addr.u.prefix4 = tlv->destination; dest_addr.u.prefix4 = tlv->destination;
dest_addr.prefixlen = tlv->prefix_length; dest_addr.prefixlen = tlv->prefix_length;
struct eigrp_prefix_entry *dest = struct eigrp_prefix_entry *dest =
eigrp_topology_table_lookup_ipv4( eigrp_topology_table_lookup_ipv4(eigrp->topology_table,
eigrp->topology_table, &dest_addr); &dest_addr);
/* /*
* Destination must exists * Destination must exists
*/ */
if (!dest) { if (!dest) {
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
zlog_err("%s: Received prefix %s which we do not know about", zlog_err(
__PRETTY_FUNCTION__, "%s: Received prefix %s which we do not know about",
prefix2str(&dest_addr, buf, sizeof(buf))); __PRETTY_FUNCTION__,
prefix2str(&dest_addr, buf, sizeof(buf)));
eigrp_IPv4_InternalTLV_free(tlv); eigrp_IPv4_InternalTLV_free(tlv);
continue; continue;
} }
@ -182,8 +181,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
struct eigrp_nexthop_entry *entry = struct eigrp_nexthop_entry *entry =
eigrp_prefix_entry_lookup(dest->entries, nbr); eigrp_prefix_entry_lookup(dest->entries, nbr);
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN,
EIGRP_FILTER_IN,
&dest_addr)) { &dest_addr)) {
tlv->metric.delay = EIGRP_MAX_METRIC; tlv->metric.delay = EIGRP_MAX_METRIC;
} }

View File

@ -11,8 +11,7 @@
#include "if_rmap.h" #include "if_rmap.h"
extern bool eigrp_routemap_prefix_apply(struct eigrp *eigrp, extern bool eigrp_routemap_prefix_apply(struct eigrp *eigrp,
struct eigrp_interface *ei, struct eigrp_interface *ei, int in,
int in,
struct prefix *prefix); struct prefix *prefix);
extern void eigrp_route_map_update(const char *); extern void eigrp_route_map_update(const char *);
extern void eigrp_route_map_init(); extern void eigrp_route_map_init();

View File

@ -104,9 +104,8 @@ struct eigrp {
uint64_t serno; /* Global serial number counter for topology entry uint64_t serno; /* Global serial number counter for topology entry
changes*/ changes*/
uint64_t uint64_t serno_last_update; /* Highest serial number of information send
serno_last_update; /* Highest serial number of information send by last update*/
by last update*/
struct list *topology_changes_internalIPV4; struct list *topology_changes_internalIPV4;
struct list *topology_changes_externalIPV4; struct list *topology_changes_externalIPV4;
@ -140,14 +139,14 @@ struct eigrp_if_params {
u_char passive_interface; u_char passive_interface;
u_int32_t v_hello; u_int32_t v_hello;
u_int16_t v_wait; u_int16_t v_wait;
u_char type; /* type of interface */ u_char type; /* type of interface */
u_int32_t bandwidth; u_int32_t bandwidth;
u_int32_t delay; u_int32_t delay;
u_char reliability; u_char reliability;
u_char load; u_char load;
char *auth_keychain; /* Associated keychain with interface*/ char *auth_keychain; /* Associated keychain with interface*/
int auth_type; /* EIGRP authentication type */ int auth_type; /* EIGRP authentication type */
}; };
enum { MEMBER_ALLROUTERS = 0, enum { MEMBER_ALLROUTERS = 0,
@ -160,7 +159,7 @@ struct eigrp_interface {
/*multicast group refcnts */ /*multicast group refcnts */
bool member_allrouters; bool member_allrouters;
/* This interface's parent eigrp instance. */ /* This interface's parent eigrp instance. */
struct eigrp *eigrp; struct eigrp *eigrp;

View File

@ -52,7 +52,7 @@
#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_memory.h"
static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *, static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *,
struct eigrp_nexthop_entry *); struct eigrp_nexthop_entry *);
/* /*
* Returns linkedlist used as topology table * Returns linkedlist used as topology table
@ -87,7 +87,7 @@ struct eigrp_prefix_entry *eigrp_prefix_entry_new()
* Topology entry comparison * Topology entry comparison
*/ */
static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1, static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1,
struct eigrp_nexthop_entry *entry2) struct eigrp_nexthop_entry *entry2)
{ {
if (entry1->distance < entry2->distance) if (entry1->distance < entry2->distance)
return -1; return -1;
@ -142,10 +142,10 @@ void eigrp_prefix_entry_add(struct route_table *topology,
if (IS_DEBUG_EIGRP_EVENT) { if (IS_DEBUG_EIGRP_EVENT) {
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
zlog_debug("%s: %s Should we have found this entry in the topo table?", zlog_debug(
__PRETTY_FUNCTION__, "%s: %s Should we have found this entry in the topo table?",
prefix2str(pe->destination, buf, __PRETTY_FUNCTION__,
sizeof(buf))); prefix2str(pe->destination, buf, sizeof(buf)));
} }
} }
@ -157,7 +157,7 @@ void eigrp_prefix_entry_add(struct route_table *topology,
* Adding topology entry to topology node * Adding topology entry to topology node
*/ */
void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node, void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node,
struct eigrp_nexthop_entry *entry) struct eigrp_nexthop_entry *entry)
{ {
struct list *l = list_new(); struct list *l = list_new();
@ -197,8 +197,8 @@ void eigrp_prefix_entry_delete(struct route_table *table,
eigrp_zebra_route_delete(pe->destination); eigrp_zebra_route_delete(pe->destination);
rn->info = NULL; rn->info = NULL;
route_unlock_node(rn); //Lookup above route_unlock_node(rn); // Lookup above
route_unlock_node(rn); //Initial creation route_unlock_node(rn); // Initial creation
XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe); XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe);
} }
@ -206,7 +206,7 @@ void eigrp_prefix_entry_delete(struct route_table *table,
* Deleting topology entry from topology node * Deleting topology entry from topology node
*/ */
void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *node, void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *node,
struct eigrp_nexthop_entry *entry) struct eigrp_nexthop_entry *entry)
{ {
if (listnode_lookup(node->entries, entry) != NULL) { if (listnode_lookup(node->entries, entry) != NULL) {
listnode_delete(node->entries, entry); listnode_delete(node->entries, entry);
@ -355,7 +355,8 @@ struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
return prefixes; return prefixes;
} }
enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg) enum metric_change
eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg)
{ {
struct eigrp *eigrp = msg->eigrp; struct eigrp *eigrp = msg->eigrp;
struct eigrp_prefix_entry *prefix = msg->prefix; struct eigrp_prefix_entry *prefix = msg->prefix;
@ -365,7 +366,7 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag
assert(entry); assert(entry);
switch(msg->data_type) { switch (msg->data_type) {
case EIGRP_CONNECTED: case EIGRP_CONNECTED:
if (prefix->nt == EIGRP_TOPOLOGY_TYPE_CONNECTED) if (prefix->nt == EIGRP_TOPOLOGY_TYPE_CONNECTED)
return change; return change;
@ -382,8 +383,8 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag
return change; // No change return change; // No change
} }
new_reported_distance = eigrp_calculate_metrics(eigrp, new_reported_distance =
msg->metrics); eigrp_calculate_metrics(eigrp, msg->metrics);
if (entry->reported_distance < new_reported_distance) { if (entry->reported_distance < new_reported_distance) {
change = METRIC_INCREASE; change = METRIC_INCREASE;
@ -410,7 +411,7 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag
zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__); zlog_err("%s: Please implement handler", __PRETTY_FUNCTION__);
break; break;
} }
distance_done: distance_done:
/* /*
* Move to correct position in list according to new distance * Move to correct position in list according to new distance
*/ */
@ -469,8 +470,7 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix)
struct eigrp_nexthop_entry *entry; struct eigrp_nexthop_entry *entry;
if (successors) { if (successors) {
eigrp_zebra_route_add(prefix->destination, eigrp_zebra_route_add(prefix->destination, successors);
successors);
for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) for (ALL_LIST_ELEMENTS_RO(successors, node, entry))
entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG;

View File

@ -42,16 +42,15 @@ extern void eigrp_topology_cleanup(struct route_table *table);
extern void eigrp_prefix_entry_add(struct route_table *table, extern void eigrp_prefix_entry_add(struct route_table *table,
struct eigrp_prefix_entry *pe); struct eigrp_prefix_entry *pe);
extern void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *, extern void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *,
struct eigrp_nexthop_entry *); struct eigrp_nexthop_entry *);
extern void eigrp_prefix_entry_delete(struct route_table *table, extern void eigrp_prefix_entry_delete(struct route_table *table,
struct eigrp_prefix_entry *pe); struct eigrp_prefix_entry *pe);
extern void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *, extern void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *,
struct eigrp_nexthop_entry *); struct eigrp_nexthop_entry *);
extern void eigrp_topology_delete_all(struct route_table *table); extern void eigrp_topology_delete_all(struct route_table *table);
extern unsigned int eigrp_topology_table_isempty(struct list *); extern unsigned int eigrp_topology_table_isempty(struct list *);
extern struct eigrp_prefix_entry * extern struct eigrp_prefix_entry *
eigrp_topology_table_lookup_ipv4(struct route_table *table, eigrp_topology_table_lookup_ipv4(struct route_table *table, struct prefix *p);
struct prefix *p);
extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *); extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *);
extern struct list * extern struct list *
eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe, eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe,
@ -62,7 +61,8 @@ extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *,
struct eigrp_neighbor *); struct eigrp_neighbor *);
extern void eigrp_topology_update_all_node_flags(struct eigrp *); extern void eigrp_topology_update_all_node_flags(struct eigrp *);
extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *); extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *);
extern enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *); extern enum metric_change
eigrp_topology_update_distance(struct eigrp_fsm_action_message *);
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *); extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
extern void eigrp_topology_neighbor_down(struct eigrp *, extern void eigrp_topology_neighbor_down(struct eigrp *,
struct eigrp_neighbor *); struct eigrp_neighbor *);

View File

@ -63,8 +63,7 @@
#include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_network.h"
#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_memory.h"
bool eigrp_update_prefix_apply(struct eigrp *eigrp, bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei,
struct eigrp_interface *ei,
int in, struct prefix *prefix) int in, struct prefix *prefix)
{ {
struct access_list *alist; struct access_list *alist;
@ -143,9 +142,9 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp,
/* iterate over all prefixes which weren't advertised by neighbor */ /* iterate over all prefixes which weren't advertised by neighbor */
for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) { for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) {
char buffer[PREFIX_STRLEN]; char buffer[PREFIX_STRLEN];
zlog_debug("GR receive: Neighbor not advertised %s", zlog_debug(
prefix2str(prefix->destination, "GR receive: Neighbor not advertised %s",
buffer, PREFIX_STRLEN)); prefix2str(prefix->destination, buffer, PREFIX_STRLEN));
fsm_msg.metrics = prefix->reported_metric; fsm_msg.metrics = prefix->reported_metric;
/* set delay to MAX */ /* set delay to MAX */
@ -335,9 +334,9 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
/*Here comes topology information save*/ /*Here comes topology information save*/
pe = eigrp_prefix_entry_new(); pe = eigrp_prefix_entry_new();
pe->serno = eigrp->serno; pe->serno = eigrp->serno;
pe->destination = (struct prefix *)prefix_ipv4_new(); pe->destination =
prefix_copy(pe->destination, (struct prefix *)prefix_ipv4_new();
&dest_addr); prefix_copy(pe->destination, &dest_addr);
pe->af = AF_INET; pe->af = AF_INET;
pe->state = EIGRP_FSM_STATE_PASSIVE; pe->state = EIGRP_FSM_STATE_PASSIVE;
pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE; pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE;
@ -354,7 +353,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(eigrp, ei,
EIGRP_FILTER_IN, EIGRP_FILTER_IN,
&dest_addr)) &dest_addr))
ne->reported_metric.delay = EIGRP_MAX_METRIC; ne->reported_metric.delay =
EIGRP_MAX_METRIC;
ne->distance = eigrp_calculate_total_metrics( ne->distance = eigrp_calculate_total_metrics(
eigrp, ne); eigrp, ne);
@ -381,13 +381,13 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
break; break;
case EIGRP_TLV_IPv4_EXT: case EIGRP_TLV_IPv4_EXT:
/* DVS: processing of external routes needs packet and fsm work. /* DVS: processing of external routes needs packet and fsm work.
* for now, lets just not creash the box * for now, lets just not creash the box
*/ */
default: default:
length = stream_getw(s); length = stream_getw(s);
// -2 for type, -2 for len // -2 for type, -2 for len
for (length-=4; length ; length--) { for (length -= 4; length; length--) {
(void)stream_getc(s); (void)stream_getc(s);
} }
} }
@ -428,10 +428,9 @@ void eigrp_update_send_init(struct eigrp_neighbor *nbr)
nbr->ei->eigrp->sequence_number, nbr->ei->eigrp->sequence_number,
nbr->recv_sequence_number); nbr->recv_sequence_number);
eigrp_packet_header_init(EIGRP_OPC_UPDATE, nbr->ei->eigrp, eigrp_packet_header_init(
ep->s, EIGRP_INIT_FLAG, EIGRP_OPC_UPDATE, nbr->ei->eigrp, ep->s, EIGRP_INIT_FLAG,
nbr->ei->eigrp->sequence_number, nbr->ei->eigrp->sequence_number, nbr->recv_sequence_number);
nbr->recv_sequence_number);
// encode Authentication TLV, if needed // encode Authentication TLV, if needed
if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
@ -464,12 +463,11 @@ void eigrp_update_send_init(struct eigrp_neighbor *nbr)
static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr, static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr,
struct eigrp_packet *ep, struct eigrp_packet *ep,
u_int32_t seq_no, u_int32_t seq_no, int length)
int length)
{ {
if((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
(nbr->ei->params.auth_keychain != NULL)) { && (nbr->ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG); eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
} }
/* EIGRP Checksum */ /* EIGRP Checksum */
@ -541,14 +539,13 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
ep = eigrp_packet_new(mtu, nbr); ep = eigrp_packet_new(mtu, nbr);
/* Prepare EIGRP EOT UPDATE header */ /* Prepare EIGRP EOT UPDATE header */
eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s, EIGRP_EOT_FLAG,
ep->s, EIGRP_EOT_FLAG,
seq_no, nbr->recv_sequence_number); seq_no, nbr->recv_sequence_number);
// encode Authentication TLV, if needed // encode Authentication TLV, if needed
if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
(ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei); length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
} }
for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) { for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
@ -561,38 +558,40 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
continue; continue;
if ((length + EIGRP_TLV_MAX_IPV4_BYTE) > mtu) { if ((length + EIGRP_TLV_MAX_IPV4_BYTE) > mtu) {
eigrp_update_place_on_nbr_queue (nbr, ep, seq_no, length); eigrp_update_place_on_nbr_queue(nbr, ep, seq_no,
length);
seq_no++; seq_no++;
length = EIGRP_HEADER_LEN; length = EIGRP_HEADER_LEN;
ep = eigrp_packet_new(mtu, nbr); ep = eigrp_packet_new(mtu, nbr);
eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp_packet_header_init(
nbr->ei->eigrp, EIGRP_OPC_UPDATE, nbr->ei->eigrp, ep->s,
ep->s, EIGRP_EOT_FLAG, EIGRP_EOT_FLAG, seq_no,
seq_no, nbr->recv_sequence_number);
nbr->recv_sequence_number);
if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) && if ((ei->params.auth_type
(ei->params.auth_keychain != NULL)) == EIGRP_AUTH_TYPE_MD5)
{ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei); length +=
eigrp_add_authTLV_MD5_to_stream(
ep->s, ei);
} }
} }
/* Get destination address from prefix */ /* Get destination address from prefix */
dest_addr = pe->destination; dest_addr = pe->destination;
/* Check if any list fits */ /* Check if any list fits */
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(
EIGRP_FILTER_OUT, eigrp, ei, EIGRP_FILTER_OUT, dest_addr))
dest_addr))
continue; continue;
else { else {
length += eigrp_add_internalTLV_to_stream(ep->s, pe); length += eigrp_add_internalTLV_to_stream(ep->s,
pe);
} }
} }
} }
eigrp_update_place_on_nbr_queue (nbr, ep, seq_no, length); eigrp_update_place_on_nbr_queue(nbr, ep, seq_no, length);
eigrp->sequence_number = seq_no++; eigrp->sequence_number = seq_no++;
} }
@ -614,8 +613,7 @@ void eigrp_update_send(struct eigrp_interface *ei)
ep = eigrp_packet_new(ei->ifp->mtu, NULL); ep = eigrp_packet_new(ei->ifp->mtu, NULL);
/* Prepare EIGRP INIT UPDATE header */ /* Prepare EIGRP INIT UPDATE header */
eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s, 0, seq_no, 0);
ep->s, 0, seq_no, 0);
// encode Authentication TLV, if needed // encode Authentication TLV, if needed
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
@ -635,11 +633,12 @@ void eigrp_update_send(struct eigrp_interface *ei)
if (eigrp_nbr_split_horizon_check(ne, ei)) if (eigrp_nbr_split_horizon_check(ne, ei))
continue; continue;
if ((length + EIGRP_TLV_MAX_IPV4_BYTE) > if ((length + EIGRP_TLV_MAX_IPV4_BYTE)
(u_int16_t)ei->ifp->mtu) { > (u_int16_t)ei->ifp->mtu) {
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); eigrp_make_md5_digest(ei, ep->s,
EIGRP_AUTH_UPDATE_FLAG);
} }
eigrp_packet_checksum(ei, ep->s, length); eigrp_packet_checksum(ei, ep->s, length);
@ -653,25 +652,24 @@ void eigrp_update_send(struct eigrp_interface *ei)
length = EIGRP_HEADER_LEN; length = EIGRP_HEADER_LEN;
ep = eigrp_packet_new(ei->ifp->mtu, NULL); ep = eigrp_packet_new(ei->ifp->mtu, NULL);
eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp, ep->s,
ep->s, 0, seq_no, 0); 0, seq_no, 0);
if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
&& (ei->params.auth_keychain != NULL)) { && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei); length += eigrp_add_authTLV_MD5_to_stream(ep->s,
ei);
} }
has_tlv = 0; has_tlv = 0;
} }
/* Get destination address from prefix */ /* Get destination address from prefix */
dest_addr = pe->destination; dest_addr = pe->destination;
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
EIGRP_FILTER_OUT,
dest_addr)) { dest_addr)) {
// pe->reported_metric.delay = EIGRP_MAX_METRIC; // pe->reported_metric.delay = EIGRP_MAX_METRIC;
continue; continue;
} else { } else {
length += eigrp_add_internalTLV_to_stream(ep->s, length += eigrp_add_internalTLV_to_stream(ep->s, pe);
pe);
has_tlv = 1; has_tlv = 1;
} }
} }
@ -729,7 +727,8 @@ void eigrp_update_send_all(struct eigrp *eigrp,
/** /**
* @fn eigrp_update_send_GR_part * @fn eigrp_update_send_GR_part
* *
* @param[in] nbr contains neighbor who would receive Graceful * @param[in] nbr contains neighbor who would receive
* Graceful
* restart * restart
* *
* @return void * @return void
@ -814,8 +813,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
*/ */
dest_addr = pe->destination; dest_addr = pe->destination;
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
EIGRP_FILTER_OUT,
dest_addr)) { dest_addr)) {
/* do not send filtered route */ /* do not send filtered route */
zlog_info("Filtered prefix %s won't be sent out.", zlog_info("Filtered prefix %s won't be sent out.",
@ -830,8 +828,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
* This makes no sense, Filter out then filter in??? * This makes no sense, Filter out then filter in???
* Look into this more - DBS * Look into this more - DBS
*/ */
if (eigrp_update_prefix_apply(eigrp, ei, if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN,
EIGRP_FILTER_IN,
dest_addr)) { dest_addr)) {
/* do not send filtered route */ /* do not send filtered route */
zlog_info("Filtered prefix %s will be removed.", zlog_info("Filtered prefix %s will be removed.",
@ -942,7 +939,8 @@ int eigrp_update_send_GR_thread(struct thread *thread)
/** /**
* @fn eigrp_update_send_GR * @fn eigrp_update_send_GR
* *
* @param[in] nbr Neighbor who would receive Graceful * @param[in] nbr Neighbor who would receive
* Graceful
* restart * restart
* @param[in] gr_type Who executed Graceful restart * @param[in] gr_type Who executed Graceful restart
* @param[in] vty Virtual terminal for log output * @param[in] vty Virtual terminal for log output
@ -980,8 +978,7 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
vty_out(vty, vty_out(vty,
"Neighbor %s (%s) is resync: manually cleared\n", "Neighbor %s (%s) is resync: manually cleared\n",
inet_ntoa(nbr->src), inet_ntoa(nbr->src),
ifindex2ifname(ei->ifp->ifindex, ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
VRF_DEFAULT));
} }
} }
@ -1007,7 +1004,9 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
/** /**
* @fn eigrp_update_send_interface_GR * @fn eigrp_update_send_interface_GR
* *
* @param[in] ei Interface to neighbors of which the GR * @param[in] ei Interface to neighbors of which
* the
* GR
* is sent * is sent
* @param[in] gr_type Who executed Graceful restart * @param[in] gr_type Who executed Graceful restart
* @param[in] vty Virtual terminal for log output * @param[in] vty Virtual terminal for log output

View File

@ -109,8 +109,7 @@ static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp)
if (ei->params.auth_keychain) { if (ei->params.auth_keychain) {
vty_out(vty, vty_out(vty,
" ip authentication key-chain eigrp %d %s\n", " ip authentication key-chain eigrp %d %s\n",
eigrp->AS, eigrp->AS, ei->params.auth_keychain);
ei->params.auth_keychain);
} }
if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) { if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) {
@ -147,8 +146,7 @@ static int eigrp_write_interface(struct vty *vty)
vty_out(vty, " description %s\n", ifp->desc); vty_out(vty, " description %s\n", ifp->desc);
if (ei->params.bandwidth != EIGRP_BANDWIDTH_DEFAULT) if (ei->params.bandwidth != EIGRP_BANDWIDTH_DEFAULT)
vty_out(vty, " bandwidth %u\n", vty_out(vty, " bandwidth %u\n", ei->params.bandwidth);
ei->params.bandwidth);
if (ei->params.delay != EIGRP_DELAY_DEFAULT) if (ei->params.delay != EIGRP_DELAY_DEFAULT)
vty_out(vty, " delay %u\n", ei->params.delay); vty_out(vty, " delay %u\n", ei->params.delay);
if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT)
@ -495,7 +493,7 @@ DEFUN (show_ip_eigrp_topology,
& EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG)
== EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) {
show_ip_eigrp_nexthop_entry(vty, eigrp, te, show_ip_eigrp_nexthop_entry(vty, eigrp, te,
&first); &first);
first = 0; first = 0;
} }
} }
@ -777,8 +775,7 @@ DEFUN (no_eigrp_if_ip_hellointerval,
ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
THREAD_TIMER_OFF(ei->t_hello); THREAD_TIMER_OFF(ei->t_hello);
thread_add_timer(master, eigrp_hello_timer, ei, 1, thread_add_timer(master, eigrp_hello_timer, ei, 1, &ei->t_hello);
&ei->t_hello);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1008,11 +1005,9 @@ DEFUN (eigrp_authentication_keychain,
if (keychain != NULL) { if (keychain != NULL) {
if (ei->params.auth_keychain) { if (ei->params.auth_keychain) {
free(ei->params.auth_keychain); free(ei->params.auth_keychain);
ei->params.auth_keychain = ei->params.auth_keychain = strdup(keychain->name);
strdup(keychain->name);
} else } else
ei->params.auth_keychain = ei->params.auth_keychain = strdup(keychain->name);
strdup(keychain->name);
} else } else
vty_out(vty, "Key chain with specified name not found\n"); vty_out(vty, "Key chain with specified name not found\n");
@ -1339,8 +1334,7 @@ DEFUN (clear_ip_eigrp_neighbors_IP,
struct in_addr nbr_addr; struct in_addr nbr_addr;
if (!inet_aton(argv[4]->arg, &nbr_addr)) { if (!inet_aton(argv[4]->arg, &nbr_addr)) {
vty_out(vty, "Unable to parse %s", vty_out(vty, "Unable to parse %s", argv[4]->arg);
argv[4]->arg);
return CMD_WARNING; return CMD_WARNING;
} }
@ -1446,8 +1440,7 @@ DEFUN (clear_ip_eigrp_neighbors_IP_soft,
struct in_addr nbr_addr; struct in_addr nbr_addr;
if (!inet_aton(argv[4]->arg, &nbr_addr)) { if (!inet_aton(argv[4]->arg, &nbr_addr)) {
vty_out(vty, "Unable to parse: %s", vty_out(vty, "Unable to parse: %s", argv[4]->arg);
argv[4]->arg);
return CMD_WARNING; return CMD_WARNING;
} }

View File

@ -114,7 +114,7 @@ static void eigrp_zebra_connected(struct zclient *zclient)
void eigrp_zebra_init(void) void eigrp_zebra_init(void)
{ {
struct zclient_options opt = { .receive_notify = false }; struct zclient_options opt = {.receive_notify = false};
zclient = zclient_new_notify(master, &opt); zclient = zclient_new_notify(master, &opt);
@ -205,8 +205,7 @@ static int eigrp_interface_delete(int command, struct zclient *zclient,
ifp->metric, ifp->mtu); ifp->metric, ifp->mtu);
if (ifp->info) if (ifp->info)
eigrp_if_free(ifp->info, eigrp_if_free(ifp->info, INTERFACE_DOWN_BY_ZEBRA);
INTERFACE_DOWN_BY_ZEBRA);
if_set_index(ifp, IFINDEX_INTERNAL); if_set_index(ifp, IFINDEX_INTERNAL);
return 0; return 0;

74
include/linux/fib_rules.h Normal file
View File

@ -0,0 +1,74 @@
#ifndef __LINUX_FIB_RULES_H
#define __LINUX_FIB_RULES_H
#include <linux/types.h>
#include <linux/rtnetlink.h>
/* rule is permanent, and cannot be deleted */
#define FIB_RULE_PERMANENT 0x00000001
#define FIB_RULE_INVERT 0x00000002
#define FIB_RULE_UNRESOLVED 0x00000004
#define FIB_RULE_IIF_DETACHED 0x00000008
#define FIB_RULE_DEV_DETACHED FIB_RULE_IIF_DETACHED
#define FIB_RULE_OIF_DETACHED 0x00000010
/* try to find source address in routing lookups */
#define FIB_RULE_FIND_SADDR 0x00010000
struct fib_rule_hdr {
__u8 family;
__u8 dst_len;
__u8 src_len;
__u8 tos;
__u8 table;
__u8 res1; /* reserved */
__u8 res2; /* reserved */
__u8 action;
__u32 flags;
};
enum {
FRA_UNSPEC,
FRA_DST, /* destination address */
FRA_SRC, /* source address */
FRA_IIFNAME, /* interface name */
#define FRA_IFNAME FRA_IIFNAME
FRA_GOTO, /* target to jump to (FR_ACT_GOTO) */
FRA_UNUSED2,
FRA_PRIORITY, /* priority/preference */
FRA_UNUSED3,
FRA_UNUSED4,
FRA_UNUSED5,
FRA_FWMARK, /* mark */
FRA_FLOW, /* flow/class id */
FRA_UNUSED6,
FRA_SUPPRESS_IFGROUP,
FRA_SUPPRESS_PREFIXLEN,
FRA_TABLE, /* Extended table id */
FRA_FWMASK, /* mask for netfilter mark */
FRA_OIFNAME,
FRA_PAD,
FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
__FRA_MAX
};
#define FRA_MAX (__FRA_MAX - 1)
enum {
FR_ACT_UNSPEC,
FR_ACT_TO_TBL, /* Pass to fixed table */
FR_ACT_GOTO, /* Jump to another rule */
FR_ACT_NOP, /* No operation */
FR_ACT_RES3,
FR_ACT_RES4,
FR_ACT_BLACKHOLE, /* Drop without notification */
FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */
FR_ACT_PROHIBIT, /* Drop with EACCES */
__FR_ACT_MAX,
};
#define FR_ACT_MAX (__FR_ACT_MAX - 1)
#endif

View File

@ -7,4 +7,5 @@ noinst_HEADERS += \
include/linux/rtnetlink.h \ include/linux/rtnetlink.h \
include/linux/socket.h \ include/linux/socket.h \
include/linux/net_namespace.h \ include/linux/net_namespace.h \
include/linux/fib_rules.h \
# end # end

View File

@ -437,10 +437,10 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
for (unsigned int i = 0; i < adj->area_address_count; for (unsigned int i = 0; i < adj->area_address_count;
i++) { i++) {
vty_out(vty, " %s\n", vty_out(vty, " %s\n",
isonet_print(adj->area_addresses[i] isonet_print(adj->area_addresses[i]
.area_addr, .area_addr,
adj->area_addresses[i] adj->area_addresses[i]
.addr_len)); .addr_len));
} }
} }
if (adj->ipv4_address_count) { if (adj->ipv4_address_count) {
@ -448,7 +448,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
for (unsigned int i = 0; i < adj->ipv4_address_count; for (unsigned int i = 0; i < adj->ipv4_address_count;
i++) i++)
vty_out(vty, " %s\n", vty_out(vty, " %s\n",
inet_ntoa(adj->ipv4_addresses[i])); inet_ntoa(adj->ipv4_addresses[i]));
} }
if (adj->ipv6_address_count) { if (adj->ipv6_address_count) {
vty_out(vty, " IPv6 Address(es):\n"); vty_out(vty, " IPv6 Address(es):\n");

View File

@ -248,8 +248,7 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa)
bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN); bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
stream_set_getp(circuit->rcv_stream, 0); stream_set_getp(circuit->rcv_stream, 0);
memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETH_ALEN, memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETH_ALEN, ETH_ALEN);
ETH_ALEN);
if (ioctl(circuit->fd, BIOCFLUSH, &one) < 0) if (ioctl(circuit->fd, BIOCFLUSH, &one) < 0)
zlog_warn("Flushing failed: %s", safe_strerror(errno)); zlog_warn("Flushing failed: %s", safe_strerror(errno));

View File

@ -382,10 +382,12 @@ static uint8_t isis_circuit_id_gen(struct interface *ifp)
/* Circuit ids MUST be unique for any broadcast circuits. Otherwise, /* Circuit ids MUST be unique for any broadcast circuits. Otherwise,
* Pseudo-Node LSPs cannot be generated correctly. * Pseudo-Node LSPs cannot be generated correctly.
* *
* Currently, allocate one circuit ID for any circuit, limiting the total * Currently, allocate one circuit ID for any circuit, limiting the
* total
* numer of circuits IS-IS can run on to 255. * numer of circuits IS-IS can run on to 255.
* *
* We should revisit this when implementing 3-way adjacencies for p2p, since * We should revisit this when implementing 3-way adjacencies for p2p,
* since
* we then have extended interface IDs available. * we then have extended interface IDs available.
*/ */
uint8_t id = ifp->ifindex; uint8_t id = ifp->ifindex;
@ -398,7 +400,8 @@ static uint8_t isis_circuit_id_gen(struct interface *ifp)
} }
if (i == 256) { if (i == 256) {
zlog_warn("Could not allocate a circuit id for '%s'", ifp->name); zlog_warn("Could not allocate a circuit id for '%s'",
ifp->name);
return 0; return 0;
} }
@ -1349,7 +1352,8 @@ void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit)
{ {
if (circuit->t_send_lsp) if (circuit->t_send_lsp)
return; return;
circuit->t_send_lsp = thread_add_event(master, send_lsp, circuit, 0, NULL); circuit->t_send_lsp =
thread_add_event(master, send_lsp, circuit, 0, NULL);
} }
void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp) void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp)

View File

@ -82,8 +82,9 @@ struct isis_circuit {
struct thread *t_send_csnp[2]; struct thread *t_send_csnp[2];
struct thread *t_send_psnp[2]; struct thread *t_send_psnp[2];
struct thread *t_send_lsp; struct thread *t_send_lsp;
struct list *lsp_queue; /* LSPs to be txed (both levels) */ struct list *lsp_queue; /* LSPs to be txed (both levels) */
struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */ struct isis_lsp_hash
*lsp_hash; /* Hashtable synchronized with lsp_queue */
time_t lsp_queue_last_push[2]; /* timestamp used to enforce transmit time_t lsp_queue_last_push[2]; /* timestamp used to enforce transmit
* interval; * interval;
* for scalability, use one timestamp per * for scalability, use one timestamp per
@ -96,8 +97,6 @@ struct isis_circuit {
int (*tx)(struct isis_circuit *circuit, int level); int (*tx)(struct isis_circuit *circuit, int level);
struct stream *snd_stream; /* Stream for sending */ struct stream *snd_stream; /* Stream for sending */
int idx; /* idx in S[RM|SN] flags */ int idx; /* idx in S[RM|SN] flags */
/* $FRR indent$ */
/* clang-format off */
#define CIRCUIT_T_UNKNOWN 0 #define CIRCUIT_T_UNKNOWN 0
#define CIRCUIT_T_BROADCAST 1 #define CIRCUIT_T_BROADCAST 1
#define CIRCUIT_T_P2P 2 #define CIRCUIT_T_P2P 2
@ -185,7 +184,7 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
bool ipv6_router); bool ipv6_router);
ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive); ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive);
void isis_circuit_is_type_set(struct isis_circuit *circuit, int is_type); void isis_circuit_is_type_set(struct isis_circuit *circuit, int is_type);
ferr_r isis_circuit_circ_type_set (struct isis_circuit *circuit, int circ_type); ferr_r isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type);
ferr_r isis_circuit_metric_set(struct isis_circuit *circuit, int level, ferr_r isis_circuit_metric_set(struct isis_circuit *circuit, int level,
int metric); int metric);

View File

@ -41,20 +41,18 @@ long int flags_get_index(struct flags *flags);
void flags_free_index(struct flags *flags, long int index); void flags_free_index(struct flags *flags, long int index);
int flags_any_set(u_int32_t *flags); int flags_any_set(u_int32_t *flags);
#define _ISIS_SET_FLAG(F, C) \ #define _ISIS_SET_FLAG(F, C) \
{ \ { \
F[(C) >> 5] |= (1 << ((C) & 0x1F)); \ F[(C) >> 5] |= (1 << ((C)&0x1F)); \
} }
#define ISIS_SET_FLAG(F, C) _ISIS_SET_FLAG(F, C->idx) #define ISIS_SET_FLAG(F, C) _ISIS_SET_FLAG(F, C->idx)
#define _ISIS_CLEAR_FLAG(F, C) \
#define _ISIS_CLEAR_FLAG(F, C) \ { \
{ \ F[(C) >> 5] &= ~(1 << ((C)&0x1F)); \
F[(C) >> 5] &= ~(1 << ((C) & 0x1F)); \
} }
#define ISIS_CLEAR_FLAG(F, C) _ISIS_CLEAR_FLAG(F, C->idx) #define ISIS_CLEAR_FLAG(F, C) _ISIS_CLEAR_FLAG(F, C->idx)
#define _ISIS_CHECK_FLAG(F, C) (F[(C)>>5] & (1<<((C) & 0x1F))) #define _ISIS_CHECK_FLAG(F, C) (F[(C)>>5] & (1<<((C) & 0x1F)))
#define ISIS_CHECK_FLAG(F, C) _ISIS_CHECK_FLAG(F, C->idx) #define ISIS_CHECK_FLAG(F, C) _ISIS_CHECK_FLAG(F, C->idx)

View File

@ -1106,7 +1106,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
struct list *fragments = isis_fragment_tlvs(tlvs, tlv_space); struct list *fragments = isis_fragment_tlvs(tlvs, tlv_space);
if (!fragments) { if (!fragments) {
zlog_warn("BUG: could not fragment own LSP:"); zlog_warn("BUG: could not fragment own LSP:");
log_multiline(LOG_WARNING, " ", "%s", isis_format_tlvs(tlvs)); log_multiline(LOG_WARNING, " ", "%s",
isis_format_tlvs(tlvs));
isis_free_tlvs(tlvs); isis_free_tlvs(tlvs);
return; return;
} }
@ -1119,8 +1120,9 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
if (LSP_FRAGMENT(frag->hdr.lsp_id) == 255) { if (LSP_FRAGMENT(frag->hdr.lsp_id) == 255) {
if (!fragment_overflow) { if (!fragment_overflow) {
fragment_overflow = true; fragment_overflow = true;
zlog_warn("ISIS (%s): Too much information for 256 fragments", zlog_warn(
area->area_tag); "ISIS (%s): Too much information for 256 fragments",
area->area_tag);
} }
isis_free_tlvs(tlvs); isis_free_tlvs(tlvs);
continue; continue;
@ -1794,7 +1796,7 @@ int lsp_tick(struct thread *thread)
dnode_t *dnode, *dnode_next; dnode_t *dnode, *dnode_next;
int level; int level;
u_int16_t rem_lifetime; u_int16_t rem_lifetime;
time_t now = monotime(NULL); time_t now = monotime(NULL);
lsp_list = list_new(); lsp_list = list_new();
@ -1873,12 +1875,15 @@ int lsp_tick(struct thread *thread)
if (!circuit->lsp_queue) if (!circuit->lsp_queue)
continue; continue;
if (now - circuit->lsp_queue_last_push[level] if (now
- circuit->lsp_queue_last_push
[level]
< MIN_LSP_RETRANS_INTERVAL) { < MIN_LSP_RETRANS_INTERVAL) {
continue; continue;
} }
circuit->lsp_queue_last_push[level] = now; circuit->lsp_queue_last_push[level] =
now;
for (ALL_LIST_ELEMENTS_RO( for (ALL_LIST_ELEMENTS_RO(
lsp_list, lspnode, lsp)) { lsp_list, lspnode, lsp)) {
@ -1887,7 +1892,8 @@ int lsp_tick(struct thread *thread)
&& ISIS_CHECK_FLAG( && ISIS_CHECK_FLAG(
lsp->SRMflags, lsp->SRMflags,
circuit)) { circuit)) {
isis_circuit_queue_lsp(circuit, lsp); isis_circuit_queue_lsp(
circuit, lsp);
} }
} }
} }

View File

@ -71,7 +71,7 @@ void isis_lsp_hash_free(struct isis_lsp_hash *ih)
} }
struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih, struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
struct isis_lsp *lsp) struct isis_lsp *lsp)
{ {
return hash_lookup(ih->h, lsp); return hash_lookup(ih->h, lsp);
} }

View File

@ -887,11 +887,10 @@ dontcheckadj:
lsp_set_all_srmflags(lsp); lsp_set_all_srmflags(lsp);
/* v */ /* v */
ISIS_FLAGS_CLEAR_ALL( ISIS_FLAGS_CLEAR_ALL(
lsp lsp->SSNflags); /* FIXME:
->SSNflags); /* FIXME: OTHER
OTHER than c
than c */
*/
/* For the case of lsp confusion, flood /* For the case of lsp confusion, flood
* the purge back to its * the purge back to its
@ -1185,7 +1184,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
entry = entry->next) { entry = entry->next) {
zlog_debug( zlog_debug(
"ISIS-Snp (%s): %cSNP entry %s, seq 0x%08" PRIx32 "ISIS-Snp (%s): %cSNP entry %s, seq 0x%08" PRIx32
", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 "s", ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
"s",
circuit->area->area_tag, typechar, circuit->area->area_tag, typechar,
rawlspid_print(entry->id), entry->seqno, rawlspid_print(entry->id), entry->seqno,
entry->checksum, entry->rem_lifetime); entry->checksum, entry->rem_lifetime);
@ -1244,10 +1244,12 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
ISIS_SYS_ID_LEN + 1); ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lspid) = 0; LSP_FRAGMENT(lspid) = 0;
lsp0 = lsp_search( lsp0 = lsp_search(
lspid, lspid,
circuit->area->lspdb[level - 1]); circuit->area
->lspdb[level - 1]);
if (!lsp0) { if (!lsp0) {
zlog_debug("Got lsp frag in snp, while zero not in database"); zlog_debug(
"Got lsp frag in snp, while zero not in database");
continue; continue;
} }
} }

View File

@ -45,17 +45,16 @@
#include "privs.h" #include "privs.h"
/* tcpdump -i eth0 'isis' -dd */ /* tcpdump -i eth0 'isis' -dd */
static struct sock_filter isisfilter[] = static struct sock_filter isisfilter[] = {
{ /* NB: we're in SOCK_DGRAM, so src/dst mac + length are stripped
/* NB: we're in SOCK_DGRAM, so src/dst mac + length are stripped * off!
* off! * (OTOH it's a bit more lower-layer agnostic and might work
* (OTOH it's a bit more lower-layer agnostic and might work * over GRE?) */
* over GRE?) */ /* { 0x28, 0, 0, 0x0000000c - 14 }, */
/* { 0x28, 0, 0, 0x0000000c - 14 }, */ /* { 0x25, 5, 0, 0x000005dc }, */
/* { 0x25, 5, 0, 0x000005dc }, */ {0x28, 0, 0, 0x0000000e - 14}, {0x15, 0, 3, 0x0000fefe},
{0x28, 0, 0, 0x0000000e - 14}, {0x15, 0, 3, 0x0000fefe}, {0x30, 0, 0, 0x00000011 - 14}, {0x15, 0, 1, 0x00000083},
{0x30, 0, 0, 0x00000011 - 14}, {0x15, 0, 1, 0x00000083}, {0x6, 0, 0, 0x00040000}, {0x6, 0, 0, 0x00000000},
{0x6, 0, 0, 0x00040000}, {0x6, 0, 0, 0x00000000},
}; };
static struct sock_fprog bpf = { static struct sock_fprog bpf = {

View File

@ -85,10 +85,10 @@ struct isis_vertex {
struct prefix prefix; struct prefix prefix;
} N; } N;
u_int32_t d_N; /* d(N) Distance from this IS */ u_int32_t d_N; /* d(N) Distance from this IS */
u_int16_t depth; /* The depth in the imaginary tree */ u_int16_t depth; /* The depth in the imaginary tree */
struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */ struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */
struct list *parents; /* list of parents for ECMP */ struct list *parents; /* list of parents for ECMP */
uint64_t insert_counter; uint64_t insert_counter;
}; };
@ -161,7 +161,8 @@ static struct skiplist *isis_vertex_queue_skiplist(void)
return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL); return skiplist_new(0, isis_vertex_queue_tent_cmp, NULL);
} }
static void isis_vertex_queue_init(struct isis_vertex_queue *queue, const char *name, bool ordered) static void isis_vertex_queue_init(struct isis_vertex_queue *queue,
const char *name, bool ordered)
{ {
if (ordered) { if (ordered) {
queue->insert_counter = 1; queue->insert_counter = 1;
@ -171,8 +172,7 @@ static void isis_vertex_queue_init(struct isis_vertex_queue *queue, const char *
queue->l.list = list_new(); queue->l.list = list_new();
} }
queue->hash = hash_create(isis_vertex_queue_hash_key, queue->hash = hash_create(isis_vertex_queue_hash_key,
isis_vertex_queue_hash_cmp, isis_vertex_queue_hash_cmp, name);
name);
} }
static void isis_vertex_del(struct isis_vertex *vertex); static void isis_vertex_del(struct isis_vertex *vertex);
@ -183,7 +183,8 @@ static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
if (queue->insert_counter) { if (queue->insert_counter) {
struct isis_vertex *vertex; struct isis_vertex *vertex;
while (0 == skiplist_first(queue->l.slist, NULL, (void**)&vertex)) { while (0 == skiplist_first(queue->l.slist, NULL,
(void **)&vertex)) {
isis_vertex_del(vertex); isis_vertex_del(vertex);
skiplist_delete_first(queue->l.slist); skiplist_delete_first(queue->l.slist);
} }
@ -241,13 +242,14 @@ static void isis_vertex_queue_insert(struct isis_vertex_queue *queue,
assert(inserted == vertex); assert(inserted == vertex);
} }
static struct isis_vertex *isis_vertex_queue_pop(struct isis_vertex_queue *queue) static struct isis_vertex *
isis_vertex_queue_pop(struct isis_vertex_queue *queue)
{ {
assert(queue->insert_counter); assert(queue->insert_counter);
struct isis_vertex *rv; struct isis_vertex *rv;
if (skiplist_first(queue->l.slist, NULL, (void**)&rv)) if (skiplist_first(queue->l.slist, NULL, (void **)&rv))
return NULL; return NULL;
skiplist_delete_first(queue->l.slist); skiplist_delete_first(queue->l.slist);
@ -265,8 +267,8 @@ static void isis_vertex_queue_delete(struct isis_vertex_queue *queue,
hash_release(queue->hash, vertex); hash_release(queue->hash, vertex);
} }
#define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \ #define ALL_QUEUE_ELEMENTS_RO(queue, node, data) \
ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data) ALL_LIST_ELEMENTS_RO((queue)->l.list, node, data)
/* End of vertex queue definitions */ /* End of vertex queue definitions */
@ -274,11 +276,12 @@ static void isis_vertex_queue_delete(struct isis_vertex_queue *queue,
struct isis_spftree { struct isis_spftree {
struct isis_vertex_queue paths; /* the SPT */ struct isis_vertex_queue paths; /* the SPT */
struct isis_vertex_queue tents; /* TENT */ struct isis_vertex_queue tents; /* TENT */
struct isis_area *area; /* back pointer to area */ struct isis_area *area; /* back pointer to area */
unsigned int runcount; /* number of runs since uptime */ unsigned int runcount; /* number of runs since uptime */
time_t last_run_timestamp; /* last run timestamp as wall time for display */ time_t last_run_timestamp; /* last run timestamp as wall time for
time_t last_run_monotime; /* last run as monotime for scheduling */ display */
time_t last_run_duration; /* last run duration in msec */ time_t last_run_monotime; /* last run as monotime for scheduling */
time_t last_run_duration; /* last run duration in msec */
uint16_t mtid; uint16_t mtid;
int family; int family;
@ -405,7 +408,8 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
return "UNKNOWN"; return "UNKNOWN";
} }
static void isis_vertex_id_init(struct isis_vertex *vertex, void *id, enum vertextype vtype) static void isis_vertex_id_init(struct isis_vertex *vertex, void *id,
enum vertextype vtype)
{ {
vertex->type = vtype; vertex->type = vtype;
@ -621,8 +625,8 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
return vertex; return vertex;
} }
static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue, void *id, static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
enum vertextype vtype) void *id, enum vertextype vtype)
{ {
struct isis_vertex querier; struct isis_vertex querier;
@ -827,10 +831,10 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
return ISIS_OK; return ISIS_OK;
/* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */ /* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
bool no_overload = (pseudo_lsp bool no_overload =
|| (spftree->mtid == ISIS_MT_IPV4_UNICAST (pseudo_lsp || (spftree->mtid == ISIS_MT_IPV4_UNICAST
&& !ISIS_MASK_LSP_OL_BIT(lsp->hdr.lsp_bits)) && !ISIS_MASK_LSP_OL_BIT(lsp->hdr.lsp_bits))
|| (mt_router_info && !mt_router_info->overload)); || (mt_router_info && !mt_router_info->overload));
lspfragloop: lspfragloop:
if (lsp->hdr.seqno == 0) { if (lsp->hdr.seqno == 0) {
@ -1372,10 +1376,10 @@ static int isis_run_spf_cb(struct thread *thread)
if (area->ip_circuits) if (area->ip_circuits)
retval = isis_run_spf(area, level, AF_INET, isis->sysid, retval = isis_run_spf(area, level, AF_INET, isis->sysid,
&thread->real); &thread->real);
if (area->ipv6_circuits) if (area->ipv6_circuits)
retval = isis_run_spf(area, level, AF_INET6, isis->sysid, retval = isis_run_spf(area, level, AF_INET6, isis->sysid,
&thread->real); &thread->real);
return retval; return retval;
} }
@ -1426,7 +1430,8 @@ int isis_spf_schedule(struct isis_area *area, int level)
/* wait configured min_spf_interval before doing the SPF */ /* wait configured min_spf_interval before doing the SPF */
long timer; long timer;
if (diff >= area->min_spf_interval[level - 1]) { if (diff >= area->min_spf_interval[level - 1]) {
/* Last run is more than min interval ago, schedule immediate run */ /* Last run is more than min interval ago, schedule immediate
* run */
timer = 0; timer = 0;
} else { } else {
timer = area->min_spf_interval[level - 1] - diff; timer = area->min_spf_interval[level - 1] - diff;
@ -1469,9 +1474,9 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue,
vty_out(vty, "%-20s %-12s %-6u ", vty_out(vty, "%-20s %-12s %-6u ",
vid2string(vertex, buff, sizeof(buff)), vid2string(vertex, buff, sizeof(buff)),
vtype2string(vertex->type), vertex->d_N); vtype2string(vertex->type), vertex->d_N);
for (unsigned int i = 0; for (unsigned int i = 0; i < MAX(listcount(vertex->Adj_N),
i < MAX(listcount(vertex->Adj_N), listcount(vertex->parents));
listcount(vertex->parents)); i++) { i++) {
if (anode) { if (anode) {
adj = listgetdata(anode); adj = listgetdata(anode);
anode = anode->next; anode = anode->next;
@ -1502,8 +1507,7 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue,
vty_out(vty, "%-20s %-9s ", "", ""); vty_out(vty, "%-20s %-9s ", "", "");
vty_out(vty, "%s(%d)", vty_out(vty, "%s(%d)",
vid2string(pvertex, buff, vid2string(pvertex, buff, sizeof(buff)),
sizeof(buff)),
pvertex->type); pvertex->type);
} }
@ -1545,7 +1549,9 @@ DEFUN (show_isis_topology,
continue; continue;
if (area->ip_circuits > 0 && area->spftree[level - 1] if (area->ip_circuits > 0 && area->spftree[level - 1]
&& isis_vertex_queue_count(&area->spftree[level - 1]->paths) > 0) { && isis_vertex_queue_count(
&area->spftree[level - 1]->paths)
> 0) {
vty_out(vty, vty_out(vty,
"IS-IS paths to level-%d routers that speak IP\n", "IS-IS paths to level-%d routers that speak IP\n",
level); level);
@ -1555,7 +1561,9 @@ DEFUN (show_isis_topology,
vty_out(vty, "\n"); vty_out(vty, "\n");
} }
if (area->ipv6_circuits > 0 && area->spftree6[level - 1] if (area->ipv6_circuits > 0 && area->spftree6[level - 1]
&& isis_vertex_queue_count(&area->spftree6[level - 1]->paths) > 0) { && isis_vertex_queue_count(
&area->spftree6[level - 1]->paths)
> 0) {
vty_out(vty, vty_out(vty,
"IS-IS paths to level-%d routers that speak IPv6\n", "IS-IS paths to level-%d routers that speak IPv6\n",
level); level);
@ -1586,6 +1594,5 @@ void isis_spf_print(struct isis_spftree *spftree, struct vty *vty)
vty_out(vty, " last run duration : %u usec\n", vty_out(vty, " last run duration : %u usec\n",
(u_int32_t)spftree->last_run_duration); (u_int32_t)spftree->last_run_duration);
vty_out(vty, " run count : %u\n", vty_out(vty, " run count : %u\n", spftree->runcount);
spftree->runcount);
} }

View File

@ -725,7 +725,8 @@ static u_char print_subtlv_max_rsv_bw(struct sbuf *buf, int indent,
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
sbuf_push(buf, indent, "Maximum Reservable Bandwidth: %g (Bytes/sec)\n", fval); sbuf_push(buf, indent, "Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
@ -741,8 +742,9 @@ static u_char print_subtlv_unrsv_bw(struct sbuf *buf, int indent,
for (i = 0; i < MAX_CLASS_TYPE; i += 2) { for (i = 0; i < MAX_CLASS_TYPE; i += 2) {
fval1 = ntohf(tlv->value[i]); fval1 = ntohf(tlv->value[i]);
fval2 = ntohf(tlv->value[i + 1]); fval2 = ntohf(tlv->value[i + 1]);
sbuf_push(buf, indent + 2, "[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", sbuf_push(buf, indent + 2,
i, fval1, i + 1, fval2); "[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n", i,
fval1, i + 1, fval2);
} }
return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE); return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE);
@ -786,7 +788,8 @@ static u_char print_subtlv_av_delay(struct sbuf *buf, int indent,
delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL; A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
sbuf_push(buf, indent, "%s Average Link Delay: %" PRIu32 " (micro-sec)\n", sbuf_push(buf, indent,
"%s Average Link Delay: %" PRIu32 " (micro-sec)\n",
A ? "Anomalous" : "Normal", delay); A ? "Anomalous" : "Normal", delay);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
@ -802,7 +805,8 @@ static u_char print_subtlv_mm_delay(struct sbuf *buf, int indent,
A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL; A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL;
high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK; high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK;
sbuf_push(buf, indent, "%s Min/Max Link Delay: %" PRIu32 " / %" PRIu32 " (micro-sec)\n", sbuf_push(buf, indent, "%s Min/Max Link Delay: %" PRIu32 " / %" PRIu32
" (micro-sec)\n",
A ? "Anomalous" : "Normal", low, high); A ? "Anomalous" : "Normal", low, high);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
@ -815,7 +819,8 @@ static u_char print_subtlv_delay_var(struct sbuf *buf, int indent,
jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
sbuf_push(buf, indent, "Delay Variation: %" PRIu32 " (micro-sec)\n", jitter); sbuf_push(buf, indent, "Delay Variation: %" PRIu32 " (micro-sec)\n",
jitter);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
@ -844,8 +849,8 @@ static u_char print_subtlv_res_bw(struct sbuf *buf, int indent,
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
sbuf_push(buf, indent, "Unidirectional Residual Bandwidth: %g (Bytes/sec)\n", sbuf_push(buf, indent,
fval); "Unidirectional Residual Bandwidth: %g (Bytes/sec)\n", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
@ -857,8 +862,8 @@ static u_char print_subtlv_ava_bw(struct sbuf *buf, int indent,
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
sbuf_push(buf, indent, "Unidirectional Available Bandwidth: %g (Bytes/sec)\n", sbuf_push(buf, indent,
fval); "Unidirectional Available Bandwidth: %g (Bytes/sec)\n", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
@ -870,8 +875,8 @@ static u_char print_subtlv_use_bw(struct sbuf *buf, int indent,
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
sbuf_push(buf, indent, "Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n", sbuf_push(buf, indent,
fval); "Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
@ -892,8 +897,7 @@ static u_char print_unknown_tlv(struct sbuf *buf, int indent,
sbuf_push(buf, 0, " %#.2x", v[i]); sbuf_push(buf, 0, " %#.2x", v[i]);
if (rtn == 8) { if (rtn == 8) {
sbuf_push(buf, 0, "\n"); sbuf_push(buf, 0, "\n");
sbuf_push(buf, indent + 8, sbuf_push(buf, indent + 8, "[%.2x]", i + 1);
"[%.2x]", i + 1);
rtn = 1; rtn = 1;
} else } else
rtn++; rtn++;
@ -909,8 +913,8 @@ static u_char print_unknown_tlv(struct sbuf *buf, int indent,
} }
/* Main Show function */ /* Main Show function */
void mpls_te_print_detail(struct sbuf *buf, int indent, void mpls_te_print_detail(struct sbuf *buf, int indent, uint8_t *subtlvs,
uint8_t *subtlvs, uint8_t subtlv_len) uint8_t subtlv_len)
{ {
struct subtlv_header *tlvh = (struct subtlv_header *)subtlvs; struct subtlv_header *tlvh = (struct subtlv_header *)subtlvs;
uint16_t sum = 0; uint16_t sum = 0;
@ -918,72 +922,78 @@ void mpls_te_print_detail(struct sbuf *buf, int indent,
for (; sum < subtlv_len; tlvh = SUBTLV_HDR_NEXT(tlvh)) { for (; sum < subtlv_len; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
switch (tlvh->type) { switch (tlvh->type) {
case TE_SUBTLV_ADMIN_GRP: case TE_SUBTLV_ADMIN_GRP:
sum += print_subtlv_admin_grp(buf, indent, sum += print_subtlv_admin_grp(
buf, indent,
(struct te_subtlv_admin_grp *)tlvh); (struct te_subtlv_admin_grp *)tlvh);
break; break;
case TE_SUBTLV_LLRI: case TE_SUBTLV_LLRI:
sum += print_subtlv_llri(buf, indent, sum += print_subtlv_llri(buf, indent,
(struct te_subtlv_llri *)tlvh); (struct te_subtlv_llri *)tlvh);
break; break;
case TE_SUBTLV_LOCAL_IPADDR: case TE_SUBTLV_LOCAL_IPADDR:
sum += print_subtlv_local_ipaddr(buf, indent, sum += print_subtlv_local_ipaddr(
buf, indent,
(struct te_subtlv_local_ipaddr *)tlvh); (struct te_subtlv_local_ipaddr *)tlvh);
break; break;
case TE_SUBTLV_RMT_IPADDR: case TE_SUBTLV_RMT_IPADDR:
sum += print_subtlv_rmt_ipaddr(buf, indent, sum += print_subtlv_rmt_ipaddr(
buf, indent,
(struct te_subtlv_rmt_ipaddr *)tlvh); (struct te_subtlv_rmt_ipaddr *)tlvh);
break; break;
case TE_SUBTLV_MAX_BW: case TE_SUBTLV_MAX_BW:
sum += print_subtlv_max_bw(buf, indent, sum += print_subtlv_max_bw(
(struct te_subtlv_max_bw *)tlvh); buf, indent, (struct te_subtlv_max_bw *)tlvh);
break; break;
case TE_SUBTLV_MAX_RSV_BW: case TE_SUBTLV_MAX_RSV_BW:
sum += print_subtlv_max_rsv_bw(buf, indent, sum += print_subtlv_max_rsv_bw(
buf, indent,
(struct te_subtlv_max_rsv_bw *)tlvh); (struct te_subtlv_max_rsv_bw *)tlvh);
break; break;
case TE_SUBTLV_UNRSV_BW: case TE_SUBTLV_UNRSV_BW:
sum += print_subtlv_unrsv_bw(buf, indent, sum += print_subtlv_unrsv_bw(
(struct te_subtlv_unrsv_bw *)tlvh); buf, indent, (struct te_subtlv_unrsv_bw *)tlvh);
break; break;
case TE_SUBTLV_TE_METRIC: case TE_SUBTLV_TE_METRIC:
sum += print_subtlv_te_metric(buf, indent, sum += print_subtlv_te_metric(
buf, indent,
(struct te_subtlv_te_metric *)tlvh); (struct te_subtlv_te_metric *)tlvh);
break; break;
case TE_SUBTLV_RAS: case TE_SUBTLV_RAS:
sum += print_subtlv_ras(buf, indent, sum += print_subtlv_ras(buf, indent,
(struct te_subtlv_ras *)tlvh); (struct te_subtlv_ras *)tlvh);
break; break;
case TE_SUBTLV_RIP: case TE_SUBTLV_RIP:
sum += print_subtlv_rip(buf, indent, sum += print_subtlv_rip(buf, indent,
(struct te_subtlv_rip *)tlvh); (struct te_subtlv_rip *)tlvh);
break; break;
case TE_SUBTLV_AV_DELAY: case TE_SUBTLV_AV_DELAY:
sum += print_subtlv_av_delay(buf, indent, sum += print_subtlv_av_delay(
(struct te_subtlv_av_delay *)tlvh); buf, indent, (struct te_subtlv_av_delay *)tlvh);
break; break;
case TE_SUBTLV_MM_DELAY: case TE_SUBTLV_MM_DELAY:
sum += print_subtlv_mm_delay(buf, indent, sum += print_subtlv_mm_delay(
(struct te_subtlv_mm_delay *)tlvh); buf, indent, (struct te_subtlv_mm_delay *)tlvh);
break; break;
case TE_SUBTLV_DELAY_VAR: case TE_SUBTLV_DELAY_VAR:
sum += print_subtlv_delay_var(buf, indent, sum += print_subtlv_delay_var(
buf, indent,
(struct te_subtlv_delay_var *)tlvh); (struct te_subtlv_delay_var *)tlvh);
break; break;
case TE_SUBTLV_PKT_LOSS: case TE_SUBTLV_PKT_LOSS:
sum += print_subtlv_pkt_loss(buf, indent, sum += print_subtlv_pkt_loss(
(struct te_subtlv_pkt_loss *)tlvh); buf, indent, (struct te_subtlv_pkt_loss *)tlvh);
break; break;
case TE_SUBTLV_RES_BW: case TE_SUBTLV_RES_BW:
sum += print_subtlv_res_bw(buf, indent, sum += print_subtlv_res_bw(
(struct te_subtlv_res_bw *)tlvh); buf, indent, (struct te_subtlv_res_bw *)tlvh);
break; break;
case TE_SUBTLV_AVA_BW: case TE_SUBTLV_AVA_BW:
sum += print_subtlv_ava_bw(buf, indent, sum += print_subtlv_ava_bw(
(struct te_subtlv_ava_bw *)tlvh); buf, indent, (struct te_subtlv_ava_bw *)tlvh);
break; break;
case TE_SUBTLV_USE_BW: case TE_SUBTLV_USE_BW:
sum += print_subtlv_use_bw(buf, indent, sum += print_subtlv_use_bw(
(struct te_subtlv_use_bw *)tlvh); buf, indent, (struct te_subtlv_use_bw *)tlvh);
break; break;
default: default:
sum += print_unknown_tlv(buf, indent, tlvh); sum += print_unknown_tlv(buf, indent, tlvh);

View File

@ -309,7 +309,8 @@ struct mpls_te_circuit {
void isis_mpls_te_init(void); void isis_mpls_te_init(void);
struct mpls_te_circuit *mpls_te_circuit_new(void); struct mpls_te_circuit *mpls_te_circuit_new(void);
struct sbuf; struct sbuf;
void mpls_te_print_detail(struct sbuf *buf, int indent, uint8_t *subtlvs, uint8_t subtlv_len); void mpls_te_print_detail(struct sbuf *buf, int indent, uint8_t *subtlvs,
uint8_t subtlv_len);
void set_circuitparams_local_ipaddr(struct mpls_te_circuit *, struct in_addr); void set_circuitparams_local_ipaddr(struct mpls_te_circuit *, struct in_addr);
void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *, struct in_addr); void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *, struct in_addr);
uint8_t subtlvs_len(struct mpls_te_circuit *); uint8_t subtlvs_len(struct mpls_te_circuit *);

View File

@ -161,9 +161,11 @@ static int unpack_subtlv_ipv6_source_prefix(enum isis_tlv_context context,
sbuf_push(log, indent, "Unpacking IPv6 Source Prefix Sub-TLV...\n"); sbuf_push(log, indent, "Unpacking IPv6 Source Prefix Sub-TLV...\n");
if (tlv_len < 1) { if (tlv_len < 1) {
sbuf_push(log, indent, sbuf_push(
"Not enough data left. (expected 1 or more bytes, got %" PRIu8 ")\n", log, indent,
tlv_len); "Not enough data left. (expected 1 or more bytes, got %" PRIu8
")\n",
tlv_len);
return 1; return 1;
} }
@ -496,8 +498,9 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i,
{ {
struct isis_lsp_entry *e = (struct isis_lsp_entry *)i; struct isis_lsp_entry *e = (struct isis_lsp_entry *)i;
sbuf_push(buf, indent, "LSP Entry: %s, seq 0x%08" PRIx32 sbuf_push(buf, indent,
", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 "s\n", "LSP Entry: %s, seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16
", lifetime %" PRIu16 "s\n",
isis_format_id(e->id, 8), e->seqno, e->checksum, isis_format_id(e->id, 8), e->seqno, e->checksum,
e->rem_lifetime); e->rem_lifetime);
} }
@ -579,7 +582,8 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i,
sbuf_push(buf, 0, "\n"); sbuf_push(buf, 0, "\n");
if (r->subtlv_len && r->subtlvs) if (r->subtlv_len && r->subtlvs)
mpls_te_print_detail(buf, indent + 2, r->subtlvs, r->subtlv_len); mpls_te_print_detail(buf, indent + 2, r->subtlvs,
r->subtlv_len);
} }
static void free_item_extended_reach(struct isis_item *i) static void free_item_extended_reach(struct isis_item *i)
@ -621,10 +625,11 @@ static int unpack_item_extended_reach(uint16_t mtid, uint8_t len,
(mtid == ISIS_MT_IPV4_UNICAST) ? "extended" : "mt"); (mtid == ISIS_MT_IPV4_UNICAST) ? "extended" : "mt");
if (len < 11) { if (len < 11) {
sbuf_push(log, indent, sbuf_push(
"Not enough data left. (expected 11 or more bytes, got %" log, indent,
PRIu8 ")\n", "Not enough data left. (expected 11 or more bytes, got %" PRIu8
len); ")\n",
len);
goto out; goto out;
} }
@ -690,7 +695,8 @@ static void format_item_oldstyle_ip_reach(uint16_t mtid, struct isis_item *i,
char prefixbuf[PREFIX2STR_BUFFER]; char prefixbuf[PREFIX2STR_BUFFER];
sbuf_push(buf, indent, "IP Reachability: %s (Metric: %" PRIu8 ")\n", sbuf_push(buf, indent, "IP Reachability: %s (Metric: %" PRIu8 ")\n",
prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)), r->metric); prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)),
r->metric);
} }
static void free_item_oldstyle_ip_reach(struct isis_item *i) static void free_item_oldstyle_ip_reach(struct isis_item *i)
@ -971,8 +977,7 @@ static void format_item_mt_router_info(uint16_t mtid, struct isis_item *i,
struct isis_mt_router_info *info = (struct isis_mt_router_info *)i; struct isis_mt_router_info *info = (struct isis_mt_router_info *)i;
sbuf_push(buf, indent, "MT Router Info: %s%s%s\n", sbuf_push(buf, indent, "MT Router Info: %s%s%s\n",
isis_mtid2str(info->mtid), isis_mtid2str(info->mtid), info->overload ? " Overload" : "",
info->overload ? " Overload" : "",
info->attached ? " Attached" : ""); info->attached ? " Attached" : "");
} }
@ -1121,8 +1126,8 @@ static void format_item_extended_ip_reach(uint16_t mtid, struct isis_item *i,
sbuf_push(buf, indent, "%s IP Reachability: %s (Metric: %u)%s", sbuf_push(buf, indent, "%s IP Reachability: %s (Metric: %u)%s",
(mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT", (mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT",
prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)), r->metric, prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)),
r->down ? " Down" : ""); r->metric, r->down ? " Down" : "");
if (mtid != ISIS_MT_IPV4_UNICAST) if (mtid != ISIS_MT_IPV4_UNICAST)
sbuf_push(buf, 0, " %s", isis_mtid2str(mtid)); sbuf_push(buf, 0, " %s", isis_mtid2str(mtid));
sbuf_push(buf, 0, "\n"); sbuf_push(buf, 0, "\n");
@ -1175,9 +1180,11 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len,
consume = 5; consume = 5;
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Not enough data left. (expected 5 or more bytes, got %" PRIu8 ")\n", log, indent,
len); "Not enough data left. (expected 5 or more bytes, got %" PRIu8
")\n",
len);
goto out; goto out;
} }
@ -1196,9 +1203,10 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len,
consume += PSIZE(rv->prefix.prefixlen); consume += PSIZE(rv->prefix.prefixlen);
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Expected %u bytes of prefix, but only %u bytes available.\n", log, indent,
PSIZE(rv->prefix.prefixlen), len - 5); "Expected %u bytes of prefix, but only %u bytes available.\n",
PSIZE(rv->prefix.prefixlen), len - 5);
goto out; goto out;
} }
stream_get(&rv->prefix.prefix.s_addr, s, PSIZE(rv->prefix.prefixlen)); stream_get(&rv->prefix.prefix.s_addr, s, PSIZE(rv->prefix.prefixlen));
@ -1213,23 +1221,26 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len,
if (control & ISIS_EXTENDED_IP_REACH_SUBTLV) { if (control & ISIS_EXTENDED_IP_REACH_SUBTLV) {
consume += 1; consume += 1;
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Expected 1 byte of subtlv len, but no more data present.\n"); log, indent,
"Expected 1 byte of subtlv len, but no more data present.\n");
goto out; goto out;
} }
subtlv_len = stream_getc(s); subtlv_len = stream_getc(s);
if (!subtlv_len) { if (!subtlv_len) {
sbuf_push(log, indent + 2, sbuf_push(
" WARNING: subtlv bit is set, but there are no subtlvs.\n"); log, indent + 2,
" WARNING: subtlv bit is set, but there are no subtlvs.\n");
} }
consume += subtlv_len; consume += subtlv_len;
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Expected %" PRIu8 log, indent,
" bytes of subtlvs, but only %u bytes available.\n", "Expected %" PRIu8
subtlv_len, " bytes of subtlvs, but only %u bytes available.\n",
len - 6 - PSIZE(rv->prefix.prefixlen)); subtlv_len,
len - 6 - PSIZE(rv->prefix.prefixlen));
goto out; goto out;
} }
sbuf_push(log, indent, "Skipping %" PRIu8 " bytes of subvls", sbuf_push(log, indent, "Skipping %" PRIu8 " bytes of subvls",
@ -1350,8 +1361,7 @@ static void format_item_ipv6_reach(uint16_t mtid, struct isis_item *i,
sbuf_push(buf, indent, "%sIPv6 Reachability: %s (Metric: %u)%s%s", sbuf_push(buf, indent, "%sIPv6 Reachability: %s (Metric: %u)%s%s",
(mtid == ISIS_MT_IPV4_UNICAST) ? "" : "MT ", (mtid == ISIS_MT_IPV4_UNICAST) ? "" : "MT ",
prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)), prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)),
r->metric, r->metric, r->down ? " Down" : "",
r->down ? " Down" : "",
r->external ? " External" : ""); r->external ? " External" : "");
if (mtid != ISIS_MT_IPV4_UNICAST) if (mtid != ISIS_MT_IPV4_UNICAST)
sbuf_push(buf, 0, " %s", isis_mtid2str(mtid)); sbuf_push(buf, 0, " %s", isis_mtid2str(mtid));
@ -1416,10 +1426,11 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s,
(mtid == ISIS_MT_IPV4_UNICAST) ? "" : "mt "); (mtid == ISIS_MT_IPV4_UNICAST) ? "" : "mt ");
consume = 6; consume = 6;
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Not enough data left. (expected 6 or more bytes, got %" log, indent,
PRIu8 ")\n", "Not enough data left. (expected 6 or more bytes, got %" PRIu8
len); ")\n",
len);
goto out; goto out;
} }
@ -1440,9 +1451,10 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s,
consume += PSIZE(rv->prefix.prefixlen); consume += PSIZE(rv->prefix.prefixlen);
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Expected %u bytes of prefix, but only %u bytes available.\n", log, indent,
PSIZE(rv->prefix.prefixlen), len - 6); "Expected %u bytes of prefix, but only %u bytes available.\n",
PSIZE(rv->prefix.prefixlen), len - 6);
goto out; goto out;
} }
stream_get(&rv->prefix.prefix.s6_addr, s, PSIZE(rv->prefix.prefixlen)); stream_get(&rv->prefix.prefix.s6_addr, s, PSIZE(rv->prefix.prefixlen));
@ -1456,23 +1468,26 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s,
if (control & ISIS_IPV6_REACH_SUBTLV) { if (control & ISIS_IPV6_REACH_SUBTLV) {
consume += 1; consume += 1;
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Expected 1 byte of subtlv len, but no more data persent.\n"); log, indent,
"Expected 1 byte of subtlv len, but no more data persent.\n");
goto out; goto out;
} }
subtlv_len = stream_getc(s); subtlv_len = stream_getc(s);
if (!subtlv_len) { if (!subtlv_len) {
sbuf_push(log, indent + 2, sbuf_push(
" WARNING: subtlv bit set, but there are no subtlvs.\n"); log, indent + 2,
" WARNING: subtlv bit set, but there are no subtlvs.\n");
} }
consume += subtlv_len; consume += subtlv_len;
if (len < consume) { if (len < consume) {
sbuf_push(log, indent, sbuf_push(
"Expected %" PRIu8 log, indent,
" bytes of subtlvs, but only %u bytes available.\n", "Expected %" PRIu8
subtlv_len, " bytes of subtlvs, but only %u bytes available.\n",
len - 6 - PSIZE(rv->prefix.prefixlen)); subtlv_len,
len - 6 - PSIZE(rv->prefix.prefixlen));
goto out; goto out;
} }
@ -1695,16 +1710,19 @@ static int pack_item(enum isis_tlv_context context, enum isis_tlv_type type,
return 1; return 1;
} }
static void add_item_to_fragment(struct isis_item *i, struct pack_order_entry *pe, static void add_item_to_fragment(struct isis_item *i,
struct pack_order_entry *pe,
struct isis_tlvs *fragment_tlvs, uint16_t mtid) struct isis_tlvs *fragment_tlvs, uint16_t mtid)
{ {
struct isis_item_list *l; struct isis_item_list *l;
if (pe->how_to_pack == ISIS_ITEMS) { if (pe->how_to_pack == ISIS_ITEMS) {
l = (struct isis_item_list *)(((char *)fragment_tlvs) + pe->what_to_pack); l = (struct isis_item_list *)(((char *)fragment_tlvs)
+ pe->what_to_pack);
} else { } else {
struct isis_mt_item_list *m; struct isis_mt_item_list *m;
m = (struct isis_mt_item_list *)(((char *)fragment_tlvs) + pe->what_to_pack); m = (struct isis_mt_item_list *)(((char *)fragment_tlvs)
+ pe->what_to_pack);
l = isis_get_mt_items(m, mtid); l = isis_get_mt_items(m, mtid);
} }
@ -2284,8 +2302,9 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream,
/* When fragmenting, don't add auth as it's already accounted for in the /* When fragmenting, don't add auth as it's already accounted for in the
* size we are given. */ * size we are given. */
if (!fragment_tlvs) { if (!fragment_tlvs) {
rv = pack_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH, &tlvs->isis_auth, rv = pack_items(ISIS_CONTEXT_LSP, ISIS_TLV_AUTH,
stream, NULL, NULL, NULL, NULL); &tlvs->isis_auth, stream, NULL, NULL, NULL,
NULL);
if (rv) if (rv)
return rv; return rv;
} }
@ -2440,9 +2459,11 @@ static int unpack_tlv(enum isis_tlv_context context, size_t avail_len,
tlv_type, tlv_len); tlv_type, tlv_len);
if (avail_len < ((size_t)tlv_len) + 2) { if (avail_len < ((size_t)tlv_len) + 2) {
sbuf_push(log, indent + 2, sbuf_push(
"Available data %zu too short for claimed TLV len %" PRIu8 ".\n", log, indent + 2,
avail_len - 2, tlv_len); "Available data %zu too short for claimed TLV len %" PRIu8
".\n",
avail_len - 2, tlv_len);
return 1; return 1;
} }
@ -2520,7 +2541,7 @@ int isis_unpack_tlvs(size_t avail_len, struct stream *stream,
static const struct tlv_ops tlv_##_name_##_ops = { \ static const struct tlv_ops tlv_##_name_##_ops = { \
.name = _desc_, \ .name = _desc_, \
.unpack = unpack_tlv_with_items, \ .unpack = unpack_tlv_with_items, \
\ \
.pack_item = pack_item_##_name_, \ .pack_item = pack_item_##_name_, \
.free_item = free_item_##_name_, \ .free_item = free_item_##_name_, \
.unpack_item = unpack_item_##_name_, \ .unpack_item = unpack_item_##_name_, \
@ -2550,34 +2571,49 @@ ITEM_TLV_OPS(ipv6_reach, "TLV 236 IPv6 Reachability");
SUBTLV_OPS(ipv6_source_prefix, "Sub-TLV 22 IPv6 Source Prefix"); SUBTLV_OPS(ipv6_source_prefix, "Sub-TLV 22 IPv6 Source Prefix");
static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] =
[ISIS_CONTEXT_LSP] = { {[ISIS_CONTEXT_LSP] =
[ISIS_TLV_AREA_ADDRESSES] = &tlv_area_address_ops, {
[ISIS_TLV_OLDSTYLE_REACH] = &tlv_oldstyle_reach_ops, [ISIS_TLV_AREA_ADDRESSES] =
[ISIS_TLV_LAN_NEIGHBORS] = &tlv_lan_neighbor_ops, &tlv_area_address_ops,
[ISIS_TLV_LSP_ENTRY] = &tlv_lsp_entry_ops, [ISIS_TLV_OLDSTYLE_REACH] =
[ISIS_TLV_AUTH] = &tlv_auth_ops, &tlv_oldstyle_reach_ops,
[ISIS_TLV_EXTENDED_REACH] = &tlv_extended_reach_ops, [ISIS_TLV_LAN_NEIGHBORS] =
[ISIS_TLV_MT_REACH] = &tlv_extended_reach_ops, &tlv_lan_neighbor_ops,
[ISIS_TLV_OLDSTYLE_IP_REACH] = &tlv_oldstyle_ip_reach_ops, [ISIS_TLV_LSP_ENTRY] = &tlv_lsp_entry_ops,
[ISIS_TLV_PROTOCOLS_SUPPORTED] = &tlv_protocols_supported_ops, [ISIS_TLV_AUTH] = &tlv_auth_ops,
[ISIS_TLV_OLDSTYLE_IP_REACH_EXT] = &tlv_oldstyle_ip_reach_ops, [ISIS_TLV_EXTENDED_REACH] =
[ISIS_TLV_IPV4_ADDRESS] = &tlv_ipv4_address_ops, &tlv_extended_reach_ops,
[ISIS_TLV_TE_ROUTER_ID] = &tlv_te_router_id_ops, [ISIS_TLV_MT_REACH] = &tlv_extended_reach_ops,
[ISIS_TLV_EXTENDED_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_OLDSTYLE_IP_REACH] =
[ISIS_TLV_MT_IP_REACH] = &tlv_extended_ip_reach_ops, &tlv_oldstyle_ip_reach_ops,
[ISIS_TLV_DYNAMIC_HOSTNAME] = &tlv_dynamic_hostname_ops, [ISIS_TLV_PROTOCOLS_SUPPORTED] =
[ISIS_TLV_MT_ROUTER_INFO] = &tlv_mt_router_info_ops, &tlv_protocols_supported_ops,
[ISIS_TLV_IPV6_ADDRESS] = &tlv_ipv6_address_ops, [ISIS_TLV_OLDSTYLE_IP_REACH_EXT] =
[ISIS_TLV_IPV6_REACH] = &tlv_ipv6_reach_ops, &tlv_oldstyle_ip_reach_ops,
[ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops, [ISIS_TLV_IPV4_ADDRESS] =
}, &tlv_ipv4_address_ops,
[ISIS_CONTEXT_SUBTLV_NE_REACH] = {}, [ISIS_TLV_TE_ROUTER_ID] =
[ISIS_CONTEXT_SUBTLV_IP_REACH] = {}, &tlv_te_router_id_ops,
[ISIS_CONTEXT_SUBTLV_IPV6_REACH] = { [ISIS_TLV_EXTENDED_IP_REACH] =
[ISIS_SUBTLV_IPV6_SOURCE_PREFIX] = &subtlv_ipv6_source_prefix_ops, &tlv_extended_ip_reach_ops,
} [ISIS_TLV_MT_IP_REACH] =
}; &tlv_extended_ip_reach_ops,
[ISIS_TLV_DYNAMIC_HOSTNAME] =
&tlv_dynamic_hostname_ops,
[ISIS_TLV_MT_ROUTER_INFO] =
&tlv_mt_router_info_ops,
[ISIS_TLV_IPV6_ADDRESS] =
&tlv_ipv6_address_ops,
[ISIS_TLV_IPV6_REACH] = &tlv_ipv6_reach_ops,
[ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops,
},
[ISIS_CONTEXT_SUBTLV_NE_REACH] = {},
[ISIS_CONTEXT_SUBTLV_IP_REACH] = {},
[ISIS_CONTEXT_SUBTLV_IPV6_REACH] = {
[ISIS_SUBTLV_IPV6_SOURCE_PREFIX] =
&subtlv_ipv6_source_prefix_ops,
}};
/* Accessor functions */ /* Accessor functions */

View File

@ -764,7 +764,7 @@ DEFUN_NOSH (show_debugging,
"State of each debugging option\n" "State of each debugging option\n"
ISIS_STR) ISIS_STR)
{ {
vty_out (vty, "IS-IS debugging status:\n"); vty_out(vty, "IS-IS debugging status:\n");
if (isis->debugs) if (isis->debugs)
print_debug(vty, isis->debugs, 1); print_debug(vty, isis->debugs, 1);

View File

@ -52,8 +52,9 @@ struct isis {
struct area_addr *man_area_addrs; /* manualAreaAddresses */ struct area_addr *man_area_addrs; /* manualAreaAddresses */
u_int32_t debugs; /* bitmap for debug */ u_int32_t debugs; /* bitmap for debug */
time_t uptime; /* when did we start */ time_t uptime; /* when did we start */
struct thread *t_dync_clean; /* dynamic hostname cache cleanup thread */ struct thread *t_dync_clean; /* dynamic hostname cache cleanup thread */
uint32_t circuit_ids_used[8]; /* 256 bits to track circuit ids 0 through 255 */ uint32_t circuit_ids_used
[8]; /* 256 bits to track circuit ids 0 through 255 */
struct route_table *ext_info[REDIST_PROTOCOL_COUNT]; struct route_table *ext_info[REDIST_PROTOCOL_COUNT];
@ -70,8 +71,6 @@ struct isis_area {
struct route_table *route_table[ISIS_LEVELS]; /* IPv4 routes */ struct route_table *route_table[ISIS_LEVELS]; /* IPv4 routes */
struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v6 SPTs */ struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v6 SPTs */
struct route_table *route_table6[ISIS_LEVELS]; /* IPv6 routes */ struct route_table *route_table6[ISIS_LEVELS]; /* IPv6 routes */
/* $FRR indent$ */
/* clang-format off */
#define DEFAULT_LSP_MTU 1497 #define DEFAULT_LSP_MTU 1497
unsigned int lsp_mtu; /* Size of LSPs to generate */ unsigned int lsp_mtu; /* Size of LSPs to generate */
struct list *circuit_list; /* IS-IS circuits */ struct list *circuit_list; /* IS-IS circuits */

1
ldpd/.gitignore vendored
View File

@ -15,4 +15,3 @@ TAGS
.arch-ids .arch-ids
*~ *~
*.loT *.loT
ldp_vty_cmds_clippy.c

1
lib/.gitignore vendored
View File

@ -24,4 +24,3 @@ refix
grammar_sandbox grammar_sandbox
clippy clippy
defun_lex.c defun_lex.c
plist_clippy.c

View File

@ -62,9 +62,10 @@ const char *node_names[] = {
"aaa", // AAA_NODE, "aaa", // AAA_NODE,
"keychain", // KEYCHAIN_NODE, "keychain", // KEYCHAIN_NODE,
"keychain key", // KEYCHAIN_KEY_NODE, "keychain key", // KEYCHAIN_KEY_NODE,
"logical-router", // LOGICALROUTER_NODE, "logical-router", // LOGICALROUTER_NODE,
"vrf", // VRF_NODE, "vrf", // VRF_NODE,
"interface", // INTERFACE_NODE, "interface", // INTERFACE_NODE,
"nexthop-group", // NH_GROUP_NODE,
"zebra", // ZEBRA_NODE, "zebra", // ZEBRA_NODE,
"table", // TABLE_NODE, "table", // TABLE_NODE,
"rip", // RIP_NODE, "rip", // RIP_NODE,
@ -74,14 +75,14 @@ const char *node_names[] = {
"bgp", // BGP_NODE, "bgp", // BGP_NODE,
"bgp vpnv4", // BGP_VPNV4_NODE, "bgp vpnv4", // BGP_VPNV4_NODE,
"bgp vpnv6", // BGP_VPNV6_NODE, "bgp vpnv6", // BGP_VPNV6_NODE,
"bgp ipv4 unicast", // BGP_IPV4_NODE, "bgp ipv4 unicast", // BGP_IPV4_NODE,
"bgp ipv4 multicast", // BGP_IPV4M_NODE, "bgp ipv4 multicast", // BGP_IPV4M_NODE,
"bgp ipv4 labeled unicast", // BGP_IPV4L_NODE, "bgp ipv4 labeled unicast", // BGP_IPV4L_NODE,
"bgp ipv6", // BGP_IPV6_NODE, "bgp ipv6", // BGP_IPV6_NODE,
"bgp ipv6 multicast", // BGP_IPV6M_NODE, "bgp ipv6 multicast", // BGP_IPV6M_NODE,
"bgp ipv6 labeled unicast", // BGP_IPV6L_NODE, "bgp ipv6 labeled unicast", // BGP_IPV6L_NODE,
"bgp vrf policy", // BGP_VRF_POLICY_NODE, "bgp vrf policy", // BGP_VRF_POLICY_NODE,
"bgp vnc defaults", // BGP_VNC_DEFAULTS_NODE, "bgp vnc defaults", // BGP_VNC_DEFAULTS_NODE,
"bgp vnc nve", // BGP_VNC_NVE_GROUP_NODE, "bgp vnc nve", // BGP_VNC_NVE_GROUP_NODE,
"bgp vnc l2", // BGP_VNC_L2_GROUP_NODE, "bgp vnc l2", // BGP_VNC_L2_GROUP_NODE,
"rfp defaults", // RFP_DEFAULTS_NODE, "rfp defaults", // RFP_DEFAULTS_NODE,
@ -99,13 +100,13 @@ const char *node_names[] = {
"masc", // MASC_NODE, "masc", // MASC_NODE,
"irdp", // IRDP_NODE, "irdp", // IRDP_NODE,
"static ip", // IP_NODE, "static ip", // IP_NODE,
"ipv4 access list", // ACCESS_NODE, "ipv4 access list", // ACCESS_NODE,
"ipv4 prefix list", // PREFIX_NODE, "ipv4 prefix list", // PREFIX_NODE,
"ipv6 access list", // ACCESS_IPV6_NODE, "ipv6 access list", // ACCESS_IPV6_NODE,
"MAC access list", // ACCESS_MAC_NODE, "MAC access list", // ACCESS_MAC_NODE,
"ipv6 prefix list", // PREFIX_IPV6_NODE, "ipv6 prefix list", // PREFIX_IPV6_NODE,
"as list", // AS_LIST_NODE, "as list", // AS_LIST_NODE,
"community list", // COMMUNITY_LIST_NODE, "community list", // COMMUNITY_LIST_NODE,
"routemap", // RMAP_NODE, "routemap", // RMAP_NODE,
"smux", // SMUX_NODE, "smux", // SMUX_NODE,
"dump", // DUMP_NODE, "dump", // DUMP_NODE,
@ -301,8 +302,7 @@ void install_node(struct cmd_node *node, int (*func)(struct vty *))
cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL); cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
graph_new_node(node->cmdgraph, token, graph_new_node(node->cmdgraph, token,
(void (*)(void *)) & cmd_token_del); (void (*)(void *)) & cmd_token_del);
node->cmd_hash = hash_create_size(16, cmd_hash_key, node->cmd_hash = hash_create_size(16, cmd_hash_key, cmd_hash_cmp,
cmd_hash_cmp,
"Command Hash"); "Command Hash");
} }
@ -500,6 +500,9 @@ static int config_write_host(struct vty *vty)
if (cmd_hostname_get()) if (cmd_hostname_get())
vty_out(vty, "hostname %s\n", cmd_hostname_get()); vty_out(vty, "hostname %s\n", cmd_hostname_get());
if (cmd_domainname_get())
vty_out(vty, "domainname %s\n", cmd_domainname_get());
if (host.encrypt) { if (host.encrypt) {
if (host.password_encrypt) if (host.password_encrypt)
vty_out(vty, "password 8 %s\n", host.password_encrypt); vty_out(vty, "password 8 %s\n", host.password_encrypt);
@ -1167,8 +1170,7 @@ int command_config_read_one_line(struct vty *vty,
if (!(use_daemon && ret == CMD_SUCCESS_DAEMON) if (!(use_daemon && ret == CMD_SUCCESS_DAEMON)
&& !(!use_daemon && ret == CMD_ERR_NOTHING_TODO) && !(!use_daemon && ret == CMD_ERR_NOTHING_TODO)
&& ret != CMD_SUCCESS && ret != CMD_WARNING && ret != CMD_SUCCESS && ret != CMD_WARNING
&& ret != CMD_NOT_MY_INSTANCE && ret != CMD_NOT_MY_INSTANCE && ret != CMD_WARNING_CONFIG_FAILED
&& ret != CMD_WARNING_CONFIG_FAILED
&& vty->node != CONFIG_NODE) { && vty->node != CONFIG_NODE) {
saved_node = vty->node; saved_node = vty->node;
@ -1293,6 +1295,7 @@ void cmd_exit(struct vty *vty)
case PW_NODE: case PW_NODE:
case LOGICALROUTER_NODE: case LOGICALROUTER_NODE:
case VRF_NODE: case VRF_NODE:
case NH_GROUP_NODE:
case ZEBRA_NODE: case ZEBRA_NODE:
case BGP_NODE: case BGP_NODE:
case RIP_NODE: case RIP_NODE:
@ -1378,6 +1381,7 @@ DEFUN (config_end,
case PW_NODE: case PW_NODE:
case LOGICALROUTER_NODE: case LOGICALROUTER_NODE:
case VRF_NODE: case VRF_NODE:
case NH_GROUP_NODE:
case ZEBRA_NODE: case ZEBRA_NODE:
case RIP_NODE: case RIP_NODE:
case RIPNG_NODE: case RIPNG_NODE:

View File

@ -85,9 +85,10 @@ enum node_type {
AAA_NODE, /* AAA node. */ AAA_NODE, /* AAA node. */
KEYCHAIN_NODE, /* Key-chain node. */ KEYCHAIN_NODE, /* Key-chain node. */
KEYCHAIN_KEY_NODE, /* Key-chain key node. */ KEYCHAIN_KEY_NODE, /* Key-chain key node. */
LOGICALROUTER_NODE, /* Logical-Router node. */ LOGICALROUTER_NODE, /* Logical-Router node. */
VRF_NODE, /* VRF mode node. */ VRF_NODE, /* VRF mode node. */
INTERFACE_NODE, /* Interface mode node. */ INTERFACE_NODE, /* Interface mode node. */
NH_GROUP_NODE, /* Nexthop-Group mode node. */
ZEBRA_NODE, /* zebra connection node. */ ZEBRA_NODE, /* zebra connection node. */
TABLE_NODE, /* rtm_table selection node. */ TABLE_NODE, /* rtm_table selection node. */
RIP_NODE, /* RIP protocol mode node. */ RIP_NODE, /* RIP protocol mode node. */
@ -139,8 +140,9 @@ enum node_type {
VTY_NODE, /* Vty node. */ VTY_NODE, /* Vty node. */
LINK_PARAMS_NODE, /* Link-parameters node */ LINK_PARAMS_NODE, /* Link-parameters node */
BGP_EVPN_VNI_NODE, /* BGP EVPN VNI */ BGP_EVPN_VNI_NODE, /* BGP EVPN VNI */
RPKI_NODE, /* RPKI node for configuration of RPKI cache server connections.*/ RPKI_NODE, /* RPKI node for configuration of RPKI cache server
NODE_TYPE_MAX, /* maximum */ connections.*/
NODE_TYPE_MAX, /* maximum */
}; };
extern vector cmdvec; extern vector cmdvec;

View File

@ -21,25 +21,25 @@
* void prototype(void) __attribute__((_CONSTRUCTOR(100))); * void prototype(void) __attribute__((_CONSTRUCTOR(100)));
*/ */
#if defined(__clang__) #if defined(__clang__)
# if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5) #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)
# define _RET_NONNULL , returns_nonnull # define _RET_NONNULL , returns_nonnull
# endif #endif
# define _CONSTRUCTOR(x) constructor(x) # define _CONSTRUCTOR(x) constructor(x)
#elif defined(__GNUC__) #elif defined(__GNUC__)
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
# define _RET_NONNULL , returns_nonnull # define _RET_NONNULL , returns_nonnull
# endif #endif
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
# define _CONSTRUCTOR(x) constructor(x) # define _CONSTRUCTOR(x) constructor(x)
# define _DESTRUCTOR(x) destructor(x) # define _DESTRUCTOR(x) destructor(x)
# define _ALLOC_SIZE(x) alloc_size(x) # define _ALLOC_SIZE(x) alloc_size(x)
# endif #endif
#endif #endif
#ifdef __sun #ifdef __sun
/* Solaris doesn't do constructor priorities due to linker restrictions */ /* Solaris doesn't do constructor priorities due to linker restrictions */
# undef _CONSTRUCTOR #undef _CONSTRUCTOR
# undef _DESTRUCTOR #undef _DESTRUCTOR
#endif #endif
/* fallback versions */ /* fallback versions */

46
lib/debug.c Normal file
View File

@ -0,0 +1,46 @@
/*
* Debugging utilities.
* Copyright (C) 2018 Cumulus Networks, Inc.
* 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
*/
#include <zebra.h>
#include "debug.h"
#include "command.h"
static const struct debug_callbacks *callbacks;
/* All code in this section should be reentrant and MT-safe */
DEFUN_NOSH(debug_all, debug_all_cmd, "[no] debug all",
NO_STR DEBUG_STR "Toggle all debugging output\n")
{
bool set = strmatch(argv[0]->text, "no");
uint32_t mode = DEBUG_NODE2MODE(vty->node);
if (callbacks->debug_set_all)
callbacks->debug_set_all(mode, set);
return CMD_SUCCESS;
}
/* ------------------------------------------------------------------------- */
void debug_init(const struct debug_callbacks *cb)
{
callbacks = cb;
install_element(ENABLE_NODE, &debug_all_cmd);
install_element(CONFIG_NODE, &debug_all_cmd);
}

234
lib/debug.h Normal file
View File

@ -0,0 +1,234 @@
/*
* Debugging utilities.
* Copyright (C) 2018 Cumulus Networks, Inc.
* 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 _FRRDEBUG_H
#define _FRRDEBUG_H
#include <zebra.h>
#include "command.h"
#include "frratomic.h"
/*
* Debugging modes.
*
* FRR's convention is that a debug statement issued under the vty CONFIG_NODE
* persists to the config file, whereas the same debug statement issued from
* the ENABLE_NODE only persists for the current session. These are mapped to
* DEBUG_MODE_CONF and DEBUG_MODE_TERM respectively.
*
* They are not mutually exclusive and are placed in the MSB of the flags
* field in a debugging record.
*/
#define DEBUG_MODE_TERM 0x01000000
#define DEBUG_MODE_CONF 0x02000000
#define DEBUG_MODE_ALL (DEBUG_MODE_TERM | DEBUG_MODE_CONF)
#define DEBUG_MODE_NONE 0x00000000
#define DEBUG_OPT_ALL 0x00FFFFFF
#define DEBUG_OPT_NONE 0x00000000
/*
* Debugging record.
*
* All operations on this record exposed in this header are MT-safe.
*
* flags
* A bitfield with the following format (bytes high to low)
* - [0] Debugging mode field (MSB) | Mode
* - [1] Arbitrary flag field | Option
* - [2] Arbitrary flag field | Option
* - [3] Arbitrary flag field (LSB) | Option
*
* ALL THESE BYTES ARE YOURS - EXCEPT MODE.
* ATTEMPT NO BIT OPS THERE.
*
* The MSB of this field determines the debug mode, Use the DEBUG_MODE*
* macros to manipulate this byte.
*
* The low 3 bytes of this field may be used to store arbitrary information.
* Usually they are used to store flags that tune how detailed the logging
* for a particular debug record is. Use the DEBUG_OPT* macros to manipulate
* those bytes.
*
* All operations performed on this field should be done using the macros
* later in this header file. They are guaranteed to be atomic operations
* with respect to this field. Using anything except the macros to
* manipulate the flags field in a multithreaded environment results in
* undefined behavior.
*
* desc
* Human-readable description of this debugging record.
*/
struct debug {
_Atomic uint32_t flags;
const char *desc;
};
/*
* Callback set for debugging code.
*
* debug_set_all
* Function pointer to call when the user requests that all debugs have a
* mode set.
*/
struct debug_callbacks {
/*
* flags
* flags to set on debug flag fields
*
* set
* true: set flags
* false: unset flags
*/
void (*debug_set_all)(uint32_t flags, bool set);
};
/*
* Check if a mode is set for a debug.
*
* MT-Safe
*/
#define DEBUG_MODE_CHECK(name, mode) \
CHECK_FLAG_ATOMIC(&(name)->flags, (mode)&DEBUG_MODE_ALL)
/*
* Check if an option bit is set for a debug.
*
* MT-Safe
*/
#define DEBUG_OPT_CHECK(name, opt) \
CHECK_FLAG_ATOMIC(&(name)->flags, (opt)&DEBUG_OPT_ALL)
/*
* Check if bits are set for a debug.
*
* MT-Safe
*/
#define DEBUG_FLAGS_CHECK(name, fl) CHECK_FLAG_ATOMIC(&(name)->flags, (fl))
/*
* Set modes on a debug.
*
* MT-Safe
*/
#define DEBUG_MODE_SET(name, mode, onoff) \
do { \
if (onoff) \
SET_FLAG_ATOMIC(&(name)->flags, \
(mode)&DEBUG_MODE_ALL); \
else \
UNSET_FLAG_ATOMIC(&(name)->flags, \
(mode)&DEBUG_MODE_ALL); \
} while (0)
/* Convenience macros for specific set operations. */
#define DEBUG_MODE_ON(name, mode) DEBUG_MODE_SET(name, mode, true)
#define DEBUG_MODE_OFF(name, mode) DEBUG_MODE_SET(name, mode, false)
/*
* Set options on a debug.
*
* MT-Safe
*/
#define DEBUG_OPT_SET(name, opt, onoff) \
do { \
if (onoff) \
SET_FLAG_ATOMIC(&(name)->flags, (opt)&DEBUG_OPT_ALL); \
else \
UNSET_FLAG_ATOMIC(&(name)->flags, \
(opt)&DEBUG_OPT_ALL); \
} while (0)
/* Convenience macros for specific set operations. */
#define DEBUG_OPT_ON(name, opt) DEBUG_OPT_SET(name, opt, true)
#define DEBUG_OPT_OFF(name, opt) DEBUG_OPT_SET(name, opt, true)
/*
* Set bits on a debug.
*
* MT-Safe
*/
#define DEBUG_FLAGS_SET(name, fl, onoff) \
do { \
if (onoff) \
SET_FLAG_ATOMIC(&(name)->flags, (fl)); \
else \
UNSET_FLAG_ATOMIC(&(name)->flags, (fl)); \
} while (0)
/* Convenience macros for specific set operations. */
#define DEBUG_FLAGS_ON(name, fl) DEBUG_FLAGS_SET(&(name)->flags, (type), true)
#define DEBUG_FLAGS_OFF(name, fl) DEBUG_FLAGS_SET(&(name)->flags, (type), false)
/*
* Unset all modes and options on a debug.
*
* MT-Safe
*/
#define DEBUG_CLEAR(name) RESET_FLAG_ATOMIC(&(name)->flags)
/*
* Set all modes and options on a debug.
*
* MT-Safe
*/
#define DEBUG_ON(name) \
SET_FLAG_ATOMIC(&(name)->flags, DEBUG_MODE_ALL | DEBUG_OPT_ALL)
/*
* Map a vty node to the correct debugging mode flags. FRR behaves such that a
* debug statement issued under the config node persists to the config file,
* whereas the same debug statement issued from the enable node only persists
* for the current session.
*
* MT-Safe
*/
#define DEBUG_NODE2MODE(vtynode) \
(((vtynode) == CONFIG_NODE) ? DEBUG_MODE_ALL : DEBUG_MODE_TERM)
/*
* Debug at the given level to the default logging destination.
*
* MT-Safe
*/
#define DEBUG(level, name, fmt, ...) \
do { \
if (DEBUG_MODE_CHECK(name, DEBUG_MODE_ALL)) \
zlog_##level(fmt, ##__VA_ARGS__); \
} while (0)
/* Convenience macros for the various levels. */
#define DEBUGE(name, fmt, ...) DEBUG(err, name, fmt, ##__VA_ARGS__)
#define DEBUGW(name, fmt, ...) DEBUG(warn, name, fmt, ##__VA_ARGS__)
#define DEBUGI(name, fmt, ...) DEBUG(info, name, fmt, ##__VA_ARGS__)
#define DEBUGN(name, fmt, ...) DEBUG(notice, name, fmt, ##__VA_ARGS__)
#define DEBUGD(name, fmt, ...) DEBUG(debug, name, fmt, ##__VA_ARGS__)
/*
* Optional initializer for debugging. Highly recommended.
*
* This function installs common debugging commands and allows the caller to
* specify callbacks to take when these commands are issued, allowing the
* caller to respond to events such as a request to turn off all debugs.
*
* MT-Safe
*/
void debug_init(const struct debug_callbacks *cb);
#endif /* _FRRDEBUG_H */

View File

@ -63,8 +63,8 @@ ferr_r ferr_clear(void)
} }
static ferr_r ferr_set_va(const char *file, int line, const char *func, static ferr_r ferr_set_va(const char *file, int line, const char *func,
enum ferr_kind kind, const char *pathname, int errno_val, enum ferr_kind kind, const char *pathname,
const char *text, va_list va) int errno_val, const char *text, va_list va)
{ {
struct ferr *error = pthread_getspecific(errkey); struct ferr *error = pthread_getspecific(errkey);
@ -74,7 +74,8 @@ static ferr_r ferr_set_va(const char *file, int line, const char *func,
/* we're screwed */ /* we're screwed */
zlog_err("out of memory while allocating error info"); zlog_err("out of memory while allocating error info");
raise(SIGSEGV); raise(SIGSEGV);
abort(); /* raise() can return, but raise(SIGSEGV) shall not */ abort(); /* raise() can return, but raise(SIGSEGV) shall
not */
} }
pthread_setspecific(errkey, error); pthread_setspecific(errkey, error);
@ -86,12 +87,12 @@ static ferr_r ferr_set_va(const char *file, int line, const char *func,
error->kind = kind; error->kind = kind;
error->unique_id = jhash(text, strlen(text), error->unique_id = jhash(text, strlen(text),
jhash(file, strlen(file), 0xd4ed0298)); jhash(file, strlen(file), 0xd4ed0298));
error->errno_val = errno_val; error->errno_val = errno_val;
if (pathname) if (pathname)
snprintf(error->pathname, sizeof(error->pathname), snprintf(error->pathname, sizeof(error->pathname), "%s",
"%s", pathname); pathname);
else else
error->pathname[0] = '\0'; error->pathname[0] = '\0';
@ -100,7 +101,7 @@ static ferr_r ferr_set_va(const char *file, int line, const char *func,
} }
ferr_r ferr_set_internal(const char *file, int line, const char *func, ferr_r ferr_set_internal(const char *file, int line, const char *func,
enum ferr_kind kind, const char *text, ...) enum ferr_kind kind, const char *text, ...)
{ {
ferr_r rv; ferr_r rv;
va_list va; va_list va;
@ -111,8 +112,8 @@ ferr_r ferr_set_internal(const char *file, int line, const char *func,
} }
ferr_r ferr_set_internal_ext(const char *file, int line, const char *func, ferr_r ferr_set_internal_ext(const char *file, int line, const char *func,
enum ferr_kind kind, const char *pathname, int errno_val, enum ferr_kind kind, const char *pathname,
const char *text, ...) int errno_val, const char *text, ...)
{ {
ferr_r rv; ferr_r rv;
va_list va; va_list va;
@ -139,10 +140,8 @@ void vty_print_error(struct vty *vty, ferr_r err, const char *msg, ...)
else { else {
replacepos[0] = '\0'; replacepos[0] = '\0';
replacepos += sizeof(REPLACE) - 1; replacepos += sizeof(REPLACE) - 1;
vty_out(vty, "%s%s%s\n", vty_out(vty, "%s%s%s\n", tmpmsg,
tmpmsg,
last_error ? last_error->message : "(no error?)", last_error ? last_error->message : "(no error?)",
replacepos); replacepos);
} }
} }

View File

@ -107,13 +107,12 @@ ferr_r ferr_clear(void);
/* do NOT call these functions directly. only for macro use! */ /* do NOT call these functions directly. only for macro use! */
ferr_r ferr_set_internal(const char *file, int line, const char *func, ferr_r ferr_set_internal(const char *file, int line, const char *func,
enum ferr_kind kind, const char *text, ...); enum ferr_kind kind, const char *text, ...);
ferr_r ferr_set_internal_ext(const char *file, int line, const char *func, ferr_r ferr_set_internal_ext(const char *file, int line, const char *func,
enum ferr_kind kind, const char *pathname, int errno_val, enum ferr_kind kind, const char *pathname,
const char *text, ...); int errno_val, const char *text, ...);
#define ferr_ok() \ #define ferr_ok() 0
0
/* Report an error. /* Report an error.
* *
@ -122,58 +121,60 @@ ferr_r ferr_set_internal_ext(const char *file, int line, const char *func,
* *
* Don't put a \n at the end of the error message. * Don't put a \n at the end of the error message.
*/ */
#define ferr_code_bug(...) \ #define ferr_code_bug(...) \
ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CODE_BUG, \ ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CODE_BUG, \
__VA_ARGS__) __VA_ARGS__)
#define ferr_cfg_invalid(...) \ #define ferr_cfg_invalid(...) \
ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CONFIG_INVALID, \ ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CONFIG_INVALID, \
__VA_ARGS__) __VA_ARGS__)
#define ferr_cfg_reality(...) \ #define ferr_cfg_reality(...) \
ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CONFIG_REALITY, \ ferr_set_internal(__FILE__, __LINE__, __func__, FERR_CONFIG_REALITY, \
__VA_ARGS__) __VA_ARGS__)
#define ferr_cfg_resource(...) \ #define ferr_cfg_resource(...) \
ferr_set_internal(__FILE__, __LINE__, __func__, FERR_RESOURCE, \ ferr_set_internal(__FILE__, __LINE__, __func__, FERR_RESOURCE, \
__VA_ARGS__) __VA_ARGS__)
#define ferr_system(...) \ #define ferr_system(...) \
ferr_set_internal(__FILE__, __LINE__, __func__, FERR_SYSTEM, \ ferr_set_internal(__FILE__, __LINE__, __func__, FERR_SYSTEM, \
__VA_ARGS__) __VA_ARGS__)
#define ferr_library(...) \ #define ferr_library(...) \
ferr_set_internal(__FILE__, __LINE__, __func__, FERR_LIBRARY, \ ferr_set_internal(__FILE__, __LINE__, __func__, FERR_LIBRARY, \
__VA_ARGS__) __VA_ARGS__)
/* extended information variants */ /* extended information variants */
#define ferr_system_errno(...) \ #define ferr_system_errno(...) \
ferr_set_internal_ext(__FILE__, __LINE__, __func__, FERR_SYSTEM, \ ferr_set_internal_ext(__FILE__, __LINE__, __func__, FERR_SYSTEM, NULL, \
NULL, errno, __VA_ARGS__) errno, __VA_ARGS__)
#define ferr_system_path_errno(path, ...) \ #define ferr_system_path_errno(path, ...) \
ferr_set_internal_ext(__FILE__, __LINE__, __func__, FERR_SYSTEM, \ ferr_set_internal_ext(__FILE__, __LINE__, __func__, FERR_SYSTEM, path, \
path, errno, __VA_ARGS__) errno, __VA_ARGS__)
#include "vty.h" #include "vty.h"
/* print error message to vty; $ERR is replaced by the error's message */ /* print error message to vty; $ERR is replaced by the error's message */
void vty_print_error(struct vty *vty, ferr_r err, const char *msg, ...); void vty_print_error(struct vty *vty, ferr_r err, const char *msg, ...);
#define CMD_FERR_DO(func, action, ...) \ #define CMD_FERR_DO(func, action, ...) \
do { ferr_r cmd_retval = func; \ do { \
if (cmd_retval) { \ ferr_r cmd_retval = func; \
vty_print_error(vty, cmd_retval, __VA_ARGS__); \ if (cmd_retval) { \
action; \ vty_print_error(vty, cmd_retval, __VA_ARGS__); \
} \ action; \
} \
} while (0) } while (0)
#define CMD_FERR_RETURN(func, ...) \ #define CMD_FERR_RETURN(func, ...) \
CMD_FERR_DO(func, return CMD_WARNING_CONFIG_FAILED, __VA_ARGS__) CMD_FERR_DO(func, return CMD_WARNING_CONFIG_FAILED, __VA_ARGS__)
#define CMD_FERR_GOTO(func, label, ...) \ #define CMD_FERR_GOTO(func, label, ...) \
CMD_FERR_DO(func, goto label, __VA_ARGS__) CMD_FERR_DO(func, goto label, __VA_ARGS__)
/* example: /* example: uses bogus #define to keep indent.py happy */
#ifdef THIS_IS_AN_EXAMPLE
ferr_r foo_bar_set(struct object *obj, int bar) ferr_r foo_bar_set(struct object *obj, int bar)
{ {
if (bar < 1 || bar >= 100) if (bar < 1 || bar >= 100)
return ferr_config_invalid("bar setting (%d) must be 0<x<100", bar); return ferr_config_invalid("bar setting (%d) must be 0<x<100",
bar);
obj->bar = bar; obj->bar = bar;
if (ioctl (obj->fd, bar)) if (ioctl(obj->fd, bar))
return ferr_system_errno("couldn't set bar to %d", bar); return ferr_system_errno("couldn't set bar to %d", bar);
return ferr_ok(); return ferr_ok();
@ -182,10 +183,10 @@ ferr_r foo_bar_set(struct object *obj, int bar)
DEFUN("bla") DEFUN("bla")
{ {
CMD_FERR_RETURN(foo_bar_set(obj, atoi(argv[1])), CMD_FERR_RETURN(foo_bar_set(obj, atoi(argv[1])),
"command failed: $ERR\n"); "command failed: $ERR\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
*/ #endif /* THIS_IS_AN_EXAMPLE */
#endif /* _FERR_H */ #endif /* _FERR_H */

View File

@ -302,8 +302,7 @@ struct qm_trace {
(STAILQ_EMPTY((head)) \ (STAILQ_EMPTY((head)) \
? NULL \ ? NULL \
: ((struct type *)(void *)((char *)((head)->stqh_last) \ : ((struct type *)(void *)((char *)((head)->stqh_last) \
- offsetof(struct type, \ - offsetof(struct type, field))))
field))))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)

View File

@ -46,6 +46,8 @@
#define atomic_exchange_explicit __atomic_exchange_n #define atomic_exchange_explicit __atomic_exchange_n
#define atomic_fetch_add_explicit __atomic_fetch_add #define atomic_fetch_add_explicit __atomic_fetch_add
#define atomic_fetch_sub_explicit __atomic_fetch_sub #define atomic_fetch_sub_explicit __atomic_fetch_sub
#define atomic_fetch_and_explicit __atomic_fetch_and
#define atomic_fetch_or_explicit __atomic_fetch_or
#define atomic_compare_exchange_weak_explicit(atom, expect, desire, mem1, \ #define atomic_compare_exchange_weak_explicit(atom, expect, desire, mem1, \
mem2) \ mem2) \
@ -135,6 +137,20 @@
*_expect = rval; \ *_expect = rval; \
ret; \ ret; \
}) })
#define atomic_fetch_and_explicit(ptr, val, mem) \
({ \
__sync_synchronize(); \
typeof(*ptr) rval = __sync_fetch_and_and(ptr, val); \
__sync_synchronize(); \
rval; \
})
#define atomic_fetch_or_explicit(ptr, val, mem) \
({ \
__sync_synchronize(); \
typeof(*ptr) rval = __sync_fetch_and_or(ptr, val); \
__sync_synchronize(); \
rval; \
})
#else /* !HAVE___ATOMIC && !HAVE_STDATOMIC_H */ #else /* !HAVE___ATOMIC && !HAVE_STDATOMIC_H */
#error no atomic functions... #error no atomic functions...

View File

@ -402,8 +402,8 @@ DEFUN (grammar_findambig,
nodegraph = cnode->cmdgraph; nodegraph = cnode->cmdgraph;
if (!nodegraph) if (!nodegraph)
continue; continue;
vty_out(vty, "scanning node %d (%s)\n", vty_out(vty, "scanning node %d (%s)\n", scannode - 1,
scannode - 1, node_names[scannode - 1]); node_names[scannode - 1]);
} }
commands = cmd_graph_permutations(nodegraph); commands = cmd_graph_permutations(nodegraph);

View File

@ -38,9 +38,8 @@ void _hook_register(struct hook *hook, void *funcptr, void *arg, bool has_arg,
he->priority = priority; he->priority = priority;
for (pos = &hook->entries; *pos; pos = &(*pos)->next) for (pos = &hook->entries; *pos; pos = &(*pos)->next)
if (hook->reverse if (hook->reverse ? (*pos)->priority < priority
? (*pos)->priority < priority : (*pos)->priority >= priority)
: (*pos)->priority >= priority)
break; break;
he->next = *pos; he->next = *pos;

View File

@ -150,8 +150,8 @@ extern void _hook_register(struct hook *hook, void *funcptr, void *arg,
NULL, false, THIS_MODULE, #func, prio) NULL, false, THIS_MODULE, #func, prio)
#define hook_register_arg_prio(hookname, prio, func, arg) \ #define hook_register_arg_prio(hookname, prio, func, arg) \
_hook_register(&_hook_##hookname, \ _hook_register(&_hook_##hookname, \
_hook_typecheck_arg_##hookname(func), \ _hook_typecheck_arg_##hookname(func), arg, true, \
arg, true, THIS_MODULE, #func, prio) THIS_MODULE, #func, prio)
extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
bool has_arg); bool has_arg);
@ -190,7 +190,7 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
{ \ { \
return (void *)funcptr; \ return (void *)funcptr; \
} }
#define DECLARE_KOOH(hookname, arglist, passlist) \ #define DECLARE_KOOH(hookname, arglist, passlist) \
DECLARE_HOOK(hookname, arglist, passlist) DECLARE_HOOK(hookname, arglist, passlist)
/* use in source file - contains hook-related definitions. /* use in source file - contains hook-related definitions.
@ -220,9 +220,9 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
return hooksum; \ return hooksum; \
} }
#define DEFINE_HOOK(hookname, arglist, passlist) \ #define DEFINE_HOOK(hookname, arglist, passlist) \
DEFINE_HOOK_INT(hookname, arglist, passlist, false) DEFINE_HOOK_INT(hookname, arglist, passlist, false)
#define DEFINE_KOOH(hookname, arglist, passlist) \ #define DEFINE_KOOH(hookname, arglist, passlist) \
DEFINE_HOOK_INT(hookname, arglist, passlist, true) DEFINE_HOOK_INT(hookname, arglist, passlist, true)
#endif /* _FRR_HOOK_H */ #endif /* _FRR_HOOK_H */

View File

@ -48,8 +48,8 @@ RB_GENERATE(if_index_head, interface, index_entry, if_cmp_index_func);
DEFINE_QOBJ_TYPE(interface) DEFINE_QOBJ_TYPE(interface)
DEFINE_HOOK(if_add, (struct interface *ifp), (ifp)) DEFINE_HOOK(if_add, (struct interface * ifp), (ifp))
DEFINE_KOOH(if_del, (struct interface *ifp), (ifp)) DEFINE_KOOH(if_del, (struct interface * ifp), (ifp))
/* List of interfaces in only the default VRF */ /* List of interfaces in only the default VRF */
int ptm_enable = 0; int ptm_enable = 0;
@ -152,7 +152,7 @@ struct interface *if_create(const char *name, vrf_id_t vrf_id)
SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
QOBJ_REG(ifp, interface); QOBJ_REG(ifp, interface);
hook_call(if_add, ifp); hook_call(if_add, ifp);
return ifp; return ifp;
} }
@ -181,7 +181,7 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
/* Delete interface structure. */ /* Delete interface structure. */
void if_delete_retain(struct interface *ifp) void if_delete_retain(struct interface *ifp)
{ {
hook_call(if_del, ifp); hook_call(if_del, ifp);
QOBJ_UNREG(ifp); QOBJ_UNREG(ifp);
/* Free connected address list */ /* Free connected address list */
@ -225,7 +225,7 @@ struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id)
if (vrf_id == VRF_UNKNOWN) { if (vrf_id == VRF_UNKNOWN) {
struct interface *ifp; struct interface *ifp;
RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
ifp = if_lookup_by_index(ifindex, vrf->vrf_id); ifp = if_lookup_by_index(ifindex, vrf->vrf_id);
if (ifp) if (ifp)
return ifp; return ifp;
@ -404,8 +404,7 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty)
* this should not be considered as an update * this should not be considered as an update
* then create the new interface * then create the new interface
*/ */
if (ifp->vrf_id != vrf_id && if (ifp->vrf_id != vrf_id && vrf_is_mapped_on_netns(vrf_id))
vrf_is_mapped_on_netns(vrf_id))
return if_create(name, vrf_id); return if_create(name, vrf_id);
/* If it came from the kernel /* If it came from the kernel
* or by way of zclient, believe it and update * or by way of zclient, believe it and update
@ -477,6 +476,12 @@ int if_is_loopback(struct interface *ifp)
return (ifp->flags & (IFF_LOOPBACK | IFF_NOXMIT | IFF_VIRTUAL)); return (ifp->flags & (IFF_LOOPBACK | IFF_NOXMIT | IFF_VIRTUAL));
} }
/* Check interface is VRF */
int if_is_vrf(struct interface *ifp)
{
return CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
}
/* Does this interface support broadcast ? */ /* Does this interface support broadcast ? */
int if_is_broadcast(struct interface *ifp) int if_is_broadcast(struct interface *ifp)
{ {

View File

@ -288,6 +288,7 @@ struct interface {
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(if_name_head, interface); RB_HEAD(if_name_head, interface);
RB_PROTOTYPE(if_name_head, interface, name_entry, if_cmp_func); RB_PROTOTYPE(if_name_head, interface, name_entry, if_cmp_func);
RB_HEAD(if_index_head, interface); RB_HEAD(if_index_head, interface);
@ -337,8 +338,8 @@ DECLARE_QOBJ_TYPE(interface)
* can use 1000+ so they run after the daemon has initialised daemon-specific * can use 1000+ so they run after the daemon has initialised daemon-specific
* interface data * interface data
*/ */
DECLARE_HOOK(if_add, (struct interface *ifp), (ifp)) DECLARE_HOOK(if_add, (struct interface * ifp), (ifp))
DECLARE_KOOH(if_del, (struct interface *ifp), (ifp)) DECLARE_KOOH(if_del, (struct interface * ifp), (ifp))
/* Connected address structure. */ /* Connected address structure. */
struct connected { struct connected {
@ -460,7 +461,7 @@ extern int if_cmp_name_func(char *, char *);
* else think before you use VRF_UNKNOWN * else think before you use VRF_UNKNOWN
*/ */
extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id); extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
extern struct interface *if_create(const char *name, vrf_id_t vrf_id); extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_lookup_exact_address(void *matchaddr, int family, extern struct interface *if_lookup_exact_address(void *matchaddr, int family,
vrf_id_t vrf_id); vrf_id_t vrf_id);
@ -491,6 +492,7 @@ extern int if_is_running(struct interface *);
extern int if_is_operative(struct interface *); extern int if_is_operative(struct interface *);
extern int if_is_no_ptm_operative(struct interface *); extern int if_is_no_ptm_operative(struct interface *);
extern int if_is_loopback(struct interface *); extern int if_is_loopback(struct interface *);
extern int if_is_vrf(struct interface *ifp);
extern int if_is_broadcast(struct interface *); extern int if_is_broadcast(struct interface *);
extern int if_is_pointopoint(struct interface *); extern int if_is_pointopoint(struct interface *);
extern int if_is_multicast(struct interface *); extern int if_is_multicast(struct interface *);

Some files were not shown because too many files have changed in this diff Show More