summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am5
-rw-r--r--bfdd/bfd.c15
-rw-r--r--bfdd/bfdd_vty.c2
-rw-r--r--bgpd/bgp_advertise.c2
-rw-r--r--bgpd/bgp_advertise.h2
-rw-r--r--bgpd/bgp_aspath.c26
-rw-r--r--bgpd/bgp_aspath.h5
-rw-r--r--bgpd/bgp_attr.c28
-rw-r--r--bgpd/bgp_attr.h13
-rw-r--r--bgpd/bgp_community.c12
-rw-r--r--bgpd/bgp_community.h3
-rw-r--r--bgpd/bgp_damp.c3
-rw-r--r--bgpd/bgp_ecommunity.c6
-rw-r--r--bgpd/bgp_ecommunity.h2
-rw-r--r--bgpd/bgp_evpn.c24
-rw-r--r--bgpd/bgp_keepalives.c3
-rw-r--r--bgpd/bgp_lcommunity.c8
-rw-r--r--bgpd/bgp_lcommunity.h2
-rw-r--r--bgpd/bgp_nexthop.c19
-rw-r--r--bgpd/bgp_nht.c11
-rw-r--r--bgpd/bgp_nht.h7
-rw-r--r--bgpd/bgp_pbr.c63
-rw-r--r--bgpd/bgp_pbr.h6
-rw-r--r--bgpd/bgp_route.c119
-rw-r--r--bgpd/bgp_routemap.c70
-rw-r--r--bgpd/bgp_updgrp.c38
-rw-r--r--bgpd/bgp_vty.c21
-rw-r--r--bgpd/bgpd.c36
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c27
-rw-r--r--bgpd/rfapi/rfapi_import.c2
-rw-r--r--bgpd/rfapi/rfapi_vty.c4
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c1
-rw-r--r--bgpd/rfapi/vnc_zebra.c17
-rwxr-xr-xconfigure.ac141
-rw-r--r--debianpkg/control2
-rw-r--r--debianpkg/frr.dirs1
-rw-r--r--debianpkg/frr.install1
-rwxr-xr-xdebianpkg/rules57
-rw-r--r--isisd/fabricd.c2
-rw-r--r--isisd/isis_spf_private.h6
-rw-r--r--isisd/isis_tx_queue.c8
-rw-r--r--lib/command.c22
-rw-r--r--lib/command.h2
-rw-r--r--lib/distribute.c10
-rw-r--r--lib/ferr.c2
-rw-r--r--lib/hash.c4
-rw-r--r--lib/hash.h7
-rw-r--r--lib/if_rmap.c2
-rw-r--r--lib/log.c81
-rw-r--r--lib/qobj.c2
-rw-r--r--lib/routemap.c16
-rw-r--r--lib/subdir.am2
-rw-r--r--lib/table.c2
-rw-r--r--lib/thread.c4
-rw-r--r--lib/vrf.c2
-rw-r--r--lib/vty.c28
-rw-r--r--lib/vty.h7
-rw-r--r--nhrpd/nhrp_cache.c4
-rw-r--r--nhrpd/nhrp_peer.c3
-rw-r--r--nhrpd/nhrp_vc.c3
-rw-r--r--nhrpd/reqid.c3
-rw-r--r--ospf6d/ospf6_interface.c14
-rw-r--r--ospf6d/ospf6_neighbor.c6
-rw-r--r--ospfd/ospf_packet.c4
-rw-r--r--ospfd/ospf_sr.c5
-rw-r--r--pbrd/pbr_nht.c20
-rw-r--r--pimd/pim_igmp.c6
-rw-r--r--pimd/pim_msdp.c4
-rw-r--r--pimd/pim_oil.c6
-rw-r--r--pimd/pim_rpf.c2
-rw-r--r--pimd/pim_rpf.h2
-rw-r--r--pimd/pim_upstream.c6
-rw-r--r--pimd/pim_upstream.h2
-rw-r--r--ripd/rip_peer.c5
-rw-r--r--ripngd/ripng_peer.c2
-rw-r--r--staticd/static_routes.c7
-rw-r--r--staticd/static_routes.h9
-rw-r--r--staticd/static_vty.c70
-rw-r--r--staticd/static_zebra.c6
-rw-r--r--tests/lib/test_segv.c31
-rw-r--r--vtysh/subdir.am2
-rw-r--r--vtysh/vtysh.c2
-rw-r--r--zebra/zebra_mpls.c4
-rw-r--r--zebra/zebra_pbr.c82
-rw-r--r--zebra/zebra_pbr.h9
-rw-r--r--zebra/zebra_rib.c11
-rw-r--r--zebra/zebra_vxlan.c42
87 files changed, 872 insertions, 513 deletions
diff --git a/Makefile.am b/Makefile.am
index 65aed79152..474f8ab5b5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,6 +4,7 @@ AUTOMAKE_OPTIONS = subdir-objects 1.12
ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = \
+ $(UNWIND_CFLAGS) \
$(SAN_FLAGS) \
$(WERROR) \
# end
@@ -18,6 +19,10 @@ AM_LDFLAGS = \
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DCONFDATE=$(CONFDATE)
LIBCAP = @LIBCAP@
+AR_FLAGS = @AR_FLAGS@
+ARFLAGS = @ARFLAGS@
+RANLIB = @RANLIB@
+
# these two targets are provided to easily grab autoconf/Makefile variables
# you can use either:
# eval `make VARFD=3 shvar-CFLAGS 3>&1 1>&2`
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 32fa02d99d..814366f320 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -861,15 +861,10 @@ static struct hash *bfd_vrf_hash;
static struct hash *bfd_iface_hash;
static unsigned int bfd_id_hash_do(void *p);
-static int bfd_id_hash_cmp(const void *n1, const void *n2);
static unsigned int bfd_shop_hash_do(void *p);
-static int bfd_shop_hash_cmp(const void *n1, const void *n2);
static unsigned int bfd_mhop_hash_do(void *p);
-static int bfd_mhop_hash_cmp(const void *n1, const void *n2);
static unsigned int bfd_vrf_hash_do(void *p);
-static int bfd_vrf_hash_cmp(const void *n1, const void *n2);
static unsigned int bfd_iface_hash_do(void *p);
-static int bfd_iface_hash_cmp(const void *n1, const void *n2);
static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop);
static void _shop_key2(struct bfd_session *bs, const struct bfd_shop_key *shop);
@@ -889,7 +884,7 @@ static unsigned int bfd_id_hash_do(void *p)
return jhash_1word(bs->discrs.my_discr, 0);
}
-static int bfd_id_hash_cmp(const void *n1, const void *n2)
+static bool bfd_id_hash_cmp(const void *n1, const void *n2)
{
const struct bfd_session *bs1 = n1, *bs2 = n2;
@@ -904,7 +899,7 @@ static unsigned int bfd_shop_hash_do(void *p)
return jhash(&bs->shop, sizeof(bs->shop), 0);
}
-static int bfd_shop_hash_cmp(const void *n1, const void *n2)
+static bool bfd_shop_hash_cmp(const void *n1, const void *n2)
{
const struct bfd_session *bs1 = n1, *bs2 = n2;
@@ -919,7 +914,7 @@ static unsigned int bfd_mhop_hash_do(void *p)
return jhash(&bs->mhop, sizeof(bs->mhop), 0);
}
-static int bfd_mhop_hash_cmp(const void *n1, const void *n2)
+static bool bfd_mhop_hash_cmp(const void *n1, const void *n2)
{
const struct bfd_session *bs1 = n1, *bs2 = n2;
@@ -934,7 +929,7 @@ static unsigned int bfd_vrf_hash_do(void *p)
return jhash_1word(vrf->vrf_id, 0);
}
-static int bfd_vrf_hash_cmp(const void *n1, const void *n2)
+static bool bfd_vrf_hash_cmp(const void *n1, const void *n2)
{
const struct bfd_vrf *v1 = n1, *v2 = n2;
@@ -949,7 +944,7 @@ static unsigned int bfd_iface_hash_do(void *p)
return string_hash_make(iface->ifname);
}
-static int bfd_iface_hash_cmp(const void *n1, const void *n2)
+static bool bfd_iface_hash_cmp(const void *n1, const void *n2)
{
const struct bfd_iface *i1 = n1, *i2 = n2;
diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c
index 51dd9cb26d..8f8fff6b18 100644
--- a/bfdd/bfdd_vty.c
+++ b/bfdd/bfdd_vty.c
@@ -90,7 +90,7 @@ DEFUN_NOSH(bfd_enter, bfd_enter_cmd, "bfd", "Configure BFD peers\n")
DEFUN_NOSH(
bfd_peer_enter, bfd_peer_enter_cmd,
- "peer <A.B.C.D|X:X::X:X> [{multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
+ "peer <A.B.C.D|X:X::X:X> [{[multihop] local-address <A.B.C.D|X:X::X:X>|interface IFNAME|vrf NAME}]",
PEER_STR PEER_IPV4_STR PEER_IPV6_STR
MHOP_STR
LOCAL_STR LOCAL_IPV4_STR LOCAL_IPV6_STR
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index be47cbb6d8..5b2cb57921 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -71,7 +71,7 @@ unsigned int baa_hash_key(void *p)
return attrhash_key_make(baa->attr);
}
-int baa_hash_cmp(const void *p1, const void *p2)
+bool baa_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_advertise_attr *baa1 = p1;
const struct bgp_advertise_attr *baa2 = p2;
diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h
index 6ff476e7b8..1912aec1bf 100644
--- a/bgpd/bgp_advertise.h
+++ b/bgpd/bgp_advertise.h
@@ -177,7 +177,7 @@ extern void bgp_adj_in_remove(struct bgp_node *, struct bgp_adj_in *);
extern void bgp_sync_init(struct peer *);
extern void bgp_sync_delete(struct peer *);
extern unsigned int baa_hash_key(void *p);
-extern int baa_hash_cmp(const void *p1, const void *p2);
+extern bool baa_hash_cmp(const void *p1, const void *p2);
extern void bgp_advertise_add(struct bgp_advertise_attr *baa,
struct bgp_advertise *adv);
extern struct bgp_advertise *bgp_advertise_new(void);
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 0924223ddc..4f756519ca 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -1726,23 +1726,23 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
/* Compare leftmost AS value for MED check. If as1's leftmost AS and
as2's leftmost AS is same return 1. (confederation as-path
only). */
-int aspath_cmp_left_confed(const struct aspath *aspath1,
- const struct aspath *aspath2)
+bool aspath_cmp_left_confed(const struct aspath *aspath1,
+ const struct aspath *aspath2)
{
if (!(aspath1 && aspath2))
- return 0;
+ return false;
if (!(aspath1->segments && aspath2->segments))
- return 0;
+ return false;
if ((aspath1->segments->type != AS_CONFED_SEQUENCE)
|| (aspath2->segments->type != AS_CONFED_SEQUENCE))
- return 0;
+ return false;
if (aspath1->segments->as[0] == aspath2->segments->as[0])
- return 1;
+ return true;
- return 0;
+ return false;
}
/* Delete all AS_CONFED_SEQUENCE/SET segments from aspath.
@@ -2008,7 +2008,7 @@ unsigned int aspath_key_make(void *p)
}
/* If two aspath have same value then return 1 else return 0 */
-int aspath_cmp(const void *arg1, const void *arg2)
+bool aspath_cmp(const void *arg1, const void *arg2)
{
const struct assegment *seg1 = ((const struct aspath *)arg1)->segments;
const struct assegment *seg2 = ((const struct aspath *)arg2)->segments;
@@ -2016,18 +2016,18 @@ int aspath_cmp(const void *arg1, const void *arg2)
while (seg1 || seg2) {
int i;
if ((!seg1 && seg2) || (seg1 && !seg2))
- return 0;
+ return false;
if (seg1->type != seg2->type)
- return 0;
+ return false;
if (seg1->length != seg2->length)
- return 0;
+ return false;
for (i = 0; i < seg1->length; i++)
if (seg1->as[i] != seg2->as[i])
- return 0;
+ return false;
seg1 = seg1->next;
seg2 = seg2->next;
}
- return 1;
+ return true;
}
/* AS path hash initialize. */
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index 1acc2f67a6..9c9c687a6b 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -85,9 +85,10 @@ extern struct aspath *aspath_filter_exclude(struct aspath *, struct aspath *);
extern struct aspath *aspath_add_seq_n(struct aspath *, as_t, unsigned);
extern struct aspath *aspath_add_seq(struct aspath *, as_t);
extern struct aspath *aspath_add_confed_seq(struct aspath *, as_t);
-extern int aspath_cmp(const void *, const void *);
+extern bool aspath_cmp(const void *as1, const void *as2);
extern int aspath_cmp_left(const struct aspath *, const struct aspath *);
-extern int aspath_cmp_left_confed(const struct aspath *, const struct aspath *);
+extern bool aspath_cmp_left_confed(const struct aspath *as1,
+ const struct aspath *as2xs);
extern struct aspath *aspath_delete_confed_seq(struct aspath *);
extern struct aspath *aspath_empty(void);
extern struct aspath *aspath_empty_get(void);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index c7d7c56a12..e183073eca 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -146,7 +146,7 @@ static unsigned int cluster_hash_key_make(void *p)
return jhash(cluster->list, cluster->length, 0);
}
-static int cluster_hash_cmp(const void *p1, const void *p2)
+static bool cluster_hash_cmp(const void *p1, const void *p2)
{
const struct cluster_list *cluster1 = p1;
const struct cluster_list *cluster2 = p2;
@@ -355,7 +355,7 @@ static unsigned int encap_hash_key_make(void *p)
return jhash(encap->value, encap->length, 0);
}
-static int encap_hash_cmp(const void *p1, const void *p2)
+static bool encap_hash_cmp(const void *p1, const void *p2)
{
return encap_same((const struct bgp_attr_encap_subtlv *)p1,
(const struct bgp_attr_encap_subtlv *)p2);
@@ -441,7 +441,7 @@ static unsigned int transit_hash_key_make(void *p)
return jhash(transit->val, transit->length, 0);
}
-static int transit_hash_cmp(const void *p1, const void *p2)
+static bool transit_hash_cmp(const void *p1, const void *p2)
{
const struct transit *transit1 = p1;
const struct transit *transit2 = p2;
@@ -527,7 +527,7 @@ unsigned int attrhash_key_make(void *p)
return key;
}
-int attrhash_cmp(const void *p1, const void *p2)
+bool attrhash_cmp(const void *p1, const void *p2)
{
const struct attr *attr1 = p1;
const struct attr *attr2 = p2;
@@ -565,10 +565,10 @@ int attrhash_cmp(const void *p1, const void *p2)
&& overlay_index_same(attr1, attr2)
&& attr1->nh_ifindex == attr2->nh_ifindex
&& attr1->nh_lla_ifindex == attr2->nh_lla_ifindex)
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static void attrhash_init(void)
@@ -723,8 +723,10 @@ struct attr *bgp_attr_default_set(struct attr *attr, uint8_t origin)
/* Create the attributes for an aggregate */
struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
struct aspath *aspath,
- struct community *community, int as_set,
- uint8_t atomic_aggregate)
+ struct community *community,
+ struct ecommunity *ecommunity,
+ struct lcommunity *lcommunity,
+ int as_set, uint8_t atomic_aggregate)
{
struct attr attr;
struct attr *new;
@@ -760,6 +762,16 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
+ if (ecommunity) {
+ attr.ecommunity = ecommunity;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
+ }
+
+ if (lcommunity) {
+ attr.lcommunity = lcommunity;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
+ }
+
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
bgp_attr_add_gshut_community(&attr);
}
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 883b129136..47a4182fee 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -272,10 +272,13 @@ extern void bgp_attr_unintern_sub(struct attr *);
extern void bgp_attr_unintern(struct attr **);
extern void bgp_attr_flush(struct attr *);
extern struct attr *bgp_attr_default_set(struct attr *attr, uint8_t);
-extern struct attr *bgp_attr_aggregate_intern(struct bgp *, uint8_t,
- struct aspath *,
- struct community *, int as_set,
- uint8_t);
+extern struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
+ struct aspath *aspath,
+ struct community *community,
+ struct ecommunity *ecommunity,
+ struct lcommunity *lcommunity,
+ int as_set,
+ uint8_t atomic_aggregate);
extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
struct stream *, struct attr *,
struct bpacket_attr_vec_arr *vecarr,
@@ -284,7 +287,7 @@ extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
mpls_label_t *, uint32_t, int, uint32_t);
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
struct prefix *);
-extern int attrhash_cmp(const void *, const void *);
+extern bool attrhash_cmp(const void *arg1, const void *arg2);
extern unsigned int attrhash_key_make(void *);
extern void attr_show_all(struct vty *);
extern unsigned long int attr_count(void);
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index e40674d635..9e5eb273a0 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -614,17 +614,17 @@ int community_match(const struct community *com1, const struct community *com2)
/* If two aspath have same value then return 1 else return 0. This
function is used by hash package. */
-int community_cmp(const struct community *com1, const struct community *com2)
+bool community_cmp(const struct community *com1, const struct community *com2)
{
if (com1 == NULL && com2 == NULL)
- return 1;
+ return true;
if (com1 == NULL || com2 == NULL)
- return 0;
+ return false;
if (com1->size == com2->size)
if (memcmp(com1->val, com2->val, com1->size * 4) == 0)
- return 1;
- return 0;
+ return true;
+ return false;
}
/* Add com2 to the end of com1. */
@@ -902,7 +902,7 @@ void community_init(void)
{
comhash =
hash_create((unsigned int (*)(void *))community_hash_make,
- (int (*)(const void *, const void *))community_cmp,
+ (bool (*)(const void *, const void *))community_cmp,
"BGP Community Hash");
}
diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h
index 61af9f038c..afb9876f29 100644
--- a/bgpd/bgp_community.h
+++ b/bgpd/bgp_community.h
@@ -77,7 +77,8 @@ extern char *community_str(struct community *, bool make_json);
extern unsigned int community_hash_make(struct community *);
extern struct community *community_str2com(const char *);
extern int community_match(const struct community *, const struct community *);
-extern int community_cmp(const struct community *, const struct community *);
+extern bool community_cmp(const struct community *c1,
+ const struct community *c2);
extern struct community *community_merge(struct community *,
struct community *);
extern struct community *community_delete(struct community *,
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index cff5caf52f..86cee39a62 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -448,12 +448,15 @@ static void bgp_damp_config_clean(struct bgp_damp_config *damp)
{
/* Free decay array */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
+ damp->decay_array_size = 0;
/* Free reuse index array */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
+ damp->reuse_index_size = 0;
/* Free reuse list array. */
XFREE(MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
+ damp->reuse_list_size = 0;
}
/* Clean all the bgp_damp_info stored in reuse_list. */
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 2e5b219ef9..8029164184 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -253,16 +253,16 @@ unsigned int ecommunity_hash_make(void *arg)
}
/* Compare two Extended Communities Attribute structure. */
-int ecommunity_cmp(const void *arg1, const void *arg2)
+bool ecommunity_cmp(const void *arg1, const void *arg2)
{
const struct ecommunity *ecom1 = arg1;
const struct ecommunity *ecom2 = arg2;
if (ecom1 == NULL && ecom2 == NULL)
- return 1;
+ return true;
if (ecom1 == NULL || ecom2 == NULL)
- return 0;
+ return false;
return (ecom1->size == ecom2->size
&& memcmp(ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE)
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index c71f371a97..d43403ed8d 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -154,7 +154,7 @@ extern struct ecommunity *ecommunity_merge(struct ecommunity *,
struct ecommunity *);
extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
extern struct ecommunity *ecommunity_intern(struct ecommunity *);
-extern int ecommunity_cmp(const void *, const void *);
+extern bool ecommunity_cmp(const void *arg1, const void *arg2);
extern void ecommunity_unintern(struct ecommunity **);
extern unsigned int ecommunity_hash_make(void *);
extern struct ecommunity *ecommunity_str2com(const char *, int, int);
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index d6ed84ff56..b67d93d4f5 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -92,16 +92,16 @@ static unsigned int esi_hash_keymake(void *p)
/*
* Compare two ESIs.
*/
-static int esi_cmp(const void *p1, const void *p2)
+static bool esi_cmp(const void *p1, const void *p2)
{
const struct evpnes *pes1 = p1;
const struct evpnes *pes2 = p2;
if (pes1 == NULL && pes2 == NULL)
- return 1;
+ return true;
if (pes1 == NULL || pes2 == NULL)
- return 0;
+ return false;
return (memcmp(pes1->esi.val, pes2->esi.val, ESI_BYTES) == 0);
}
@@ -118,15 +118,15 @@ static unsigned int vni_hash_key_make(void *p)
/*
* Comparison function for vni hash
*/
-static int vni_hash_cmp(const void *p1, const void *p2)
+static bool vni_hash_cmp(const void *p1, const void *p2)
{
const struct bgpevpn *vpn1 = p1;
const struct bgpevpn *vpn2 = p2;
if (!vpn1 && !vpn2)
- return 1;
+ return true;
if (!vpn1 || !vpn2)
- return 0;
+ return false;
return (vpn1->vni == vpn2->vni);
}
@@ -152,16 +152,16 @@ static unsigned int vrf_import_rt_hash_key_make(void *p)
/*
* Comparison function for vrf import rt hash
*/
-static int vrf_import_rt_hash_cmp(const void *p1, const void *p2)
+static bool vrf_import_rt_hash_cmp(const void *p1, const void *p2)
{
const struct vrf_irt_node *irt1 = p1;
const struct vrf_irt_node *irt2 = p2;
if (irt1 == NULL && irt2 == NULL)
- return 1;
+ return true;
if (irt1 == NULL || irt2 == NULL)
- return 0;
+ return false;
return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
}
@@ -269,16 +269,16 @@ static unsigned int import_rt_hash_key_make(void *p)
/*
* Comparison function for import rt hash
*/
-static int import_rt_hash_cmp(const void *p1, const void *p2)
+static bool import_rt_hash_cmp(const void *p1, const void *p2)
{
const struct irt_node *irt1 = p1;
const struct irt_node *irt2 = p2;
if (irt1 == NULL && irt2 == NULL)
- return 1;
+ return true;
if (irt1 == NULL || irt2 == NULL)
- return 0;
+ return false;
return (memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
}
diff --git a/bgpd/bgp_keepalives.c b/bgpd/bgp_keepalives.c
index 91fa8fa373..50aad70ddc 100644
--- a/bgpd/bgp_keepalives.c
+++ b/bgpd/bgp_keepalives.c
@@ -123,10 +123,11 @@ static void peer_process(struct hash_backet *hb, void *arg)
*next_update = diff;
}
-static int peer_hash_cmp(const void *f, const void *s)
+static bool peer_hash_cmp(const void *f, const void *s)
{
const struct pkat *p1 = f;
const struct pkat *p2 = s;
+
return p1->peer == p2->peer;
}
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index 3e160bc56e..cfc9af7777 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -313,11 +313,17 @@ unsigned int lcommunity_hash_make(void *arg)
}
/* Compare two Large Communities Attribute structure. */
-int lcommunity_cmp(const void *arg1, const void *arg2)
+bool lcommunity_cmp(const void *arg1, const void *arg2)
{
const struct lcommunity *lcom1 = arg1;
const struct lcommunity *lcom2 = arg2;
+ if (lcom1 == NULL && lcom2 == NULL)
+ return 1;
+
+ if (lcom1 == NULL || lcom2 == NULL)
+ return 0;
+
return (lcom1->size == lcom2->size
&& memcmp(lcom1->val, lcom2->val, lcom_length(lcom1)) == 0);
}
diff --git a/bgpd/bgp_lcommunity.h b/bgpd/bgp_lcommunity.h
index c88a016396..23c777d9fd 100644
--- a/bgpd/bgp_lcommunity.h
+++ b/bgpd/bgp_lcommunity.h
@@ -60,7 +60,7 @@ extern struct lcommunity *lcommunity_merge(struct lcommunity *,
struct lcommunity *);
extern struct lcommunity *lcommunity_uniq_sort(struct lcommunity *);
extern struct lcommunity *lcommunity_intern(struct lcommunity *);
-extern int lcommunity_cmp(const void *, const void *);
+extern bool lcommunity_cmp(const void *arg1, const void *arg2);
extern void lcommunity_unintern(struct lcommunity **);
extern unsigned int lcommunity_hash_make(void *);
extern struct hash *lcommunity_hash(void);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 45c596254f..5ed6fd6ebe 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -84,11 +84,18 @@ static void bgp_nexthop_cache_reset(struct bgp_table *table)
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
bnc = bgp_nexthop_get_node_info(rn);
- if (bnc != NULL) {
- bnc_free(bnc);
- bgp_nexthop_set_node_info(rn, NULL);
- bgp_unlock_node(rn);
+ if (!bnc)
+ continue;
+
+ while (!LIST_EMPTY(&(bnc->paths))) {
+ struct bgp_path_info *path = LIST_FIRST(&(bnc->paths));
+
+ path_nh_map(path, bnc, false);
}
+
+ bnc_free(bnc);
+ bgp_nexthop_set_node_info(rn, NULL);
+ bgp_unlock_node(rn);
}
}
@@ -116,7 +123,7 @@ static unsigned int bgp_tip_hash_key_make(void *p)
return jhash_1word(addr->addr.s_addr, 0);
}
-static int bgp_tip_hash_cmp(const void *p1, const void *p2)
+static bool bgp_tip_hash_cmp(const void *p1, const void *p2)
{
const struct tip_addr *addr1 = p1;
const struct tip_addr *addr2 = p2;
@@ -239,7 +246,7 @@ static unsigned int bgp_address_hash_key_make(void *p)
return jhash_1word(addr->addr.s_addr, 0);
}
-static int bgp_address_hash_cmp(const void *p1, const void *p2)
+static bool bgp_address_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_addr *addr1 = p1;
const struct bgp_addr *addr2 = p2;
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 5203e6eefd..e764860bcc 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -51,8 +51,6 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
int is_bgp_static_route);
static void evaluate_paths(struct bgp_nexthop_cache *bnc);
static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
-static void path_nh_map(struct bgp_path_info *path,
- struct bgp_nexthop_cache *bnc, int keep);
static int bgp_isvalid_nexthop(struct bgp_nexthop_cache *bnc)
{
@@ -111,7 +109,7 @@ void bgp_unlink_nexthop(struct bgp_path_info *path)
if (!bnc)
return;
- path_nh_map(path, NULL, 0);
+ path_nh_map(path, NULL, false);
bgp_unlink_nexthop_check(bnc);
}
@@ -253,7 +251,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
*/
bgp_unlink_nexthop(pi);
- path_nh_map(pi, bnc, 1); /* updates NHT pi list reference */
+ /* updates NHT pi list reference */
+ path_nh_map(pi, bnc, true);
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
(bgp_path_info_extra_get(pi))->igpmetric = bnc->metric;
@@ -789,8 +788,8 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
* make - if set, make the association. if unset, just break the existing
* association.
*/
-static void path_nh_map(struct bgp_path_info *path,
- struct bgp_nexthop_cache *bnc, int make)
+void path_nh_map(struct bgp_path_info *path, struct bgp_nexthop_cache *bnc,
+ bool make)
{
if (path->nexthop) {
LIST_REMOVE(path, nh_thread);
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index 7b29fa818f..0cc045a065 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -75,4 +75,11 @@ extern void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer);
*/
extern void bgp_cleanup_nexthops(struct bgp *bgp);
+/*
+ * Add or remove the tracking of the bgp_path_info that
+ * uses this nexthop
+ */
+extern void path_nh_map(struct bgp_path_info *path,
+ struct bgp_nexthop_cache *bnc, bool make);
+
#endif /* _BGP_NHT_H */
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 263a3ebf4d..edd8317c31 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -847,7 +847,7 @@ uint32_t bgp_pbr_match_hash_key(void *arg)
return jhash_1word(pbm->type, key);
}
-int bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
+bool bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
{
const struct bgp_pbr_match *r1, *r2;
@@ -855,35 +855,35 @@ int bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
r2 = (const struct bgp_pbr_match *)arg2;
if (r1->vrf_id != r2->vrf_id)
- return 0;
+ return false;
if (r1->type != r2->type)
- return 0;
+ return false;
if (r1->flags != r2->flags)
- return 0;
+ return false;
if (r1->action != r2->action)
- return 0;
+ return false;
if (r1->pkt_len_min != r2->pkt_len_min)
- return 0;
+ return false;
if (r1->pkt_len_max != r2->pkt_len_max)
- return 0;
+ return false;
if (r1->tcp_flags != r2->tcp_flags)
- return 0;
+ return false;
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
- return 0;
+ return false;
if (r1->dscp_value != r2->dscp_value)
- return 0;
+ return false;
if (r1->fragment != r2->fragment)
- return 0;
- return 1;
+ return false;
+ return true;
}
uint32_t bgp_pbr_match_entry_hash_key(void *arg)
@@ -903,45 +903,41 @@ uint32_t bgp_pbr_match_entry_hash_key(void *arg)
return key;
}
-int bgp_pbr_match_entry_hash_equal(const void *arg1, const void *arg2)
+bool bgp_pbr_match_entry_hash_equal(const void *arg1, const void *arg2)
{
const struct bgp_pbr_match_entry *r1, *r2;
r1 = (const struct bgp_pbr_match_entry *)arg1;
r2 = (const struct bgp_pbr_match_entry *)arg2;
- /* on updates, comparing
- * backpointer is not necessary
- */
-
- /* unique value is self calculated
- */
-
- /* rate is ignored for now
+ /*
+ * on updates, comparing backpointer is not necessary
+ * unique value is self calculated
+ * rate is ignored for now
*/
if (!prefix_same(&r1->src, &r2->src))
- return 0;
+ return false;
if (!prefix_same(&r1->dst, &r2->dst))
- return 0;
+ return false;
if (r1->src_port_min != r2->src_port_min)
- return 0;
+ return false;
if (r1->dst_port_min != r2->dst_port_min)
- return 0;
+ return false;
if (r1->src_port_max != r2->src_port_max)
- return 0;
+ return false;
if (r1->dst_port_max != r2->dst_port_max)
- return 0;
+ return false;
if (r1->proto != r2->proto)
- return 0;
+ return false;
- return 1;
+ return true;
}
uint32_t bgp_pbr_action_hash_key(void *arg)
@@ -955,7 +951,7 @@ uint32_t bgp_pbr_action_hash_key(void *arg)
return key;
}
-int bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
+bool bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
{
const struct bgp_pbr_action *r1, *r2;
@@ -967,11 +963,12 @@ int bgp_pbr_action_hash_equal(const void *arg1, const void *arg2)
* rate is ignored
*/
if (r1->vrf_id != r2->vrf_id)
- return 0;
+ return false;
if (memcmp(&r1->nh, &r2->nh, sizeof(struct nexthop)))
- return 0;
- return 1;
+ return false;
+
+ return true;
}
struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index d15cb39c32..84095f9ab9 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -267,13 +267,13 @@ extern void bgp_pbr_cleanup(struct bgp *bgp);
extern void bgp_pbr_init(struct bgp *bgp);
extern uint32_t bgp_pbr_action_hash_key(void *arg);
-extern int bgp_pbr_action_hash_equal(const void *arg1,
+extern bool bgp_pbr_action_hash_equal(const void *arg1,
const void *arg2);
extern uint32_t bgp_pbr_match_entry_hash_key(void *arg);
-extern int bgp_pbr_match_entry_hash_equal(const void *arg1,
+extern bool bgp_pbr_match_entry_hash_equal(const void *arg1,
const void *arg2);
extern uint32_t bgp_pbr_match_hash_key(void *arg);
-extern int bgp_pbr_match_hash_equal(const void *arg1,
+extern bool bgp_pbr_match_hash_equal(const void *arg1,
const void *arg2);
void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index c15ce7d9aa..bb6b8aab3c 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -5482,7 +5482,9 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
struct aspath *aspath,
- struct community *comm)
+ struct community *comm,
+ struct ecommunity *ecomm,
+ struct lcommunity *lcomm)
{
static struct aspath *ae = NULL;
@@ -5501,6 +5503,12 @@ static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
if (!community_cmp(pi->attr->community, comm))
return 0;
+ if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
+ return 0;
+
+ if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
+ return 0;
+
if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
return 0;
@@ -5511,6 +5519,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
struct prefix *p, uint8_t origin,
struct aspath *aspath,
struct community *community,
+ struct ecommunity *ecommunity,
+ struct lcommunity *lcommunity,
uint8_t atomic_aggregate,
struct bgp_aggregate *aggregate)
{
@@ -5532,14 +5542,18 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
* If the aggregate information has not changed
* no need to re-install it again.
*/
- if (bgp_aggregate_info_same(rn->info, origin, aspath,
- community)) {
+ if (bgp_aggregate_info_same(rn->info, origin, aspath, community,
+ ecommunity, lcommunity)) {
bgp_unlock_node(rn);
if (aspath)
aspath_free(aspath);
if (community)
community_free(community);
+ if (ecommunity)
+ ecommunity_free(&ecommunity);
+ if (lcommunity)
+ lcommunity_free(&lcommunity);
return;
}
@@ -5550,12 +5564,14 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
if (pi)
bgp_path_info_delete(rn, pi);
- new = info_make(
- ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
- bgp_attr_aggregate_intern(bgp, origin, aspath,
- community, aggregate->as_set,
- atomic_aggregate),
- rn);
+ new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
+ bgp->peer_self,
+ bgp_attr_aggregate_intern(bgp, origin, aspath,
+ community, ecommunity,
+ lcommunity,
+ aggregate->as_set,
+ atomic_aggregate),
+ rn);
SET_FLAG(new->flags, BGP_PATH_VALID);
bgp_path_info_add(rn, new);
@@ -5591,6 +5607,10 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
struct aspath *asmerge = NULL;
struct community *community = NULL;
struct community *commerge = NULL;
+ struct ecommunity *ecommunity = NULL;
+ struct ecommunity *ecommerge = NULL;
+ struct lcommunity *lcommunity = NULL;
+ struct lcommunity *lcommerge = NULL;
struct bgp_path_info *pi;
unsigned long match = 0;
uint8_t atomic_aggregate = 0;
@@ -5670,16 +5690,43 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
} else
aspath = aspath_dup(pi->attr->aspath);
- if (!pi->attr->community)
- continue;
+ if (pi->attr->community) {
+ if (community) {
+ commerge = community_merge(
+ community, pi->attr->community);
+ community =
+ community_uniq_sort(commerge);
+ community_free(commerge);
+ } else
+ community = community_dup(
+ pi->attr->community);
+ }
- if (community) {
- commerge = community_merge(community,
- pi->attr->community);
- community = community_uniq_sort(commerge);
- community_free(commerge);
- } else
- community = community_dup(pi->attr->community);
+ if (pi->attr->ecommunity) {
+ if (ecommunity) {
+ ecommerge = ecommunity_merge(
+ ecommunity,
+ pi->attr->ecommunity);
+ ecommunity =
+ ecommunity_uniq_sort(ecommerge);
+ ecommunity_free(&ecommerge);
+ } else
+ ecommunity = ecommunity_dup(
+ pi->attr->ecommunity);
+ }
+
+ if (pi->attr->lcommunity) {
+ if (lcommunity) {
+ lcommerge = lcommunity_merge(
+ lcommunity,
+ pi->attr->lcommunity);
+ lcommunity =
+ lcommunity_uniq_sort(lcommerge);
+ lcommunity_free(&lcommerge);
+ } else
+ lcommunity = lcommunity_dup(
+ pi->attr->lcommunity);
+ }
}
if (match)
bgp_process(bgp, rn, afi, safi);
@@ -5716,17 +5763,48 @@ static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
community = community_dup(
pinew->attr->community);
}
+
+ if (pinew->attr->ecommunity) {
+ if (ecommunity) {
+ ecommerge = ecommunity_merge(
+ ecommunity,
+ pinew->attr->ecommunity);
+ ecommunity =
+ ecommunity_uniq_sort(ecommerge);
+ ecommunity_free(&ecommerge);
+ } else
+ ecommunity = ecommunity_dup(
+ pinew->attr->ecommunity);
+ }
+
+ if (pinew->attr->lcommunity) {
+ if (lcommunity) {
+ lcommerge = lcommunity_merge(
+ lcommunity,
+ pinew->attr->lcommunity);
+ lcommunity =
+ lcommunity_uniq_sort(lcommerge);
+ lcommunity_free(&lcommerge);
+ } else
+ lcommunity = lcommunity_dup(
+ pinew->attr->lcommunity);
+ }
}
}
bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
- atomic_aggregate, aggregate);
+ ecommunity, lcommunity, atomic_aggregate,
+ aggregate);
if (aggregate->count == 0) {
if (aspath)
aspath_free(aspath);
if (community)
community_free(community);
+ if (ecommunity)
+ ecommunity_free(&ecommunity);
+ if (lcommunity)
+ lcommunity_free(&lcommunity);
}
}
@@ -5871,7 +5949,8 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
aggregate = bgp_aggregate_get_node_info(rn);
bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
- bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, 0, aggregate);
+ bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
+ NULL, NULL, 0, aggregate);
/* Unlock aggregate address configuration. */
bgp_aggregate_set_node_info(rn, NULL);
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index d468d48d86..ca0291d0a1 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1403,45 +1403,45 @@ static route_map_result_t route_set_ip_nexthop(void *rule,
struct bgp_path_info *path;
struct peer *peer;
- if (type == RMAP_BGP) {
- path = object;
- peer = path->peer;
+ if (type != RMAP_BGP)
+ return RMAP_OKAY;
- if (rins->unchanged) {
- SET_FLAG(path->attr->rmap_change_flags,
- BATTR_RMAP_NEXTHOP_UNCHANGED);
- } else if (rins->peer_address) {
- if ((CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN)
- || CHECK_FLAG(peer->rmap_type,
- PEER_RMAP_TYPE_IMPORT))
- && peer->su_remote
- && sockunion_family(peer->su_remote) == AF_INET) {
- path->attr->nexthop.s_addr =
- sockunion2ip(peer->su_remote);
- path->attr->flag |=
- ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
- } else if (CHECK_FLAG(peer->rmap_type,
- PEER_RMAP_TYPE_OUT)) {
- /* The next hop value will be set as part of
- * packet rewrite.
- * Set the flags here to indicate that rewrite
- * needs to be done.
- * Also, clear the value.
- */
- SET_FLAG(path->attr->rmap_change_flags,
- BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
- path->attr->nexthop.s_addr = 0;
- }
- } else {
- /* Set next hop value. */
+ if (prefix->family == AF_INET6)
+ return RMAP_OKAY;
+
+ path = object;
+ peer = path->peer;
+
+ if (rins->unchanged) {
+ SET_FLAG(path->attr->rmap_change_flags,
+ BATTR_RMAP_NEXTHOP_UNCHANGED);
+ } else if (rins->peer_address) {
+ if ((CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN)
+ || CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
+ && peer->su_remote
+ && sockunion_family(peer->su_remote) == AF_INET) {
+ path->attr->nexthop.s_addr =
+ sockunion2ip(peer->su_remote);
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
- path->attr->nexthop = *rins->address;
+ } else if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT)) {
+ /* The next hop value will be set as part of
+ * packet rewrite. Set the flags here to indicate
+ * that rewrite needs to be done.
+ * Also, clear the value.
+ */
SET_FLAG(path->attr->rmap_change_flags,
- BATTR_RMAP_IPV4_NHOP_CHANGED);
- /* case for MP-BGP : MPLS VPN */
- path->attr->mp_nexthop_global_in = *rins->address;
- path->attr->mp_nexthop_len = sizeof(*rins->address);
+ BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
+ path->attr->nexthop.s_addr = 0;
}
+ } else {
+ /* Set next hop value. */
+ path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ path->attr->nexthop = *rins->address;
+ SET_FLAG(path->attr->rmap_change_flags,
+ BATTR_RMAP_IPV4_NHOP_CHANGED);
+ /* case for MP-BGP : MPLS VPN */
+ path->attr->mp_nexthop_global_in = *rins->address;
+ path->attr->mp_nexthop_len = sizeof(*rins->address);
}
return RMAP_OKAY;
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 6ebfc4af02..393586dbec 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -393,7 +393,7 @@ static unsigned int updgrp_hash_key_make(void *p)
return key;
}
-static int updgrp_hash_cmp(const void *p1, const void *p2)
+static bool updgrp_hash_cmp(const void *p1, const void *p2)
{
const struct update_group *grp1;
const struct update_group *grp2;
@@ -407,7 +407,7 @@ static int updgrp_hash_cmp(const void *p1, const void *p2)
safi_t safi;
if (!p1 || !p2)
- return 0;
+ return false;
grp1 = p1;
grp2 = p2;
@@ -422,68 +422,68 @@ static int updgrp_hash_cmp(const void *p1, const void *p2)
/* put EBGP and IBGP peers in different update groups */
if (pe1->sort != pe2->sort)
- return 0;
+ return false;
/* check peer flags */
if ((pe1->flags & PEER_UPDGRP_FLAGS)
!= (pe2->flags & PEER_UPDGRP_FLAGS))
- return 0;
+ return false;
/* If there is 'local-as' configured, it should match. */
if (pe1->change_local_as != pe2->change_local_as)
- return 0;
+ return false;
/* flags like route reflector client */
if ((flags1 & PEER_UPDGRP_AF_FLAGS) != (flags2 & PEER_UPDGRP_AF_FLAGS))
- return 0;
+ return false;
if ((pe1->cap & PEER_UPDGRP_CAP_FLAGS)
!= (pe2->cap & PEER_UPDGRP_CAP_FLAGS))
- return 0;
+ return false;
if ((pe1->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS)
!= (pe2->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS))
- return 0;
+ return false;
if (pe1->v_routeadv != pe2->v_routeadv)
- return 0;
+ return false;
if (pe1->group != pe2->group)
- return 0;
+ return false;
/* route-map names should be the same */
if ((fl1->map[RMAP_OUT].name && !fl2->map[RMAP_OUT].name)
|| (!fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name)
|| (fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name
&& strcmp(fl1->map[RMAP_OUT].name, fl2->map[RMAP_OUT].name)))
- return 0;
+ return false;
if ((fl1->dlist[FILTER_OUT].name && !fl2->dlist[FILTER_OUT].name)
|| (!fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name)
|| (fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name
&& strcmp(fl1->dlist[FILTER_OUT].name,
fl2->dlist[FILTER_OUT].name)))
- return 0;
+ return false;
if ((fl1->plist[FILTER_OUT].name && !fl2->plist[FILTER_OUT].name)
|| (!fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name)
|| (fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name
&& strcmp(fl1->plist[FILTER_OUT].name,
fl2->plist[FILTER_OUT].name)))
- return 0;
+ return false;
if ((fl1->aslist[FILTER_OUT].name && !fl2->aslist[FILTER_OUT].name)
|| (!fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name)
|| (fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name
&& strcmp(fl1->aslist[FILTER_OUT].name,
fl2->aslist[FILTER_OUT].name)))
- return 0;
+ return false;
if ((fl1->usmap.name && !fl2->usmap.name)
|| (!fl1->usmap.name && fl2->usmap.name)
|| (fl1->usmap.name && fl2->usmap.name
&& strcmp(fl1->usmap.name, fl2->usmap.name)))
- return 0;
+ return false;
if ((pe1->default_rmap[afi][safi].name
&& !pe2->default_rmap[afi][safi].name)
@@ -493,19 +493,19 @@ static int updgrp_hash_cmp(const void *p1, const void *p2)
&& pe2->default_rmap[afi][safi].name
&& strcmp(pe1->default_rmap[afi][safi].name,
pe2->default_rmap[afi][safi].name)))
- return 0;
+ return false;
if ((afi == AFI_IP6) && (pe1->shared_network != pe2->shared_network))
- return 0;
+ return false;
if ((CHECK_FLAG(pe1->flags, PEER_FLAG_LONESOUL)
|| CHECK_FLAG(pe1->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
|| CHECK_FLAG(pe1->af_cap[afi][safi],
PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
&& !sockunion_same(&pe1->su, &pe2->su))
- return 0;
+ return false;
- return 1;
+ return true;
}
static void peer_lonesoul_or_not(struct peer *peer, int set)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 88025337b2..01d33a869d 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2740,7 +2740,8 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
if (ret < 0) {
vty_out(vty,
- "%% Create the peer-group or interface first\n");
+ "%% Create the peer-group or interface first or specify \"interface\" keyword\n");
+ vty_out(vty, "%% if using an unnumbered interface neighbor\n");
return CMD_WARNING_CONFIG_FAILED;
}
return CMD_SUCCESS;
@@ -11375,6 +11376,23 @@ DEFUN (show_bgp_instance_all_ipv6_updgrps,
return CMD_SUCCESS;
}
+DEFUN (show_bgp_l2vpn_evpn_updgrps,
+ show_bgp_l2vpn_evpn_updgrps_cmd,
+ "show [ip] bgp l2vpn evpn update-groups",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "l2vpn address family\n"
+ "evpn sub-address family\n"
+ "Detailed info about dynamic update groups\n")
+{
+ char *vrf = NULL;
+ uint64_t subgrp_id = 0;
+
+ bgp_show_update_groups(vty, vrf, AFI_L2VPN, SAFI_EVPN, subgrp_id);
+ return CMD_SUCCESS;
+}
+
DEFUN (show_bgp_updgrps_stats,
show_bgp_updgrps_stats_cmd,
"show [ip] bgp update-groups statistics",
@@ -13606,6 +13624,7 @@ void bgp_vty_init(void)
/* "show [ip] bgp summary" commands. */
install_element(VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd);
+ install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_updgrps_cmd);
install_element(VIEW_NODE, &show_bgp_instance_updgrps_stats_cmd);
install_element(VIEW_NODE, &show_bgp_updgrps_stats_cmd);
install_element(VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 9272eae95f..be092e9501 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -769,7 +769,7 @@ static unsigned int peer_hash_key_make(void *p)
return sockunion_hash(&peer->su);
}
-static int peer_hash_same(const void *p1, const void *p2)
+static bool peer_hash_same(const void *p1, const void *p2)
{
const struct peer *peer1 = p1;
const struct peer *peer2 = p2;
@@ -6306,9 +6306,6 @@ int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
{
- struct peer *member;
- struct listnode *node, *nnode;
-
/* Inherit configuration from peer-group if peer is member. */
if (peer_group_active(peer)) {
peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
@@ -6332,19 +6329,26 @@ int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
* Remove flags and configuration from all peer-group members, unless
* they are explicitely overriding peer-group configuration.
*/
- for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
- /* Skip peers with overridden configuration. */
- if (CHECK_FLAG(member->af_flags_override[afi][safi],
- PEER_FLAG_MAX_PREFIX))
- continue;
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+ struct peer *member;
+ struct listnode *node;
- /* Remove flag and configuration on peer-group member. */
- UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
- UNSET_FLAG(member->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING);
- member->pmax[afi][safi] = 0;
- member->pmax_threshold[afi][safi] = 0;
- member->pmax_restart[afi][safi] = 0;
+ for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
+ /* Skip peers with overridden configuration. */
+ if (CHECK_FLAG(member->af_flags_override[afi][safi],
+ PEER_FLAG_MAX_PREFIX))
+ continue;
+
+ /* Remove flag and configuration on peer-group member.
+ */
+ UNSET_FLAG(member->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX);
+ UNSET_FLAG(member->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING);
+ member->pmax[afi][safi] = 0;
+ member->pmax_threshold[afi][safi] = 0;
+ member->pmax_restart[afi][safi] = 0;
+ }
}
return 0;
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index cb45fc8da4..e4e6760612 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -1601,8 +1601,10 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
idx += 2; /* skip afi and keyword */
if (is_bgp) {
- if (idx == argc || strmatch(argv[idx]->arg,
- rfg->plist_export_bgp_name[afi])) {
+ if (idx == argc
+ || (rfg->plist_export_bgp_name[afi]
+ && strmatch(argv[idx]->arg,
+ rfg->plist_export_bgp_name[afi]))) {
if (rfg->plist_export_bgp_name[afi])
free(rfg->plist_export_bgp_name[afi]);
rfg->plist_export_bgp_name[afi] = NULL;
@@ -1612,8 +1614,9 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
}
} else {
if (idx == argc
- || strmatch(argv[idx]->arg,
- rfg->plist_export_zebra_name[afi])) {
+ || (rfg->plist_export_zebra_name[afi]
+ && strmatch(argv[idx]->arg,
+ rfg->plist_export_zebra_name[afi]))) {
if (rfg->plist_export_zebra_name[afi])
free(rfg->plist_export_zebra_name[afi]);
rfg->plist_export_zebra_name[afi] = NULL;
@@ -1732,8 +1735,10 @@ DEFUN (vnc_nve_group_export_no_routemap,
}
if (is_bgp) {
- if (idx == argc || strmatch(argv[idx]->arg,
- rfg->routemap_export_bgp_name)) {
+ if (idx == argc
+ || (rfg->routemap_export_bgp_name
+ && strmatch(argv[idx]->arg,
+ rfg->routemap_export_bgp_name))) {
if (rfg->routemap_export_bgp_name)
free(rfg->routemap_export_bgp_name);
rfg->routemap_export_bgp_name = NULL;
@@ -1743,8 +1748,10 @@ DEFUN (vnc_nve_group_export_no_routemap,
vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
}
} else {
- if (idx == argc || strmatch(argv[idx]->arg,
- rfg->routemap_export_zebra_name)) {
+ if (idx == argc
+ || (rfg->routemap_export_zebra_name
+ && strmatch(argv[idx]->arg,
+ rfg->routemap_export_zebra_name))) {
if (rfg->routemap_export_zebra_name)
free(rfg->routemap_export_zebra_name);
rfg->routemap_export_zebra_name = NULL;
@@ -3468,7 +3475,7 @@ DEFUN (vnc_l2_group_lni,
DEFUN (vnc_l2_group_labels,
vnc_l2_group_labels_cmd,
- "labels LABELLIST...",
+ "labels (0-1048575)...",
"Specify label values associated with group\n"
"Space separated list of label values <0-1048575>\n")
{
@@ -3502,7 +3509,7 @@ DEFUN (vnc_l2_group_labels,
DEFUN (vnc_l2_group_no_labels,
vnc_l2_group_no_labels_cmd,
- "no labels LABELLIST...",
+ "no labels (0-1048575)...",
NO_STR
"Specify label values associated with L2 group\n"
"Space separated list of label values <0-1048575>\n")
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index 7b304c7fbc..6f5af5182a 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -4485,7 +4485,7 @@ static void rfapiDeleteRemotePrefixesIt(
struct bgp_path_info *bpi;
struct bgp_path_info *next;
- if (VNC_DEBUG(IMPORT_DEL_REMOTE)) {
+ if (p && VNC_DEBUG(IMPORT_DEL_REMOTE)) {
char p1line[PREFIX_STRLEN];
char p2line[PREFIX_STRLEN];
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index cdf281f240..1844839f25 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -4845,6 +4845,10 @@ DEFUN (add_vrf_prefix_rd_label_pref,
static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
{
int count = 0;
+
+ if (rfg->rfapi_import_table == NULL)
+ return 0;
+
afi_t afi = AFI_MAX;
while (afi-- > 0) {
count += rfg->rfapi_import_table->local_count[afi];
diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c
index 3d010e25f8..212d394fdc 100644
--- a/bgpd/rfapi/vnc_export_bgp.c
+++ b/bgpd/rfapi/vnc_export_bgp.c
@@ -1403,7 +1403,6 @@ static void vnc_direct_bgp_del_group_afi(struct bgp *bgp,
return;
}
- assert(afi == AFI_IP || afi == AFI_IP6);
rt = import_table->imported_vpn[afi];
if (!rfg->nves && rfg->type != RFAPI_GROUP_CFG_VRF) {
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index a57f908f62..97d520eda7 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -313,6 +313,8 @@ static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type)
/* This is the per-RD table of prefixes */
table = prn->info;
+ if (!table)
+ continue;
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
@@ -576,7 +578,9 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp,
return;
}
- if (!zclient_vnc->redist[family2afi(rn->p.family)][ZEBRA_ROUTE_VNC])
+ if (!vrf_bitmap_check(zclient_vnc->redist[family2afi(rn->p.family)]
+ [ZEBRA_ROUTE_VNC],
+ VRF_DEFAULT))
return;
if (!bgp->rfapi_cfg) {
@@ -640,7 +644,8 @@ static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd,
if (zclient_vnc->sock < 0)
return;
- if (!zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC])
+ if (!vrf_bitmap_check(zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC],
+ VRF_DEFAULT))
return;
if (afi != AFI_IP && afi != AFI_IP6) {
@@ -839,12 +844,12 @@ int vnc_redistribute_set(struct bgp *bgp, afi_t afi, int type)
// bgp->redist[afi][type] = 1;
/* Return if already redistribute flag is set. */
- if (zclient_vnc->redist[afi][type])
+ if (vrf_bitmap_check(zclient_vnc->redist[afi][type], VRF_DEFAULT))
return CMD_WARNING_CONFIG_FAILED;
vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
- // zclient_vnc->redist[afi][type] = 1;
+ // vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
/* Return if zebra connection is not established. */
if (zclient_vnc->sock < 0)
@@ -875,9 +880,9 @@ int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type)
bgp->rfapi_cfg->redist[afi][type] = 0;
/* Return if zebra connection is disabled. */
- if (!zclient_vnc->redist[afi][type])
+ if (!vrf_bitmap_check(zclient_vnc->redist[afi][type], VRF_DEFAULT))
return CMD_WARNING_CONFIG_FAILED;
- zclient_vnc->redist[afi][type] = 0;
+ vrf_bitmap_unset(zclient_vnc->redist[afi][type], VRF_DEFAULT);
if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0
&& bgp->rfapi_cfg->redist[AFI_IP6][type] == 0
diff --git a/configure.ac b/configure.ac
index 12100121d6..15bf059c89 100755
--- a/configure.ac
+++ b/configure.ac
@@ -323,6 +323,32 @@ fi
AC_SUBST(AC_LDFLAGS)
AM_CONDITIONAL([STATIC_BIN], [test "x$enable_static_bin" = "xyes"])
+dnl $AR and $RANLIB are set by LT_INIT above
+AC_MSG_CHECKING([whether $AR supports D option])
+if $AR crD conftest.a; then
+ AC_MSG_RESULT([yes])
+ dnl ARFLAGS is for automake, AR_FLAGS for libtool m-(
+ ARFLAGS="crD"
+ AR_FLAGS="crD"
+else
+ AC_MSG_RESULT([no])
+ ARFLAGS="cru"
+ AR_FLAGS="cru"
+fi
+AC_SUBST(ARFLAGS)
+AC_SUBST(AR_FLAGS)
+
+AC_MSG_CHECKING([whether $RANLIB supports D option])
+if $RANLIB -D conftest.a; then
+ AC_MSG_RESULT([yes])
+ RANLIB="$RANLIB -D"
+else
+ AC_MSG_RESULT([no])
+fi
+AC_SUBST(RANLIB)
+
+test -f conftest.a && rm conftest.a
+
dnl ----------------------
dnl Packages configuration
dnl ----------------------
@@ -462,9 +488,9 @@ AC_ARG_ENABLE([memory-sanitizer],
AS_IF([test "${enable_clippy_only}" != "yes"], [
AC_CHECK_HEADERS(json-c/json.h)
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c", [], [-lm])
-if test $ac_cv_lib_json_c_json_object_get = no; then
+if test "$ac_cv_lib_json_c_json_object_get" = no; then
AC_CHECK_LIB(json, json_object_get, LIBS="$LIBS -ljson")
- if test $ac_cv_lib_json_json_object_get = no; then
+ if test "$ac_cv_lib_json_json_object_get" = no; then
AC_MSG_ERROR([lib json is needed to compile])
fi
fi
@@ -958,11 +984,6 @@ case "$host_os" in
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
AC_CHECK_LIB(umem, main)
- AC_CHECK_FUNCS([printstack], [
- AC_DEFINE([HAVE_PRINTSTACK],1,[Solaris printstack])
- AC_DEFINE([HAVE_STACK_TRACE],1,[Stack symbols decode functionality])
- ])
- CURSES=-lcurses
SOLARIS="solaris"
;;
linux*)
@@ -1028,40 +1049,47 @@ dnl ---------------------
dnl Integrated VTY option
dnl ---------------------
case "${enable_vtysh}" in
- "no") VTYSH="";;
- *) VTYSH="vtysh";
- AC_DEFINE(VTYSH,,VTY shell)
-dnl Vtysh uses libreadline, which looks for termcap functions at
-dnl configure time. We follow readlines search order.
-dnl The required procedures are in libtermcap on NetBSD, in
-dnl [TODO] on Linux, and in [TODO] on Solaris.
- AC_CHECK_LIB(termcap, tputs, LIBREADLINE="$LIBREADLINE -ltermcap",
- [AC_CHECK_LIB(tinfo, tputs, LIBREADLINE="$LIBREADLINE -ltinfo",
- [AC_CHECK_LIB(curses, tputs, LIBREADLINE="$LIBREADLINE -lcurses",
- [AC_CHECK_LIB(ncurses, tputs,
- LIBREADLINE="$LIBREADLINE -lncurses")]
- )]
- )]
- )
- AC_CHECK_LIB(readline, main, LIBREADLINE="-lreadline $LIBREADLINE",,
- "$LIBREADLINE")
- if test $ac_cv_lib_readline_main = no; then
- AC_MSG_ERROR([vtysh needs libreadline but was not found and usable on your system.])
- fi
- AC_CHECK_HEADER(readline/history.h)
- if test $ac_cv_header_readline_history_h = no;then
- AC_MSG_ERROR([readline is too old to have readline/history.h, please update to the latest readline library.])
- fi
- AC_CHECK_LIB(readline, rl_completion_matches,
- LIBREADLINE="$LIBREADLINE",, "$LIBREADLINE")
- if test $ac_cv_lib_readline_rl_completion_matches = no; then
- AC_DEFINE(rl_completion_matches,completion_matches,Old readline)
- fi
- AC_SEARCH_LIBS([append_history], [readline], [frr_cv_append_history=yes], [frr_cv_append_history=no])
- if test "$frr_cv_append_history" = yes; then
- AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history])
- fi
- ;;
+"no")
+ VTYSH="";;
+*)
+ VTYSH="vtysh";
+ AC_DEFINE(VTYSH,,VTY shell)
+
+ prev_libs="$LIBS"
+ AC_CHECK_LIB(readline, main, [
+ LIBREADLINE="-lreadline"
+ ], [
+ dnl readline failed - it might be incorrectly linked and missing its
+ dnl termcap/tinfo/curses dependency. see if we can fix that...
+ AC_SEARCH_LIBS(tputs, [termcap tinfo curses ncurses], [
+ LIBREADLINE="$ac_cv_search_tputs"
+ ], [
+ AC_MSG_ERROR([libreadline (needed for vtysh) not found and/or missing dependencies])
+ ])
+
+ dnl re-try with the lib we found above
+ unset ac_cv_lib_readline_main
+ AC_CHECK_LIB(readline, main, [
+ LIBREADLINE="-lreadline $LIBREADLINE"
+ ], [
+ AC_MSG_ERROR([libreadline (needed for vtysh) not found and/or missing dependencies])
+ ], [$LIBREADLINE])
+ ], [])
+ LIBS="$prev_libs"
+
+ AC_CHECK_HEADER(readline/history.h)
+ if test $ac_cv_header_readline_history_h = no;then
+ AC_MSG_ERROR([readline is too old to have readline/history.h, please update to the latest readline library.])
+ fi
+ AC_CHECK_LIB(readline, rl_completion_matches, [true], [], [$LIBREADLINE])
+ if test $ac_cv_lib_readline_rl_completion_matches = no; then
+ AC_DEFINE(rl_completion_matches,completion_matches,Old readline)
+ fi
+ AC_CHECK_LIB(readline, [append_history], [frr_cv_append_history=yes], [frr_cv_append_history=no], [$LIBREADLINE])
+ if test "$frr_cv_append_history" = yes; then
+ AC_DEFINE(HAVE_APPEND_HISTORY, 1, [Have history.h append_history])
+ fi
+ ;;
esac
AC_SUBST(LIBREADLINE)
AM_CONDITIONAL(VTYSH, test "x$VTYSH" = "xvtysh")
@@ -1402,7 +1430,7 @@ fi
AM_CONDITIONAL(BFDD, [test "x$BFDD" = "xbfdd"])
-if test $ac_cv_lib_json_c_json_object_get = no -a "x$BFDD" = "xbfdd"; then
+if test "$ac_cv_lib_json_c_json_object_get" = no -a "x$BFDD" = "xbfdd"; then
AC_MSG_ERROR(["you must use json-c library to use bfdd"])
fi
@@ -1462,7 +1490,6 @@ fi
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
AC_SUBST(SOLARIS)
-AC_SUBST(CURSES)
AC_CHECK_LIB(crypt, crypt, [],
[AC_CHECK_LIB(crypto, DES_crypt)])
AC_CHECK_LIB(resolv, res_init)
@@ -1811,17 +1838,31 @@ dnl check for glibc 'backtrace'
dnl ---------------------------
if test x"${enable_backtrace}" != x"no" ; then
backtrace_ok=no
- AC_CHECK_HEADER([execinfo.h], [
- AC_SEARCH_LIBS([backtrace], [execinfo], [
- AC_DEFINE(HAVE_GLIBC_BACKTRACE,,[Glibc backtrace])
- AC_DEFINE(HAVE_STACK_TRACE,,[Stack symbol decoding])
- backtrace_ok=yes
- ],, [-lm])
+ PKG_CHECK_MODULES([UNWIND], [libunwind], [
+ AC_DEFINE(HAVE_LIBUNWIND, 1, [libunwind])
+ backtrace_ok=yes
+ ], [
+ case "$host_os" in
+ sunos* | solaris2*)
+ AC_CHECK_FUNCS([printstack], [
+ AC_DEFINE([HAVE_PRINTSTACK], 1, [Solaris printstack])
+ backtrace_ok=yes
+ ])
+ ;;
+ esac
+ if test "$backtrace_ok" = no; then
+ AC_CHECK_HEADER([execinfo.h], [
+ AC_SEARCH_LIBS([backtrace], [execinfo], [
+ AC_DEFINE(HAVE_GLIBC_BACKTRACE, 1, [Glibc backtrace])
+ backtrace_ok=yes
+ ],, [-lm])
+ ])
+ fi
])
if test x"${enable_backtrace}" = x"yes" -a x"${backtrace_ok}" = x"no"; then
dnl user explicitly requested backtrace but we failed to find support
- AC_MSG_FAILURE([failed to find backtrace support])
+ AC_MSG_FAILURE([failed to find backtrace or libunwind support])
fi
fi
diff --git a/debianpkg/control b/debianpkg/control
index 71c412a960..ea977937bf 100644
--- a/debianpkg/control
+++ b/debianpkg/control
@@ -4,7 +4,7 @@ Priority: optional
Maintainer: Nobody <nobody@frrouting.org>
Uploaders: Nobody <nobody@frrouting.org>
XSBC-Original-Maintainer: <maintainers@frrouting.org>
-Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr, python-sphinx, libpython-dev, install-info
+Build-Depends: debhelper (>= 7.0.50~), libreadline-dev, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7) | python3, python-sphinx | python3-sphinx, libpython-dev | libpython3-dev, install-info
Standards-Version: 3.9.6
Homepage: http://www.frrouting.org/
diff --git a/debianpkg/frr.dirs b/debianpkg/frr.dirs
index 56699b2daa..f3fff26441 100644
--- a/debianpkg/frr.dirs
+++ b/debianpkg/frr.dirs
@@ -4,5 +4,4 @@ etc/iproute2/rt_protos.d/
usr/share/doc/frr/
usr/share/doc/frr/examples/
usr/share/lintian/overrides/
-usr/share/snmp/mibs/
var/log/frr/
diff --git a/debianpkg/frr.install b/debianpkg/frr.install
index 20a58bb0e9..e430868fe3 100644
--- a/debianpkg/frr.install
+++ b/debianpkg/frr.install
@@ -5,7 +5,6 @@ usr/include/frr/
usr/lib/
tools/frr usr/lib/frr
usr/share/doc/frr/
-usr/share/snmp/mibs/
tools/etc/* etc/
tools/*.service lib/systemd/system
tools/frr-reload usr/lib/frr/
diff --git a/debianpkg/rules b/debianpkg/rules
index 811d45bc0b..894cd7f198 100755
--- a/debianpkg/rules
+++ b/debianpkg/rules
@@ -7,15 +7,15 @@
# The following are the defaults. They can be overridden by setting a
# env variable to a different value
-WANT_LDP ?= 1
-WANT_PIM ?= 1
+# -Werror - don't enable this unless you're doing a dev package build
+WANT_WERROR ?= 0
+
WANT_OSPFAPI ?= 1
WANT_BGP_VNC ?= 1
WANT_CUMULUS_MODE ?= 0
WANT_MULTIPATH ?= 1
WANT_SNMP ?= 0
WANT_RPKI ?= 0
-WANT_BFD ?= 1
# NOTES:
#
@@ -39,6 +39,7 @@ WANT_FRR_USER ?= frr
WANT_FRR_VTY_GROUP ?= frrvty
# Don't build PDF docs by default
+# add build deps: texlive-latex-base, texlive-generic-recommended
GENERATE_PDF ?= 0
#
@@ -56,18 +57,6 @@ else
$(warning "DEBIAN: SNMP disabled, see README.Debian")
endif
-ifeq ($(WANT_LDP), 1)
- USE_LDP=--enable-ldpd
-else
- USE_LDP=--disable-ldpd
-endif
-
-ifeq ($(WANT_PIM), 1)
- USE_PIM=--enable-pimd
-else
- USE_PIM=--disable-pimd
-endif
-
ifeq ($(WANT_OSPFAPI), 1)
USE_OSPFAPI=--enable-ospfapi=yes
else
@@ -102,10 +91,10 @@ else
USE_RPKI=--disable-rpki
endif
-ifeq ($(WANT_BFD), 1)
- USE_BFD=--enable-bfdd
+ifeq ($(WANT_WERROR), 1)
+ USE_WERROR=--enable-werror
else
- USE_BFD=--disable-bfdd
+ USE_WERROR=--disable-werror
endif
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
@@ -127,14 +116,6 @@ else
endif
override_dh_auto_configure:
- # Frr needs /proc to check some BSD vs Linux specific stuff.
- # Else it fails with an obscure error message pointing out that
- # IPCTL_FORWARDING is an undefined symbol which is not very helpful.
- @if ! [ -d /proc/1 ]; then \
- echo "./configure needs a mounted /proc"; \
- exit 1; \
- fi
-
if ! [ -e config.status ]; then \
dh_auto_configure -- \
--enable-exampledir=/usr/share/doc/frr/examples/ \
@@ -144,32 +125,23 @@ override_dh_auto_configure:
$(USE_SNMP) \
$(USE_OSPFAPI) \
$(USE_MULTIPATH) \
- $(USE_LDP) \
--enable-fpm \
$(USE_FRR_USER) $(USE_FRR_GROUP) \
$(USE_FRR_VTY_GROUP) \
--enable-configfile-mask=0640 \
--enable-logfile-mask=0640 \
- --enable-werror \
+ $(USE_WERROR) \
--with-libpam \
--enable-systemd=yes \
- --enable-poll=yes \
$(USE_CUMULUS) \
- $(USE_PIM) \
- --enable-dependency-tracking \
+ --disable-dependency-tracking \
$(USE_BGP_VNC) \
$(USE_RPKI) \
- $(USE_BFD) \
$(shell dpkg-buildflags --export=configure); \
fi
override_dh_auto_build:
- # doc/ is a bit crazy
-ifeq ($(GENERATE_PDF), 1)
- dh_auto_build -- -C doc pdf
-endif
- rm -vf doc/user/_build/texinfo/frr.info
- dh_auto_build -- -C doc info
+ dh_auto_build
override_dh_auto_test:
@@ -186,12 +158,9 @@ override_dh_auto_install:
mkdir -p debian/tmp/etc/frr/
perl -pi -e 's#^!log file #!log file /var/log/frr/#' debian/tmp/usr/share/doc/frr/examples/*sample*
- # leftover from previously shipping SMUX client OID MIB
- mkdir -p debian/tmp/usr/share/snmp/mibs/
-
- # cleaning .la files
- sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
- sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/frr/modules/*.la
+ # we don't need .la files
+ rm debian/tmp/usr/lib/*.la
+ rm debian/tmp/usr/lib/frr/modules/*.la
override_dh_systemd_start:
dh_systemd_start frr.service
diff --git a/isisd/fabricd.c b/isisd/fabricd.c
index 7951efe5a1..76c8087f2d 100644
--- a/isisd/fabricd.c
+++ b/isisd/fabricd.c
@@ -105,7 +105,7 @@ static unsigned neighbor_entry_hash_key(void *np)
return jhash(n->vertex->N.id, ISIS_SYS_ID_LEN, 0x55aa5a5a);
}
-static int neighbor_entry_hash_cmp(const void *a, const void *b)
+static bool neighbor_entry_hash_cmp(const void *a, const void *b)
{
const struct neighbor_entry *na = a, *nb = b;
diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h
index 131fa37991..3a05df3f14 100644
--- a/isisd/isis_spf_private.h
+++ b/isisd/isis_spf_private.h
@@ -95,16 +95,16 @@ static unsigned isis_vertex_queue_hash_key(void *vp)
}
__attribute__((__unused__))
-static int isis_vertex_queue_hash_cmp(const void *a, const void *b)
+static bool isis_vertex_queue_hash_cmp(const void *a, const void *b)
{
const struct isis_vertex *va = a, *vb = b;
if (va->type != vb->type)
- return 0;
+ return false;
if (VTYPE_IP(va->type)) {
if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
- return 0;
+ return false;
return prefix_cmp((const struct prefix *)&va->N.ip.src,
(const struct prefix *)&vb->N.ip.src) == 0;
diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c
index 32427628ad..fe67a3f4d1 100644
--- a/isisd/isis_tx_queue.c
+++ b/isisd/isis_tx_queue.c
@@ -58,18 +58,18 @@ static unsigned tx_queue_hash_key(void *p)
return jhash_1word(e->lsp->level, id_key);
}
-static int tx_queue_hash_cmp(const void *a, const void *b)
+static bool tx_queue_hash_cmp(const void *a, const void *b)
{
const struct isis_tx_queue_entry *ea = a, *eb = b;
if (ea->lsp->level != eb->lsp->level)
- return 0;
+ return false;
if (memcmp(ea->lsp->hdr.lsp_id, eb->lsp->hdr.lsp_id,
ISIS_SYS_ID_LEN + 2))
- return 0;
+ return false;
- return 1;
+ return true;
}
struct isis_tx_queue *isis_tx_queue_new(void *arg,
diff --git a/lib/command.c b/lib/command.c
index 60c5f4e75b..839c37b102 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -337,7 +337,7 @@ static unsigned int cmd_hash_key(void *p)
return jhash(p, size, 0);
}
-static int cmd_hash_cmp(const void *a, const void *b)
+static bool cmd_hash_cmp(const void *a, const void *b)
{
return a == b;
}
@@ -1281,7 +1281,8 @@ int cmd_execute(struct vty *vty, const char *cmd,
* as to why no command could be executed.
*/
int command_config_read_one_line(struct vty *vty,
- const struct cmd_element **cmd, int use_daemon)
+ const struct cmd_element **cmd,
+ uint32_t line_num, int use_daemon)
{
vector vline;
int saved_node;
@@ -1322,8 +1323,16 @@ int command_config_read_one_line(struct vty *vty,
}
}
- if (ret != CMD_SUCCESS && ret != CMD_WARNING)
- memcpy(vty->error_buf, vty->buf, VTY_BUFSIZ);
+ if (ret != CMD_SUCCESS && ret != CMD_WARNING) {
+ struct vty_error *ve = XCALLOC(MTYPE_TMP, sizeof(*ve));
+
+ memcpy(ve->error_buf, vty->buf, VTY_BUFSIZ);
+ ve->line_num = line_num;
+ if (!vty->error)
+ vty->error = list_new();
+
+ listnode_add(vty->error, ve);
+ }
cmd_free_strvec(vline);
@@ -1337,10 +1346,9 @@ int config_from_file(struct vty *vty, FILE *fp, unsigned int *line_num)
*line_num = 0;
while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
- if (!error_ret)
- ++(*line_num);
+ ++(*line_num);
- ret = command_config_read_one_line(vty, NULL, 0);
+ ret = command_config_read_one_line(vty, NULL, *line_num, 0);
if (ret != CMD_SUCCESS && ret != CMD_WARNING
&& ret != CMD_ERR_NOTHING_TODO)
diff --git a/lib/command.h b/lib/command.h
index 8e51641b88..fbff1e67f4 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -419,7 +419,7 @@ extern char **cmd_complete_command(vector, struct vty *, int *status);
extern const char *cmd_prompt(enum node_type);
extern int command_config_read_one_line(struct vty *vty,
const struct cmd_element **,
- int use_config_node);
+ uint32_t line_num, int use_config_node);
extern int config_from_file(struct vty *, FILE *, unsigned int *line_num);
extern enum node_type node_parent(enum node_type);
/*
diff --git a/lib/distribute.c b/lib/distribute.c
index 25fcd92580..0f1d666aeb 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -140,15 +140,15 @@ static unsigned int distribute_hash_make(void *arg)
/* If two distribute-list have same value then return 1 else return
0. This function is used by hash package. */
-static int distribute_cmp(const struct distribute *dist1,
+static bool distribute_cmp(const struct distribute *dist1,
const struct distribute *dist2)
{
if (dist1->ifname && dist2->ifname)
if (strcmp(dist1->ifname, dist2->ifname) == 0)
- return 1;
+ return true;
if (!dist1->ifname && !dist2->ifname)
- return 1;
- return 0;
+ return true;
+ return false;
}
/* Set access-list name to the distribute list. */
@@ -521,7 +521,7 @@ void distribute_list_init(int node)
{
disthash = hash_create(
distribute_hash_make,
- (int (*)(const void *, const void *))distribute_cmp, NULL);
+ (bool (*)(const void *, const void *))distribute_cmp, NULL);
/* vtysh command-extraction doesn't grok install_element(node, ) */
if (node == RIP_NODE) {
diff --git a/lib/ferr.c b/lib/ferr.c
index bf89cc7f46..e18597afb0 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -64,7 +64,7 @@ static void err_key_fini(void)
pthread_mutex_t refs_mtx = PTHREAD_MUTEX_INITIALIZER;
struct hash *refs;
-static int ferr_hash_cmp(const void *a, const void *b)
+static bool ferr_hash_cmp(const void *a, const void *b)
{
const struct log_ref *f_a = a;
const struct log_ref *f_b = b;
diff --git a/lib/hash.c b/lib/hash.c
index 114522a75a..641c751368 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -38,7 +38,7 @@ static struct list *_hashes;
struct hash *hash_create_size(unsigned int size,
unsigned int (*hash_key)(void *),
- int (*hash_cmp)(const void *, const void *),
+ bool (*hash_cmp)(const void *, const void *),
const char *name)
{
struct hash *hash;
@@ -67,7 +67,7 @@ struct hash *hash_create_size(unsigned int size,
}
struct hash *hash_create(unsigned int (*hash_key)(void *),
- int (*hash_cmp)(const void *, const void *),
+ bool (*hash_cmp)(const void *, const void *),
const char *name)
{
return hash_create_size(HASH_INITIAL_SIZE, hash_key, hash_cmp, name);
diff --git a/lib/hash.h b/lib/hash.h
index 2b4ea48f38..45ae6ce60a 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -73,7 +73,7 @@ struct hash {
unsigned int (*hash_key)(void *);
/* Data compare function. */
- int (*hash_cmp)(const void *, const void *);
+ bool (*hash_cmp)(const void *, const void *);
/* Backet alloc. */
unsigned long count;
@@ -115,7 +115,7 @@ struct hash {
* a new hash table
*/
extern struct hash *hash_create(unsigned int (*hash_key)(void *),
- int (*hash_cmp)(const void *, const void *),
+ bool (*hash_cmp)(const void *, const void *),
const char *name);
/*
@@ -150,7 +150,8 @@ extern struct hash *hash_create(unsigned int (*hash_key)(void *),
*/
extern struct hash *
hash_create_size(unsigned int size, unsigned int (*hash_key)(void *),
- int (*hash_cmp)(const void *, const void *), const char *name);
+ bool (*hash_cmp)(const void *, const void *),
+ const char *name);
/*
* Retrieve or insert data from / into a hash table.
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 2c686ecb85..108ab7ec6b 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -117,7 +117,7 @@ static unsigned int if_rmap_hash_make(void *data)
return string_hash_make(if_rmap->ifname);
}
-static int if_rmap_hash_cmp(const void *arg1, const void *arg2)
+static bool if_rmap_hash_cmp(const void *arg1, const void *arg2)
{
const struct if_rmap *if_rmap1 = arg1;
const struct if_rmap *if_rmap2 = arg2;
diff --git a/lib/log.c b/lib/log.c
index 10cb2cd8a4..5cc303daf0 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -38,6 +38,12 @@
#include <ucontext.h>
#endif
+#ifdef HAVE_LIBUNWIND
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#include <dlfcn.h>
+#endif
+
DEFINE_MTYPE_STATIC(LIB, ZLOG, "Logging")
static int logfile_fd = -1; /* Used in signal handler. */
@@ -313,7 +319,9 @@ static char *num_append(char *s, int len, unsigned long x)
return str_append(s, len, t);
}
-#if defined(SA_SIGINFO) || defined(HAVE_STACK_TRACE)
+#if defined(SA_SIGINFO) \
+ || defined(HAVE_PRINTSTACK) \
+ || defined(HAVE_GLIBC_BACKTRACE)
static char *hex_append(char *s, int len, unsigned long x)
{
char buf[30];
@@ -533,7 +541,37 @@ void zlog_signal(int signo, const char *action
Needs to be enhanced to support syslog logging. */
void zlog_backtrace_sigsafe(int priority, void *program_counter)
{
-#ifdef HAVE_STACK_TRACE
+#ifdef HAVE_LIBUNWIND
+ char buf[100];
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ unw_word_t ip, off, sp;
+ Dl_info dlinfo;
+
+ unw_getcontext(&uc);
+ unw_init_local(&cursor, &uc);
+ while (unw_step(&cursor) > 0) {
+ char name[128] = "?";
+
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+ if (unw_is_signal_frame(&cursor))
+ dprintf(2, " ---- signal ----\n");
+
+ if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off)) {
+ snprintf(name, sizeof(name), "%s+%#lx",
+ buf, (long)off);
+ }
+ dprintf(2, "%-30s %16lx %16lx", name, (long)ip, (long)sp);
+ if (dladdr((void *)ip, &dlinfo)) {
+ dprintf(2, " %s (mapped at %p)",
+ dlinfo.dli_fname, dlinfo.dli_fbase);
+ }
+ dprintf(2, "\n");
+
+ }
+#elif defined(HAVE_GLIBC_BACKTRACE) || defined(HAVE_PRINTSTACK)
static const char pclabel[] = "Program counter: ";
void *array[64];
int size;
@@ -624,9 +662,38 @@ void zlog_backtrace_sigsafe(int priority, void *program_counter)
void zlog_backtrace(int priority)
{
-#ifndef HAVE_GLIBC_BACKTRACE
- zlog(priority, "No backtrace available on this platform.");
-#else
+#ifdef HAVE_LIBUNWIND
+ char buf[100];
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ unw_word_t ip, off, sp;
+ Dl_info dlinfo;
+
+ unw_getcontext(&uc);
+ unw_init_local(&cursor, &uc);
+ zlog(priority, "Backtrace:");
+ while (unw_step(&cursor) > 0) {
+ char name[128] = "?";
+
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+ if (unw_is_signal_frame(&cursor))
+ zlog(priority, " ---- signal ----");
+
+ if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off))
+ snprintf(name, sizeof(name), "%s+%#lx",
+ buf, (long)off);
+
+ if (dladdr((void *)ip, &dlinfo))
+ zlog(priority, "%-30s %16lx %16lx %s (mapped at %p)",
+ name, (long)ip, (long)sp,
+ dlinfo.dli_fname, dlinfo.dli_fbase);
+ else
+ zlog(priority, "%-30s %16lx %16lx",
+ name, (long)ip, (long)sp);
+ }
+#elif defined(HAVE_GLIBC_BACKTRACE)
void *array[20];
int size, i;
char **strings;
@@ -651,7 +718,9 @@ void zlog_backtrace(int priority)
zlog(priority, "[bt %d] %s", i, strings[i]);
free(strings);
}
-#endif /* HAVE_GLIBC_BACKTRACE */
+#else /* !HAVE_GLIBC_BACKTRACE && !HAVE_LIBUNWIND */
+ zlog(priority, "No backtrace available on this platform.");
+#endif
}
void zlog(int priority, const char *format, ...)
diff --git a/lib/qobj.c b/lib/qobj.c
index c3f1a27c82..811645f3c3 100644
--- a/lib/qobj.c
+++ b/lib/qobj.c
@@ -36,7 +36,7 @@ static unsigned int qobj_key(void *data)
return (unsigned int)node->nid;
}
-static int qobj_cmp(const void *a, const void *b)
+static bool qobj_cmp(const void *a, const void *b)
{
const struct qobj_node *na = a, *nb = b;
return na->nid == nb->nid;
diff --git a/lib/routemap.c b/lib/routemap.c
index 3a20ed5cda..5c6d106d83 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -631,7 +631,7 @@ static unsigned int route_map_hash_key_make(void *p)
return string_hash_make(map->name);
}
-static int route_map_hash_cmp(const void *p1, const void *p2)
+static bool route_map_hash_cmp(const void *p1, const void *p2)
{
const struct route_map *map1 = p1;
const struct route_map *map2 = p2;
@@ -639,14 +639,14 @@ static int route_map_hash_cmp(const void *p1, const void *p2)
if (map1->deleted == map2->deleted) {
if (map1->name && map2->name) {
if (!strcmp(map1->name, map2->name)) {
- return 1;
+ return true;
}
} else if (!map1->name && !map2->name) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
enum route_map_upd8_type {
@@ -676,7 +676,6 @@ struct route_map_dep {
struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
static unsigned int route_map_dep_hash_make_key(void *p);
-static int route_map_dep_hash_cmp(const void *p1, const void *p2);
static void route_map_clear_all_references(char *rmap_name);
static void route_map_rule_delete(struct route_map_rule_list *,
struct route_map_rule *);
@@ -1624,12 +1623,12 @@ void route_map_event_hook(void (*func)(route_map_event_t, const char *))
}
/* Routines for route map dependency lists and dependency processing */
-static int route_map_rmap_hash_cmp(const void *p1, const void *p2)
+static bool route_map_rmap_hash_cmp(const void *p1, const void *p2)
{
return (strcmp((const char *)p1, (const char *)p2) == 0);
}
-static int route_map_dep_hash_cmp(const void *p1, const void *p2)
+static bool route_map_dep_hash_cmp(const void *p1, const void *p2)
{
return (strcmp(((const struct route_map_dep *)p1)->dep_name,
@@ -2251,7 +2250,8 @@ DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
if (rmap_match_set_hook.no_match_ipv6_next_hop_type)
return rmap_match_set_hook.no_match_ipv6_next_hop_type(
- vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
+ vty, index, "ipv6 next-hop type",
+ (argc <= idx_word) ? NULL : argv[idx_word]->arg,
RMAP_EVENT_MATCH_DELETED);
return CMD_SUCCESS;
}
diff --git a/lib/subdir.am b/lib/subdir.am
index dd2731f74c..eef00a9086 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -3,7 +3,7 @@
#
lib_LTLIBRARIES += lib/libfrr.la
lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version
-lib_libfrr_la_LIBADD = @LIBCAP@
+lib_libfrr_la_LIBADD = @LIBCAP@ $(UNWIND_LIBS)
lib_libfrr_la_SOURCES = \
lib/agg_table.c \
diff --git a/lib/table.c b/lib/table.c
index 3adb793891..0026b7692b 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -33,7 +33,7 @@ DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node")
static void route_table_free(struct route_table *);
-static int route_table_hash_cmp(const void *a, const void *b)
+static bool route_table_hash_cmp(const void *a, const void *b)
{
const struct prefix *pa = a, *pb = b;
return prefix_cmp(pa, pb) == 0;
diff --git a/lib/thread.c b/lib/thread.c
index 267dcd1cfc..d104c4f598 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -68,7 +68,7 @@ static unsigned int cpu_record_hash_key(struct cpu_thread_history *a)
return jhash(&a->func, size, 0);
}
-static int cpu_record_hash_cmp(const struct cpu_thread_history *a,
+static bool cpu_record_hash_cmp(const struct cpu_thread_history *a,
const struct cpu_thread_history *b)
{
return a->func == b->func;
@@ -434,7 +434,7 @@ struct thread_master *thread_master_create(const char *name)
rv->cpu_record = hash_create_size(
8, (unsigned int (*)(void *))cpu_record_hash_key,
- (int (*)(const void *, const void *))cpu_record_hash_cmp,
+ (bool (*)(const void *, const void *))cpu_record_hash_cmp,
"Thread Hash");
diff --git a/lib/vrf.c b/lib/vrf.c
index eca9913e1f..498aef4580 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -366,7 +366,7 @@ static unsigned int vrf_hash_bitmap_key(void *data)
return bit->vrf_id;
}
-static int vrf_hash_bitmap_cmp(const void *a, const void *b)
+static bool vrf_hash_bitmap_cmp(const void *a, const void *b)
{
const struct vrf_bit_set *bit1 = a;
const struct vrf_bit_set *bit2 = b;
diff --git a/lib/vty.c b/lib/vty.c
index f812dd4279..a73cc23b97 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1695,7 +1695,6 @@ struct vty *vty_new()
new->lbuf = buffer_new(0);
new->obuf = buffer_new(0); /* Use default buffer size. */
new->buf = XCALLOC(MTYPE_VTY, VTY_BUFSIZ);
- new->error_buf = XCALLOC(MTYPE_VTY, VTY_BUFSIZ);
new->max = VTY_BUFSIZ;
return new;
@@ -2278,6 +2277,13 @@ void vty_serv_sock(const char *addr, unsigned short port, const char *path)
#endif /* VTYSH */
}
+static void vty_error_delete(void *arg)
+{
+ struct vty_error *ve = arg;
+
+ XFREE(MTYPE_TMP, ve);
+}
+
/* Close vty interface. Warning: call this only from functions that
will be careful not to access the vty afterwards (since it has
now been freed). This is safest from top-level functions (called
@@ -2329,8 +2335,10 @@ void vty_close(struct vty *vty)
if (vty->buf)
XFREE(MTYPE_VTY, vty->buf);
- if (vty->error_buf)
- XFREE(MTYPE_VTY, vty->error_buf);
+ if (vty->error) {
+ vty->error->del = vty_error_delete;
+ list_delete(&vty->error);
+ }
/* Check configure. */
vty_config_unlock(vty);
@@ -2368,6 +2376,8 @@ static void vty_read_file(FILE *confp)
{
int ret;
struct vty *vty;
+ struct vty_error *ve;
+ struct listnode *node;
unsigned int line_num = 0;
vty = vty_new();
@@ -2417,11 +2427,13 @@ static void vty_read_file(FILE *confp)
break;
}
- nl = strchr(vty->error_buf, '\n');
- if (nl)
- *nl = '\0';
- flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s", message,
- line_num, vty->error_buf);
+ for (ALL_LIST_ELEMENTS_RO(vty->error, node, ve)) {
+ nl = strchr(ve->error_buf, '\n');
+ if (nl)
+ *nl = '\0';
+ flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s",
+ message, ve->line_num, ve->error_buf);
+ }
}
vty_close(vty);
diff --git a/lib/vty.h b/lib/vty.h
index b55abf2204..efe91a568b 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -33,6 +33,11 @@
#define VTY_BUFSIZ 4096
#define VTY_MAXHIST 20
+struct vty_error {
+ char error_buf[VTY_BUFSIZ];
+ uint32_t line_num;
+};
+
/* VTY struct. */
struct vty {
/* File descripter of this vty. */
@@ -71,7 +76,7 @@ struct vty {
char *buf;
/* Command input error buffer */
- char *error_buf;
+ struct list *error;
/* Command cursor point */
int cp;
diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c
index f3a33eb28f..1316a4aad3 100644
--- a/nhrpd/nhrp_cache.c
+++ b/nhrpd/nhrp_cache.c
@@ -36,10 +36,12 @@ static unsigned int nhrp_cache_protocol_key(void *peer_data)
return sockunion_hash(&p->remote_addr);
}
-static int nhrp_cache_protocol_cmp(const void *cache_data, const void *key_data)
+static bool nhrp_cache_protocol_cmp(const void *cache_data,
+ const void *key_data)
{
const struct nhrp_cache *a = cache_data;
const struct nhrp_cache *b = key_data;
+
return sockunion_same(&a->remote_addr, &b->remote_addr);
}
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 203d4aa98c..db2f72ac22 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -157,10 +157,11 @@ static unsigned int nhrp_peer_key(void *peer_data)
return sockunion_hash(&p->vc->remote.nbma);
}
-static int nhrp_peer_cmp(const void *cache_data, const void *key_data)
+static bool nhrp_peer_cmp(const void *cache_data, const void *key_data)
{
const struct nhrp_peer *a = cache_data;
const struct nhrp_peer *b = key_data;
+
return a->ifp == b->ifp && a->vc == b->vc;
}
diff --git a/nhrpd/nhrp_vc.c b/nhrpd/nhrp_vc.c
index 41a87d4adb..79a655396b 100644
--- a/nhrpd/nhrp_vc.c
+++ b/nhrpd/nhrp_vc.c
@@ -35,10 +35,11 @@ static unsigned int nhrp_vc_key(void *peer_data)
sockunion_hash(&vc->remote.nbma), 0);
}
-static int nhrp_vc_cmp(const void *cache_data, const void *key_data)
+static bool nhrp_vc_cmp(const void *cache_data, const void *key_data)
{
const struct nhrp_vc *a = cache_data;
const struct nhrp_vc *b = key_data;
+
return sockunion_same(&a->local.nbma, &b->local.nbma)
&& sockunion_same(&a->remote.nbma, &b->remote.nbma);
}
diff --git a/nhrpd/reqid.c b/nhrpd/reqid.c
index e8ad518e58..08a007bdf9 100644
--- a/nhrpd/reqid.c
+++ b/nhrpd/reqid.c
@@ -8,9 +8,10 @@ static unsigned int nhrp_reqid_key(void *data)
return r->request_id;
}
-static int nhrp_reqid_cmp(const void *data, const void *key)
+static bool nhrp_reqid_cmp(const void *data, const void *key)
{
const struct nhrp_reqid *a = data, *b = key;
+
return a->request_id == b->request_id;
}
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 17a30188c7..2bfa4201cb 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -1073,13 +1073,18 @@ DEFUN (show_ipv6_ospf6_interface_traffic,
DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
show_ipv6_ospf6_interface_ifname_prefix_cmd,
- "show ipv6 ospf6 interface IFNAME prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
+ "show ipv6 ospf6 interface IFNAME prefix\
+ [<\
+ detail\
+ |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
+ >]",
SHOW_STR
IP6_STR
OSPF6_STR
INTERFACE_STR
IFNAME_STR
"Display connected prefixes to advertise\n"
+ "Display details of the prefixes\n"
OSPF6_ROUTE_ADDRESS_STR
OSPF6_ROUTE_PREFIX_STR
OSPF6_ROUTE_MATCH_STR
@@ -1111,12 +1116,17 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
DEFUN (show_ipv6_ospf6_interface_prefix,
show_ipv6_ospf6_interface_prefix_cmd,
- "show ipv6 ospf6 interface prefix [<X:X::X:X|X:X::X:X/M>] [<match|detail>]",
+ "show ipv6 ospf6 interface prefix\
+ [<\
+ detail\
+ |<X:X::X:X|X:X::X:X/M> [<match|detail>]\
+ >]",
SHOW_STR
IP6_STR
OSPF6_STR
INTERFACE_STR
"Display connected prefixes to advertise\n"
+ "Display details of the prefixes\n"
OSPF6_ROUTE_ADDRESS_STR
OSPF6_ROUTE_PREFIX_STR
OSPF6_ROUTE_MATCH_STR
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index 4c24f47131..bb451c239e 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -59,7 +59,11 @@ int ospf6_neighbor_cmp(void *va, void *vb)
{
struct ospf6_neighbor *ona = (struct ospf6_neighbor *)va;
struct ospf6_neighbor *onb = (struct ospf6_neighbor *)vb;
- return (ntohl(ona->router_id) < ntohl(onb->router_id) ? -1 : 1);
+
+ if (ona->router_id == onb->router_id)
+ return 0;
+
+ return (ntohl(ona->router_id) < ntohl(onb->router_id)) ? -1 : 1;
}
struct ospf6_neighbor *ospf6_neighbor_lookup(uint32_t router_id,
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 359d59cb58..79b4648805 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -875,11 +875,9 @@ static int ospf_write(struct thread *thread)
}
/* If packets still remain in queue, call write thread. */
- if (!list_isempty(ospf->oi_write_q)) {
- ospf->t_write = NULL;
+ if (!list_isempty(ospf->oi_write_q))
thread_add_write(master, ospf_write, ospf, ospf->fd,
&ospf->t_write);
- }
return 0;
}
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index d793735003..43842e414e 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -94,7 +94,7 @@ static unsigned int sr_hash(void *p)
}
/* Compare 2 Router ID hash entries based on SR Node */
-static int sr_cmp(const void *p1, const void *p2)
+static bool sr_cmp(const void *p1, const void *p2)
{
const struct sr_node *srn = p1;
const struct in_addr *rid = p2;
@@ -2053,6 +2053,9 @@ DEFUN (no_sr_prefix_sid,
bool found = false;
int rc;
+ if (!ospf_sr_enabled(vty))
+ return CMD_WARNING_CONFIG_FAILED;
+
/* Get network prefix */
argv_find(argv, argc, "A.B.C.D/M", &idx);
rc = str2prefix(argv[idx]->arg, &p);
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index 7376e3e95b..6103bd7db5 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -69,7 +69,7 @@ static void *pbr_nhrc_hash_alloc(void *p)
return nhrc;
}
-static int pbr_nhrc_hash_equal(const void *arg1, const void *arg2)
+static bool pbr_nhrc_hash_equal(const void *arg1, const void *arg2)
{
const struct nexthop *nh1, *nh2;
@@ -139,7 +139,7 @@ static uint32_t pbr_nh_hash_key(void *arg)
return key;
}
-static int pbr_nh_hash_equal(const void *arg1, const void *arg2)
+static bool pbr_nh_hash_equal(const void *arg1, const void *arg2)
{
const struct pbr_nexthop_cache *pbrnc1 =
(const struct pbr_nexthop_cache *)arg1;
@@ -147,25 +147,25 @@ static int pbr_nh_hash_equal(const void *arg1, const void *arg2)
(const struct pbr_nexthop_cache *)arg2;
if (pbrnc1->nexthop->vrf_id != pbrnc2->nexthop->vrf_id)
- return 0;
+ return false;
if (pbrnc1->nexthop->ifindex != pbrnc2->nexthop->ifindex)
- return 0;
+ return false;
if (pbrnc1->nexthop->type != pbrnc2->nexthop->type)
- return 0;
+ return false;
switch (pbrnc1->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
- return 1;
+ return true;
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4:
return pbrnc1->nexthop->gate.ipv4.s_addr
== pbrnc2->nexthop->gate.ipv4.s_addr;
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_IPV6:
- return !memcmp(&pbrnc1->nexthop->gate.ipv6,
- &pbrnc2->nexthop->gate.ipv6, 16);
+ return !!memcmp(&pbrnc1->nexthop->gate.ipv6,
+ &pbrnc2->nexthop->gate.ipv6, 16);
case NEXTHOP_TYPE_BLACKHOLE:
return pbrnc1->nexthop->bh_type == pbrnc2->nexthop->bh_type;
}
@@ -173,7 +173,7 @@ static int pbr_nh_hash_equal(const void *arg1, const void *arg2)
/*
* We should not get here
*/
- return 0;
+ return false;
}
static void pbr_nhgc_delete(struct pbr_nexthop_group_cache *p)
@@ -724,7 +724,7 @@ static uint32_t pbr_nhg_hash_key(void *arg)
return jhash(&nhgc->name, strlen(nhgc->name), 0x52c34a96);
}
-static int pbr_nhg_hash_equal(const void *arg1, const void *arg2)
+static bool pbr_nhg_hash_equal(const void *arg1, const void *arg2)
{
const struct pbr_nexthop_group_cache *nhgc1 =
(const struct pbr_nexthop_group_cache *)arg1;
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 8a2efd41ad..7a19d25a7b 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -836,15 +836,15 @@ static unsigned int igmp_group_hash_key(void *arg)
return jhash_1word(group->group_addr.s_addr, 0);
}
-static int igmp_group_hash_equal(const void *arg1, const void *arg2)
+static bool igmp_group_hash_equal(const void *arg1, const void *arg2)
{
const struct igmp_group *g1 = (const struct igmp_group *)arg1;
const struct igmp_group *g2 = (const struct igmp_group *)arg2;
if (g1->group_addr.s_addr == g2->group_addr.s_addr)
- return 1;
+ return true;
- return 0;
+ return false;
}
static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 9ef343a0c5..807ad2bd12 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -687,7 +687,7 @@ static unsigned int pim_msdp_sa_hash_key_make(void *p)
return (jhash_2words(sa->sg.src.s_addr, sa->sg.grp.s_addr, 0));
}
-static int pim_msdp_sa_hash_eq(const void *p1, const void *p2)
+static bool pim_msdp_sa_hash_eq(const void *p1, const void *p2)
{
const struct pim_msdp_sa *sa1 = p1;
const struct pim_msdp_sa *sa2 = p2;
@@ -1221,7 +1221,7 @@ static unsigned int pim_msdp_peer_hash_key_make(void *p)
return (jhash_1word(mp->peer.s_addr, 0));
}
-static int pim_msdp_peer_hash_eq(const void *p1, const void *p2)
+static bool pim_msdp_peer_hash_eq(const void *p1, const void *p2)
{
const struct pim_msdp_peer *mp1 = p1;
const struct pim_msdp_peer *mp2 = p2;
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 68f7dae128..1290bfe56b 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -79,16 +79,16 @@ static int pim_channel_oil_compare(struct channel_oil *c1,
return 0;
}
-static int pim_oil_equal(const void *arg1, const void *arg2)
+static bool pim_oil_equal(const void *arg1, const void *arg2)
{
const struct channel_oil *c1 = (const struct channel_oil *)arg1;
const struct channel_oil *c2 = (const struct channel_oil *)arg2;
if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr)
&& (c1->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
- return 1;
+ return true;
- return 0;
+ return false;
}
static unsigned int pim_oil_hash_key(void *arg)
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index b02102c8fd..814d2e076b 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -407,7 +407,7 @@ unsigned int pim_rpf_hash_key(void *arg)
return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0);
}
-int pim_rpf_equal(const void *arg1, const void *arg2)
+bool pim_rpf_equal(const void *arg1, const void *arg2)
{
const struct pim_nexthop_cache *r1 =
(const struct pim_nexthop_cache *)arg1;
diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h
index 78bbfc7ed9..b9fe162f21 100644
--- a/pimd/pim_rpf.h
+++ b/pimd/pim_rpf.h
@@ -57,7 +57,7 @@ enum pim_rpf_result { PIM_RPF_OK = 0, PIM_RPF_CHANGED, PIM_RPF_FAILURE };
struct pim_upstream;
unsigned int pim_rpf_hash_key(void *arg);
-int pim_rpf_equal(const void *arg1, const void *arg2);
+bool pim_rpf_equal(const void *arg1, const void *arg2);
int pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
struct in_addr addr, int neighbor_needed);
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index cd6326f097..e5f5b34f2f 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1554,16 +1554,16 @@ void pim_upstream_terminate(struct pim_instance *pim)
pim->upstream_sg_wheel = NULL;
}
-int pim_upstream_equal(const void *arg1, const void *arg2)
+bool pim_upstream_equal(const void *arg1, const void *arg2)
{
const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
if ((up1->sg.grp.s_addr == up2->sg.grp.s_addr)
&& (up1->sg.src.s_addr == up2->sg.src.s_addr))
- return 1;
+ return true;
- return 0;
+ return false;
}
/* rfc4601:section-4.2:"Data Packet Forwarding Rules" defines
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index ba133b39dd..a347ab991c 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -223,5 +223,5 @@ void pim_upstream_spt_prefix_list_update(struct pim_instance *pim,
struct prefix_list *pl);
unsigned int pim_upstream_hash_key(void *arg);
-int pim_upstream_equal(const void *arg1, const void *arg2);
+bool pim_upstream_equal(const void *arg1, const void *arg2);
#endif /* PIM_UPSTREAM_H */
diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c
index ae62835a74..21317915d4 100644
--- a/ripd/rip_peer.c
+++ b/ripd/rip_peer.c
@@ -172,7 +172,10 @@ void rip_peer_display(struct vty *vty)
static int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2)
{
- return htonl(p1->addr.s_addr) > htonl(p2->addr.s_addr);
+ if (p2->addr.s_addr == p1->addr.s_addr)
+ return 0;
+
+ return (htonl(p1->addr.s_addr) < htonl(p2->addr.s_addr)) ? -1 : 1;
}
void rip_peer_init(void)
diff --git a/ripngd/ripng_peer.c b/ripngd/ripng_peer.c
index 2f75898482..6b2a183539 100644
--- a/ripngd/ripng_peer.c
+++ b/ripngd/ripng_peer.c
@@ -180,7 +180,7 @@ void ripng_peer_display(struct vty *vty)
static int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
{
- return addr6_cmp(&p1->addr, &p2->addr) > 0;
+ return memcmp(&p1->addr, &p2->addr, sizeof(struct in6_addr));
}
void ripng_peer_init()
diff --git a/staticd/static_routes.c b/staticd/static_routes.c
index ef0e6d057a..cd0330ed82 100644
--- a/staticd/static_routes.c
+++ b/staticd/static_routes.c
@@ -64,8 +64,8 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
const char *ifname, enum static_blackhole_type bh_type,
route_tag_t tag, uint8_t distance, struct static_vrf *svrf,
struct static_vrf *nh_svrf,
- struct static_nh_label *snh_label,
- uint32_t table_id)
+ struct static_nh_label *snh_label, uint32_t table_id,
+ bool onlink)
{
struct route_node *rn;
struct static_route *si;
@@ -104,7 +104,7 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
&& (table_id == si->table_id)
&& !memcmp(&si->snh_label, snh_label,
sizeof(struct static_nh_label))
- && si->bh_type == bh_type) {
+ && si->bh_type == bh_type && si->onlink == onlink) {
route_unlock_node(rn);
return 0;
}
@@ -129,6 +129,7 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
si->nh_vrf_id = nh_svrf->vrf->vrf_id;
strcpy(si->nh_vrfname, nh_svrf->vrf->name);
si->table_id = table_id;
+ si->onlink = onlink;
if (ifname)
strlcpy(si->ifname, ifname, sizeof(si->ifname));
diff --git a/staticd/static_routes.h b/staticd/static_routes.h
index bb1b664378..916ddcd7eb 100644
--- a/staticd/static_routes.h
+++ b/staticd/static_routes.h
@@ -79,6 +79,13 @@ struct static_route {
struct static_nh_label snh_label;
uint32_t table_id;
+
+ /*
+ * Whether to pretend the nexthop is directly attached to the specified
+ * link. Only meaningful when both a gateway address and interface name
+ * are specified.
+ */
+ bool onlink;
};
extern bool mpls_enabled;
@@ -94,7 +101,7 @@ extern int static_add_route(afi_t afi, safi_t safi, uint8_t type,
uint8_t distance, struct static_vrf *svrf,
struct static_vrf *nh_svrf,
struct static_nh_label *snh_label,
- uint32_t table_id);
+ uint32_t table_id, bool onlink);
extern int static_delete_route(afi_t afi, safi_t safi, uint8_t type,
struct prefix *p, struct prefix_ipv6 *src_p,
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index f697969a72..28fac0c870 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -79,6 +79,7 @@ struct static_hold_route {
char *distance_str;
char *label_str;
char *table_str;
+ bool onlink;
/* processed & masked destination, used for config display */
struct prefix dest;
@@ -273,7 +274,8 @@ static int static_route_leak(
afi_t afi, safi_t safi, const char *negate, const char *dest_str,
const char *mask_str, const char *src_str, const char *gate_str,
const char *ifname, const char *flag_str, const char *tag_str,
- const char *distance_str, const char *label_str, const char *table_str)
+ const char *distance_str, const char *label_str, const char *table_str,
+ bool onlink)
{
int ret;
uint8_t distance;
@@ -509,7 +511,7 @@ static int static_route_leak(
if (!negate) {
static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
bh_type, tag, distance, svrf, nh_svrf,
- &snh_label, table_id);
+ &snh_label, table_id, onlink);
/* Mark as having FRR configuration */
vrf_set_user_cfged(svrf->vrf);
} else {
@@ -550,10 +552,10 @@ static int static_route(struct vty *vty, afi_t afi, safi_t safi,
if (!svrf)
return CMD_WARNING_CONFIG_FAILED;
}
- return static_route_leak(
- vty, svrf, svrf, afi, safi, negate, dest_str, mask_str, src_str,
- gate_str, ifname, flag_str, tag_str, distance_str, label_str,
- table_str);
+ return static_route_leak(vty, svrf, svrf, afi, safi, negate, dest_str,
+ mask_str, src_str, gate_str, ifname, flag_str,
+ tag_str, distance_str, label_str, table_str,
+ false);
}
void static_config_install_delayed_routes(struct static_vrf *svrf)
@@ -578,7 +580,8 @@ void static_config_install_delayed_routes(struct static_vrf *svrf)
NULL, osvrf, nh_svrf, shr->afi, shr->safi, NULL,
shr->dest_str, shr->mask_str, shr->src_str,
shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str,
- shr->distance_str, shr->label_str, shr->table_str);
+ shr->distance_str, shr->label_str, shr->table_str,
+ shr->onlink);
if (installed != CMD_SUCCESS)
zlog_debug(
@@ -817,9 +820,10 @@ DEFPY(ip_route_blackhole_vrf,
* valid. Add an assert to make it happy
*/
assert(prefix);
- return static_route_leak(vty, svrf, svrf, AFI_IP, SAFI_UNICAST,
- no, prefix, mask_str, NULL, NULL, NULL,
- flag, tag_str, distance_str, label, table_str);
+ return static_route_leak(vty, svrf, svrf, AFI_IP, SAFI_UNICAST, no,
+ prefix, mask_str, NULL, NULL, NULL, flag,
+ tag_str, distance_str, label, table_str,
+ false);
}
DEFPY(ip_route_address_interface,
@@ -835,6 +839,7 @@ DEFPY(ip_route_address_interface,
|label WORD \
|table (1-4294967295) \
|nexthop-vrf NAME \
+ |onlink$onlink \
}]",
NO_STR IP_STR
"Establish static routes\n"
@@ -851,7 +856,8 @@ DEFPY(ip_route_address_interface,
MPLS_LABEL_HELPSTR
"Table to configure\n"
"The table number to configure\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Treat the nexthop as directly attached to the interface")
{
struct static_vrf *svrf;
struct static_vrf *nh_svrf;
@@ -884,10 +890,10 @@ DEFPY(ip_route_address_interface,
return CMD_WARNING_CONFIG_FAILED;
}
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str);
+ return static_route_leak(vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no,
+ prefix, mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label, table_str,
+ !!onlink);
}
DEFPY(ip_route_address_interface_vrf,
@@ -902,6 +908,7 @@ DEFPY(ip_route_address_interface_vrf,
|label WORD \
|table (1-4294967295) \
|nexthop-vrf NAME \
+ |onlink$onlink \
}]",
NO_STR IP_STR
"Establish static routes\n"
@@ -917,7 +924,8 @@ DEFPY(ip_route_address_interface_vrf,
MPLS_LABEL_HELPSTR
"Table to configure\n"
"The table number to configure\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Treat the nexthop as directly attached to the interface")
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
const char *flag = NULL;
@@ -945,10 +953,10 @@ DEFPY(ip_route_address_interface_vrf,
return CMD_WARNING_CONFIG_FAILED;
}
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str);
+ return static_route_leak(vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no,
+ prefix, mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label, table_str,
+ !!onlink);
}
DEFPY(ip_route,
@@ -1014,7 +1022,7 @@ DEFPY(ip_route,
return static_route_leak(
vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
NULL, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str);
+ table_str, false);
}
DEFPY(ip_route_vrf,
@@ -1073,7 +1081,7 @@ DEFPY(ip_route_vrf,
return static_route_leak(
vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
NULL, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str);
+ table_str, false);
}
DEFPY(ipv6_route_blackhole,
@@ -1159,7 +1167,7 @@ DEFPY(ipv6_route_blackhole_vrf,
return static_route_leak(
vty, svrf, svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, NULL, NULL, flag, tag_str, distance_str, label,
- table_str);
+ table_str, false);
}
DEFPY(ipv6_route_address_interface,
@@ -1174,6 +1182,7 @@ DEFPY(ipv6_route_address_interface,
|label WORD \
|table (1-4294967295) \
|nexthop-vrf NAME \
+ |onlink$onlink \
}]",
NO_STR
IPV6_STR
@@ -1190,7 +1199,8 @@ DEFPY(ipv6_route_address_interface,
MPLS_LABEL_HELPSTR
"Table to configure\n"
"The table number to configure\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Treat the nexthop as directly attached to the interface")
{
struct static_vrf *svrf;
struct static_vrf *nh_svrf;
@@ -1220,7 +1230,7 @@ DEFPY(ipv6_route_address_interface,
return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
- table_str);
+ table_str, !!onlink);
}
DEFPY(ipv6_route_address_interface_vrf,
@@ -1234,6 +1244,7 @@ DEFPY(ipv6_route_address_interface_vrf,
|label WORD \
|table (1-4294967295) \
|nexthop-vrf NAME \
+ |onlink$onlink \
}]",
NO_STR
IPV6_STR
@@ -1249,7 +1260,8 @@ DEFPY(ipv6_route_address_interface_vrf,
MPLS_LABEL_HELPSTR
"Table to configure\n"
"The table number to configure\n"
- VRF_CMD_HELP_STR)
+ VRF_CMD_HELP_STR
+ "Treat the nexthop as directly attached to the interface")
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
struct static_vrf *svrf = vrf->info;
@@ -1274,7 +1286,7 @@ DEFPY(ipv6_route_address_interface_vrf,
return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
- table_str);
+ table_str, !!onlink);
}
DEFPY(ipv6_route,
@@ -1334,7 +1346,7 @@ DEFPY(ipv6_route,
return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
- table_str);
+ table_str, false);
}
DEFPY(ipv6_route_vrf,
@@ -1387,7 +1399,7 @@ DEFPY(ipv6_route_vrf,
return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
- table_str);
+ table_str, false);
}
DEFUN_NOSH (show_debugging_staticd,
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index c540942a8d..4e168e142c 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -234,13 +234,13 @@ static unsigned int static_nht_hash_key(void *data)
return jhash_1word(nhtd->nh_vrf_id, key);
}
-static int static_nht_hash_cmp(const void *d1, const void *d2)
+static bool static_nht_hash_cmp(const void *d1, const void *d2)
{
const struct static_nht_data *nhtd1 = d1;
const struct static_nht_data *nhtd2 = d2;
if (nhtd1->nh_vrf_id != nhtd2->nh_vrf_id)
- return 0;
+ return false;
return prefix_same(nhtd1->nh, nhtd2->nh);
}
@@ -364,6 +364,8 @@ extern void static_zebra_route_add(struct route_node *rn,
memcpy(&api.src_prefix, src_pp, sizeof(api.src_prefix));
}
SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE);
+ if (si_changed->onlink)
+ SET_FLAG(api.flags, ZEBRA_FLAG_ONLINK);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
if (si_changed->distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
diff --git a/tests/lib/test_segv.c b/tests/lib/test_segv.c
index 3c9b57f049..43ca0837d5 100644
--- a/tests/lib/test_segv.c
+++ b/tests/lib/test_segv.c
@@ -32,10 +32,39 @@ struct quagga_signal_t sigs[] = {};
struct thread_master *master;
-static int threadfunc(struct thread *thread)
+void func1(int *arg);
+void func3(void);
+
+void func1(int *arg)
{
int *null = NULL;
*null += 1;
+ *arg = 1;
+}
+
+static void func2(size_t depth, int *arg)
+{
+ /* variable stack frame size */
+ int buf[depth];
+ for (size_t i = 0; i < depth; i++)
+ buf[i] = arg[i] + 1;
+ if (depth > 0)
+ func2(depth - 1, buf);
+ else
+ func1(&buf[0]);
+ for (size_t i = 0; i < depth; i++)
+ buf[i] = arg[i] + 2;
+}
+
+void func3(void)
+{
+ int buf[6];
+ func2(6, buf);
+}
+
+static int threadfunc(struct thread *thread)
+{
+ func3();
return 0;
}
diff --git a/vtysh/subdir.am b/vtysh/subdir.am
index 932429a87c..66a31ffff3 100644
--- a/vtysh/subdir.am
+++ b/vtysh/subdir.am
@@ -24,7 +24,7 @@ noinst_HEADERS += \
vtysh/vtysh_user.h \
# end
-vtysh_vtysh_LDADD = lib/libfrr.la @LIBCAP@ @LIBREADLINE@ @LIBS@ @CURSES@ @LIBPAM@
+vtysh_vtysh_LDADD = lib/libfrr.la @LIBCAP@ @LIBREADLINE@ @LIBS@ @LIBPAM@
EXTRA_DIST += vtysh/extract.pl
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 6a92b90813..8ed11f1876 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -856,7 +856,7 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp)
while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
lineno++;
- ret = command_config_read_one_line(vty, &cmd, 1);
+ ret = command_config_read_one_line(vty, &cmd, lineno, 1);
switch (ret) {
case CMD_WARNING:
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 0ccd3242d5..5fe0116158 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -79,7 +79,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
static int fec_del(zebra_fec_t *fec);
static unsigned int label_hash(void *p);
-static int label_cmp(const void *p1, const void *p2);
+static bool label_cmp(const void *p1, const void *p2);
static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
struct nexthop *nexthop);
static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
@@ -592,7 +592,7 @@ static unsigned int label_hash(void *p)
/*
* Compare 2 LSP hash entries based on in-label.
*/
-static int label_cmp(const void *p1, const void *p2)
+static bool label_cmp(const void *p1, const void *p2)
{
const zebra_ile_t *ile1 = p1;
const zebra_ile_t *ile2 = p2;
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 40f97765da..1a528780c1 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -164,7 +164,7 @@ uint32_t zebra_pbr_rules_hash_key(void *arg)
jhash_1word(rule->rule.unique, key));
}
-int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
+bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
{
const struct zebra_pbr_rule *r1, *r2;
@@ -172,36 +172,36 @@ int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
r2 = (const struct zebra_pbr_rule *)arg2;
if (r1->rule.seq != r2->rule.seq)
- return 0;
+ return false;
if (r1->rule.priority != r2->rule.priority)
- return 0;
+ return false;
if (r1->rule.unique != r2->rule.unique)
- return 0;
+ return false;
if (r1->rule.action.table != r2->rule.action.table)
- return 0;
+ return false;
if (r1->rule.filter.src_port != r2->rule.filter.src_port)
- return 0;
+ return false;
if (r1->rule.filter.dst_port != r2->rule.filter.dst_port)
- return 0;
+ return false;
if (r1->rule.filter.fwmark != r2->rule.filter.fwmark)
- return 0;
+ return false;
if (!prefix_same(&r1->rule.filter.src_ip, &r2->rule.filter.src_ip))
- return 0;
+ return false;
if (!prefix_same(&r1->rule.filter.dst_ip, &r2->rule.filter.dst_ip))
- return 0;
+ return false;
if (r1->ifp != r2->ifp)
- return 0;
+ return false;
- return 1;
+ return true;
}
struct pbr_rule_unique_lookup {
@@ -260,7 +260,7 @@ uint32_t zebra_pbr_ipset_hash_key(void *arg)
return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, 0x63ab42de);
}
-int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
+bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
{
const struct zebra_pbr_ipset *r1, *r2;
@@ -268,13 +268,13 @@ int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
r2 = (const struct zebra_pbr_ipset *)arg2;
if (r1->type != r2->type)
- return 0;
+ return false;
if (r1->unique != r2->unique)
- return 0;
+ return false;
if (strncmp(r1->ipset_name, r2->ipset_name,
ZEBRA_IPSET_NAME_SIZE))
- return 0;
- return 1;
+ return false;
+ return true;
}
void zebra_pbr_ipset_entry_free(void *arg)
@@ -313,7 +313,7 @@ uint32_t zebra_pbr_ipset_entry_hash_key(void *arg)
return key;
}
-int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2)
+bool zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2)
{
const struct zebra_pbr_ipset_entry *r1, *r2;
@@ -321,29 +321,29 @@ int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2)
r2 = (const struct zebra_pbr_ipset_entry *)arg2;
if (r1->unique != r2->unique)
- return 0;
+ return false;
if (!prefix_same(&r1->src, &r2->src))
- return 0;
+ return false;
if (!prefix_same(&r1->dst, &r2->dst))
- return 0;
+ return false;
if (r1->src_port_min != r2->src_port_min)
- return 0;
+ return false;
if (r1->src_port_max != r2->src_port_max)
- return 0;
+ return false;
if (r1->dst_port_min != r2->dst_port_min)
- return 0;
+ return false;
if (r1->dst_port_max != r2->dst_port_max)
- return 0;
+ return false;
if (r1->proto != r2->proto)
- return 0;
- return 1;
+ return false;
+ return true;
}
void zebra_pbr_iptable_free(void *arg)
@@ -389,7 +389,7 @@ uint32_t zebra_pbr_iptable_hash_key(void *arg)
iptable->unique, key);
}
-int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
+bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
{
const struct zebra_pbr_iptable *r1, *r2;
@@ -397,31 +397,31 @@ int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
r2 = (const struct zebra_pbr_iptable *)arg2;
if (r1->type != r2->type)
- return 0;
+ return false;
if (r1->unique != r2->unique)
- return 0;
+ return false;
if (r1->filter_bm != r2->filter_bm)
- return 0;
+ return false;
if (r1->fwmark != r2->fwmark)
- return 0;
+ return false;
if (r1->action != r2->action)
- return 0;
+ return false;
if (strncmp(r1->ipset_name, r2->ipset_name,
ZEBRA_IPSET_NAME_SIZE))
- return 0;
+ return false;
if (r1->pkt_len_min != r2->pkt_len_min)
- return 0;
+ return false;
if (r1->pkt_len_max != r2->pkt_len_max)
- return 0;
+ return false;
if (r1->tcp_flags != r2->tcp_flags)
- return 0;
+ return false;
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
- return 0;
+ return false;
if (r1->dscp_value != r2->dscp_value)
- return 0;
+ return false;
if (r1->fragment != r2->fragment)
- return 0;
- return 1;
+ return false;
+ return true;
}
static void *pbr_rule_alloc_intern(void *arg)
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 3311af4d26..093fcfa8b0 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -213,7 +213,7 @@ extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule);
extern void zebra_pbr_rules_free(void *arg);
extern uint32_t zebra_pbr_rules_hash_key(void *arg);
-extern int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
+extern bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
/* has operates on 32bit pointer
* and field is a string of 8bit
@@ -222,15 +222,16 @@ extern int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
extern void zebra_pbr_ipset_free(void *arg);
extern uint32_t zebra_pbr_ipset_hash_key(void *arg);
-extern int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2);
+extern bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2);
extern void zebra_pbr_ipset_entry_free(void *arg);
extern uint32_t zebra_pbr_ipset_entry_hash_key(void *arg);
-extern int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2);
+extern bool zebra_pbr_ipset_entry_hash_equal(const void *arg1,
+ const void *arg2);
extern void zebra_pbr_iptable_free(void *arg);
extern uint32_t zebra_pbr_iptable_hash_key(void *arg);
-extern int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2);
+extern bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2);
extern void zebra_pbr_init(void);
extern void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 2192907b21..db610098f0 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -601,9 +601,20 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
__PRETTY_FUNCTION__);
return resolved;
} else {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ zlog_debug("\t%s: Route Type %s has not turned on recursion",
+ __PRETTY_FUNCTION__,
+ zebra_route_string(re->type));
+ if (re->type == ZEBRA_ROUTE_BGP &&
+ !CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP))
+ zlog_debug("\tEBGP: see \"disable-ebgp-connected-route-check\" or \"disable-connected-check\"");
+ }
return 0;
}
}
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug("\t%s: Nexthop did not lookup in table",
+ __PRETTY_FUNCTION__);
return 0;
}
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 5078eff590..fe182780be 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -81,7 +81,6 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
struct ipaddr *ip, uint8_t flags,
uint32_t seq, uint16_t cmd);
static unsigned int neigh_hash_keymake(void *p);
-static int neigh_cmp(const void *p1, const void *p2);
static void *zvni_neigh_alloc(void *p);
static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
struct ethaddr *mac);
@@ -137,7 +136,7 @@ static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni);
static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni);
static unsigned int mac_hash_keymake(void *p);
-static int mac_cmp(const void *p1, const void *p2);
+static bool mac_cmp(const void *p1, const void *p2);
static void *zvni_mac_alloc(void *p);
static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr);
static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
@@ -157,7 +156,6 @@ static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac);
static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
static unsigned int vni_hash_keymake(void *p);
-static int vni_hash_cmp(const void *p1, const void *p2);
static void *zvni_alloc(void *p);
static zebra_vni_t *zvni_lookup(vni_t vni);
static zebra_vni_t *zvni_add(vni_t vni);
@@ -1254,20 +1252,28 @@ static unsigned int neigh_hash_keymake(void *p)
/*
* Compare two neighbor hash structures.
*/
-static int neigh_cmp(const void *p1, const void *p2)
+static bool neigh_cmp(const void *p1, const void *p2)
{
const zebra_neigh_t *n1 = p1;
const zebra_neigh_t *n2 = p2;
if (n1 == NULL && n2 == NULL)
- return 1;
+ return true;
if (n1 == NULL || n2 == NULL)
- return 0;
+ return false;
return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
}
+static int neigh_list_cmp(void *p1, void *p2)
+{
+ const zebra_neigh_t *n1 = p1;
+ const zebra_neigh_t *n2 = p2;
+
+ return memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr));
+}
+
/*
* Callback to allocate neighbor hash entry.
*/
@@ -2232,16 +2238,16 @@ static unsigned int mac_hash_keymake(void *p)
/*
* Compare two MAC addresses.
*/
-static int mac_cmp(const void *p1, const void *p2)
+static bool mac_cmp(const void *p1, const void *p2)
{
const zebra_mac_t *pmac1 = p1;
const zebra_mac_t *pmac2 = p2;
if (pmac1 == NULL && pmac2 == NULL)
- return 1;
+ return true;
if (pmac1 == NULL || pmac2 == NULL)
- return 0;
+ return false;
return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN)
== 0);
@@ -2275,7 +2281,7 @@ static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
assert(mac);
mac->neigh_list = list_new();
- mac->neigh_list->cmp = (int (*)(void *, void *))neigh_cmp;
+ mac->neigh_list->cmp = neigh_list_cmp;
return mac;
}
@@ -2753,7 +2759,7 @@ static unsigned int vni_hash_keymake(void *p)
/*
* Compare 2 VNI hash entries.
*/
-static int vni_hash_cmp(const void *p1, const void *p2)
+static bool vni_hash_cmp(const void *p1, const void *p2)
{
const zebra_vni_t *zvni1 = p1;
const zebra_vni_t *zvni2 = p2;
@@ -2761,6 +2767,16 @@ static int vni_hash_cmp(const void *p1, const void *p2)
return (zvni1->vni == zvni2->vni);
}
+static int vni_list_cmp(void *p1, void *p2)
+{
+ const zebra_vni_t *zvni1 = p1;
+ const zebra_vni_t *zvni2 = p2;
+
+ if (zvni1->vni == zvni2->vni)
+ return 0;
+ return (zvni1->vni < zvni2->vni) ? -1 : 1;
+}
+
/*
* Callback to allocate VNI hash entry.
*/
@@ -3601,7 +3617,7 @@ static unsigned int l3vni_hash_keymake(void *p)
/*
* Compare 2 L3 VNI hash entries.
*/
-static int l3vni_hash_cmp(const void *p1, const void *p2)
+static bool l3vni_hash_cmp(const void *p1, const void *p2)
{
const zebra_l3vni_t *zl3vni1 = p1;
const zebra_l3vni_t *zl3vni2 = p2;
@@ -3662,7 +3678,7 @@ static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
zl3vni->svi_if = NULL;
zl3vni->vxlan_if = NULL;
zl3vni->l2vnis = list_new();
- zl3vni->l2vnis->cmp = (int (*)(void *, void *))vni_hash_cmp;
+ zl3vni->l2vnis->cmp = vni_list_cmp;
/* Create hash table for remote RMAC */
zl3vni->rmac_table = hash_create(mac_hash_keymake, mac_cmp,