summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfdd/bfd.c23
-rw-r--r--bfdd/bfd.h8
-rw-r--r--bfdd/bfd_packet.c9
-rw-r--r--bfdd/bfdctl.h2
-rw-r--r--bfdd/ptm_adapter.c13
-rw-r--r--bgpd/bgp_advertise.c4
-rw-r--r--bgpd/bgp_advertise.h2
-rw-r--r--bgpd/bgp_aspath.c6
-rw-r--r--bgpd/bgp_aspath.h2
-rw-r--r--bgpd/bgp_attr.c8
-rw-r--r--bgpd/bgp_attr.h2
-rw-r--r--bgpd/bgp_bfd.c118
-rw-r--r--bgpd/bgp_clist.c4
-rw-r--r--bgpd/bgp_community.c6
-rw-r--r--bgpd/bgp_community.h2
-rw-r--r--bgpd/bgp_ecommunity.c2
-rw-r--r--bgpd/bgp_ecommunity.h2
-rw-r--r--bgpd/bgp_evpn.c20
-rw-r--r--bgpd/bgp_evpn_vty.c5
-rw-r--r--bgpd/bgp_fsm.c2
-rw-r--r--bgpd/bgp_keepalives.c4
-rw-r--r--bgpd/bgp_lcommunity.c2
-rw-r--r--bgpd/bgp_lcommunity.h2
-rw-r--r--bgpd/bgp_mac.c4
-rw-r--r--bgpd/bgp_nexthop.c75
-rw-r--r--bgpd/bgp_nexthop.h10
-rw-r--r--bgpd/bgp_pbr.c20
-rw-r--r--bgpd/bgp_pbr.h8
-rw-r--r--bgpd/bgp_route.c120
-rw-r--r--bgpd/bgp_updgrp.c2
-rw-r--r--bgpd/bgp_updgrp_packet.c6
-rw-r--r--bgpd/bgp_vty.c1
-rw-r--r--bgpd/bgpd.c4
-rw-r--r--doc/developer/topotests.rst6
-rw-r--r--doc/user/bfd.rst15
-rw-r--r--isisd/fabricd.c4
-rw-r--r--isisd/isis_bfd.c5
-rw-r--r--isisd/isis_spf_private.h4
-rw-r--r--isisd/isis_tx_queue.c4
-rw-r--r--lib/bfd.c14
-rw-r--r--lib/bfd.h7
-rw-r--r--lib/command.c2
-rw-r--r--lib/distribute.c2
-rw-r--r--lib/ferr.c4
-rw-r--r--lib/hash.c4
-rw-r--r--lib/hash.h6
-rw-r--r--lib/if_rmap.c2
-rw-r--r--lib/northbound.c2
-rw-r--r--lib/routemap.c15
-rw-r--r--lib/thread.c4
-rw-r--r--lib/vrf.c4
-rw-r--r--lib/wheel.c2
-rw-r--r--lib/wheel.h8
-rw-r--r--lib/yang_translator.c2
-rw-r--r--lib/zebra.h8
-rw-r--r--nhrpd/nhrp_cache.c4
-rw-r--r--nhrpd/nhrp_peer.c4
-rw-r--r--nhrpd/nhrp_vc.c4
-rw-r--r--nhrpd/reqid.c4
-rw-r--r--ospf6d/ospf6_bfd.c10
-rw-r--r--ospfd/ospf_bfd.c8
-rw-r--r--ospfd/ospf_sr.c2
-rw-r--r--pbrd/pbr_nht.c11
-rw-r--r--pbrd/pbr_zebra.c10
-rw-r--r--pimd/pim_bfd.c10
-rw-r--r--pimd/pim_ifchannel.c4
-rw-r--r--pimd/pim_ifchannel.h2
-rw-r--r--pimd/pim_igmp.c4
-rw-r--r--pimd/pim_msdp.c8
-rw-r--r--pimd/pim_oil.c4
-rw-r--r--pimd/pim_rpf.c4
-rw-r--r--pimd/pim_rpf.h2
-rw-r--r--pimd/pim_upstream.c4
-rw-r--r--pimd/pim_upstream.h2
-rw-r--r--pimd/pim_vxlan.c4
-rw-r--r--staticd/static_zebra.c4
-rw-r--r--tests/lib/test_srcdest_table.c4
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/__init__.py0
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/bgp_ipv6_routes_down.json103
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf20
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/ipv6_routes.json80
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/peers.json16
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/peers_down.json14
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/zebra.conf8
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r2/zebra.conf9
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/bgp_ipv6_routes_down.json55
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf25
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/ipv6_routes.json80
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/peers.json16
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/peers_down.json14
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/zebra.conf7
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.dot58
-rwxr-xr-xtests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py248
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf10
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/sharpd.conf0
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf10
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/sharpd.conf0
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf6
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py20
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py66
-rwxr-xr-xtests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py18
-rw-r--r--tests/topotests/lib/ltemplate.py25
-rw-r--r--tests/topotests/lib/topogen.py2
-rw-r--r--tools/coccinelle/hash_const.cocci76
-rw-r--r--zebra/main.c8
-rw-r--r--zebra/redistribute.c7
-rw-r--r--zebra/rtadv.c138
-rw-r--r--zebra/rtadv.h4
-rw-r--r--zebra/zapi_msg.c6
-rw-r--r--zebra/zebra_fpm_netlink.c3
-rw-r--r--zebra/zebra_fpm_protobuf.c3
-rw-r--r--zebra/zebra_mpls.c4
-rw-r--r--zebra/zebra_mpls_openbsd.c3
-rw-r--r--zebra/zebra_ns.c8
-rw-r--r--zebra/zebra_pbr.c20
-rw-r--r--zebra/zebra_pbr.h8
-rw-r--r--zebra/zebra_ptm.c6
-rw-r--r--zebra/zebra_rib.c26
-rw-r--r--zebra/zebra_routemap.c20
-rw-r--r--zebra/zebra_router.c17
-rw-r--r--zebra/zebra_router.h9
-rw-r--r--zebra/zebra_vrf.c91
-rw-r--r--zebra/zebra_vrf.h39
-rw-r--r--zebra/zebra_vxlan.c26
-rw-r--r--zebra/zserv.h2
127 files changed, 1743 insertions, 429 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index a2e84e928d..4354431820 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -600,6 +600,17 @@ skip_echo:
bfd_recvtimer_update(bs);
bfd_xmttimer_update(bs, bs->xmt_TO);
}
+ if (bpc->bpc_cbit) {
+ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
+ return;
+
+ BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ } else {
+ if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CBIT))
+ return;
+
+ BFD_UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ }
}
static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
@@ -1271,16 +1282,16 @@ void bs_to_bpc(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
static struct hash *bfd_id_hash;
static struct hash *bfd_key_hash;
-static unsigned int bfd_id_hash_do(void *p);
-static unsigned int bfd_key_hash_do(void *p);
+static unsigned int bfd_id_hash_do(const void *p);
+static unsigned int bfd_key_hash_do(const void *p);
static void _bfd_free(struct hash_bucket *hb,
void *arg __attribute__((__unused__)));
/* BFD hash for our discriminator. */
-static unsigned int bfd_id_hash_do(void *p)
+static unsigned int bfd_id_hash_do(const void *p)
{
- struct bfd_session *bs = p;
+ const struct bfd_session *bs = p;
return jhash_1word(bs->discrs.my_discr, 0);
}
@@ -1293,9 +1304,9 @@ static bool bfd_id_hash_cmp(const void *n1, const void *n2)
}
/* BFD hash for single hop. */
-static unsigned int bfd_key_hash_do(void *p)
+static unsigned int bfd_key_hash_do(const void *p)
{
- struct bfd_session *bs = p;
+ const struct bfd_session *bs = p;
return jhash(&bs->key, sizeof(bs->key), 0);
}
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 3f3d603832..213e905bf0 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -129,6 +129,12 @@ struct bfd_echo_pkt {
flags |= (val & 0x3) << 6; \
}
#define BFD_GETSTATE(flags) ((flags >> 6) & 0x3)
+#define BFD_SETCBIT(flags, val) \
+ { \
+ if ((val)) \
+ flags |= val; \
+ }
+#define BFD_GETCBIT(flags) (flags & BFD_FBIT)
#define BFD_ECHO_VERSION 1
#define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt)
@@ -168,6 +174,7 @@ enum bfd_session_flags {
*/
BFD_SESS_FLAG_SHUTDOWN = 1 << 7, /* disable BGP peer function */
BFD_SESS_FLAG_CONFIG = 1 << 8, /* Session configured with bfd NB API */
+ BFD_SESS_FLAG_CBIT = 1 << 9, /* CBIT is set */
};
#define BFD_SET_FLAG(field, flag) (field |= flag)
@@ -210,6 +217,7 @@ struct bfd_session {
uint8_t detect_mult;
uint8_t remote_detect_mult;
uint8_t mh_ttl;
+ uint8_t remote_cbit;
/* Timers */
struct bfd_timers timers;
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 8edba05d12..f3acfa4167 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -221,6 +221,10 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit)
BFD_SETVER(cp.diag, BFD_VERSION);
cp.flags = 0;
BFD_SETSTATE(cp.flags, bfd->ses_state);
+
+ if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_CBIT))
+ BFD_SETCBIT(cp.flags, BFD_CBIT);
+
BFD_SETDEMANDBIT(cp.flags, BFD_DEF_DEMAND);
/*
@@ -646,6 +650,11 @@ int bfd_recv_cb(struct thread *t)
ntohl(cp->timers.required_min_echo);
bfd->remote_detect_mult = cp->detect_mult;
+ if (BFD_GETCBIT(cp->flags))
+ bfd->remote_cbit = 1;
+ else
+ bfd->remote_cbit = 0;
+
/* State switch from section 6.2. */
bs_state_handler(bfd, BFD_GETSTATE(cp->flags));
diff --git a/bfdd/bfdctl.h b/bfdd/bfdctl.h
index 0da1ca8df6..4ce23a8f27 100644
--- a/bfdd/bfdctl.h
+++ b/bfdd/bfdctl.h
@@ -88,6 +88,8 @@ struct bfd_peer_cfg {
bool bpc_createonly;
bool bpc_shutdown;
+ bool bpc_cbit;
+
/* Status information */
enum bfd_peer_status bpc_bps;
uint32_t bpc_id;
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index a12a3c196b..3e2ace6ea6 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -89,6 +89,7 @@ static void debug_printbpc(const char *func, unsigned int line,
{
char addr[3][128];
char timers[3][128];
+ char cbit_str[10];
addr[0][0] = addr[1][0] = addr[2][0] = timers[0][0] = timers[1][0] =
timers[2][0] = 0;
@@ -117,9 +118,11 @@ static void debug_printbpc(const char *func, unsigned int line,
snprintf(timers[2], sizeof(timers[2]), " detect-multiplier:%d",
bpc->bpc_detectmultiplier);
- log_debug("%s:%d: %s %s%s%s%s%s%s", func, line,
+ sprintf(cbit_str, "CB %x", bpc->bpc_cbit);
+
+ log_debug("%s:%d: %s %s%s%s%s%s%s %s", func, line,
bpc->bpc_mhop ? "multi-hop" : "single-hop", addr[0], addr[1],
- addr[2], timers[0], timers[1], timers[2]);
+ addr[2], timers[0], timers[1], timers[2], cbit_str);
}
#define DEBUG_PRINTBPC(bpc) debug_printbpc(__FILE__, __LINE__, (bpc))
@@ -173,6 +176,7 @@ int ptm_bfd_notify(struct bfd_session *bs)
* - AF_INET6:
* - 16 bytes: ipv6
* - c: prefix length
+ * - c: cbit
*
* Commands: ZEBRA_BFD_DEST_REPLAY
*
@@ -219,6 +223,8 @@ int ptm_bfd_notify(struct bfd_session *bs)
/* BFD source prefix information. */
_ptm_msg_address(msg, bs->key.family, &bs->key.local);
+ stream_putc(msg, bs->remote_cbit);
+
/* Write packet size. */
stream_putw_at(msg, 0, stream_get_endp(msg));
@@ -293,6 +299,7 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
* - 16 bytes: ipv6 address
* - c: ifname length
* - X bytes: interface name
+ * - c: bfd_cbit
*
* q(64), l(32), w(16), c(8)
*/
@@ -371,6 +378,8 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
}
}
+ STREAM_GETC(msg, bpc->bpc_cbit);
+
/* Sanity check: peer and local address must match IP types. */
if (bpc->bpc_local.sa_sin.sin_family != 0
&& (bpc->bpc_local.sa_sin.sin_family
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index c9f68d037b..497fb0749e 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -64,9 +64,9 @@ static void *baa_hash_alloc(void *p)
return baa;
}
-unsigned int baa_hash_key(void *p)
+unsigned int baa_hash_key(const void *p)
{
- struct bgp_advertise_attr *baa = (struct bgp_advertise_attr *)p;
+ const struct bgp_advertise_attr *baa = p;
return attrhash_key_make(baa->attr);
}
diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h
index cc845b93e7..7d2fdf1f0b 100644
--- a/bgpd/bgp_advertise.h
+++ b/bgpd/bgp_advertise.h
@@ -144,7 +144,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 unsigned int baa_hash_key(const void *p);
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);
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 92c37fabd2..05577cb8bd 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -2008,13 +2008,13 @@ struct aspath *aspath_str2aspath(const char *str)
}
/* Make hash value by raw aspath data. */
-unsigned int aspath_key_make(void *p)
+unsigned int aspath_key_make(const void *p)
{
- struct aspath *aspath = (struct aspath *)p;
+ const struct aspath *aspath = p;
unsigned int key = 0;
if (!aspath->str)
- aspath_str_update(aspath, false);
+ aspath_str_update((struct aspath *)aspath, false);
key = jhash(aspath->str, aspath->str_len, 2334325);
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index be5725c1ae..6f3d94cdb3 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -102,7 +102,7 @@ extern const char *aspath_print(struct aspath *);
extern void aspath_print_vty(struct vty *, const char *, struct aspath *,
const char *);
extern void aspath_print_all_vty(struct vty *);
-extern unsigned int aspath_key_make(void *);
+extern unsigned int aspath_key_make(const void *);
extern unsigned int aspath_get_first_as(struct aspath *);
extern unsigned int aspath_get_last_as(struct aspath *);
extern int aspath_loop_check(struct aspath *, as_t);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index bdcce596ce..5a4105b400 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -139,7 +139,7 @@ int cluster_loop_check(struct cluster_list *cluster, struct in_addr originator)
return 0;
}
-static unsigned int cluster_hash_key_make(void *p)
+static unsigned int cluster_hash_key_make(const void *p)
{
const struct cluster_list *cluster = p;
@@ -347,7 +347,7 @@ static void encap_unintern(struct bgp_attr_encap_subtlv **encapp,
}
}
-static unsigned int encap_hash_key_make(void *p)
+static unsigned int encap_hash_key_make(const void *p)
{
const struct bgp_attr_encap_subtlv *encap = p;
@@ -432,7 +432,7 @@ void transit_unintern(struct transit *transit)
}
}
-static unsigned int transit_hash_key_make(void *p)
+static unsigned int transit_hash_key_make(const void *p)
{
const struct transit *transit = p;
@@ -483,7 +483,7 @@ unsigned long int attr_unknown_count(void)
return transit_hash->count;
}
-unsigned int attrhash_key_make(void *p)
+unsigned int attrhash_key_make(const void *p)
{
const struct attr *attr = (struct attr *)p;
uint32_t key = 0;
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index a6fdac9ebf..1592a8df4e 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -283,7 +283,7 @@ extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
struct prefix *);
extern bool attrhash_cmp(const void *arg1, const void *arg2);
-extern unsigned int attrhash_key_make(void *);
+extern unsigned int attrhash_key_make(const void *);
extern void attr_show_all(struct vty *);
extern unsigned long int attr_count(void);
extern unsigned long int attr_unknown_count(void);
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index a9c30acafb..57fef8e913 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -96,7 +96,7 @@ int bgp_bfd_is_peer_multihop(struct peer *peer)
static void bgp_bfd_peer_sendmsg(struct peer *peer, int command)
{
struct bfd_info *bfd_info;
- int multihop;
+ int multihop, cbit = 0;
vrf_id_t vrf_id;
bfd_info = (struct bfd_info *)peer->bfd_info;
@@ -112,20 +112,30 @@ static void bgp_bfd_peer_sendmsg(struct peer *peer, int command)
if ((command == ZEBRA_BFD_DEST_REGISTER) && multihop)
SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
}
+ /* while graceful restart with fwd path preserved
+ * and bfd controlplane check not configured is not kept
+ * keep bfd independent controlplane bit set to 1
+ */
+ if (!bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_RESTART)
+ && !bgp_flag_check(peer->bgp, BGP_FLAG_GR_PRESERVE_FWD)
+ && !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE))
+ SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
+
+ cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
if (peer->su.sa.sa_family == AF_INET)
bfd_peer_sendmsg(
zclient, bfd_info, AF_INET, &peer->su.sin.sin_addr,
(peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
- peer->ttl, multihop, command, 1, vrf_id);
+ peer->ttl, multihop, cbit, command, 1, vrf_id);
else if (peer->su.sa.sa_family == AF_INET6)
bfd_peer_sendmsg(
zclient, bfd_info, AF_INET6, &peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr
: NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
- peer->ttl, multihop, command, 1, vrf_id);
+ peer->ttl, multihop, cbit, command, 1, vrf_id);
}
/*
@@ -260,7 +270,8 @@ static int bgp_bfd_dest_replay(ZAPI_CALLBACK_ARGS)
* down the peer if the BFD session went down from
* * up.
*/
-static void bgp_bfd_peer_status_update(struct peer *peer, int status)
+static void bgp_bfd_peer_status_update(struct peer *peer, int status,
+ int remote_cbit)
{
struct bfd_info *bfd_info;
int old_status;
@@ -280,6 +291,14 @@ static void bgp_bfd_peer_status_update(struct peer *peer, int status)
bfd_get_status_str(status));
}
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP)) {
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE) &&
+ CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE) &&
+ !remote_cbit) {
+ zlog_info("%s BFD DOWN message ignored in the process"
+ " of graceful restart when C bit is cleared",
+ peer->host);
+ return;
+ }
peer->last_reset = PEER_DOWN_BFD_DOWN;
BGP_EVENT_ADD(peer, BGP_Stop);
}
@@ -303,23 +322,27 @@ static int bgp_bfd_dest_update(ZAPI_CALLBACK_ARGS)
struct prefix dp;
struct prefix sp;
int status;
+ int remote_cbit;
- ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, vrf_id);
+ ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status,
+ &remote_cbit, vrf_id);
if (BGP_DEBUG(zebra, ZEBRA)) {
char buf[2][PREFIX2STR_BUFFER];
prefix2str(&dp, buf[0], sizeof(buf[0]));
if (ifp) {
zlog_debug(
- "Zebra: vrf %u interface %s bfd destination %s %s",
+ "Zebra: vrf %u interface %s bfd destination %s %s %s",
vrf_id, ifp->name, buf[0],
- bfd_get_status_str(status));
+ bfd_get_status_str(status),
+ remote_cbit ? "(cbit on)" : "");
} else {
prefix2str(&sp, buf[1], sizeof(buf[1]));
zlog_debug(
- "Zebra: vrf %u source %s bfd destination %s %s",
+ "Zebra: vrf %u source %s bfd destination %s %s %s",
vrf_id, buf[1], buf[0],
- bfd_get_status_str(status));
+ bfd_get_status_str(status),
+ remote_cbit ? "(cbit on)" : "");
}
}
@@ -351,7 +374,8 @@ static int bgp_bfd_dest_update(ZAPI_CALLBACK_ARGS)
if (ifp && (ifp == peer->nexthop.ifp)) {
bgp_bfd_peer_status_update(peer,
- status);
+ status,
+ remote_cbit);
} else {
if (!peer->su_local)
continue;
@@ -381,7 +405,8 @@ static int bgp_bfd_dest_update(ZAPI_CALLBACK_ARGS)
continue;
bgp_bfd_peer_status_update(peer,
- status);
+ status,
+ remote_cbit);
}
}
}
@@ -534,6 +559,9 @@ void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)
&& (bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
vty_out(vty, " neighbor %s bfd\n", addr);
+
+ if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE))
+ vty_out(vty, " neighbor %s bfd check-control-plane-failure\n", addr);
}
/*
@@ -644,6 +672,73 @@ DEFUN_HIDDEN (neighbor_bfd_type,
return CMD_SUCCESS;
}
+static int bgp_bfd_set_check_controlplane_failure_peer(struct vty *vty, struct peer *peer,
+ const char *no)
+{
+ struct bfd_info *bfd_info;
+
+ if (!peer->bfd_info) {
+ if (no)
+ return CMD_SUCCESS;
+ vty_out(vty, "%% Specify bfd command first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ bfd_info = (struct bfd_info *)peer->bfd_info;
+ if (!no) {
+ if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE)) {
+ SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE);
+ bgp_bfd_update_peer(peer);
+ }
+ } else {
+ if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE)) {
+ UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_CHECK_CONTROLPLANE);
+ bgp_bfd_update_peer(peer);
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+
+DEFUN (neighbor_bfd_check_controlplane_failure,
+ neighbor_bfd_check_controlplane_failure_cmd,
+ "[no] neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "BFD support\n"
+ "Link dataplane status with BGP controlplane\n")
+{
+ const char *no = strmatch(argv[0]->text, "no") ? "no" : NULL;
+ int idx_peer = 0;
+ struct peer *peer;
+ struct peer_group *group;
+ struct listnode *node, *nnode;
+ int ret = CMD_SUCCESS;
+
+ if (no)
+ idx_peer = 2;
+ else
+ idx_peer = 1;
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer) {
+ vty_out(vty, "%% Specify remote-as or peer-group commands first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (!peer->bfd_info) {
+ if (no)
+ return CMD_SUCCESS;
+ vty_out(vty, "%% Specify bfd command first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer))
+ ret = bgp_bfd_set_check_controlplane_failure_peer(vty, peer, no);
+ } else
+ ret = bgp_bfd_set_check_controlplane_failure_peer(vty, peer, no);
+ return ret;
+ }
+
DEFUN (no_neighbor_bfd,
no_neighbor_bfd_cmd,
#if HAVE_BFDD > 0
@@ -718,6 +813,7 @@ void bgp_bfd_init(void)
install_element(BGP_NODE, &neighbor_bfd_cmd);
install_element(BGP_NODE, &neighbor_bfd_param_cmd);
install_element(BGP_NODE, &neighbor_bfd_type_cmd);
+ install_element(BGP_NODE, &neighbor_bfd_check_controlplane_failure_cmd);
install_element(BGP_NODE, &no_neighbor_bfd_cmd);
install_element(BGP_NODE, &no_neighbor_bfd_type_cmd);
}
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index e308e963b5..b9a5784799 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -36,9 +36,9 @@
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_clist.h"
-static uint32_t bgp_clist_hash_key_community_list(void *data)
+static uint32_t bgp_clist_hash_key_community_list(const void *data)
{
- struct community_list *cl = data;
+ struct community_list *cl = (struct community_list *) data;
if (cl->name_hash)
return cl->name_hash;
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index 67cd2be214..82762072df 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -574,7 +574,7 @@ char *community_str(struct community *com, bool make_json)
/* Make hash value of community attribute. This function is used by
hash package.*/
-unsigned int community_hash_make(struct community *com)
+unsigned int community_hash_make(const struct community *com)
{
uint32_t *pnt = (uint32_t *)com->val;
@@ -897,7 +897,7 @@ struct hash *community_hash(void)
void community_init(void)
{
comhash =
- hash_create((unsigned int (*)(void *))community_hash_make,
+ hash_create((unsigned int (*)(const void *))community_hash_make,
(bool (*)(const void *, const void *))community_cmp,
"BGP Community Hash");
}
@@ -957,7 +957,7 @@ void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
*/
if (aggregate->community_hash == NULL)
aggregate->community_hash = hash_create(
- (unsigned int (*)(void *))community_hash_make,
+ (unsigned int (*)(const void *))community_hash_make,
(bool (*)(const void *, const void *))community_cmp,
"BGP Aggregator community hash");
diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h
index 4ff4d214a5..f761a8f5e0 100644
--- a/bgpd/bgp_community.h
+++ b/bgpd/bgp_community.h
@@ -75,7 +75,7 @@ extern struct community *community_parse(uint32_t *, unsigned short);
extern struct community *community_intern(struct community *);
extern void community_unintern(struct community **);
extern char *community_str(struct community *, bool make_json);
-extern unsigned int community_hash_make(struct community *);
+extern unsigned int community_hash_make(const struct community *);
extern struct community *community_str2com(const char *);
extern int community_match(const struct community *, const struct community *);
extern bool community_cmp(const struct community *c1,
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 8ef398952d..76bd0e815e 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -241,7 +241,7 @@ void ecommunity_unintern(struct ecommunity **ecom)
}
/* Utinity function to make hash key. */
-unsigned int ecommunity_hash_make(void *arg)
+unsigned int ecommunity_hash_make(const void *arg)
{
const struct ecommunity *ecom = arg;
int size = ecom->size * ECOMMUNITY_SIZE;
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index 165ab8fe14..79be4ee422 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -163,7 +163,7 @@ extern struct ecommunity *ecommunity_uniq_sort(struct ecommunity *);
extern struct ecommunity *ecommunity_intern(struct ecommunity *);
extern bool ecommunity_cmp(const void *arg1, const void *arg2);
extern void ecommunity_unintern(struct ecommunity **);
-extern unsigned int ecommunity_hash_make(void *);
+extern unsigned int ecommunity_hash_make(const void *);
extern struct ecommunity *ecommunity_str2com(const char *, int, int);
extern char *ecommunity_ecom2str(struct ecommunity *, int, int);
extern void ecommunity_strfree(char **s);
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 52aa923959..112e4b836c 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -83,9 +83,9 @@ static int evpn_vtep_ip_cmp(void *p1, void *p2)
/*
* Make hash key for ESI.
*/
-static unsigned int esi_hash_keymake(void *p)
+static unsigned int esi_hash_keymake(const void *p)
{
- struct evpnes *pes = p;
+ const struct evpnes *pes = p;
const void *pnt = (void *)pes->esi.val;
return jhash(pnt, ESI_BYTES, 0xa5a5a55a);
@@ -111,9 +111,9 @@ static bool esi_cmp(const void *p1, const void *p2)
/*
* Make vni hash key.
*/
-static unsigned int vni_hash_key_make(void *p)
+static unsigned int vni_hash_key_make(const void *p)
{
- struct bgpevpn *vpn = p;
+ const struct bgpevpn *vpn = p;
return (jhash_1word(vpn->vni, 0));
}
@@ -143,10 +143,10 @@ static int vni_list_cmp(void *p1, void *p2)
/*
* Make vrf import route target hash key.
*/
-static unsigned int vrf_import_rt_hash_key_make(void *p)
+static unsigned int vrf_import_rt_hash_key_make(const void *p)
{
- struct vrf_irt_node *irt = p;
- char *pnt = irt->rt.val;
+ const struct vrf_irt_node *irt = p;
+ const char *pnt = irt->rt.val;
return jhash(pnt, 8, 0x5abc1234);
}
@@ -259,10 +259,10 @@ static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf)
/*
* Make import route target hash key.
*/
-static unsigned int import_rt_hash_key_make(void *p)
+static unsigned int import_rt_hash_key_make(const void *p)
{
- struct irt_node *irt = p;
- char *pnt = irt->rt.val;
+ const struct irt_node *irt = p;
+ const char *pnt = irt->rt.val;
return jhash(pnt, 8, 0xdeadbeef);
}
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 9e09d17893..67b0079c37 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -1554,14 +1554,15 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay,
show_ip_bgp_l2vpn_evpn_all_overlay_cmd,
- "show [ip] bgp l2vpn evpn all overlay",
+ "show [ip] bgp l2vpn evpn all overlay [json]",
SHOW_STR
IP_STR
BGP_STR
L2VPN_HELP_STR
EVPN_HELP_STR
"Display information about all EVPN NLRIs\n"
- "Display BGP Overlay Information for prefixes\n")
+ "Display BGP Overlay Information for prefixes\n"
+ JSON_STR)
{
return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL,
SHOW_DISPLAY_OVERLAY,
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 9e37a60188..12ae1f841a 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1115,8 +1115,6 @@ int bgp_stop(struct peer *peer)
/* Reset peer synctime */
peer->synctime = 0;
-
- bgp_bfd_deregister_peer(peer);
}
/* stop keepalives */
diff --git a/bgpd/bgp_keepalives.c b/bgpd/bgp_keepalives.c
index c2f0baff76..bec3bdcb8d 100644
--- a/bgpd/bgp_keepalives.c
+++ b/bgpd/bgp_keepalives.c
@@ -131,9 +131,9 @@ static bool peer_hash_cmp(const void *f, const void *s)
return p1->peer == p2->peer;
}
-static unsigned int peer_hash_key(void *arg)
+static unsigned int peer_hash_key(const void *arg)
{
- struct pkat *pkat = arg;
+ const struct pkat *pkat = arg;
return (uintptr_t)pkat->peer;
}
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index 44766c9b6e..098374fa9f 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -301,7 +301,7 @@ char *lcommunity_str(struct lcommunity *lcom, bool make_json)
}
/* Utility function to make hash key. */
-unsigned int lcommunity_hash_make(void *arg)
+unsigned int lcommunity_hash_make(const void *arg)
{
const struct lcommunity *lcom = arg;
int size = lcom_length(lcom);
diff --git a/bgpd/bgp_lcommunity.h b/bgpd/bgp_lcommunity.h
index aa4e8c69fe..a512395492 100644
--- a/bgpd/bgp_lcommunity.h
+++ b/bgpd/bgp_lcommunity.h
@@ -63,7 +63,7 @@ extern struct lcommunity *lcommunity_uniq_sort(struct lcommunity *);
extern struct lcommunity *lcommunity_intern(struct lcommunity *);
extern bool lcommunity_cmp(const void *arg1, const void *arg2);
extern void lcommunity_unintern(struct lcommunity **);
-extern unsigned int lcommunity_hash_make(void *);
+extern unsigned int lcommunity_hash_make(const void *);
extern struct hash *lcommunity_hash(void);
extern struct lcommunity *lcommunity_str2com(const char *);
extern int lcommunity_match(const struct lcommunity *,
diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c
index 49b5854020..f19453fecb 100644
--- a/bgpd/bgp_mac.c
+++ b/bgpd/bgp_mac.c
@@ -40,9 +40,9 @@ struct bgp_self_mac {
struct list *ifp_list;
};
-static unsigned int bgp_mac_hash_key_make(void *data)
+static unsigned int bgp_mac_hash_key_make(const void *data)
{
- struct bgp_self_mac *bsm = data;
+ const struct bgp_self_mac *bsm = data;
return jhash(&bsm->macaddr, ETH_ALEN, 0xa5a5dead);
}
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index de97b73c72..a8c507832c 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -114,7 +114,7 @@ static void bgp_tip_hash_free(void *addr)
XFREE(MTYPE_TIP_ADDR, addr);
}
-static unsigned int bgp_tip_hash_key_make(void *p)
+static unsigned int bgp_tip_hash_key_make(const void *p)
{
const struct tip_addr *addr = p;
@@ -237,7 +237,7 @@ static void bgp_address_hash_free(void *data)
XFREE(MTYPE_BGP_ADDR, addr);
}
-static unsigned int bgp_address_hash_key_make(void *p)
+static unsigned int bgp_address_hash_key_make(const void *p)
{
const struct bgp_addr *addr = p;
@@ -505,6 +505,77 @@ int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer)
return (ret);
}
+int bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer)
+{
+ struct bgp_node *rn1;
+ struct bgp_node *rn2;
+ struct prefix p;
+ int ret;
+
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_BITLEN;
+ p.u.prefix6 = nexthop;
+
+ rn1 = bgp_node_match(peer->bgp->connected_table[AFI_IP6], &p);
+ if (!rn1)
+ return 0;
+
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_BITLEN;
+ p.u.prefix6 = peer->su.sin6.sin6_addr;
+
+ rn2 = bgp_node_match(peer->bgp->connected_table[AFI_IP6], &p);
+ if (!rn2) {
+ bgp_unlock_node(rn1);
+ return 0;
+ }
+
+ ret = (rn1 == rn2) ? 1 : 0;
+
+ bgp_unlock_node(rn1);
+ bgp_unlock_node(rn2);
+
+ return ret;
+}
+
+int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop,
+ struct update_subgroup *subgrp)
+{
+ struct bgp_node *rn1 = NULL, *rn2 = NULL;
+ struct peer_af *paf = NULL;
+ struct prefix p = {0}, np = {0};
+ struct bgp *bgp = NULL;
+
+ np.family = AF_INET6;
+ np.prefixlen = IPV6_MAX_BITLEN;
+ np.u.prefix6 = nexthop;
+
+ p.family = AF_INET;
+ p.prefixlen = IPV6_MAX_BITLEN;
+
+ bgp = SUBGRP_INST(subgrp);
+ rn1 = bgp_node_match(bgp->connected_table[AFI_IP6], &np);
+ if (!rn1)
+ return 0;
+
+ SUBGRP_FOREACH_PEER (subgrp, paf) {
+
+ p.u.prefix6 = paf->peer->su.sin6.sin6_addr;
+ rn2 = bgp_node_match(bgp->connected_table[AFI_IP6], &p);
+ if (rn1 == rn2) {
+ bgp_unlock_node(rn1);
+ bgp_unlock_node(rn2);
+ return 1;
+ }
+
+ if (rn2)
+ bgp_unlock_node(rn2);
+ }
+
+ bgp_unlock_node(rn1);
+ return 0;
+}
+
int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
struct update_subgroup *subgrp)
{
diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h
index f06fae5706..d35f1ad520 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -74,11 +74,19 @@ struct tip_addr {
int refcnt;
};
+struct bgp_addrv6 {
+ struct in6_addr addrv6;
+ struct list *ifp_name_list;
+};
+
extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
struct update_subgroup *subgrp);
-extern int bgp_multiaccess_check_v4(struct in_addr, struct peer *);
+extern int bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop,
+ struct update_subgroup *subgrp);
+extern int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer);
+extern int bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer);
extern int bgp_config_write_scan_time(struct vty *);
extern int bgp_nexthop_self(struct bgp *, struct in_addr);
extern struct bgp_nexthop_cache *bnc_new(void);
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 0fddfa75a1..5eef6ac6cc 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -964,9 +964,9 @@ static void *bgp_pbr_match_entry_alloc_intern(void *arg)
return new;
}
-uint32_t bgp_pbr_match_hash_key(void *arg)
+uint32_t bgp_pbr_match_hash_key(const void *arg)
{
- struct bgp_pbr_match *pbm = (struct bgp_pbr_match *)arg;
+ const struct bgp_pbr_match *pbm = arg;
uint32_t key;
key = jhash_1word(pbm->vrf_id, 0x4312abde);
@@ -1019,9 +1019,9 @@ bool bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
return true;
}
-uint32_t bgp_pbr_rule_hash_key(void *arg)
+uint32_t bgp_pbr_rule_hash_key(const void *arg)
{
- struct bgp_pbr_rule *pbr = (struct bgp_pbr_rule *)arg;
+ const struct bgp_pbr_rule *pbr = arg;
uint32_t key;
key = prefix_hash_key(&pbr->src);
@@ -1057,12 +1057,12 @@ bool bgp_pbr_rule_hash_equal(const void *arg1, const void *arg2)
return true;
}
-uint32_t bgp_pbr_match_entry_hash_key(void *arg)
+uint32_t bgp_pbr_match_entry_hash_key(const void *arg)
{
- struct bgp_pbr_match_entry *pbme;
+ const struct bgp_pbr_match_entry *pbme;
uint32_t key;
- pbme = (struct bgp_pbr_match_entry *)arg;
+ pbme = arg;
key = prefix_hash_key(&pbme->src);
key = jhash_1word(prefix_hash_key(&pbme->dst), key);
key = jhash(&pbme->dst_port_min, 2, key);
@@ -1111,12 +1111,12 @@ bool bgp_pbr_match_entry_hash_equal(const void *arg1, const void *arg2)
return true;
}
-uint32_t bgp_pbr_action_hash_key(void *arg)
+uint32_t bgp_pbr_action_hash_key(const void *arg)
{
- struct bgp_pbr_action *pbra;
+ const struct bgp_pbr_action *pbra;
uint32_t key;
- pbra = (struct bgp_pbr_action *)arg;
+ pbra = arg;
key = jhash_1word(pbra->table_id, 0x4312abde);
key = jhash_1word(pbra->fwmark, key);
return key;
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index f7fddac7fb..b368d8892d 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -273,16 +273,16 @@ extern struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id,
extern void bgp_pbr_cleanup(struct bgp *bgp);
extern void bgp_pbr_init(struct bgp *bgp);
-extern uint32_t bgp_pbr_rule_hash_key(void *arg);
+extern uint32_t bgp_pbr_rule_hash_key(const void *arg);
extern bool bgp_pbr_rule_hash_equal(const void *arg1,
const void *arg2);
-extern uint32_t bgp_pbr_action_hash_key(void *arg);
+extern uint32_t bgp_pbr_action_hash_key(const void *arg);
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 uint32_t bgp_pbr_match_entry_hash_key(const void *arg);
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 uint32_t bgp_pbr_match_hash_key(const void *arg);
extern bool bgp_pbr_match_hash_equal(const void *arg1,
const void *arg2);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f3a69d4b25..4f89c8b5f7 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1888,13 +1888,28 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
* Note: 3rd party nexthop currently implemented for
* IPv4 only.
*/
- if (!bgp_subgrp_multiaccess_check_v4(piattr->nexthop,
- subgrp))
+ if ((p->family == AF_INET) &&
+ (!bgp_subgrp_multiaccess_check_v4(
+ piattr->nexthop,
+ subgrp)))
subgroup_announce_reset_nhop(
(peer_cap_enhe(peer, afi, safi)
? AF_INET6
: p->family),
- attr);
+ attr);
+
+ if ((p->family == AF_INET6) &&
+ (!bgp_subgrp_multiaccess_check_v6(
+ piattr->mp_nexthop_global,
+ subgrp)))
+ subgroup_announce_reset_nhop(
+ (peer_cap_enhe(peer, afi, safi)
+ ? AF_INET6
+ : p->family),
+ attr);
+
+
+
} else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
/*
* This flag is used for leaked vpn-vrf routes
@@ -7571,21 +7586,26 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
json_object *json_paths)
{
struct attr *attr;
- char buf[BUFSIZ];
+ char buf[BUFSIZ] = {0};
json_object *json_path = NULL;
-
- if (json_paths)
- json_path = json_object_new_object();
+ json_object *json_nexthop = NULL;
+ json_object *json_overlay = NULL;
if (!path->extra)
return;
+ if (json_paths) {
+ json_path = json_object_new_object();
+ json_overlay = json_object_new_object();
+ json_nexthop = json_object_new_object();
+ }
+
/* short status lead text */
route_vty_short_status_out(vty, path, json_path);
/* print prefix and mask */
if (!display)
- route_vty_out_route(p, vty, NULL);
+ route_vty_out_route(p, vty, json_path);
else
vty_out(vty, "%*s", 17, " ");
@@ -7597,35 +7617,69 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
switch (af) {
case AF_INET:
- vty_out(vty, "%-16s",
- inet_ntop(af, &attr->mp_nexthop_global_in, buf,
- BUFSIZ));
+ inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
+ if (!json_path) {
+ vty_out(vty, "%-16s", buf);
+ } else {
+ json_object_string_add(json_nexthop, "ip", buf);
+
+ json_object_string_add(json_nexthop, "afi",
+ "ipv4");
+
+ json_object_object_add(json_path, "nexthop",
+ json_nexthop);
+ }
break;
case AF_INET6:
- vty_out(vty, "%s(%s)",
- inet_ntop(af, &attr->mp_nexthop_global, buf,
- BUFSIZ),
- inet_ntop(af, &attr->mp_nexthop_local, buf1,
- BUFSIZ));
+ inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
+ inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
+ if (!json_path) {
+ vty_out(vty, "%s(%s)", buf, buf1);
+ } else {
+ json_object_string_add(json_nexthop,
+ "ipv6Global", buf);
+
+ json_object_string_add(json_nexthop,
+ "ipv6LinkLocal", buf1);
+
+ json_object_string_add(json_nexthop, "afi",
+ "ipv6");
+
+ json_object_object_add(json_path, "nexthop",
+ json_nexthop);
+ }
break;
default:
- vty_out(vty, "?");
+ if (!json_path) {
+ vty_out(vty, "?");
+ } else {
+ json_object_string_add(json_nexthop, "Error",
+ "Unsupported address-family");
+ }
}
char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
- vty_out(vty, "%s", str);
+ if (!json_path)
+ vty_out(vty, "%s", str);
+ else
+ json_object_string_add(json_overlay, "esi", str);
+
XFREE(MTYPE_TMP, str);
if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
- vty_out(vty, "/%s",
- inet_ntoa(attr->evpn_overlay.gw_ip.ipv4));
+ inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4),
+ buf, BUFSIZ);
} else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
- vty_out(vty, "/%s",
- inet_ntop(AF_INET6,
- &(attr->evpn_overlay.gw_ip.ipv6), buf,
- BUFSIZ));
+ inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6),
+ buf, BUFSIZ);
}
+
+ if (!json_path)
+ vty_out(vty, "/%s", buf);
+ else
+ json_object_string_add(json_overlay, "gw", buf);
+
if (attr->ecommunity) {
char *mac = NULL;
struct ecommunity_val *routermac = ecommunity_lookup(
@@ -7634,13 +7688,25 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
if (routermac)
mac = ecom_mac2str((char *)routermac->val);
if (mac) {
- vty_out(vty, "/%s", (char *)mac);
+ if (!json_path) {
+ vty_out(vty, "/%s", (char *)mac);
+ } else {
+ json_object_string_add(json_overlay,
+ "rmac", mac);
+ }
XFREE(MTYPE_TMP, mac);
}
}
- vty_out(vty, "\n");
- }
+ if (!json_path) {
+ vty_out(vty, "\n");
+ } else {
+ json_object_object_add(json_path, "overlay",
+ json_overlay);
+
+ json_object_array_add(json_paths, json_path);
+ }
+ }
}
/* dampening route */
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 57717bf59b..d0be2471af 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -288,7 +288,7 @@ static void *updgrp_hash_alloc(void *p)
* 16. Local-as should match, if configured.
* )
*/
-static unsigned int updgrp_hash_key_make(void *p)
+static unsigned int updgrp_hash_key_make(const void *p)
{
const struct update_group *updgrp;
const struct peer *peer;
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index 3556b236a7..688abae0e4 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -554,9 +554,9 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
mod_v6nhg = &peer->nexthop.v6_global;
gnh_modified = 1;
} else if (
- peer->sort == BGP_PEER_EBGP
- && !CHECK_FLAG(
- vec->flags,
+ (peer->sort == BGP_PEER_EBGP)
+ && (!bgp_multiaccess_check_v6(v6nhglobal, peer))
+ && !CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
&& !peer_af_flag_check(
peer, nhafi, paf->safi,
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index bce6fb48c7..880b877806 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -119,6 +119,7 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
case AFI_L2VPN:
return BGP_EVPN_NODE;
break;
+ case AFI_UNSPEC:
case AFI_MAX:
// We should never be here but to clarify the switch statement..
return BGP_IPV4_NODE;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 6183bbd471..c0f1f3184a 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -812,9 +812,9 @@ int peer_cmp(struct peer *p1, struct peer *p2)
return sockunion_cmp(&p1->su, &p2->su);
}
-static unsigned int peer_hash_key_make(void *p)
+static unsigned int peer_hash_key_make(const void *p)
{
- struct peer *peer = p;
+ const struct peer *peer = p;
return sockunion_hash(&peer->su);
}
diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst
index 1e165a2444..09f12ec436 100644
--- a/doc/developer/topotests.rst
+++ b/doc/developer/topotests.rst
@@ -189,13 +189,12 @@ If found, then this is added with context (calling test) to
Compiling for GCC AddressSanitizer requires to use ``gcc`` as a linker as well
(instead of ``ld``). Here is a suggest way to compile frr with AddressSanitizer
-for ``stable/3.0`` branch:
+for ``master`` branch:
.. code:: shell
git clone https://github.com/FRRouting/frr.git
cd frr
- git checkout stable/3.0
./bootstrap.sh
export CC=gcc
export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer"
@@ -208,7 +207,8 @@ for ``stable/3.0`` branch:
--enable-exampledir=/usr/lib/frr/examples \
--with-moduledir=/usr/lib/frr/modules \
--enable-multipath=0 --enable-rtadv \
- --enable-tcp-zebra --enable-fpm --enable-pimd
+ --enable-tcp-zebra --enable-fpm --enable-pimd \
+ --enable-sharpd
make
sudo make install
# Create symlink for vtysh, so topotest finds it in /usr/lib/frr
diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst
index a7c5cf28bc..33bc77049e 100644
--- a/doc/user/bfd.rst
+++ b/doc/user/bfd.rst
@@ -174,6 +174,21 @@ The following commands are available inside the BGP configuration node.
Removes any notification registration for this neighbor.
+.. index:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure
+.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure
+
+ Allow to write CBIT independence in BFD outgoing packets. Also allow to
+ read both C-BIT value of BFD and lookup BGP peer status. This command is
+ useful when a BFD down event is caught, while the BGP peer requested that
+ local BGP keeps the remote BGP entries as staled if such issue is detected.
+ This is the case when graceful restart is enabled, and it is wished to
+ ignore the BD event while waiting for the remote router to restart.
+
+.. index:: no neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure
+.. clicmd:: no neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure
+
+ Disallow to write CBIT independence in BFD outgoing packets. Also disallow
+ to ignore BFD down notification. This is the default behaviour.
.. _bfd-ospf-peer-config:
diff --git a/isisd/fabricd.c b/isisd/fabricd.c
index 96af28f0a1..b9c27d51bd 100644
--- a/isisd/fabricd.c
+++ b/isisd/fabricd.c
@@ -108,9 +108,9 @@ static void neighbor_lists_clear(struct fabricd *f)
hash_clean(f->neighbors_neighbors, neighbor_entry_del_void);
}
-static unsigned neighbor_entry_hash_key(void *np)
+static unsigned neighbor_entry_hash_key(const void *np)
{
- struct neighbor_entry *n = np;
+ const struct neighbor_entry *n = np;
return jhash(n->id, sizeof(n->id), 0x55aa5a5a);
}
diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c
index fccef0169e..fa89c80049 100644
--- a/isisd/isis_bfd.c
+++ b/isisd/isis_bfd.c
@@ -98,7 +98,8 @@ static int isis_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
struct prefix dst_ip;
int status;
- ifp = bfd_get_peer_info(zclient->ibuf, &dst_ip, NULL, &status, vrf_id);
+ ifp = bfd_get_peer_info(zclient->ibuf, &dst_ip, NULL, &status,
+ NULL, vrf_id);
if (!ifp || dst_ip.family != AF_INET)
return 0;
@@ -217,6 +218,7 @@ static void bfd_handle_adj_down(struct isis_adjacency *adj)
adj->circuit->interface->name,
0, /* ttl */
0, /* multihop */
+ 1, /* control plane independent bit is on */
ZEBRA_BFD_DEST_DEREGISTER,
0, /* set_flag */
VRF_DEFAULT);
@@ -258,6 +260,7 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj, int command)
circuit->interface->name,
0, /* ttl */
0, /* multihop */
+ 1, /* control plane independent bit is on */
command,
0, /* set flag */
VRF_DEFAULT);
diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h
index 3a2a52afac..a8185a8be0 100644
--- a/isisd/isis_spf_private.h
+++ b/isisd/isis_spf_private.h
@@ -79,9 +79,9 @@ struct isis_vertex_queue {
};
__attribute__((__unused__))
-static unsigned isis_vertex_queue_hash_key(void *vp)
+static unsigned isis_vertex_queue_hash_key(const void *vp)
{
- struct isis_vertex *vertex = vp;
+ const struct isis_vertex *vertex = vp;
if (VTYPE_IP(vertex->type)) {
uint32_t key;
diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c
index 6f46e6bec0..507fd489bc 100644
--- a/isisd/isis_tx_queue.c
+++ b/isisd/isis_tx_queue.c
@@ -50,9 +50,9 @@ struct isis_tx_queue_entry {
struct isis_tx_queue *queue;
};
-static unsigned tx_queue_hash_key(void *p)
+static unsigned tx_queue_hash_key(const void *p)
{
- struct isis_tx_queue_entry *e = p;
+ const struct isis_tx_queue_entry *e = p;
uint32_t id_key = jhash(e->lsp->hdr.lsp_id,
ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
diff --git a/lib/bfd.c b/lib/bfd.c
index a8956c315c..00dbd1b3d1 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -127,8 +127,8 @@ void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, uint32_t min_tx,
*/
void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info,
int family, void *dst_ip, void *src_ip, char *if_name,
- int ttl, int multihop, int command, int set_flag,
- vrf_id_t vrf_id)
+ int ttl, int multihop, int cbit, int command,
+ int set_flag, vrf_id_t vrf_id)
{
struct stream *s;
int ret;
@@ -208,6 +208,11 @@ void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info,
stream_putc(s, 0);
}
}
+ /* cbit */
+ if (cbit)
+ stream_putc(s, 1);
+ else
+ stream_putc(s, 0);
stream_putw_at(s, 0, stream_get_endp(s));
@@ -253,11 +258,13 @@ const char *bfd_get_command_dbg_str(int command)
*/
struct interface *bfd_get_peer_info(struct stream *s, struct prefix *dp,
struct prefix *sp, int *status,
+ int *remote_cbit,
vrf_id_t vrf_id)
{
unsigned int ifindex;
struct interface *ifp = NULL;
int plen;
+ int local_remote_cbit;
/* Get interface index. */
ifindex = stream_getl(s);
@@ -292,6 +299,9 @@ struct interface *bfd_get_peer_info(struct stream *s, struct prefix *dp,
stream_get(&sp->u.prefix, s, plen);
sp->prefixlen = stream_getc(s);
}
+ local_remote_cbit = stream_getc(s);
+ if (remote_cbit)
+ *remote_cbit = local_remote_cbit;
return ifp;
}
diff --git a/lib/bfd.h b/lib/bfd.h
index d02110a997..e4781f4eaf 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -48,6 +48,8 @@ struct bfd_gbl {
#define BFD_FLAG_PARAM_CFG (1 << 0) /* parameters have been configured */
#define BFD_FLAG_BFD_REG (1 << 1) /* Peer registered with BFD */
#define BFD_FLAG_BFD_TYPE_MULTIHOP (1 << 2) /* Peer registered with BFD as multihop */
+#define BFD_FLAG_BFD_CBIT_ON (1 << 3) /* Peer registered with CBIT set to on */
+#define BFD_FLAG_BFD_CHECK_CONTROLPLANE (1 << 4) /* BFD and controlplane daemon are linked */
#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
@@ -83,13 +85,14 @@ extern void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx,
int *command);
extern void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info,
int family, void *dst_ip, void *src_ip,
- char *if_name, int ttl, int multihop, int command,
- int set_flag, vrf_id_t vrf_id);
+ char *if_name, int ttl, int multihop, int cbit,
+ int command, int set_flag, vrf_id_t vrf_id);
extern const char *bfd_get_command_dbg_str(int command);
extern struct interface *bfd_get_peer_info(struct stream *s, struct prefix *dp,
struct prefix *sp, int *status,
+ int *remote_cbit,
vrf_id_t vrf_id);
const char *bfd_get_status_str(int status);
diff --git a/lib/command.c b/lib/command.c
index d6fd1fa561..b7a323e358 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -332,7 +332,7 @@ int argv_find(struct cmd_token **argv, int argc, const char *text, int *index)
return found;
}
-static unsigned int cmd_hash_key(void *p)
+static unsigned int cmd_hash_key(const void *p)
{
int size = sizeof(p);
diff --git a/lib/distribute.c b/lib/distribute.c
index be40bd2603..2aa6b927fb 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -131,7 +131,7 @@ static struct distribute *distribute_get(struct distribute_ctx *ctx,
return ret;
}
-static unsigned int distribute_hash_make(void *arg)
+static unsigned int distribute_hash_make(const void *arg)
{
const struct distribute *dist = arg;
diff --git a/lib/ferr.c b/lib/ferr.c
index d7fa1a84f8..65c0cf886d 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -72,9 +72,9 @@ static bool ferr_hash_cmp(const void *a, const void *b)
return f_a->code == f_b->code;
}
-static inline unsigned int ferr_hash_key(void *a)
+static inline unsigned int ferr_hash_key(const void *a)
{
- struct log_ref *f = a;
+ const struct log_ref *f = a;
return f->code;
}
diff --git a/lib/hash.c b/lib/hash.c
index 884c8f22af..fad7de5138 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -37,7 +37,7 @@ static pthread_mutex_t _hashes_mtx = PTHREAD_MUTEX_INITIALIZER;
static struct list *_hashes;
struct hash *hash_create_size(unsigned int size,
- unsigned int (*hash_key)(void *),
+ unsigned int (*hash_key)(const void *),
bool (*hash_cmp)(const void *, const void *),
const char *name)
{
@@ -66,7 +66,7 @@ struct hash *hash_create_size(unsigned int size,
return hash;
}
-struct hash *hash_create(unsigned int (*hash_key)(void *),
+struct hash *hash_create(unsigned int (*hash_key)(const void *),
bool (*hash_cmp)(const void *, const void *),
const char *name)
{
diff --git a/lib/hash.h b/lib/hash.h
index 60c412b8e0..c56a98d50c 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -79,7 +79,7 @@ struct hash {
unsigned int max_size;
/* Key make function. */
- unsigned int (*hash_key)(void *);
+ unsigned int (*hash_key)(const void *);
/* Data compare function. */
bool (*hash_cmp)(const void *, const void *);
@@ -123,7 +123,7 @@ struct hash {
* Returns:
* a new hash table
*/
-extern struct hash *hash_create(unsigned int (*hash_key)(void *),
+extern struct hash *hash_create(unsigned int (*hash_key)(const void *),
bool (*hash_cmp)(const void *, const void *),
const char *name);
@@ -158,7 +158,7 @@ extern struct hash *hash_create(unsigned int (*hash_key)(void *),
* a new hash table
*/
extern struct hash *
-hash_create_size(unsigned int size, unsigned int (*hash_key)(void *),
+hash_create_size(unsigned int size, unsigned int (*hash_key)(const void *),
bool (*hash_cmp)(const void *, const void *),
const char *name);
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index b0802da961..ca6f512ec6 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -107,7 +107,7 @@ static struct if_rmap *if_rmap_get(struct if_rmap_ctx *ctx, const char *ifname)
return ret;
}
-static unsigned int if_rmap_hash_make(void *data)
+static unsigned int if_rmap_hash_make(const void *data)
{
const struct if_rmap *if_rmap = data;
diff --git a/lib/northbound.c b/lib/northbound.c
index e8b3e46c19..dbf90c58d4 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -1654,7 +1654,7 @@ static bool running_config_entry_cmp(const void *value1, const void *value2)
return strmatch(c1->xpath, c2->xpath);
}
-static unsigned int running_config_entry_key_make(void *value)
+static unsigned int running_config_entry_key_make(const void *value)
{
return string_hash_make(value);
}
diff --git a/lib/routemap.c b/lib/routemap.c
index 0c75be3323..3542994e65 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -623,7 +623,7 @@ struct route_map_list {
static struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
struct hash *route_map_master_hash = NULL;
-static unsigned int route_map_hash_key_make(void *p)
+static unsigned int route_map_hash_key_make(const void *p)
{
const struct route_map *map = p;
return string_hash_make(map->name);
@@ -673,7 +673,7 @@ struct route_map_dep {
/* Hashes maintaining dependency between various sublists used by route maps */
struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX];
-static unsigned int route_map_dep_hash_make_key(void *p);
+static unsigned int route_map_dep_hash_make_key(const void *p);
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 *);
@@ -906,6 +906,8 @@ static const char *route_map_type_str(enum route_map_type type)
return "";
break;
}
+
+ return "";
}
static int route_map_empty(struct route_map *map)
@@ -1287,7 +1289,6 @@ int route_map_add_match(struct route_map_index *index, const char *match_name,
struct route_map_rule *next;
struct route_map_rule_cmd *cmd;
void *compile;
- int replaced = 0;
/* First lookup rule for add match statement. */
cmd = route_map_lookup_match(match_name);
@@ -1317,7 +1318,6 @@ int route_map_add_match(struct route_map_index *index, const char *match_name,
}
route_map_rule_delete(&index->match_list, rule);
- replaced = 1;
}
}
@@ -1379,7 +1379,6 @@ int route_map_add_set(struct route_map_index *index, const char *set_name,
struct route_map_rule *next;
struct route_map_rule_cmd *cmd;
void *compile;
- int replaced = 0;
cmd = route_map_lookup_set(set_name);
if (cmd == NULL)
@@ -1398,10 +1397,8 @@ int route_map_add_set(struct route_map_index *index, const char *set_name,
route_map_index. */
for (rule = index->set_list.head; rule; rule = next) {
next = rule->next;
- if (rule->cmd == cmd) {
+ if (rule->cmd == cmd)
route_map_rule_delete(&index->set_list, rule);
- replaced = 1;
- }
}
/* Add new route map match rule. */
@@ -1709,7 +1706,7 @@ static void *route_map_name_hash_alloc(void *p)
return ((void *)XSTRDUP(MTYPE_ROUTE_MAP_NAME, (const char *)p));
}
-static unsigned int route_map_dep_hash_make_key(void *p)
+static unsigned int route_map_dep_hash_make_key(const void *p)
{
return (string_hash_make((char *)p));
}
diff --git a/lib/thread.c b/lib/thread.c
index 5ca859a74d..9489e3e923 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -63,7 +63,7 @@ static struct list *masters;
static void thread_free(struct thread_master *master, struct thread *thread);
/* CLI start ---------------------------------------------------------------- */
-static unsigned int cpu_record_hash_key(struct cpu_thread_history *a)
+static unsigned int cpu_record_hash_key(const struct cpu_thread_history *a)
{
int size = sizeof(a->func);
@@ -433,7 +433,7 @@ struct thread_master *thread_master_create(const char *name)
sizeof(struct thread *) * rv->fd_limit);
rv->cpu_record = hash_create_size(
- 8, (unsigned int (*)(void *))cpu_record_hash_key,
+ 8, (unsigned int (*)(const void *))cpu_record_hash_key,
(bool (*)(const void *, const void *))cpu_record_hash_cmp,
"Thread Hash");
diff --git a/lib/vrf.c b/lib/vrf.c
index 6ec3cc8e0d..229f19f29a 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -362,9 +362,9 @@ struct vrf_bit_set {
bool set;
};
-static unsigned int vrf_hash_bitmap_key(void *data)
+static unsigned int vrf_hash_bitmap_key(const void *data)
{
- struct vrf_bit_set *bit = data;
+ const struct vrf_bit_set *bit = data;
return bit->vrf_id;
}
diff --git a/lib/wheel.c b/lib/wheel.c
index 69d2fa48dc..8e479c931b 100644
--- a/lib/wheel.c
+++ b/lib/wheel.c
@@ -80,7 +80,7 @@ static int wheel_timer_thread(struct thread *t)
}
struct timer_wheel *wheel_init(struct thread_master *master, int period,
- size_t slots, unsigned int (*slot_key)(void *),
+ size_t slots, unsigned int (*slot_key)(const void *),
void (*slot_run)(void *),
const char *run_name)
{
diff --git a/lib/wheel.h b/lib/wheel.h
index e66751c1d0..401789e1a0 100644
--- a/lib/wheel.h
+++ b/lib/wheel.h
@@ -38,7 +38,7 @@ struct timer_wheel {
/*
* Key to determine what slot the item belongs in
*/
- unsigned int (*slot_key)(void *);
+ unsigned int (*slot_key)(const void *);
void (*slot_run)(void *);
};
@@ -80,9 +80,9 @@ struct timer_wheel {
* of running your code.
*/
struct timer_wheel *wheel_init(struct thread_master *master, int period,
- size_t slots, unsigned int (*slot_key)(void *),
- void (*slot_run)(void *),
- const char *run_name);
+ size_t slots,
+ unsigned int (*slot_key)(const void *),
+ void (*slot_run)(void *), const char *run_name);
/*
* Delete the specified timer wheel created
diff --git a/lib/yang_translator.c b/lib/yang_translator.c
index 69fff5dbff..341420eeda 100644
--- a/lib/yang_translator.c
+++ b/lib/yang_translator.c
@@ -61,7 +61,7 @@ static bool yang_mapping_hash_cmp(const void *value1, const void *value2)
return strmatch(c1->xpath_from_canonical, c2->xpath_from_canonical);
}
-static unsigned int yang_mapping_hash_key(void *value)
+static unsigned int yang_mapping_hash_key(const void *value)
{
return string_hash_make(value);
}
diff --git a/lib/zebra.h b/lib/zebra.h
index b1ea43c747..3e1eefdb2e 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -422,7 +422,13 @@ extern const char *zserv_command_string(unsigned int command);
#endif
/* Address family numbers from RFC1700. */
-typedef enum { AFI_IP = 1, AFI_IP6 = 2, AFI_L2VPN = 3, AFI_MAX = 4 } afi_t;
+typedef enum {
+ AFI_UNSPEC = 0,
+ AFI_IP = 1,
+ AFI_IP6 = 2,
+ AFI_L2VPN = 3,
+ AFI_MAX = 4
+} afi_t;
/* Subsequent Address Family Identifier. */
typedef enum {
diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c
index 5508778243..cc18b36f6a 100644
--- a/nhrpd/nhrp_cache.c
+++ b/nhrpd/nhrp_cache.c
@@ -30,9 +30,9 @@ const char *const nhrp_cache_type_str[] = {
[NHRP_CACHE_LOCAL] = "local",
};
-static unsigned int nhrp_cache_protocol_key(void *peer_data)
+static unsigned int nhrp_cache_protocol_key(const void *peer_data)
{
- struct nhrp_cache *p = peer_data;
+ const struct nhrp_cache *p = peer_data;
return sockunion_hash(&p->remote_addr);
}
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index db2f72ac22..ca309f2506 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -151,9 +151,9 @@ static void nhrp_peer_ifp_notify(struct notifier_block *n, unsigned long cmd)
nhrp_peer_unref(p);
}
-static unsigned int nhrp_peer_key(void *peer_data)
+static unsigned int nhrp_peer_key(const void *peer_data)
{
- struct nhrp_peer *p = peer_data;
+ const struct nhrp_peer *p = peer_data;
return sockunion_hash(&p->vc->remote.nbma);
}
diff --git a/nhrpd/nhrp_vc.c b/nhrpd/nhrp_vc.c
index fa3549f5ed..605aa34ff9 100644
--- a/nhrpd/nhrp_vc.c
+++ b/nhrpd/nhrp_vc.c
@@ -28,9 +28,9 @@ struct child_sa {
static struct hash *nhrp_vc_hash;
static struct list_head childlist_head[512];
-static unsigned int nhrp_vc_key(void *peer_data)
+static unsigned int nhrp_vc_key(const void *peer_data)
{
- struct nhrp_vc *vc = peer_data;
+ const struct nhrp_vc *vc = peer_data;
return jhash_2words(sockunion_hash(&vc->local.nbma),
sockunion_hash(&vc->remote.nbma), 0);
}
diff --git a/nhrpd/reqid.c b/nhrpd/reqid.c
index 08a007bdf9..e56bbe3bf7 100644
--- a/nhrpd/reqid.c
+++ b/nhrpd/reqid.c
@@ -2,9 +2,9 @@
#include "hash.h"
#include "nhrpd.h"
-static unsigned int nhrp_reqid_key(void *data)
+static unsigned int nhrp_reqid_key(const void *data)
{
- struct nhrp_reqid *r = data;
+ const struct nhrp_reqid *r = data;
return r->request_id;
}
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index 7a26af1f09..f0500601b0 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -74,6 +74,7 @@ void ospf6_bfd_reg_dereg_nbr(struct ospf6_neighbor *on, int command)
struct interface *ifp = oi->interface;
struct bfd_info *bfd_info;
char src[64];
+ int cbit;
if (!oi->bfd_info || !on->bfd_info)
return;
@@ -85,9 +86,11 @@ void ospf6_bfd_reg_dereg_nbr(struct ospf6_neighbor *on, int command)
bfd_get_command_dbg_str(command), src);
}
+ cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
+
bfd_peer_sendmsg(zclient, bfd_info, AF_INET6, &on->linklocal_addr,
- on->ospf6_if->linklocal_addr, ifp->name, 0, 0, command,
- 0, VRF_DEFAULT);
+ on->ospf6_if->linklocal_addr, ifp->name, 0, 0,
+ cbit, command, 0, VRF_DEFAULT);
if (command == ZEBRA_BFD_DEST_DEREGISTER)
bfd_info_free((struct bfd_info **)&on->bfd_info);
@@ -195,7 +198,8 @@ static int ospf6_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
struct bfd_info *bfd_info;
struct timeval tv;
- ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status, vrf_id);
+ ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status,
+ NULL, vrf_id);
if ((ifp == NULL) || (dp.family != AF_INET6))
return 0;
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index c8ad6d04f4..a17975270a 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -65,6 +65,7 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
struct interface *ifp = oi->ifp;
struct ospf_if_params *params;
struct bfd_info *bfd_info;
+ int cbit;
/* Check if BFD is enabled */
params = IF_DEF_PARAMS(ifp);
@@ -80,8 +81,10 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
inet_ntoa(nbr->src),
ospf_vrf_id_to_name(oi->ospf->vrf_id));
+ cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
+
bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name,
- 0, 0, command, 0, oi->ospf->vrf_id);
+ 0, 0, cbit, command, 0, oi->ospf->vrf_id);
}
/*
@@ -207,7 +210,8 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
struct bfd_info *bfd_info;
struct timeval tv;
- ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status, vrf_id);
+ ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status,
+ NULL, vrf_id);
if ((ifp == NULL) || (p.family != AF_INET))
return 0;
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index a493520868..6947393a60 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -86,7 +86,7 @@ static inline void del_sid_nhlfe(struct sr_nhlfe nhlfe);
*/
/* Hash function for Segment Routing entry */
-static unsigned int sr_hash(void *p)
+static unsigned int sr_hash(const void *p)
{
const struct in_addr *rid = p;
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index 7504752725..52506542bc 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -129,10 +129,10 @@ static void pbr_nh_delete_iterate(struct hash_bucket *b, void *p)
pbr_nh_delete((struct pbr_nexthop_cache **)&b->data);
}
-static uint32_t pbr_nh_hash_key(void *arg)
+static uint32_t pbr_nh_hash_key(const void *arg)
{
uint32_t key;
- struct pbr_nexthop_cache *pbrnc = (struct pbr_nexthop_cache *)arg;
+ const struct pbr_nexthop_cache *pbrnc = arg;
key = nexthop_hash(pbrnc->nexthop);
@@ -789,10 +789,9 @@ void pbr_nht_nexthop_interface_update(struct interface *ifp)
ifp);
}
-static uint32_t pbr_nhg_hash_key(void *arg)
+static uint32_t pbr_nhg_hash_key(const void *arg)
{
- struct pbr_nexthop_group_cache *nhgc =
- (struct pbr_nexthop_group_cache *)arg;
+ const struct pbr_nexthop_group_cache *nhgc = arg;
return jhash(&nhgc->name, strlen(nhgc->name), 0x52c34a96);
}
@@ -940,7 +939,7 @@ void pbr_nht_init(void)
pbr_nhg_hash = hash_create_size(
16, pbr_nhg_hash_key, pbr_nhg_hash_equal, "PBR NHG Cache Hash");
pbr_nhrc_hash =
- hash_create_size(16, (unsigned int (*)(void *))nexthop_hash,
+ hash_create_size(16, (unsigned int (*)(const void *))nexthop_hash,
pbr_nhrc_hash_equal, "PBR NH Hash");
pbr_nhg_low_table = PBR_NHT_DEFAULT_LOW_TABLEID;
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index aad0e4275f..466a9a13ae 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -349,6 +349,11 @@ void route_add(struct pbr_nexthop_group_cache *pnhgc, struct nexthop_group nhg,
"%s: Asked to install unsupported route type: L2VPN",
__PRETTY_FUNCTION__);
break;
+ case AFI_UNSPEC:
+ DEBUGD(&pbr_dbg_zebra,
+ "%s: Asked to install unspecified route type",
+ __PRETTY_FUNCTION__);
+ break;
}
}
@@ -391,6 +396,11 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi)
"%s: Asked to delete unsupported route type: L2VPN",
__PRETTY_FUNCTION__);
break;
+ case AFI_UNSPEC:
+ DEBUGD(&pbr_dbg_zebra,
+ "%s: Asked to delete unspecified route type",
+ __PRETTY_FUNCTION__);
+ break;
}
}
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c
index 300261e5a9..87d0f9fa22 100644
--- a/pimd/pim_bfd.c
+++ b/pimd/pim_bfd.c
@@ -111,6 +111,7 @@ static void pim_bfd_reg_dereg_nbr(struct pim_neighbor *nbr, int command)
struct pim_interface *pim_ifp = NULL;
struct bfd_info *bfd_info = NULL;
struct zclient *zclient = NULL;
+ int cbit;
zclient = pim_zebra_zclient_get();
@@ -127,8 +128,12 @@ static void pim_bfd_reg_dereg_nbr(struct pim_neighbor *nbr, int command)
zlog_debug("%s Nbr %s %s with BFD", __PRETTY_FUNCTION__, str,
bfd_get_command_dbg_str(command));
}
+
+ cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
+
bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->source_addr, NULL,
- nbr->interface->name, 0, 0, command, 0, VRF_DEFAULT);
+ nbr->interface->name, 0, 0, cbit,
+ command, 0, VRF_DEFAULT);
}
/*
@@ -222,7 +227,8 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
struct listnode *neigh_nextnode = NULL;
struct pim_neighbor *neigh = NULL;
- ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status, vrf_id);
+ ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status,
+ NULL, vrf_id);
if ((ifp == NULL) || (p.family != AF_INET))
return 0;
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 3a68176510..352177db2b 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -1425,9 +1425,9 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
pim_jp_agg_single_upstream_send(&starup->rpf, starup, true);
}
-unsigned int pim_ifchannel_hash_key(void *arg)
+unsigned int pim_ifchannel_hash_key(const void *arg)
{
- struct pim_ifchannel *ch = (struct pim_ifchannel *)arg;
+ const struct pim_ifchannel *ch = arg;
return jhash_2words(ch->sg.src.s_addr, ch->sg.grp.s_addr, 0);
}
diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h
index b9d4d291d8..b36c3236b0 100644
--- a/pimd/pim_ifchannel.h
+++ b/pimd/pim_ifchannel.h
@@ -155,5 +155,5 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
int pim_ifchannel_compare(const struct pim_ifchannel *ch1,
const struct pim_ifchannel *ch2);
-unsigned int pim_ifchannel_hash_key(void *arg);
+unsigned int pim_ifchannel_hash_key(const void *arg);
#endif /* PIM_IFCHANNEL_H */
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index cdd156b96f..213ca48bb5 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -829,9 +829,9 @@ void igmp_sock_delete_all(struct interface *ifp)
}
}
-static unsigned int igmp_group_hash_key(void *arg)
+static unsigned int igmp_group_hash_key(const void *arg)
{
- struct igmp_group *group = (struct igmp_group *)arg;
+ const struct igmp_group *group = arg;
return jhash_1word(group->group_addr.s_addr, 0);
}
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 395c4af35f..3287e13719 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -680,9 +680,9 @@ void pim_msdp_up_del(struct pim_instance *pim, struct prefix_sg *sg)
}
/* sa hash and peer list helpers */
-static unsigned int pim_msdp_sa_hash_key_make(void *p)
+static unsigned int pim_msdp_sa_hash_key_make(const void *p)
{
- struct pim_msdp_sa *sa = p;
+ const struct pim_msdp_sa *sa = p;
return (jhash_2words(sa->sg.src.s_addr, sa->sg.grp.s_addr, 0));
}
@@ -1215,9 +1215,9 @@ enum pim_msdp_err pim_msdp_peer_del(struct pim_instance *pim,
}
/* peer hash and peer list helpers */
-static unsigned int pim_msdp_peer_hash_key_make(void *p)
+static unsigned int pim_msdp_peer_hash_key_make(const void *p)
{
- struct pim_msdp_peer *mp = p;
+ const struct pim_msdp_peer *mp = p;
return (jhash_1word(mp->peer.s_addr, 0));
}
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 5945bc55fd..22045c2d33 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -91,9 +91,9 @@ static bool pim_oil_equal(const void *arg1, const void *arg2)
return false;
}
-static unsigned int pim_oil_hash_key(void *arg)
+static unsigned int pim_oil_hash_key(const void *arg)
{
- struct channel_oil *oil = (struct channel_oil *)arg;
+ const struct channel_oil *oil = arg;
return jhash_2words(oil->oil.mfcc_mcastgrp.s_addr,
oil->oil.mfcc_origin.s_addr, 0);
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index afe3886aa5..dba46e63f0 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -426,9 +426,9 @@ int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2)
return 0;
}
-unsigned int pim_rpf_hash_key(void *arg)
+unsigned int pim_rpf_hash_key(const void *arg)
{
- struct pim_nexthop_cache *r = (struct pim_nexthop_cache *)arg;
+ const struct pim_nexthop_cache *r = arg;
return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0);
}
diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h
index 57bb22674f..1172acb4b2 100644
--- a/pimd/pim_rpf.h
+++ b/pimd/pim_rpf.h
@@ -56,7 +56,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);
+unsigned int pim_rpf_hash_key(const void *arg);
bool pim_rpf_equal(const void *arg1, const void *arg2);
bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index d829d01347..55d998f270 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1629,9 +1629,9 @@ void pim_upstream_find_new_rpf(struct pim_instance *pim)
}
}
-unsigned int pim_upstream_hash_key(void *arg)
+unsigned int pim_upstream_hash_key(const void *arg)
{
- struct pim_upstream *up = (struct pim_upstream *)arg;
+ const struct pim_upstream *up = arg;
return jhash_2words(up->sg.src.s_addr, up->sg.grp.s_addr, 0);
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index 13a3dcdf8c..102826ac71 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -308,7 +308,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
void pim_upstream_spt_prefix_list_update(struct pim_instance *pim,
struct prefix_list *pl);
-unsigned int pim_upstream_hash_key(void *arg);
+unsigned int pim_upstream_hash_key(const void *arg);
bool pim_upstream_equal(const void *arg1, const void *arg2);
struct pim_upstream *pim_upstream_keep_alive_timer_proc(
struct pim_upstream *up);
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index af76c6d732..1c6b56568f 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -623,9 +623,9 @@ static void pim_vxlan_term_mr_del(struct pim_vxlan_sg *vxlan_sg)
}
/************************** vxlan SG cache management ************************/
-static unsigned int pim_vxlan_sg_hash_key_make(void *p)
+static unsigned int pim_vxlan_sg_hash_key_make(const void *p)
{
- struct pim_vxlan_sg *vxlan_sg = p;
+ const struct pim_vxlan_sg *vxlan_sg = p;
return (jhash_2words(vxlan_sg->sg.src.s_addr,
vxlan_sg->sg.grp.s_addr, 0));
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index c03a371d88..c6da00418b 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -223,9 +223,9 @@ static void static_zebra_capabilities(struct zclient_capabilities *cap)
mpls_enabled = cap->mpls_enabled;
}
-static unsigned int static_nht_hash_key(void *data)
+static unsigned int static_nht_hash_key(const void *data)
{
- struct static_nht_data *nhtd = data;
+ const struct static_nht_data *nhtd = data;
unsigned int key = 0;
key = prefix_hash_key(nhtd->nh);
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c
index 19a40b2184..0fca571d28 100644
--- a/tests/lib/test_srcdest_table.c
+++ b/tests/lib/test_srcdest_table.c
@@ -81,9 +81,9 @@ static char *format_srcdest(const struct prefix_ipv6 *dst_p,
return rv;
}
-static unsigned int log_key(void *data)
+static unsigned int log_key(const void *data)
{
- struct prefix *hash_entry = data;
+ const struct prefix *hash_entry = data;
struct prefix_ipv6 *dst_p = (struct prefix_ipv6 *)&hash_entry[0];
struct prefix_ipv6 *src_p = (struct prefix_ipv6 *)&hash_entry[1];
unsigned int hash = 0;
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/__init__.py b/tests/topotests/bfd-bgp-cbit-topo3/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/__init__.py
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/bgp_ipv6_routes_down.json b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgp_ipv6_routes_down.json
new file mode 100644
index 0000000000..54ae57f7be
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgp_ipv6_routes_down.json
@@ -0,0 +1,103 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "10.254.254.1",
+ "localAS": 101,
+ "routes":
+ {
+ "2001:db8:6::/64": [
+ {
+ "stale": true,
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "2001:db8:6::",
+ "prefixLen": 64,
+ "network": "2001:db8:6::\/64",
+ "med": 0,
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001:db8:4::1",
+ "origin": "IGP",
+ "nexthops": [
+ { "ip": "2001:db8:4::1",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:7::/64": [
+ {
+ "stale": true,
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "2001:db8:7::",
+ "prefixLen": 64, "network":
+ "2001:db8:7::\/64",
+ "med": 0,
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001:db8:4::1",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001:db8:4::1",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:8::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "2001:db8:8::",
+ "prefixLen": 64,
+ "network": "2001:db8:8::\/64",
+ "med": 0,
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "::",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:9::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "2001:db8:9::",
+ "prefixLen": 64,
+ "network": "2001:db8:9::\/64",
+ "med": 0,
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "::",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
+
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf
new file mode 100644
index 0000000000..fa6d60a8fc
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf
@@ -0,0 +1,20 @@
+debug bgp neighbor-events
+router bgp 101
+ bgp router-id 10.254.254.1
+ timers bgp 8 24
+ bgp graceful-restart
+ neighbor 2001:db8:4::1 remote-as 102
+ neighbor 2001:db8:4::1 remote-as external
+ neighbor 2001:db8:4::1 bfd
+ neighbor 2001:db8:4::1 bfd check-control-plane-failure
+ neighbor 2001:db8:4::1 update-source 2001:db8:1::1
+ neighbor 2001:db8:4::1 ebgp-multihop 5
+ address-family ipv4 unicast
+ no neighbor 2001:db8:4::1 activate
+ exit-address-family
+ address-family ipv6 unicast
+ network 2001:db8:8::/64
+ network 2001:db8:9::/64
+ neighbor 2001:db8:4::1 activate
+ exit-address-family
+!
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/ipv6_routes.json b/tests/topotests/bfd-bgp-cbit-topo3/r1/ipv6_routes.json
new file mode 100644
index 0000000000..8eea183285
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/ipv6_routes.json
@@ -0,0 +1,80 @@
+{
+ "2001:db8:1::/64": [{
+ "distance": 0,
+ "protocol": "connected",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:1::/64",
+ "nexthops": [{
+ "directlyConnected": true,
+ "interfaceName": "r1-eth0",
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:4::/64": [{
+ "distance": 1,
+ "protocol": "static",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:4::/64",
+ "nexthops": [{
+ "interfaceName": "r1-eth0",
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ],
+ "2001:db8:6::/64": [{
+ "distance": 20,
+ "protocol": "bgp",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:6::/64",
+ "nexthops": [{
+ "ip":"2001:db8:4::1",
+ "active": true,
+ "afi": "ipv6",
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"2001:db8:1::2",
+ "afi": "ipv6",
+ "interfaceName": "r1-eth0"
+ }
+ ]
+ }
+ ],
+ "2001:db8:7::/64": [{
+ "distance": 20,
+ "protocol": "bgp",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:7::/64",
+ "nexthops": [{
+ "ip":"2001:db8:4::1",
+ "active": true,
+ "afi": "ipv6",
+ "recursive": true
+ },
+ {
+ "fib":true,
+ "ip":"2001:db8:1::2",
+ "afi": "ipv6",
+ "interfaceName":"r1-eth0"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/peers.json b/tests/topotests/bfd-bgp-cbit-topo3/r1/peers.json
new file mode 100644
index 0000000000..d1927ae49a
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/peers.json
@@ -0,0 +1,16 @@
+[
+ {
+ "multihop":true,
+ "peer":"2001:db8:4::1",
+ "local":"2001:db8:1::1",
+ "status":"up",
+ "diagnostic":"ok",
+ "remote-diagnostic":"ok",
+ "receive-interval":300,
+ "transmit-interval":300,
+ "echo-interval":0,
+ "remote-receive-interval":300,
+ "remote-transmit-interval":300,
+ "remote-echo-interval":50
+ }
+]
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/peers_down.json b/tests/topotests/bfd-bgp-cbit-topo3/r1/peers_down.json
new file mode 100644
index 0000000000..25b47f18ec
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/peers_down.json
@@ -0,0 +1,14 @@
+[
+ {
+ "multihop":true,
+ "peer":"2001:db8:4::1",
+ "local":"2001:db8:1::1",
+ "status":"up",
+ "receive-interval":300,
+ "transmit-interval":300,
+ "echo-interval":0,
+ "remote-receive-interval":300,
+ "remote-transmit-interval":300,
+ "remote-echo-interval":50
+ }
+]
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/zebra.conf b/tests/topotests/bfd-bgp-cbit-topo3/r1/zebra.conf
new file mode 100644
index 0000000000..3a30cd42fb
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/zebra.conf
@@ -0,0 +1,8 @@
+interface lo
+ ip address 10.254.254.1/32
+!
+interface r1-eth0
+ ipv6 address 2001:db8:1::1/64
+!
+ipv6 route 2001:db8:4::/64 2001:db8:1::2
+
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r2/zebra.conf b/tests/topotests/bfd-bgp-cbit-topo3/r2/zebra.conf
new file mode 100644
index 0000000000..0f70be1bda
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r2/zebra.conf
@@ -0,0 +1,9 @@
+ip forwarding
+ipv6 forwarding
+!
+interface r2-eth0
+ ipv6 address 2001:db8:1::2/64
+!
+interface r2-eth1
+ ipv6 address 2001:db8:4::2/64
+!
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/bgp_ipv6_routes_down.json b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgp_ipv6_routes_down.json
new file mode 100644
index 0000000000..a3bb222504
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgp_ipv6_routes_down.json
@@ -0,0 +1,55 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "10.254.254.3",
+ "localAS": 102,
+ "routes":
+ {
+ "2001:db8:6::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "2001:db8:6::",
+ "prefixLen": 64,
+ "network": "2001:db8:6::\/64",
+ "med": 0,
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "::",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:7::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "2001:db8:7::",
+ "prefixLen": 64,
+ "network": "2001:db8:7::\/64",
+ "med": 0,
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "::",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf
new file mode 100644
index 0000000000..ea5334029c
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf
@@ -0,0 +1,25 @@
+debug bgp neighbor-events
+router bgp 102
+ bgp router-id 10.254.254.3
+ timers bgp 20 60
+ bgp graceful-restart
+ ! simulate NSF machine
+ bgp graceful-restart preserve-fw-state
+ bgp graceful-restart stalepath-time 900
+ bgp graceful-restart restart-time 900
+ neighbor 2001:db8:1::1 remote-as 101
+ neighbor 2001:db8:1::1 remote-as external
+ neighbor 2001:db8:1::1 update-source 2001:db8:4::1
+ neighbor 2001:db8:1::1 bfd
+ neighbor 2001:db8:1::1 ebgp-multihop 5
+ !
+ address-family ipv4 unicast
+ no neighbor 2001:db8:1::1 activate
+ exit-address-family
+ !
+ address-family ipv6 unicast
+ neighbor 2001:db8:1::1 activate
+ network 2001:db8:6::/64
+ network 2001:db8:7::/64
+ exit-address-family
+!
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/ipv6_routes.json b/tests/topotests/bfd-bgp-cbit-topo3/r3/ipv6_routes.json
new file mode 100644
index 0000000000..09808cc09a
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/ipv6_routes.json
@@ -0,0 +1,80 @@
+{
+ "2001:db8:1::/64": [{
+ "distance": 1,
+ "protocol": "static",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:1::/64",
+ "nexthops": [{
+ "interfaceName": "r3-eth0",
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ],
+ "2001:db8:4::/64": [{
+ "distance": 0,
+ "protocol": "connected",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:4::/64",
+ "nexthops": [{
+ "directlyConnected": true,
+ "interfaceName": "r3-eth0",
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:8::/64": [{
+ "distance": 20,
+ "protocol": "bgp",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:8::/64",
+ "nexthops": [{
+ "ip":"2001:db8:1::1",
+ "active": true,
+ "afi": "ipv6",
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"2001:db8:4::2",
+ "afi": "ipv6",
+ "interfaceName":"r3-eth0"
+ }
+ ]
+ }
+ ],
+ "2001:db8:9::/64": [{
+ "distance": 20,
+ "protocol": "bgp",
+ "metric": 0,
+ "selected": true,
+ "destSelected": true,
+ "prefix": "2001:db8:9::/64",
+ "nexthops": [{
+ "ip":"2001:db8:1::1",
+ "active": true,
+ "afi": "ipv6",
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"2001:db8:4::2",
+ "afi": "ipv6",
+ "interfaceName":"r3-eth0"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/peers.json b/tests/topotests/bfd-bgp-cbit-topo3/r3/peers.json
new file mode 100644
index 0000000000..5193f2a6e2
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/peers.json
@@ -0,0 +1,16 @@
+[
+ {
+ "multihop":true,
+ "peer":"2001:db8:1::1",
+ "local":"2001:db8:4::1",
+ "status":"up",
+ "diagnostic":"ok",
+ "remote-diagnostic":"ok",
+ "receive-interval":300,
+ "transmit-interval":300,
+ "echo-interval":0,
+ "remote-receive-interval":300,
+ "remote-transmit-interval":300,
+ "remote-echo-interval":50
+ }
+]
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/peers_down.json b/tests/topotests/bfd-bgp-cbit-topo3/r3/peers_down.json
new file mode 100644
index 0000000000..9e4bd2633f
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/peers_down.json
@@ -0,0 +1,14 @@
+[
+ {
+ "multihop":true,
+ "peer":"2001:db8:1::1",
+ "local":"2001:db8:4::1",
+ "status":"down",
+ "receive-interval":300,
+ "transmit-interval":300,
+ "echo-interval":0,
+ "remote-receive-interval":300,
+ "remote-transmit-interval":300,
+ "remote-echo-interval":50
+ }
+]
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/zebra.conf b/tests/topotests/bfd-bgp-cbit-topo3/r3/zebra.conf
new file mode 100644
index 0000000000..7759251dc5
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/zebra.conf
@@ -0,0 +1,7 @@
+interface lo
+ ip address 10.254.254.3/32
+!
+interface r3-eth0
+ ipv6 address 2001:db8:4::1/64
+!
+ipv6 route 2001:db8:1::/64 2001:db8:4::2
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.dot b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.dot
new file mode 100644
index 0000000000..270de829c3
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.dot
@@ -0,0 +1,58 @@
+## Color coding:
+#########################
+## Main FRR: #f08080 red
+## Switches: #d0e0d0 gray
+## RIP: #19e3d9 Cyan
+## RIPng: #fcb314 dark yellow
+## OSPFv2: #32b835 Green
+## OSPFv3: #19e3d9 Cyan
+## ISIS IPv4 #fcb314 dark yellow
+## ISIS IPv6 #9a81ec purple
+## BGP IPv4 #eee3d3 beige
+## BGP IPv6 #fdff00 yellow
+##### Colors (see http://www.color-hex.com/)
+
+graph template {
+ label="bfd-topo2";
+
+ # Routers
+ r1 [
+ shape=doubleoctagon,
+ label="r1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r2 [
+ shape=doubleoctagon
+ label="r2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r3 [
+ shape=doubleoctagon
+ label="r4",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+
+ # Switches
+ sw1 [
+ shape=oval,
+ label="sw1\n2001:db8:1::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ sw2 [
+ shape=oval,
+ label="sw2\n10.0.3.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+
+ # Connections
+ r1 -- sw1 [label="eth0"];
+ r2 -- sw1 [label="eth0"];
+
+ r2 -- sw2 [label="eth1"];
+ r3 -- sw2 [label="eth0"];
+}
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py
new file mode 100755
index 0000000000..59858d6fd3
--- /dev/null
+++ b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py
@@ -0,0 +1,248 @@
+#!/usr/bin/env python
+
+#
+# test_bfd_bgp_cbit_topo3.py
+#
+# Copyright (c) 2019 6WIND
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_bfd_bgp_cbit_topo3.py: Test the FRR/Quagga BFD daemon with multihop and BGP
+unnumbered.
+"""
+
+import os
+import sys
+import json
+from functools import partial
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+class BFDTopo(Topo):
+ "Test topology builder"
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Create 4 routers.
+ for routern in range(1, 4):
+ tgen.add_router('r{}'.format(routern))
+
+ switch = tgen.add_switch('s1')
+ switch.add_link(tgen.gears['r1'])
+ switch.add_link(tgen.gears['r2'])
+
+ switch = tgen.add_switch('s2')
+ switch.add_link(tgen.gears['r2'])
+ switch.add_link(tgen.gears['r3'])
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(BFDTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for rname, router in router_list.iteritems():
+ router.load_config(
+ TopoRouter.RD_ZEBRA,
+ os.path.join(CWD, '{}/zebra.conf'.format(rname)),
+ )
+ router.load_config(
+ TopoRouter.RD_BFD,
+ os.path.join(CWD, '{}/bfdd.conf'.format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP,
+ os.path.join(CWD, '{}/bgpd.conf'.format(rname))
+ )
+
+ # Initialize all routers.
+ tgen.start_router()
+
+ # Verify that we are using the proper version and that the BFD
+ # daemon exists.
+ for router in router_list.values():
+ # Check for Version
+ if router.has_version('<', '5.1'):
+ tgen.set_error('Unsupported FRR version')
+ break
+
+def teardown_module(_mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_protocols_convergence():
+ """
+ Assert that all protocols have converged before checking for the BFD
+ statuses as they depend on it.
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Check IPv6 routing tables.
+ logger.info("Checking IPv6 routes for convergence")
+ for router in tgen.routers().values():
+ if router.name == 'r2':
+ continue
+ json_file = '{}/{}/ipv6_routes.json'.format(CWD, router.name)
+ if not os.path.isfile(json_file):
+ logger.info('skipping file {}'.format(json_file))
+ continue
+ expected = json.loads(open(json_file).read())
+ test_func = partial(topotest.router_json_cmp,
+ router, 'show ipv6 route json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=40,
+ wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+
+def test_bfd_connection():
+ "Assert that the BFD peers can find themselves."
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info('waiting for bfd peers to go up')
+ for router in tgen.routers().values():
+ if router.name == 'r2':
+ continue
+ json_file = '{}/{}/peers.json'.format(CWD, router.name)
+ expected = json.loads(open(json_file).read())
+
+ test_func = partial(topotest.router_json_cmp,
+ router, 'show bfd peers json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=8, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+def test_bfd_loss_intermediate():
+ """
+ Assert that BFD notices the bfd link down failure.
+ but BGP entries should still be present
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info('removing IPv6 address from r2 to simulate loss of connectivity')
+ # Disable r2-eth0 ipv6 address
+ cmd = 'vtysh -c \"configure terminal\" -c \"interface r2-eth1\" -c "no ipv6 address 2001:db8:4::2/64\"'
+ tgen.net['r2'].cmd(cmd)
+
+ # Wait the minimum time we can before checking that BGP/BFD
+ # converged.
+ logger.info('waiting for BFD converge down')
+
+ # Check that BGP converged quickly.
+ for router in tgen.routers().values():
+ if router.name == 'r2':
+ continue
+ json_file = '{}/{}/peers_down.json'.format(CWD, router.name)
+ expected = json.loads(open(json_file).read())
+
+ test_func = partial(topotest.router_json_cmp,
+ router, 'show bfd peers json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=8, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+ logger.info('waiting for BGP entries to become stale')
+ for router in tgen.routers().values():
+ if router.name == 'r2':
+ continue
+ json_file = '{}/{}/bgp_ipv6_routes_down.json'.format(CWD, router.name)
+ expected = json.loads(open(json_file).read())
+
+ test_func = partial(topotest.router_json_cmp,
+ router, 'show bgp ipv6 json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=50, wait=1)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+ logger.info("Checking IPv6 routes on r1 should still be present")
+ for router in tgen.routers().values():
+ if router.name == 'r2':
+ continue
+ if router.name == 'r3':
+ continue
+ json_file = '{}/r1/ipv6_routes.json'.format(CWD)
+ expected = json.loads(open(json_file).read())
+ test_func = partial(topotest.router_json_cmp,
+ router, 'show ipv6 route json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=30,
+ wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+def test_bfd_comes_back_again():
+ """
+ Assert that BFD notices the bfd link up
+ and that ipv6 entries appear back
+ """
+ tgen = get_topogen()
+ logger.info('re-adding IPv6 address from r2 to simulate connectivity is back')
+ # adds back r2-eth0 ipv6 address
+ cmd = 'vtysh -c \"configure terminal\" -c \"interface r2-eth1\" -c "ipv6 address 2001:db8:4::2/64\"'
+ tgen.net['r2'].cmd(cmd)
+
+ # Wait the minimum time we can before checking that BGP/BFD
+ # converged.
+ logger.info('waiting for BFD to converge up')
+
+ # Check that BGP converged quickly.
+ for router in tgen.routers().values():
+ if router.name == 'r2':
+ continue
+ json_file = '{}/{}/peers.json'.format(CWD, router.name)
+ expected = json.loads(open(json_file).read())
+
+ test_func = partial(topotest.router_json_cmp,
+ router, 'show bfd peers json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=8, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip('Memory leak test/report is disabled')
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
index 4bd0f95f2c..a38fb1e9a1 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
@@ -15,6 +15,7 @@ router bgp 5227
network 99.0.0.1/32
network 5.1.0.0/24 route-map rm-nh
network 5.1.1.0/24 route-map rm-nh
+ redistribute sharp route-map sharp-nh
neighbor 192.168.1.1 activate
exit-address-family
!
@@ -29,6 +30,15 @@ route-map rm-nh permit 10
set extcommunity rt 89:123
set community 0:67
!
+route-map sharp-nh permit 10
+ match ip address al-any
+ set ip next-hop 99.0.0.1
+ set local-preference 200
+ set metric 200
+ set large-community 90:12:34
+ set extcommunity rt 80:987
+ set community 0:65
+!
end
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/sharpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/sharpd.conf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/sharpd.conf
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
index 2115f08741..3aeb9f9c9f 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
@@ -15,6 +15,7 @@ router bgp 5227
network 99.0.0.2/32
network 5.1.0.0/24 route-map rm-nh
network 5.1.1.0/24 route-map rm-nh
+ redistribute sharp route-map sharp-nh
neighbor 192.168.1.1 activate
exit-address-family
!
@@ -29,6 +30,15 @@ route-map rm-nh permit 10
set extcommunity rt 89:123
set community 0:67
!
+route-map sharp-nh permit 10
+ match ip address al-any
+ set ip next-hop 99.0.0.2
+ set local-preference 200
+ set metric 200
+ set large-community 78:90:12
+ set extcommunity rt 70:456
+ set community 0:66
+!
end
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/sharpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/sharpd.conf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/sharpd.conf
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf
index 2004612557..c4b6ac9bb4 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf
@@ -7,7 +7,7 @@ log monitor notifications
log commands
log file bgpd.log
-debug bgp vpn label
+#debug bgp vpn label
router bgp 5226
bgp router-id 3.3.3.3
bgp cluster-id 3.3.3.3
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf
index b2df5990ce..6295406e69 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf
@@ -7,9 +7,9 @@ log monitor notifications
log commands
log file bgpd.log debug
-debug bgp vpn label
-debug bgp nht
-debug bgp zebra
+#debug bgp vpn label
+#debug bgp nht
+#debug bgp zebra
router bgp 5226
bgp router-id 4.4.4.4
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
index f5d73a8c49..149a420a32 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py
@@ -1,5 +1,6 @@
from lutil import luCommand
from customize import l3mdev_accept
+
l3mdev_rtrs = ['r1', 'r3', 'r4', 'ce4']
for rtr in l3mdev_rtrs:
luCommand(rtr,'sysctl net.ipv4.tcp_l3mdev_accept',' = \d*','none','')
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py
new file mode 100644
index 0000000000..897fc48436
--- /dev/null
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py
@@ -0,0 +1,20 @@
+from lutil import luCommand
+ret = luCommand('ce1', 'vtysh -c "show ip route" | grep -c \\ 10\\.\\*/32','(.*)','pass', 'Looking for sharp routes')
+found = luLast()
+if ret != False and found != None:
+ num = int(found.group())
+ luCommand('ce3', 'vtysh -c "show bgp sum"',
+ '.', 'pass', 'See %s sharp routes' % num)
+ if num > 0:
+ wait = num/500
+ luCommand('ce1', 'vtysh -c "sharp remove routes 10.0.0.0 {}"'.format(num),'.','none','Removing {} routes'.format(num))
+ luCommand('ce2', 'vtysh -c "sharp remove routes 10.0.0.0 {}"'.format(num),'.','none','Removing {} routes'.format(num))
+ rtrs = ['ce1', 'ce2', 'ce3']
+ for rtr in rtrs:
+ luCommand(rtr, 'vtysh -c "show bgp ipv4 uni" | grep -c 10\\.\\*/32','^0$', 'wait', 'BGP routes removed', wait)
+ for rtr in rtrs:
+ luCommand(rtr, 'ip route show | grep -c \\^10\\.','^0$', 'wait', 'Linux routes removed', wait)
+ rtrs = ['r1', 'r3', 'r4']
+ for rtr in rtrs:
+ luCommand(rtr, 'ip route show vrf {}-cust1 | grep -c \\^10\\.'.format(rtr),'^0$','wait','VRF route removed',wait)
+#done
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py
new file mode 100644
index 0000000000..3b3aac5fbe
--- /dev/null
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py
@@ -0,0 +1,66 @@
+from lutil import luCommand
+num = 50000
+b = int(num/(256*256))
+if b > 0:
+ r = num - b * (256*256)
+else:
+ r = num
+c = int(r/256)
+if c > 0:
+ d = r - c * 256 - 1
+else:
+ d = r
+wait = num/1000
+mem = {}
+rtrs = ['ce1', 'ce2', 'ce3', 'r1', 'r2', 'r3', 'r4']
+for rtr in rtrs:
+ mem[rtr] = {'value': 0, 'units': 'unknown'}
+ ret = luCommand(rtr, 'vtysh -c "show memory"', 'bgpd: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*)', 'none', 'collect bgpd memory stats')
+ found = luLast()
+ if ret != False and found != None:
+ mem[rtr] = {'value': int(found.group(1)), 'units': found.group(2)}
+
+luCommand('ce1', 'vtysh -c "sharp data nexthop"', 'sharpd is not running', 'none','check if sharpd running')
+doSharp = True
+found = luLast()
+if ret != False and found != None:
+ if len(found.group()):
+ luCommand('ce1', 'vtysh -c "sharp data nexthop"', 'sharpd is not running', 'pass','sharpd NOT running, skipping test')
+ doSharp = False
+
+if doSharp == True:
+ luCommand('ce1', 'vtysh -c "sharp install routes 10.0.0.0 nexthop 99.0.0.1 {}"'.format(num),'','pass','Adding {} routes'.format(num))
+ luCommand('ce2', 'vtysh -c "sharp install routes 10.0.0.0 nexthop 99.0.0.2 {}"'.format(num),'','pass','Adding {} routes'.format(num))
+ rtrs = ['ce1', 'ce2', 'ce3']
+ for rtr in rtrs:
+ luCommand(rtr, 'vtysh -c "show bgp ipv4 uni 10.{}.{}.{}"'.format(b,c,d), 'Last update:', 'wait', 'RXed last route, 10.{}.{}.{}'.format(b,c,d), wait)
+ luCommand(rtr, 'vtysh -c "show bgp ipv4 uni" | grep -c 10\\.\\*/32', str(num), 'wait', 'See all sharp routes in BGP', wait)
+ luCommand('r1', 'vtysh -c "show bgp vrf r1-cust1 ipv4 uni 10.{}.{}.{}"'.format(b,c,d),'99.0.0.1','wait','RXed -> 10.{}.{}.{} from CE1'.format(b,c,d), wait)
+ luCommand('r3', 'vtysh -c "show bgp vrf r3-cust1 ipv4 uni 10.{}.{}.{}"'.format(b,c,d),'99.0.0.2','wait','RXed -> 10.{}.{}.{} from CE2'.format(b,c,d), wait)
+ luCommand('r1', 'vtysh -c "show bgp ipv4 vpn 10.{}.{}.{}"'.format(b,c,d),'99.0.0.1','wait','see VPN safi -> 10.{}.{}.{} from CE1'.format(b,c,d))
+ luCommand('r3', 'vtysh -c "show bgp ipv4 vpn 10.{}.{}.{}"'.format(b,c,d),'99.0.0.2','wait','see VPN safi -> 10.{}.{}.{} from CE2'.format(b,c,d))
+ luCommand('r3', 'vtysh -c "show bgp ipv4 vpn 10.{}.{}.{}"'.format(b,c,d),'1.1.1.1','wait','see VPN safi -> 10.{}.{}.{} from CE1'.format(b,c,d))
+ luCommand('r1', 'vtysh -c "show bgp ipv4 vpn 10.{}.{}.{}"'.format(b,c,d),'3.3.3.3','wait','see VPN safi -> 10.{}.{}.{} from CE2'.format(b,c,d))
+ luCommand('r4', 'vtysh -c "show bgp ipv4 vpn 10.{}.{}.{}"'.format(b,c,d),'1.1.1.1','wait','see VPN safi -> 10.{}.{}.{} from CE1'.format(b,c,d))
+ luCommand('r4', 'vtysh -c "show bgp ipv4 vpn 10.{}.{}.{}"'.format(b,c,d),'3.3.3.3','wait','see VPN safi -> 10.{}.{}.{} from CE2'.format(b,c,d))
+ rtrs = ['ce1', 'ce2', 'ce3']
+ for rtr in rtrs:
+ luCommand(rtr, 'ip route get 10.{}.{}.{}'.format(b,c,d),'dev','wait','Route to 10.{}.{}.{} available'.format(b,c,d), wait)
+ luCommand(rtr, 'ip route show | grep -c \\^10\\.', str(num), 'wait', 'See {} linux routes'.format(num), wait)
+
+ rtrs = ['r1', 'r3', 'r4']
+ for rtr in rtrs:
+ luCommand(rtr, 'ip route get vrf {}-cust1 10.{}.{}.{}'.format(rtr,b,c,d),'dev','wait','VRF route available',wait)
+ luCommand(rtr, 'ip route show vrf {}-cust1 | grep -c \\^10\\.'.format(rtr), str(num), 'wait','See {} linux routes'.format(num), wait)
+ rtrs = ['ce1', 'ce2', 'ce3', 'r1', 'r2', 'r3', 'r4']
+ for rtr in rtrs:
+ ret = luCommand(rtr, 'vtysh -c "show memory"', 'bgpd: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*)', 'none', 'collect bgpd memory stats')
+ found = luLast()
+ if ret != False and found != None:
+ val = int(found.group(1))
+ if mem[rtr]['units'] != found.group(2):
+ val *= 1000
+ delta = val - int(mem[rtr]['value'])
+ ave = float(delta)/float(num)
+ luCommand(rtr, 'vtysh -c "show thread cpu"', '.', 'pass', 'BGPd heap: {0} {1} --> {2} {3} ({4} {1}/route)'.format(mem[rtr]['value'], mem[rtr]['units'], found.group(1), found.group(2), round(ave,4)))
+#done
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py
index 1da1066f0e..2dad5e7687 100755
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py
@@ -75,6 +75,24 @@ def test_check_linux_mpls():
#CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')'
ltemplateTest('scripts/check_linux_mpls.py', False, CliOnFail, CheckFunc)
+def test_check_scale_up():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\', iproute2=\'4.9\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')'
+ ltemplateTest('scripts/scale_up.py', False, CliOnFail, CheckFunc)
+
+def test_check_scale_down():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\', iproute2=\'4.9\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')'
+ ltemplateTest('scripts/scale_down.py', False, CliOnFail, CheckFunc)
+
def SKIP_test_cleanup_all():
CliOnFail = None
# For debugging, uncomment the next line
diff --git a/tests/topotests/lib/ltemplate.py b/tests/topotests/lib/ltemplate.py
index 31eaec7009..1d12d11a26 100644
--- a/tests/topotests/lib/ltemplate.py
+++ b/tests/topotests/lib/ltemplate.py
@@ -83,22 +83,15 @@ class LTemplate():
# For all registred routers, load the zebra configuration file
for rname, router in router_list.iteritems():
- print("Setting up %s" % rname)
- config = os.path.join(self.testdir, '{}/zebra.conf'.format(rname))
- if os.path.exists(config):
- router.load_config(TopoRouter.RD_ZEBRA, config)
- config = os.path.join(self.testdir, '{}/ospfd.conf'.format(rname))
- if os.path.exists(config):
- router.load_config(TopoRouter.RD_OSPF, config)
- config = os.path.join(self.testdir, '{}/ldpd.conf'.format(rname))
- if os.path.exists(config):
- router.load_config(TopoRouter.RD_LDP, config)
- config = os.path.join(self.testdir, '{}/bgpd.conf'.format(rname))
- if os.path.exists(config):
- router.load_config(TopoRouter.RD_BGP, config)
- config = os.path.join(self.testdir, '{}/isisd.conf'.format(rname))
- if os.path.exists(config):
- router.load_config(TopoRouter.RD_ISIS, config)
+ logger.info("Setting up %s" % rname)
+ for rd_val in TopoRouter.RD:
+ config = os.path.join(self.testdir, '{}/{}.conf'.format(rname,TopoRouter.RD[rd_val]))
+ prog = os.path.join(tgen.net[rname].daemondir, TopoRouter.RD[rd_val])
+ if os.path.exists(config):
+ if os.path.exists(prog):
+ router.load_config(rd_val, config)
+ else:
+ logger.warning("{} not found, but have {}.conf file".format(prog, TopoRouter.RD[rd_val]))
# After loading the configurations, this function loads configured daemons.
logger.info('Starting routers')
diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py
index 0bc1596eb2..d7145c3be0 100644
--- a/tests/topotests/lib/topogen.py
+++ b/tests/topotests/lib/topogen.py
@@ -540,6 +540,7 @@ class TopoRouter(TopoGear):
RD_NHRP = 11
RD_STATIC = 12
RD_BFD = 13
+ RD_SHARP = 14
RD = {
RD_ZEBRA: 'zebra',
RD_RIP: 'ripd',
@@ -554,6 +555,7 @@ class TopoRouter(TopoGear):
RD_NHRP: 'nhrpd',
RD_STATIC: 'staticd',
RD_BFD: 'bfdd',
+ RD_SHARP: 'sharpd',
}
def __init__(self, tgen, cls, name, **params):
diff --git a/tools/coccinelle/hash_const.cocci b/tools/coccinelle/hash_const.cocci
new file mode 100644
index 0000000000..9c53cb01fb
--- /dev/null
+++ b/tools/coccinelle/hash_const.cocci
@@ -0,0 +1,76 @@
+//
+// Transition hash key signatures to take their argument as const.
+// Does not handle headers or weirdly named hash functions.
+//
+@noconst disable optional_qualifier@
+identifier A;
+identifier func =~ ".*key$|.*key_make$|.*hash_make$|.*hash_keymake$|.*hash_key$|.*hash_key.*";
+@@
+
+- func (void *A)
++ func (const void *A)
+ { ... }
+
+@ depends on noconst disable optional_qualifier @
+identifier noconst.A;
+identifier noconst.func;
+identifier b;
+type T;
+@@
+
+func( ... ) {
+<...
+- T b = A;
++ const T b = A;
+...>
+ }
+
+@ depends on noconst disable optional_qualifier @
+identifier noconst.A;
+identifier noconst.func;
+identifier b;
+type T;
+@@
+
+func(...)
+ {
+<...
+- T b = (T) A;
++ const T b = A;
+...>
+ }
+
+@ depends on noconst disable optional_qualifier @
+identifier noconst.A;
+identifier noconst.func;
+identifier b;
+type T;
+@@
+
+func(...)
+ {
+<...
+- T b;
++ const T b;
+...
+ b = A;
+...>
+ }
+
+@ depends on noconst disable optional_qualifier @
+identifier noconst.A;
+identifier noconst.func;
+identifier b;
+type T;
+@@
+
+func(...)
+ {
+<...
+- T b;
++ const T b;
+...
+- b = (T) A;
++ b = A;
+...>
+ }
diff --git a/zebra/main.c b/zebra/main.c
index 184e798bd0..cff5e06933 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -119,8 +119,6 @@ struct zebra_privs_t zserv_privs = {
.cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
-unsigned int multipath_num = MULTIPATH_NUM;
-
/* SIGHUP handler. */
static void sighup(void)
{
@@ -322,9 +320,9 @@ int main(int argc, char **argv)
keep_kernel_mode = 1;
break;
case 'e':
- multipath_num = atoi(optarg);
- if (multipath_num > MULTIPATH_NUM
- || multipath_num <= 0) {
+ zrouter.multipath_num = atoi(optarg);
+ if (zrouter.multipath_num > MULTIPATH_NUM
+ || zrouter.multipath_num <= 0) {
flog_err(
EC_ZEBRA_BAD_MULTIPATH_NUM,
"Multipath Number specified must be less than %d and greater than 0",
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index fe064f847a..f3155deb14 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -653,7 +653,8 @@ int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance,
if (afi >= AFI_MAX)
return (-1);
- table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
+ table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST,
+ table_id, VRF_DEFAULT);
if (table == NULL) {
return 0;
} else if (IS_ZEBRA_DEBUG_RIB) {
@@ -767,8 +768,8 @@ void zebra_import_table_rm_update(const char *rmap)
rmap_name = zebra_get_import_table_route_map(afi, i);
if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
continue;
- table = zebra_vrf_other_route_table(afi, i,
- VRF_DEFAULT);
+ table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST,
+ i, VRF_DEFAULT);
for (rn = route_top(table); rn; rn = route_next(rn)) {
/* For each entry in the non-default
* routing table,
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 817c65bf28..5088e2e8e1 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -42,6 +42,7 @@
#include "zebra/debug.h"
#include "zebra/rib.h"
#include "zebra/zapi_msg.h"
+#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_errors.h"
#include "zebra/zebra_router.h"
@@ -80,25 +81,18 @@ enum rtadv_event {
RTADV_READ
};
-static void rtadv_event(struct zebra_vrf *, enum rtadv_event, int);
+static void rtadv_event(struct zebra_ns *, enum rtadv_event, int);
static int if_join_all_router(int, struct interface *);
static int if_leave_all_router(int, struct interface *);
-static int rtadv_get_socket(struct zebra_vrf *zvrf)
-{
- if (zvrf->rtadv.sock >= 0)
- return zvrf->rtadv.sock;
- return zrouter.rtadv_sock;
-}
-
-static int rtadv_increment_received(struct zebra_vrf *zvrf, ifindex_t *ifindex)
+static int rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)
{
int ret = -1;
struct interface *iface;
struct zebra_if *zif;
- iface = if_lookup_by_index(*ifindex, zvrf->vrf->vrf_id);
+ iface = if_lookup_by_index_per_ns(zns, *ifindex);
if (iface && iface->info) {
zif = iface->info;
zif->ra_rcvd++;
@@ -107,7 +101,7 @@ static int rtadv_increment_received(struct zebra_vrf *zvrf, ifindex_t *ifindex)
return ret;
}
-static int rtadv_recv_packet(struct zebra_vrf *zvrf, int sock, uint8_t *buf,
+static int rtadv_recv_packet(struct zebra_ns *zns, int sock, uint8_t *buf,
int buflen, struct sockaddr_in6 *from,
ifindex_t *ifindex, int *hoplimit)
{
@@ -155,7 +149,7 @@ static int rtadv_recv_packet(struct zebra_vrf *zvrf, int sock, uint8_t *buf,
}
}
- rtadv_increment_received(zvrf, ifindex);
+ rtadv_increment_received(zns, ifindex);
return ret;
}
@@ -467,19 +461,19 @@ no_more_opts:
static int rtadv_timer(struct thread *thread)
{
- struct zebra_vrf *zvrf = THREAD_ARG(thread);
+ struct zebra_ns *zns = THREAD_ARG(thread);
struct vrf *vrf;
struct interface *ifp;
struct zebra_if *zif;
int period;
- zvrf->rtadv.ra_timer = NULL;
- if (zvrf->rtadv.adv_msec_if_count == 0) {
+ zrouter.rtadv.ra_timer = NULL;
+ if (zrouter.rtadv.adv_msec_if_count == 0) {
period = 1000; /* 1 s */
- rtadv_event(zvrf, RTADV_TIMER, 1 /* 1 s */);
+ rtadv_event(zns, RTADV_TIMER, 1 /* 1 s */);
} else {
period = 10; /* 10 ms */
- rtadv_event(zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
+ rtadv_event(zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
}
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
@@ -506,7 +500,7 @@ static int rtadv_timer(struct thread *thread)
"Fast RA Rexmit on interface %s",
ifp->name);
- rtadv_send_packet(rtadv_get_socket(zvrf),
+ rtadv_send_packet(zrouter.rtadv.sock,
ifp);
} else {
zif->rtadv.AdvIntervalTimer -= period;
@@ -520,8 +514,8 @@ static int rtadv_timer(struct thread *thread)
zif->rtadv
.MaxRtrAdvInterval;
rtadv_send_packet(
- rtadv_get_socket(zvrf),
- ifp);
+ zrouter.rtadv.sock,
+ ifp);
}
}
}
@@ -533,9 +527,10 @@ static int rtadv_timer(struct thread *thread)
static void rtadv_process_solicit(struct interface *ifp)
{
struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
+ struct zebra_ns *zns = zvrf->zns;
- assert(zvrf);
- rtadv_send_packet(rtadv_get_socket(zvrf), ifp);
+ assert(zns);
+ rtadv_send_packet(zrouter.rtadv.sock, ifp);
}
/*
@@ -657,7 +652,7 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
static void rtadv_process_packet(uint8_t *buf, unsigned int len,
ifindex_t ifindex, int hoplimit,
struct sockaddr_in6 *from,
- struct zebra_vrf *zvrf)
+ struct zebra_ns *zns)
{
struct icmp6_hdr *icmph;
struct interface *ifp;
@@ -667,7 +662,7 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len,
inet_ntop(AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
/* Interface search. */
- ifp = if_lookup_by_index(ifindex, zvrf->vrf->vrf_id);
+ ifp = if_lookup_by_index_per_ns(zns, ifindex);
if (ifp == NULL) {
flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
"RA/RS received on unknown IF %u from %s", ifindex,
@@ -729,15 +724,15 @@ static int rtadv_read(struct thread *thread)
struct sockaddr_in6 from;
ifindex_t ifindex = 0;
int hoplimit = -1;
- struct zebra_vrf *zvrf = THREAD_ARG(thread);
+ struct zebra_ns *zns = THREAD_ARG(thread);
sock = THREAD_FD(thread);
- zvrf->rtadv.ra_read = NULL;
+ zrouter.rtadv.ra_read = NULL;
/* Register myself. */
- rtadv_event(zvrf, RTADV_READ, sock);
+ rtadv_event(zns, RTADV_READ, sock);
- len = rtadv_recv_packet(zvrf, sock, buf, sizeof(buf), &from, &ifindex,
+ len = rtadv_recv_packet(zns, sock, buf, sizeof(buf), &from, &ifindex,
&hoplimit);
if (len < 0) {
@@ -747,7 +742,7 @@ static int rtadv_read(struct thread *thread)
return len;
}
- rtadv_process_packet(buf, (unsigned)len, ifindex, hoplimit, &from, zvrf);
+ rtadv_process_packet(buf, (unsigned)len, ifindex, hoplimit, &from, zns);
return 0;
}
@@ -880,27 +875,29 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
{
struct zebra_if *zif;
struct zebra_vrf *zvrf;
+ struct zebra_ns *zns;
zif = ifp->info;
zvrf = vrf_info_lookup(ifp->vrf_id);
+ zns = zvrf->zns;
if (status == RA_SUPPRESS) {
/* RA is currently enabled */
if (zif->rtadv.AdvSendAdvertisements) {
zif->rtadv.AdvSendAdvertisements = 0;
zif->rtadv.AdvIntervalTimer = 0;
- zvrf->rtadv.adv_if_count--;
+ zrouter.rtadv.adv_if_count--;
- if_leave_all_router(rtadv_get_socket(zvrf), ifp);
+ if_leave_all_router(zrouter.rtadv.sock, ifp);
- if (zvrf->rtadv.adv_if_count == 0)
- rtadv_event(zvrf, RTADV_STOP, 0);
+ if (zrouter.rtadv.adv_if_count == 0)
+ rtadv_event(zns, RTADV_STOP, 0);
}
} else {
if (!zif->rtadv.AdvSendAdvertisements) {
zif->rtadv.AdvSendAdvertisements = 1;
zif->rtadv.AdvIntervalTimer = 0;
- zvrf->rtadv.adv_if_count++;
+ zrouter.rtadv.adv_if_count++;
if (zif->rtadv.MaxRtrAdvInterval >= 1000) {
/* Enable Fast RA only when RA interval is in
@@ -910,11 +907,11 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
RTADV_NUM_FAST_REXMITS;
}
- if_join_all_router(rtadv_get_socket(zvrf), ifp);
+ if_join_all_router(zrouter.rtadv.sock, ifp);
- if (zvrf->rtadv.adv_if_count == 1)
- rtadv_event(zvrf, RTADV_START,
- rtadv_get_socket(zvrf));
+ if (zrouter.rtadv.adv_if_count == 1)
+ rtadv_event(zns, RTADV_START,
+ zrouter.rtadv.sock);
}
}
}
@@ -947,7 +944,7 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
zebra_route_string(client->proto), ra_interval);
/* Locate interface and check VRF match. */
- ifp = if_lookup_by_index(ifindex, zvrf->vrf->vrf_id);
+ ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex);
if (!ifp) {
flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
"%u: IF %u RA %s client %s - interface unknown",
@@ -1054,9 +1051,6 @@ DEFUN (ipv6_nd_ra_interval_msec,
VTY_DECLVAR_CONTEXT(interface, ifp);
unsigned interval;
struct zebra_if *zif = ifp->info;
- struct zebra_vrf *zvrf;
-
- zvrf = vrf_info_lookup(ifp->vrf_id);
interval = strtoul(argv[idx_number]->arg, NULL, 10);
if ((zif->rtadv.AdvDefaultLifetime != -1
@@ -1067,10 +1061,10 @@ DEFUN (ipv6_nd_ra_interval_msec,
}
if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zvrf->rtadv.adv_msec_if_count--;
+ zrouter.rtadv.adv_msec_if_count--;
if (interval % 1000)
- zvrf->rtadv.adv_msec_if_count++;
+ zrouter.rtadv.adv_msec_if_count++;
SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
zif->rtadv.MaxRtrAdvInterval = interval;
@@ -1092,9 +1086,6 @@ DEFUN (ipv6_nd_ra_interval,
VTY_DECLVAR_CONTEXT(interface, ifp);
unsigned interval;
struct zebra_if *zif = ifp->info;
- struct zebra_vrf *zvrf;
-
- zvrf = vrf_info_lookup(ifp->vrf_id);
interval = strtoul(argv[idx_number]->arg, NULL, 10);
if ((zif->rtadv.AdvDefaultLifetime != -1
@@ -1105,7 +1096,7 @@ DEFUN (ipv6_nd_ra_interval,
}
if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zvrf->rtadv.adv_msec_if_count--;
+ zrouter.rtadv.adv_msec_if_count--;
/* convert to milliseconds */
interval = interval * 1000;
@@ -1131,12 +1122,9 @@ DEFUN (no_ipv6_nd_ra_interval,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zif = ifp->info;
- struct zebra_vrf *zvrf = NULL;
-
- zvrf = vrf_info_lookup(ifp->vrf_id);
if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zvrf->rtadv.adv_msec_if_count--;
+ zrouter.rtadv.adv_msec_if_count--;
UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
@@ -2106,15 +2094,15 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)
}
-static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
+static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val)
{
- struct rtadv *rtadv = &zvrf->rtadv;
+ struct rtadv *rtadv = &zrouter.rtadv;
switch (event) {
case RTADV_START:
- thread_add_read(zrouter.master, rtadv_read, zvrf, val,
+ thread_add_read(zrouter.master, rtadv_read, zns, val,
&rtadv->ra_read);
- thread_add_event(zrouter.master, rtadv_timer, zvrf, 0,
+ thread_add_event(zrouter.master, rtadv_timer, zns, 0,
&rtadv->ra_timer);
break;
case RTADV_STOP:
@@ -2128,15 +2116,15 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
}
break;
case RTADV_TIMER:
- thread_add_timer(zrouter.master, rtadv_timer, zvrf, val,
+ thread_add_timer(zrouter.master, rtadv_timer, zns, val,
&rtadv->ra_timer);
break;
case RTADV_TIMER_MSEC:
- thread_add_timer_msec(zrouter.master, rtadv_timer, zvrf, val,
+ thread_add_timer_msec(zrouter.master, rtadv_timer, zns, val,
&rtadv->ra_timer);
break;
case RTADV_READ:
- thread_add_read(zrouter.master, rtadv_read, zvrf, val,
+ thread_add_read(zrouter.master, rtadv_read, zns, val,
&rtadv->ra_read);
break;
default:
@@ -2145,29 +2133,21 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
return;
}
-void rtadv_init(struct zebra_vrf *zvrf)
+void rtadv_init(struct zebra_ns *zns)
{
- if (vrf_is_backend_netns()) {
- zvrf->rtadv.sock = rtadv_make_socket(zvrf->zns->ns_id);
- zrouter.rtadv_sock = -1;
- } else if (!zrouter.rtadv_sock) {
- zvrf->rtadv.sock = -1;
- zrouter.rtadv_sock = rtadv_make_socket(zvrf->zns->ns_id);
- }
+ zrouter.rtadv.sock = rtadv_make_socket(zns->ns_id);
}
-void rtadv_terminate(struct zebra_vrf *zvrf)
+void rtadv_terminate(struct zebra_ns *zns)
{
- rtadv_event(zvrf, RTADV_STOP, 0);
- if (zvrf->rtadv.sock >= 0) {
- close(zvrf->rtadv.sock);
- zvrf->rtadv.sock = -1;
- } else if (zrouter.rtadv_sock >= 0) {
- close(zrouter.rtadv_sock);
- zrouter.rtadv_sock = -1;
+ rtadv_event(zns, RTADV_STOP, 0);
+ if (zrouter.rtadv.sock >= 0) {
+ close(zrouter.rtadv.sock);
+ zrouter.rtadv.sock = -1;
}
- zvrf->rtadv.adv_if_count = 0;
- zvrf->rtadv.adv_msec_if_count = 0;
+
+ zrouter.rtadv.adv_if_count = 0;
+ zrouter.rtadv.adv_msec_if_count = 0;
}
void rtadv_cmd_init(void)
@@ -2263,11 +2243,11 @@ static int if_leave_all_router(int sock, struct interface *ifp)
}
#else
-void rtadv_init(struct zebra_vrf *zvrf)
+void rtadv_init(struct zebra_ns *zns)
{
/* Empty.*/;
}
-void rtadv_terminate(struct zebra_vrf *zvrf)
+void rtadv_terminate(struct zebra_ns *zns)
{
/* Empty.*/;
}
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index 8ad3de7f17..53c497fc09 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -135,8 +135,8 @@ typedef enum {
RA_SUPPRESS,
} ipv6_nd_suppress_ra_status;
-extern void rtadv_init(struct zebra_vrf *);
-extern void rtadv_terminate(struct zebra_vrf *);
+extern void rtadv_init(struct zebra_ns *);
+extern void rtadv_terminate(struct zebra_ns *);
extern void rtadv_cmd_init(void);
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 974cc9de30..03b9653ce6 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1339,14 +1339,14 @@ static void zread_interface_delete(ZAPI_HANDLER_ARGS)
void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
const unsigned int nexthop_num)
{
- if (nexthop_num > multipath_num) {
+ if (nexthop_num > zrouter.multipath_num) {
char buff[PREFIX2STR_BUFFER];
prefix2str(p, buff, sizeof(buff));
flog_warn(
EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
"%s: Prefix %s has %d nexthops, but we can only use the first %d",
- caller, buff, nexthop_num, multipath_num);
+ caller, buff, nexthop_num, zrouter.multipath_num);
}
}
@@ -1651,7 +1651,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id);
stream_putl(s, vrf_get_backend());
stream_putc(s, mpls_enabled);
- stream_putl(s, multipath_num);
+ stream_putl(s, zrouter.multipath_num);
stream_putc(s, zebra_mlag_get_role());
stream_putw_at(s, 0, stream_get_endp(s));
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index 16459b606a..065bdee208 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -32,6 +32,7 @@
#include "prefix.h"
#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/zebra_dplane.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
@@ -251,7 +252,7 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
ri->metric = &re->metric;
for (ALL_NEXTHOPS(re->ng, nexthop)) {
- if (ri->num_nhs >= multipath_num)
+ if (ri->num_nhs >= zrouter.multipath_num)
break;
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c
index 0f95c9ba8b..3054b8a34d 100644
--- a/zebra/zebra_fpm_protobuf.c
+++ b/zebra/zebra_fpm_protobuf.c
@@ -34,6 +34,7 @@
#include "qpb/linear_allocator.h"
#include "fpm/fpm_pb.h"
+#include "zebra_router.h"
#include "zebra_fpm_private.h"
/*
@@ -173,7 +174,7 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
*/
num_nhs = 0;
for (ALL_NEXTHOPS(re->ng, nexthop)) {
- if (num_nhs >= multipath_num)
+ if (num_nhs >= zrouter.multipath_num)
break;
if (num_nhs >= array_size(nexthops))
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index f1082a5996..5356a7f498 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -76,7 +76,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
uint32_t label_index);
static int fec_del(zebra_fec_t *fec);
-static unsigned int label_hash(void *p);
+static unsigned int label_hash(const void *p);
static bool label_cmp(const void *p1, const void *p2);
static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
struct nexthop *nexthop);
@@ -577,7 +577,7 @@ static int fec_del(zebra_fec_t *fec)
/*
* Hash function for label.
*/
-static unsigned int label_hash(void *p)
+static unsigned int label_hash(const void *p)
{
const zebra_ile_t *ile = p;
diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c
index 977a8eaf3c..e7fdaf127d 100644
--- a/zebra/zebra_mpls_openbsd.c
+++ b/zebra/zebra_mpls_openbsd.c
@@ -27,6 +27,7 @@
#include "zebra/zebra_mpls.h"
#include "zebra/debug.h"
#include "zebra/zebra_errors.h"
+#include "zebra/zebra_router.h"
#include "privs.h"
#include "prefix.h"
@@ -262,7 +263,7 @@ static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
if (!nexthop)
continue;
- if (nexthop_num >= multipath_num)
+ if (nexthop_num >= zrouter.multipath_num)
break;
if (((action == RTM_ADD || action == RTM_CHANGE)
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index db4f9d0015..0c743d8678 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -27,6 +27,7 @@
#include "lib/prefix.h"
#include "lib/memory.h"
+#include "rtadv.h"
#include "zebra_ns.h"
#include "zebra_vrf.h"
#include "zebra_memory.h"
@@ -121,6 +122,10 @@ int zebra_ns_enable(ns_id_t ns_id, void **info)
zns->ns_id = ns_id;
+#if defined(HAVE_RTADV)
+ rtadv_init(zns);
+#endif
+
kernel_init(zns);
interface_list(zns);
route_read(zns);
@@ -137,6 +142,9 @@ int zebra_ns_enable(ns_id_t ns_id, void **info)
static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete)
{
route_table_finish(zns->if_table);
+#if defined(HAVE_RTADV)
+ rtadv_terminate(zns);
+#endif
kernel_terminate(zns, complete);
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 73db567eac..a82dd4c24a 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -135,12 +135,12 @@ void zebra_pbr_rules_free(void *arg)
XFREE(MTYPE_TMP, rule);
}
-uint32_t zebra_pbr_rules_hash_key(void *arg)
+uint32_t zebra_pbr_rules_hash_key(const void *arg)
{
- struct zebra_pbr_rule *rule;
+ const struct zebra_pbr_rule *rule;
uint32_t key;
- rule = (struct zebra_pbr_rule *)arg;
+ rule = arg;
key = jhash_3words(rule->rule.seq, rule->rule.priority,
rule->rule.action.table,
prefix_hash_key(&rule->rule.filter.src_ip));
@@ -250,9 +250,9 @@ void zebra_pbr_ipset_free(void *arg)
XFREE(MTYPE_TMP, ipset);
}
-uint32_t zebra_pbr_ipset_hash_key(void *arg)
+uint32_t zebra_pbr_ipset_hash_key(const void *arg)
{
- struct zebra_pbr_ipset *ipset = (struct zebra_pbr_ipset *)arg;
+ const struct zebra_pbr_ipset *ipset = arg;
uint32_t *pnt = (uint32_t *)&ipset->ipset_name;
uint32_t key = jhash_1word(ipset->vrf_id, 0x63ab42de);
@@ -290,12 +290,12 @@ void zebra_pbr_ipset_entry_free(void *arg)
XFREE(MTYPE_TMP, ipset);
}
-uint32_t zebra_pbr_ipset_entry_hash_key(void *arg)
+uint32_t zebra_pbr_ipset_entry_hash_key(const void *arg)
{
- struct zebra_pbr_ipset_entry *ipset;
+ const struct zebra_pbr_ipset_entry *ipset;
uint32_t key;
- ipset = (struct zebra_pbr_ipset_entry *)arg;
+ ipset = arg;
key = prefix_hash_key(&ipset->src);
key = jhash_1word(ipset->unique, key);
key = jhash_1word(prefix_hash_key(&ipset->dst), key);
@@ -359,9 +359,9 @@ void zebra_pbr_iptable_free(void *arg)
XFREE(MTYPE_TMP, iptable);
}
-uint32_t zebra_pbr_iptable_hash_key(void *arg)
+uint32_t zebra_pbr_iptable_hash_key(const void *arg)
{
- struct zebra_pbr_iptable *iptable = (struct zebra_pbr_iptable *)arg;
+ const struct zebra_pbr_iptable *iptable = arg;
uint32_t *pnt = (uint32_t *)&(iptable->ipset_name);
uint32_t key;
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 0d55491107..cc1cc5acd5 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -211,7 +211,7 @@ extern void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable *iptable,
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 uint32_t zebra_pbr_rules_hash_key(const void *arg);
extern bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
/* has operates on 32bit pointer
@@ -220,16 +220,16 @@ extern bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
#define ZEBRA_IPSET_NAME_HASH_SIZE (ZEBRA_IPSET_NAME_SIZE / 4)
extern void zebra_pbr_ipset_free(void *arg);
-extern uint32_t zebra_pbr_ipset_hash_key(void *arg);
+extern uint32_t zebra_pbr_ipset_hash_key(const void *arg);
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 uint32_t zebra_pbr_ipset_entry_hash_key(const void *arg);
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 uint32_t zebra_pbr_iptable_hash_key(const void *arg);
extern bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2);
extern void zebra_pbr_init(void);
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index d3ecd3695a..46f1385520 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -93,6 +93,7 @@ const char ZEBRA_PTM_BFD_IFNAME_FIELD[] = "ifName";
const char ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD[] = "maxHopCnt";
const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent";
const char ZEBRA_PTM_BFD_VRF_NAME_FIELD[] = "vrfName";
+const char ZEBRA_PTM_BFD_CBIT_FIELD[] = "bfdcbit";
static ptm_lib_handle_t *ptm_hdl;
@@ -688,6 +689,7 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS)
char tmp_buf[64];
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
unsigned int pid;
+ uint8_t cbit_set;
if (hdr->command == ZEBRA_BFD_DEST_UPDATE)
client->bfd_peer_upd8_cnt++;
@@ -813,6 +815,10 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS)
ptm_lib_append_msg(ptm_hdl, out_ctxt,
ZEBRA_PTM_BFD_IFNAME_FIELD, if_name);
}
+ STREAM_GETC(s, cbit_set);
+ sprintf(tmp_buf, "%d", cbit_set);
+ ptm_lib_append_msg(ptm_hdl, out_ctxt,
+ ZEBRA_PTM_BFD_CBIT_FIELD, tmp_buf);
sprintf(tmp_buf, "%d", 1);
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT,
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index eddf6c8158..8d4f49e3ee 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -955,7 +955,8 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re)
* decision point.
*/
new_active = nexthop_active_check(rn, re, nexthop);
- if (new_active && re->nexthop_active_num >= multipath_num) {
+ if (new_active
+ && re->nexthop_active_num >= zrouter.multipath_num) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
new_active = 0;
}
@@ -3207,18 +3208,23 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
+ struct other_route_table *ort;
unsigned long cnt = 0;
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
- if ((zvrf = vrf->info) != NULL)
- cnt += rib_score_proto_table(
- proto, instance,
- zvrf->table[AFI_IP][SAFI_UNICAST])
- + rib_score_proto_table(
- proto, instance,
- zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ zvrf = vrf->info;
+ if (!zvrf)
+ continue;
- cnt += zebra_router_score_proto(proto, instance);
+ cnt += rib_score_proto_table(proto, instance,
+ zvrf->table[AFI_IP][SAFI_UNICAST])
+ + rib_score_proto_table(
+ proto, instance,
+ zvrf->table[AFI_IP6][SAFI_UNICAST]);
+
+ for_each(otable, &zvrf->other_tables, ort) cnt +=
+ rib_score_proto_table(proto, instance, ort->table);
+ }
return cnt;
}
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 5355fa062e..f48bf3b033 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -705,6 +705,9 @@ DEFPY (ip_protocol,
{
int ret, rtype;
+ assert(proto);
+ assert(rmap);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -737,6 +740,8 @@ DEFPY (no_ip_protocol,
{
int ret, rtype;
+ assert(proto);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -781,6 +786,9 @@ DEFPY (ipv6_protocol,
{
int ret, rtype;
+ assert(rmap);
+ assert(proto);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -813,6 +821,8 @@ DEFPY (no_ipv6_protocol,
{
int ret, rtype;
+ assert(proto);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -858,6 +868,9 @@ DEFPY (ip_protocol_nht_rmap,
int ret, rtype;
+ assert(proto);
+ assert(rmap);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -890,6 +903,8 @@ DEFPY (no_ip_protocol_nht_rmap,
{
int ret, rtype;
+ assert(proto);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -935,6 +950,9 @@ DEFPY (ipv6_protocol_nht_rmap,
{
int ret, rtype;
+ assert(rmap);
+ assert(proto);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
@@ -967,6 +985,8 @@ DEFPY (no_ipv6_protocol_nht_rmap,
{
int ret, rtype;
+ assert(proto);
+
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
if (!zvrf)
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 63724fc350..610d51d3ea 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -30,7 +30,9 @@
#include "zebra_vxlan.h"
#include "zebra_mlag.h"
-struct zebra_router zrouter;
+struct zebra_router zrouter = {
+ .multipath_num = MULTIPATH_NUM,
+};
static inline int
zebra_router_table_entry_compare(const struct zebra_router_table *e1,
@@ -117,19 +119,6 @@ struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
return zrt->table;
}
-unsigned long zebra_router_score_proto(uint8_t proto, unsigned short instance)
-{
- struct zebra_router_table *zrt;
- unsigned long cnt = 0;
-
- RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
- if (zrt->ns_id != NS_DEFAULT)
- continue;
- cnt += rib_score_proto_table(proto, instance, zrt->table);
- }
- return cnt;
-}
-
void zebra_router_show_table_summary(struct vty *vty)
{
struct zebra_router_table *zrt;
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index c1f07397d0..b3def297ac 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -82,8 +82,9 @@ struct zebra_router {
struct hash *iptable_hash;
- /* used if vrf backend is not network namespace */
- int rtadv_sock;
+#if defined(HAVE_RTADV)
+ struct rtadv rtadv;
+#endif /* HAVE_RTADV */
/* A sequence number used for tracking routes */
_Atomic uint32_t sequence_num;
@@ -109,6 +110,8 @@ struct zebra_router {
* The EVPN instance, if any
*/
struct zebra_vrf *evpn_vrf;
+
+ uint32_t multipath_num;
};
extern struct zebra_router zrouter;
@@ -127,8 +130,6 @@ extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
extern int zebra_router_config_write(struct vty *vty);
-extern unsigned long zebra_router_score_proto(uint8_t proto,
- unsigned short instance);
extern void zebra_router_sweep_route(void);
extern void zebra_router_show_table_summary(struct vty *vty);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 1f2ff63286..6343054943 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -29,7 +29,6 @@
#include "vty.h"
#include "zebra/zebra_router.h"
-#include "zebra/rtadv.h"
#include "zebra/debug.h"
#include "zebra/zapi_msg.h"
#include "zebra/rib.h"
@@ -48,6 +47,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi,
static void zebra_rnhtable_node_cleanup(struct route_table *table,
struct route_node *node);
+DEFINE_MTYPE_STATIC(ZEBRA, OTHER_TABLE, "Other Table");
+
/* VRF information update. */
static void zebra_vrf_add_update(struct zebra_vrf *zvrf)
{
@@ -94,6 +95,9 @@ static int zebra_vrf_new(struct vrf *vrf)
zvrf = zebra_vrf_alloc();
vrf->info = zvrf;
zvrf->vrf = vrf;
+
+ otable_init(&zvrf->other_tables);
+
router_id_init(zvrf);
return 0;
}
@@ -115,10 +119,6 @@ static int zebra_vrf_enable(struct vrf *vrf)
zvrf->zns = zebra_ns_lookup((ns_id_t)vrf->vrf_id);
else
zvrf->zns = zebra_ns_lookup(NS_DEFAULT);
-#if defined(HAVE_RTADV)
- rtadv_init(zvrf);
-#endif
-
/* Inform clients that the VRF is now active. This is an
* add for the clients.
*/
@@ -161,10 +161,6 @@ static int zebra_vrf_disable(struct vrf *vrf)
/* Stop any VxLAN-EVPN processing. */
zebra_vxlan_vrf_disable(zvrf);
-#if defined(HAVE_RTADV)
- rtadv_terminate(zvrf);
-#endif
-
/* Inform clients that the VRF is now inactive. This is a
* delete for the clients.
*/
@@ -235,6 +231,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
static int zebra_vrf_delete(struct vrf *vrf)
{
struct zebra_vrf *zvrf = vrf->info;
+ struct other_route_table *otable;
struct route_table *table;
afi_t afi;
safi_t safi;
@@ -283,11 +280,22 @@ static int zebra_vrf_delete(struct vrf *vrf)
route_table_finish(zvrf->import_check_table[afi]);
}
+ otable = otable_pop(&zvrf->other_tables);
+ while (otable) {
+ zebra_router_release_table(zvrf, otable->table_id,
+ otable->afi, otable->safi);
+ XFREE(MTYPE_OTHER_TABLE, otable);
+
+ otable = otable_pop(&zvrf->other_tables);
+ }
+
/* Cleanup EVPN states for vrf */
zebra_vxlan_vrf_delete(zvrf);
list_delete_all_node(zvrf->rid_all_sorted_list);
list_delete_all_node(zvrf->rid_lo_sorted_list);
+
+ otable_fini(&zvrf->other_tables);
XFREE(MTYPE_ZEBRA_VRF, zvrf);
vrf->info = NULL;
@@ -329,25 +337,34 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
vrf_id_t vrf_id,
uint32_t table_id)
{
- struct route_table *table = NULL;
+ struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id);
+ struct other_route_table ort, *otable;
+ struct route_table *table;
+
+ if (!zvrf)
+ return NULL;
if (afi >= AFI_MAX || safi >= SAFI_MAX)
return NULL;
- if (vrf_id == VRF_DEFAULT) {
- if (table_id == RT_TABLE_MAIN)
- table = zebra_vrf_table(afi, safi, vrf_id);
- else
- table = zebra_vrf_other_route_table(afi, table_id,
- vrf_id);
- } else if (vrf_is_backend_netns()) {
- if (table_id == RT_TABLE_MAIN)
- table = zebra_vrf_table(afi, safi, vrf_id);
- else
- table = zebra_vrf_other_route_table(afi, table_id,
- vrf_id);
- } else
- table = zebra_vrf_table(afi, safi, vrf_id);
+ if (table_id == zvrf->table_id)
+ return zebra_vrf_table(afi, safi, vrf_id);
+
+ ort.afi = afi;
+ ort.safi = safi;
+ ort.table_id = table_id;
+ otable = otable_find(&zvrf->other_tables, &ort);
+ if (otable)
+ return otable->table;
+
+ table = zebra_router_get_table(zvrf, table_id, afi, safi);
+
+ otable = XCALLOC(MTYPE_OTHER_TABLE, sizeof(*otable));
+ otable->afi = afi;
+ otable->safi = safi;
+ otable->table_id = table_id;
+ otable->table = table;
+ otable_add(&zvrf->other_tables, otable);
return table;
}
@@ -447,32 +464,6 @@ struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id)
return zvrf->table[afi][safi];
}
-struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id,
- vrf_id_t vrf_id)
-{
- struct zebra_vrf *zvrf;
-
- zvrf = vrf_info_lookup(vrf_id);
- if (!zvrf)
- return NULL;
-
- if (afi >= AFI_MAX)
- return NULL;
-
- if (table_id != RT_TABLE_MAIN) {
- if (zvrf->table_id == RT_TABLE_MAIN) {
- /* this VRF use default table
- * so in all cases, it does not use specific table
- * so it is possible to configure tables in this VRF
- */
- return zebra_router_get_table(zvrf, table_id, afi,
- SAFI_UNICAST);
- }
- }
-
- return zvrf->table[afi][SAFI_UNICAST];
-}
-
static int vrf_config_write(struct vty *vty)
{
struct vrf *vrf;
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 2dd47b5561..febaf3c844 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -43,6 +43,18 @@ struct zebra_rmap {
struct route_map *map;
};
+PREDECL_RBTREE_UNIQ(otable);
+
+struct other_route_table {
+ struct otable_item next;
+
+ afi_t afi;
+ safi_t safi;
+ uint32_t table_id;
+
+ struct route_table *table;
+};
+
/* Routing table instance. */
struct zebra_vrf {
/* Back pointer */
@@ -69,6 +81,8 @@ struct zebra_vrf {
/* Import check table (used mostly by BGP */
struct route_table *import_check_table[AFI_MAX];
+ struct otable_head other_tables;
+
/* 2nd pointer type used primarily to quell a warning on
* ALL_LIST_ELEMENTS_RO
*/
@@ -155,10 +169,6 @@ struct zebra_vrf {
uint64_t lsp_removals_queued;
uint64_t lsp_installs;
uint64_t lsp_removals;
-
-#if defined(HAVE_RTADV)
- struct rtadv rtadv;
-#endif /* HAVE_RTADV */
};
#define PROTO_RM_NAME(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].name
#define NHT_RM_NAME(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].name
@@ -196,6 +206,25 @@ static inline bool zvrf_is_active(struct zebra_vrf *zvrf)
return zvrf->vrf->status & VRF_ACTIVE;
}
+static inline int
+zvrf_other_table_compare_func(const struct other_route_table *a,
+ const struct other_route_table *b)
+{
+ if (a->afi != b->afi)
+ return a->afi - b->afi;
+
+ if (a->safi != b->safi)
+ return a->safi - b->safi;
+
+ if (a->table_id != b->table_id)
+ return a->table_id - b->table_id;
+
+ return 0;
+}
+
+DECLARE_RBTREE_UNIQ(otable, struct other_route_table, next,
+ zvrf_other_table_compare_func)
+
struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
vrf_id_t vrf_id,
uint32_t table_id);
@@ -206,8 +235,6 @@ extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *);
extern struct zebra_vrf *zebra_vrf_alloc(void);
extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t);
-extern struct route_table *
-zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, vrf_id_t vrf_id);
extern int zebra_vrf_has_config(struct zebra_vrf *zvrf);
extern void zebra_vrf_init(void);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 605e9eae66..feb0aadfa8 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -93,7 +93,7 @@ static void zvni_print_hash(struct hash_bucket *bucket, void *ctxt[]);
static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
struct ipaddr *ip, uint8_t flags,
uint32_t seq, int state, uint16_t cmd);
-static unsigned int neigh_hash_keymake(void *p);
+static unsigned int neigh_hash_keymake(const void *p);
static void *zvni_neigh_alloc(void *p);
static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
struct ethaddr *mac);
@@ -149,7 +149,7 @@ static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni);
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 unsigned int mac_hash_keymake(const void *p);
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);
@@ -168,7 +168,7 @@ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac);
static void zvni_install_mac_hash(struct hash_bucket *bucket, void *ctxt);
-static unsigned int vni_hash_keymake(void *p);
+static unsigned int vni_hash_keymake(const void *p);
static void *zvni_alloc(void *p);
static zebra_vni_t *zvni_lookup(vni_t vni);
static zebra_vni_t *zvni_add(vni_t vni);
@@ -213,7 +213,7 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
bool do_dad,
bool *is_dup_detect,
bool is_local);
-static unsigned int zebra_vxlan_sg_hash_key_make(void *p);
+static unsigned int zebra_vxlan_sg_hash_key_make(const void *p);
static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2);
static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf,
struct in_addr sip, struct in_addr mcast_grp);
@@ -2158,10 +2158,10 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
/*
* Make hash key for neighbors.
*/
-static unsigned int neigh_hash_keymake(void *p)
+static unsigned int neigh_hash_keymake(const void *p)
{
- zebra_neigh_t *n = p;
- struct ipaddr *ip = &n->ip;
+ const zebra_neigh_t *n = p;
+ const struct ipaddr *ip = &n->ip;
if (IS_IPADDR_V4(ip))
return jhash_1word(ip->ipaddr_v4.s_addr, 0);
@@ -3296,9 +3296,9 @@ static int zvni_remote_neigh_update(zebra_vni_t *zvni,
/*
* Make hash key for MAC.
*/
-static unsigned int mac_hash_keymake(void *p)
+static unsigned int mac_hash_keymake(const void *p)
{
- zebra_mac_t *pmac = p;
+ const zebra_mac_t *pmac = p;
const void *pnt = (void *)pmac->macaddr.octet;
return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
@@ -3815,7 +3815,7 @@ static void zvni_read_mac_neigh(zebra_vni_t *zvni, struct interface *ifp)
/*
* Hash function for VNI.
*/
-static unsigned int vni_hash_keymake(void *p)
+static unsigned int vni_hash_keymake(const void *p)
{
const zebra_vni_t *zvni = p;
@@ -4688,7 +4688,7 @@ static int zl3vni_local_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *ip)
/*
* Hash function for L3 VNI.
*/
-static unsigned int l3vni_hash_keymake(void *p)
+static unsigned int l3vni_hash_keymake(const void *p)
{
const zebra_l3vni_t *zl3vni = p;
@@ -9457,9 +9457,9 @@ static int zebra_vxlan_sg_send(struct prefix_sg *sg,
return zserv_send_message(client, s);
}
-static unsigned int zebra_vxlan_sg_hash_key_make(void *p)
+static unsigned int zebra_vxlan_sg_hash_key_make(const void *p)
{
- zebra_vxlan_sg_t *vxlan_sg = p;
+ const zebra_vxlan_sg_t *vxlan_sg = p;
return (jhash_2words(vxlan_sg->sg.src.s_addr,
vxlan_sg->sg.grp.s_addr, 0));
diff --git a/zebra/zserv.h b/zebra/zserv.h
index d6fdc05374..34965618f2 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -173,8 +173,6 @@ struct zserv {
DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client));
DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client));
-extern unsigned int multipath_num;
-
/*
* Initialize Zebra API server.
*