summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_interface.c7
-rw-r--r--bfdd/bfd.c543
-rw-r--r--bfdd/bfd.h59
-rw-r--r--bfdd/bfd_packet.c62
-rw-r--r--bfdd/bfdd_vty.c112
-rw-r--r--bfdd/config.c48
-rw-r--r--bfdd/control.c25
-rw-r--r--bfdd/ptm_adapter.c133
-rw-r--r--bgpd/bgp_advertise.c10
-rw-r--r--bgpd/bgp_aspath.c6
-rw-r--r--bgpd/bgp_attr.c6
-rw-r--r--bgpd/bgp_attr_evpn.c4
-rw-r--r--bgpd/bgp_clist.c9
-rw-r--r--bgpd/bgp_community.c9
-rw-r--r--bgpd/bgp_ecommunity.c9
-rw-r--r--bgpd/bgp_encap_tlv.c3
-rw-r--r--bgpd/bgp_evpn.c10
-rw-r--r--bgpd/bgp_evpn_vty.c3
-rw-r--r--bgpd/bgp_filter.c6
-rw-r--r--bgpd/bgp_fsm.c6
-rw-r--r--bgpd/bgp_labelpool.c6
-rw-r--r--bgpd/bgp_lcommunity.c17
-rw-r--r--bgpd/bgp_mpath.c2
-rw-r--r--bgpd/bgp_pbr.c6
-rw-r--r--bgpd/bgp_rd.c3
-rw-r--r--bgpd/bgp_route.c43
-rw-r--r--bgpd/bgp_routemap.c67
-rw-r--r--bgpd/bgp_snmp.c14
-rw-r--r--bgpd/bgp_updgrp.c36
-rw-r--r--bgpd/bgp_updgrp_packet.c3
-rw-r--r--bgpd/bgp_vty.c176
-rw-r--r--bgpd/bgp_zebra.c9
-rw-r--r--bgpd/bgpd.c52
-rw-r--r--bgpd/bgpd.h3
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c9
-rw-r--r--bgpd/rfapi/rfapi_import.c2
-rw-r--r--bgpd/rfapi/vnc_debug.c2
-rw-r--r--bgpd/rfapi/vnc_zebra.c12
-rwxr-xr-xconfigure.ac2
-rw-r--r--doc/user/installation.rst3
-rw-r--r--eigrpd/eigrp_fsm.c2
-rw-r--r--eigrpd/eigrp_hello.c4
-rw-r--r--eigrpd/eigrp_vty.c4
-rw-r--r--isisd/dict.c8
-rw-r--r--isisd/isis_adjacency.c9
-rw-r--r--isisd/isis_dlpi.c2
-rw-r--r--isisd/isis_main.c2
-rw-r--r--isisd/isis_pdu.c16
-rw-r--r--isisd/isis_redist.c3
-rw-r--r--isisd/isis_tlvs.c5
-rw-r--r--lib/command.c45
-rw-r--r--lib/command_graph.c2
-rw-r--r--lib/distribute.c27
-rw-r--r--lib/filter.c12
-rw-r--r--lib/frr_pthread.c3
-rw-r--r--lib/frr_zmq.c4
-rw-r--r--lib/frrstr.c4
-rw-r--r--lib/hash.c5
-rw-r--r--lib/if.c12
-rw-r--r--lib/if_rmap.c23
-rw-r--r--lib/imsg.c3
-rw-r--r--lib/jhash.c4
-rw-r--r--lib/keychain.c6
-rw-r--r--lib/libfrr.c2
-rw-r--r--lib/log.c6
-rw-r--r--lib/module.c3
-rw-r--r--lib/netns_linux.c3
-rw-r--r--lib/nexthop_group.c6
-rw-r--r--lib/northbound.c94
-rw-r--r--lib/northbound_confd.c2
-rw-r--r--lib/plist.c6
-rw-r--r--lib/pqueue.c2
-rw-r--r--lib/prefix.c9
-rw-r--r--lib/privs.c19
-rw-r--r--lib/privs.h10
-rw-r--r--lib/routemap.c15
-rw-r--r--lib/thread.c8
-rw-r--r--lib/vty.c21
-rw-r--r--lib/workqueue.c2
-rw-r--r--lib/yang_wrappers.c2
-rw-r--r--nhrpd/netlink_arp.c4
-rw-r--r--ospf6d/ospf6_interface.c3
-rw-r--r--ospf6d/ospf6_lsa.c13
-rw-r--r--ospf6d/ospf6_lsdb.c4
-rw-r--r--ospf6d/ospf6_message.c6
-rw-r--r--ospf6d/ospf6_neighbor.c5
-rw-r--r--ospf6d/ospf6_route.c3
-rw-r--r--ospf6d/ospf6_snmp.c22
-rw-r--r--ospf6d/ospf6_spf.c6
-rw-r--r--ospfd/ospf_asbr.c3
-rw-r--r--ospfd/ospf_ism.c4
-rw-r--r--ospfd/ospf_snmp.c34
-rw-r--r--ospfd/ospf_vty.c26
-rw-r--r--ospfd/ospf_zebra.c6
-rw-r--r--pbrd/pbr_map.c3
-rw-r--r--pbrd/pbr_nht.c2
-rw-r--r--pimd/pim_cmd.c14
-rw-r--r--pimd/pim_iface.c3
-rw-r--r--pimd/pim_main.c2
-rw-r--r--pimd/pim_msdp.c3
-rw-r--r--pimd/pim_rp.c3
-rw-r--r--pimd/pim_ssm.c3
-rw-r--r--ripd/rip_cli.c17
-rw-r--r--ripd/rip_interface.c6
-rw-r--r--ripd/rip_northbound.c6
-rw-r--r--sharpd/sharp_globals.h1
-rw-r--r--sharpd/sharp_vty.c69
-rw-r--r--sharpd/sharp_zebra.c33
-rw-r--r--sharpd/sharp_zebra.h19
-rw-r--r--staticd/static_vty.c36
-rw-r--r--tests/bgpd/test_bgp_table.c2
-rw-r--r--tests/bgpd/test_mpath.c7
-rw-r--r--tests/lib/test_privs.c2
-rw-r--r--tests/lib/test_srcdest_table.c2
-rw-r--r--tests/lib/test_table.c2
-rw-r--r--tests/topotests/bfd-topo2/__init__.py0
-rw-r--r--tests/topotests/bfd-topo2/r1/bfdd.conf5
-rw-r--r--tests/topotests/bfd-topo2/r1/bgpd.conf13
-rw-r--r--tests/topotests/bfd-topo2/r1/ipv4_routes.json68
-rw-r--r--tests/topotests/bfd-topo2/r1/ipv6_routes.json63
-rw-r--r--tests/topotests/bfd-topo2/r1/peers.json29
-rw-r--r--tests/topotests/bfd-topo2/r1/zebra.conf6
-rw-r--r--tests/topotests/bfd-topo2/r2/bgpd.conf16
-rw-r--r--tests/topotests/bfd-topo2/r2/ipv4_routes.json108
-rw-r--r--tests/topotests/bfd-topo2/r2/ipv6_routes.json63
-rw-r--r--tests/topotests/bfd-topo2/r2/ospf6d.conf9
-rw-r--r--tests/topotests/bfd-topo2/r2/ospfd.conf9
-rw-r--r--tests/topotests/bfd-topo2/r2/peers.json42
-rw-r--r--tests/topotests/bfd-topo2/r2/zebra.conf15
-rw-r--r--tests/topotests/bfd-topo2/r3/ipv4_routes.json109
-rw-r--r--tests/topotests/bfd-topo2/r3/ipv6_routes.json2
-rw-r--r--tests/topotests/bfd-topo2/r3/ospfd.conf8
-rw-r--r--tests/topotests/bfd-topo2/r3/peers.json16
-rw-r--r--tests/topotests/bfd-topo2/r3/zebra.conf6
-rw-r--r--tests/topotests/bfd-topo2/r4/bfdd.conf5
-rw-r--r--tests/topotests/bfd-topo2/r4/ipv4_routes.json24
-rw-r--r--tests/topotests/bfd-topo2/r4/ipv6_routes.json63
-rw-r--r--tests/topotests/bfd-topo2/r4/ospf6d.conf8
-rw-r--r--tests/topotests/bfd-topo2/r4/peers.json29
-rw-r--r--tests/topotests/bfd-topo2/r4/zebra.conf6
-rw-r--r--tests/topotests/bfd-topo2/test_bfd_topo2.dot73
-rw-r--r--tests/topotests/bfd-topo2/test_bfd_topo2.jpgbin0 -> 24206 bytes
-rw-r--r--tests/topotests/bfd-topo2/test_bfd_topo2.py191
-rw-r--r--tools/coccinelle/alloc_cast.cocci101
-rw-r--r--tools/coccinelle/array_size.cocci83
-rw-r--r--tools/coccinelle/badty.cocci76
-rw-r--r--tools/coccinelle/badzero.cocci238
-rw-r--r--tools/coccinelle/boolconv.cocci90
-rw-r--r--tools/coccinelle/boolinit.cocci194
-rw-r--r--tools/coccinelle/boolreturn.cocci59
-rw-r--r--tools/coccinelle/cond_no_effect.cocci64
-rw-r--r--tools/coccinelle/deref_null.cocci282
-rw-r--r--tools/coccinelle/double_lock.cocci92
-rw-r--r--tools/coccinelle/doublebitand.cocci54
-rw-r--r--tools/coccinelle/doubleinit.cocci53
-rw-r--r--tools/coccinelle/doubletest.cocci58
-rw-r--r--tools/coccinelle/ifaddr.cocci34
-rw-r--r--tools/coccinelle/ifnullxfree.cocci15
-rw-r--r--tools/coccinelle/itnull.cocci94
-rw-r--r--tools/coccinelle/mini_lock.cocci98
-rw-r--r--tools/coccinelle/noderef.cocci81
-rw-r--r--tools/coccinelle/replace-strncpy.cocci8
-rw-r--r--tools/coccinelle/returnvar.cocci66
-rw-r--r--tools/coccinelle/semicolon.cocci83
-rw-r--r--tools/coccinelle/strncpy_truncation.cocci41
-rw-r--r--tools/coccinelle/unsigned_lesser_than_zero.cocci75
-rw-r--r--tools/coccinelle/vty_check.cocci (renamed from tools/vty_check.cocci)0
-rw-r--r--tools/coccinelle/vty_index.cocci (renamed from tools/vty_index.cocci)0
-rw-r--r--tools/coccinelle/xcalloc-simple.cocci52
-rw-r--r--tools/coccinelle/xfree.cocci122
-rw-r--r--tools/coccinelle/xfreeaddr.cocci33
-rw-r--r--tools/coccinelle/xmalloc_returnval.cocci37
-rw-r--r--tools/coccinelle/zprivs.cocci (renamed from tools/zprivs.cocci)0
-rw-r--r--vtysh/vtysh_config.c3
-rw-r--r--vtysh/vtysh_user.c2
-rw-r--r--zebra/connected.c2
-rw-r--r--zebra/if_netlink.c3
-rw-r--r--zebra/rt_netlink.c126
-rw-r--r--zebra/zebra_dplane.c77
-rw-r--r--zebra/zebra_dplane.h9
-rw-r--r--zebra/zebra_mpls.c21
-rw-r--r--zebra/zebra_mpls_openbsd.c10
-rw-r--r--zebra/zebra_pbr.c2
-rw-r--r--zebra/zebra_ptm.c2
-rw-r--r--zebra/zebra_rib.c3
-rw-r--r--zebra/zebra_routemap.c6
-rw-r--r--zebra/zebra_router.c21
-rw-r--r--zebra/zebra_router.h2
-rw-r--r--zebra/zebra_vrf.c16
-rw-r--r--zebra/zebra_vty.c5
-rw-r--r--zebra/zebra_vxlan.c69
191 files changed, 4568 insertions, 1406 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c
index 79242f5b85..0ff89abc49 100644
--- a/babeld/babel_interface.c
+++ b/babeld/babel_interface.c
@@ -1414,12 +1414,7 @@ static babel_interface_nfo *
babel_interface_allocate (void)
{
babel_interface_nfo *babel_ifp;
- babel_ifp = XMALLOC(MTYPE_BABEL_IF, sizeof(babel_interface_nfo));
- if(babel_ifp == NULL)
- return NULL;
-
- /* Here are set the default values for an interface. */
- memset(babel_ifp, 0, sizeof(babel_interface_nfo));
+ babel_ifp = XCALLOC(MTYPE_BABEL_IF, sizeof(babel_interface_nfo));
/* All flags are unset */
babel_ifp->bucket_time = babel_now.tv_sec;
babel_ifp->bucket = BUCKET_TOKENS_MAX;
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index afd5d814a0..c8adf82a83 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -36,7 +36,9 @@ DEFINE_QOBJ_TYPE(bfd_session);
/*
* Prototypes
*/
-static struct bfd_session *bs_peer_waiting_find(struct bfd_peer_cfg *bpc);
+void gen_bfd_key(struct bfd_key *key, struct sockaddr_any *peer,
+ struct sockaddr_any *local, bool mhop, const char *ifname,
+ const char *vrfname);
static uint32_t ptm_bfd_gen_ID(void);
static void ptm_bfd_echo_xmt_TO(struct bfd_session *bfd);
@@ -52,66 +54,47 @@ static void bs_down_handler(struct bfd_session *bs, int nstate);
static void bs_init_handler(struct bfd_session *bs, int nstate);
static void bs_up_handler(struct bfd_session *bs, int nstate);
+/* Zeroed array with the size of an IPv6 address. */
+struct in6_addr zero_addr;
/*
* Functions
*/
-static struct bfd_session *bs_peer_waiting_find(struct bfd_peer_cfg *bpc)
+void gen_bfd_key(struct bfd_key *key, struct sockaddr_any *peer,
+ struct sockaddr_any *local, bool mhop, const char *ifname,
+ const char *vrfname)
{
- struct bfd_session_observer *bso;
- struct bfd_session *bs = NULL;
- bool is_shop, is_ipv4;
-
- TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) {
- bs = bso->bso_bs;
-
- is_shop = !BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH);
- is_ipv4 = !BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6);
- /* Quick checks first. */
- if (is_shop != (!bpc->bpc_mhop))
- continue;
- if (is_ipv4 != bpc->bpc_ipv4)
- continue;
-
- /*
- * Slow lookup without hash because we don't have all
- * information yet.
- */
- if (is_shop) {
- if (strcmp(bs->ifname, bpc->bpc_localif))
- continue;
- if (memcmp(&bs->shop.peer, &bpc->bpc_peer,
- sizeof(bs->shop.peer)))
- continue;
-
- break;
- }
-
- if (strcmp(bs->vrfname, bpc->bpc_vrfname))
- continue;
- if (memcmp(&bs->mhop.peer, &bpc->bpc_peer,
- sizeof(bs->mhop.peer)))
- continue;
- if (memcmp(&bs->mhop.local, &bpc->bpc_local,
- sizeof(bs->mhop.local)))
- continue;
+ memset(key, 0, sizeof(*key));
+ switch (peer->sa_sin.sin_family) {
+ case AF_INET:
+ key->family = AF_INET;
+ memcpy(&key->peer, &peer->sa_sin.sin_addr,
+ sizeof(peer->sa_sin.sin_addr));
+ memcpy(&key->local, &local->sa_sin.sin_addr,
+ sizeof(local->sa_sin.sin_addr));
+ break;
+ case AF_INET6:
+ key->family = AF_INET6;
+ memcpy(&key->peer, &peer->sa_sin6.sin6_addr,
+ sizeof(peer->sa_sin6.sin6_addr));
+ memcpy(&key->local, &local->sa_sin6.sin6_addr,
+ sizeof(local->sa_sin6.sin6_addr));
break;
}
- if (bso == NULL)
- bs = NULL;
- return bs;
+ key->mhop = mhop;
+ if (ifname && ifname[0])
+ strlcpy(key->ifname, ifname, sizeof(key->ifname));
+ if (vrfname && vrfname[0])
+ strlcpy(key->vrfname, vrfname, sizeof(key->vrfname));
}
struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
{
struct bfd_session *bs;
struct peer_label *pl;
- struct interface *ifp;
- struct vrf *vrf;
- struct bfd_mhop_key mhop;
- struct bfd_shop_key shop;
+ struct bfd_key key;
/* Try to find label first. */
if (bpc->bpc_has_label) {
@@ -123,38 +106,10 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
}
/* Otherwise fallback to peer/local hash lookup. */
- if (bpc->bpc_mhop) {
- memset(&mhop, 0, sizeof(mhop));
- mhop.peer = bpc->bpc_peer;
- mhop.local = bpc->bpc_local;
- if (bpc->bpc_has_vrfname) {
- vrf = vrf_lookup_by_name(bpc->bpc_vrfname);
- if (vrf == NULL)
- return NULL;
-
- mhop.vrfid = vrf->vrf_id;
- }
+ gen_bfd_key(&key, &bpc->bpc_peer, &bpc->bpc_local, bpc->bpc_mhop,
+ bpc->bpc_localif, bpc->bpc_vrfname);
- bs = bfd_mhop_lookup(mhop);
- } else {
- memset(&shop, 0, sizeof(shop));
- shop.peer = bpc->bpc_peer;
- if (bpc->bpc_has_localif) {
- ifp = if_lookup_by_name_all_vrf(bpc->bpc_localif);
- if (ifp == NULL)
- return NULL;
-
- shop.ifindex = ifp->ifindex;
- }
-
- bs = bfd_shop_lookup(shop);
- }
-
- if (bs != NULL)
- return bs;
-
- /* Search for entries that are incomplete. */
- return bs_peer_waiting_find(bpc);
+ return bfd_key_lookup(key);
}
/*
@@ -165,7 +120,6 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
*/
int bfd_session_enable(struct bfd_session *bs)
{
- struct sockaddr_in6 *sin6;
struct interface *ifp = NULL;
struct vrf *vrf = NULL;
int psock;
@@ -174,8 +128,8 @@ int bfd_session_enable(struct bfd_session *bs)
* If the interface or VRF doesn't exist, then we must register
* the session but delay its start.
*/
- if (bs->ifname[0] != 0) {
- ifp = if_lookup_by_name_all_vrf(bs->ifname);
+ if (bs->key.ifname[0]) {
+ ifp = if_lookup_by_name_all_vrf(bs->key.ifname);
if (ifp == NULL) {
log_error(
"session-enable: specified interface doesn't exists.");
@@ -184,15 +138,17 @@ int bfd_session_enable(struct bfd_session *bs)
vrf = vrf_lookup_by_id(ifp->vrf_id);
if (vrf == NULL) {
- log_error("session-enable: specified VRF doesn't exists.");
+ log_error(
+ "session-enable: specified VRF doesn't exists.");
return 0;
}
}
- if (bs->vrfname[0] != 0) {
- vrf = vrf_lookup_by_name(bs->vrfname);
+ if (bs->key.vrfname[0]) {
+ vrf = vrf_lookup_by_name(bs->key.vrfname);
if (vrf == NULL) {
- log_error("session-enable: specified VRF doesn't exists.");
+ log_error(
+ "session-enable: specified VRF doesn't exists.");
return 0;
}
}
@@ -202,26 +158,15 @@ int bfd_session_enable(struct bfd_session *bs)
if (bs->vrf == NULL)
bs->vrf = vrf_lookup_by_id(VRF_DEFAULT);
- if (bs->ifname[0] != 0 &&
- BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
+ if (bs->key.ifname[0]
+ && BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
bs->ifp = ifp;
- /* Set the IPv6 scope id for link-local addresses. */
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) {
- sin6 = &bs->mhop.peer.sa_sin6;
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
- sin6->sin6_scope_id = bs->ifp != NULL
- ? bs->ifp->ifindex
- : IFINDEX_INTERNAL;
-
- sin6 = &bs->mhop.local.sa_sin6;
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
- sin6->sin6_scope_id = bs->ifp != NULL
- ? bs->ifp->ifindex
- : IFINDEX_INTERNAL;
-
- bs->local_ip.sa_sin6 = *sin6;
- bs->local_address.sa_sin6 = *sin6;
+ /* Sanity check: don't leak open sockets. */
+ if (bs->sock != -1) {
+ zlog_debug("session-enable: previous socket open");
+ close(bs->sock);
+ bs->sock = -1;
}
/*
@@ -232,11 +177,11 @@ int bfd_session_enable(struct bfd_session *bs)
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6) == 0) {
psock = bp_peer_socket(bs);
if (psock == -1)
- return -1;
+ return 0;
} else {
psock = bp_peer_socketv6(bs);
if (psock == -1)
- return -1;
+ return 0;
}
/*
@@ -247,25 +192,6 @@ int bfd_session_enable(struct bfd_session *bs)
bfd_recvtimer_update(bs);
ptm_bfd_start_xmt_timer(bs, false);
- /* Registrate session into data structures. */
- bs->discrs.my_discr = ptm_bfd_gen_ID();
- bfd_id_insert(bs);
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
- if (vrf != NULL)
- bs->mhop.vrfid = vrf->vrf_id;
- else
- bs->mhop.vrfid = VRF_DEFAULT;
-
- bfd_mhop_insert(bs);
- } else {
- if (ifp != NULL)
- bs->shop.ifindex = ifp->ifindex;
- else
- bs->shop.ifindex = IFINDEX_INTERNAL;
-
- bfd_shop_insert(bs);
- }
-
return 0;
}
@@ -288,13 +214,6 @@ void bfd_session_disable(struct bfd_session *bs)
bfd_echo_recvtimer_delete(bs);
bfd_xmttimer_delete(bs);
bfd_echo_xmttimer_delete(bs);
-
- /* Unregister session from hashes to avoid unwanted activation. */
- bfd_id_delete(bs->discrs.my_discr);
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
- bfd_mhop_delete(bs->mhop);
- else
- bfd_shop_delete(bs->shop);
}
static uint32_t ptm_bfd_gen_ID(void)
@@ -438,21 +357,20 @@ static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
if (bs == NULL)
return NULL;
- /* Remove unused fields. */
- switch (sa->sa_sin.sin_family) {
+ switch (bs->key.family) {
case AF_INET:
- sa->sa_sin.sin_port = 0;
- if (memcmp(sa, &bs->shop.peer, sizeof(sa->sa_sin)) == 0)
- return bs;
+ if (memcmp(&sa->sa_sin.sin_addr, &bs->key.peer,
+ sizeof(sa->sa_sin.sin_addr)))
+ return NULL;
break;
case AF_INET6:
- sa->sa_sin6.sin6_port = 0;
- if (memcmp(sa, &bs->shop.peer, sizeof(sa->sa_sin6)) == 0)
- return bs;
+ if (memcmp(&sa->sa_sin6.sin6_addr, &bs->key.peer,
+ sizeof(sa->sa_sin6.sin6_addr)))
+ return NULL;
break;
}
- return NULL;
+ return bs;
}
struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
@@ -461,32 +379,30 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
ifindex_t ifindex, vrf_id_t vrfid,
bool is_mhop)
{
- struct bfd_session *l_bfd = NULL;
- struct bfd_mhop_key mhop;
- struct bfd_shop_key shop;
+ struct interface *ifp;
+ struct vrf *vrf;
+ struct bfd_key key;
/* Find our session using the ID signaled by the remote end. */
if (cp->discrs.remote_discr)
return bfd_find_disc(peer, ntohl(cp->discrs.remote_discr));
/* Search for session without using discriminator. */
- if (is_mhop) {
- memset(&mhop, 0, sizeof(mhop));
- mhop.peer = *peer;
- mhop.local = *local;
- mhop.vrfid = vrfid;
-
- l_bfd = bfd_mhop_lookup(mhop);
- } else {
- memset(&shop, 0, sizeof(shop));
- shop.peer = *peer;
- shop.ifindex = ifindex;
+ ifp = if_lookup_by_index(ifindex, vrfid);
+ if (vrfid == VRF_DEFAULT) {
+ /*
+ * Don't use the default vrf, otherwise we won't find
+ * sessions that doesn't specify it.
+ */
+ vrf = NULL;
+ } else
+ vrf = vrf_lookup_by_id(vrfid);
- l_bfd = bfd_shop_lookup(shop);
- }
+ gen_bfd_key(&key, peer, local, is_mhop, ifp ? ifp->name : NULL,
+ vrf ? vrf->name : NULL);
/* XXX maybe remoteDiscr should be checked for remoteHeard cases. */
- return l_bfd;
+ return bfd_key_lookup(key);
}
int bfd_xmt_cb(struct thread *t)
@@ -551,8 +467,6 @@ static struct bfd_session *bfd_session_new(void)
struct bfd_session *bs;
bs = XCALLOC(MTYPE_BFDD_CONFIG, sizeof(*bs));
- if (bs == NULL)
- return NULL;
QOBJ_REG(bs, bfd_session);
@@ -703,6 +617,9 @@ static void bfd_session_free(struct bfd_session *bs)
bfd_session_disable(bs);
+ bfd_key_delete(bs->key);
+ bfd_id_delete(bs->discrs.my_discr);
+
/* Remove observer if any. */
TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) {
if (bso->bso_bs != bs)
@@ -745,29 +662,47 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
* start. See `bfd_session_enable` for more information.
*/
if (bpc->bpc_has_localif)
- strlcpy(bfd->ifname, bpc->bpc_localif, sizeof(bfd->ifname));
+ strlcpy(bfd->key.ifname, bpc->bpc_localif,
+ sizeof(bfd->key.ifname));
if (bpc->bpc_has_vrfname)
- strlcpy(bfd->vrfname, bpc->bpc_vrfname, sizeof(bfd->vrfname));
-
- /* Add observer if we have moving parts. */
- if (bfd->ifname[0] || bfd->vrfname[0])
- bs_observer_add(bfd);
+ strlcpy(bfd->key.vrfname, bpc->bpc_vrfname,
+ sizeof(bfd->key.vrfname));
/* Copy remaining data. */
if (bpc->bpc_ipv4 == false)
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
- if (bpc->bpc_mhop) {
- BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_MH);
- bfd->mhop.peer = bpc->bpc_peer;
- bfd->mhop.local = bpc->bpc_local;
- } else {
- bfd->shop.peer = bpc->bpc_peer;
+ bfd->key.family = (bpc->bpc_ipv4) ? AF_INET : AF_INET6;
+ switch (bfd->key.family) {
+ case AF_INET:
+ memcpy(&bfd->key.peer, &bpc->bpc_peer.sa_sin.sin_addr,
+ sizeof(bpc->bpc_peer.sa_sin.sin_addr));
+ memcpy(&bfd->key.local, &bpc->bpc_local.sa_sin.sin_addr,
+ sizeof(bpc->bpc_local.sa_sin.sin_addr));
+ break;
+
+ case AF_INET6:
+ memcpy(&bfd->key.peer, &bpc->bpc_peer.sa_sin6.sin6_addr,
+ sizeof(bpc->bpc_peer.sa_sin6.sin6_addr));
+ memcpy(&bfd->key.local, &bpc->bpc_local.sa_sin6.sin6_addr,
+ sizeof(bpc->bpc_local.sa_sin6.sin6_addr));
+ break;
+
+ default:
+ assert(1);
+ break;
}
- bfd->local_ip = bpc->bpc_local;
- bfd->local_address = bpc->bpc_local;
+ if (bpc->bpc_mhop)
+ BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_MH);
+
+ bfd->key.mhop = bpc->bpc_mhop;
+
+ /* Registrate session into data structures. */
+ bfd_key_insert(bfd);
+ bfd->discrs.my_discr = ptm_bfd_gen_ID();
+ bfd_id_insert(bfd);
/* Try to enable session and schedule for packet receive/send. */
if (bfd_session_enable(bfd) == -1) {
@@ -776,6 +711,10 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
return NULL;
}
+ /* Add observer if we have moving parts. */
+ if (bfd->key.ifname[0] || bfd->key.vrfname[0] || bfd->sock == -1)
+ bs_observer_add(bfd);
+
/* Apply other configurations. */
_bfd_session_update(bfd, bpc);
@@ -1221,35 +1160,26 @@ void integer2timestr(uint64_t time, char *buf, size_t buflen)
snprintf(buf, buflen, "%u second(s)", second);
}
-const char *bs_to_string(struct bfd_session *bs)
+const char *bs_to_string(const struct bfd_session *bs)
{
static char buf[256];
+ char addr_buf[INET6_ADDRSTRLEN];
int pos;
bool is_mhop = BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH);
pos = snprintf(buf, sizeof(buf), "mhop:%s", is_mhop ? "yes" : "no");
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
- pos += snprintf(buf + pos, sizeof(buf) - pos,
- " peer:%s local:%s", satostr(&bs->mhop.peer),
- satostr(&bs->mhop.local));
-
- if (bs->mhop.vrfid != VRF_DEFAULT)
- snprintf(buf + pos, sizeof(buf) - pos, " vrf:%u",
- bs->mhop.vrfid);
- } else {
- pos += snprintf(buf + pos, sizeof(buf) - pos, " peer:%s",
- satostr(&bs->shop.peer));
-
- if (bs->local_address.sa_sin.sin_family)
- pos += snprintf(buf + pos, sizeof(buf) - pos,
- " local:%s",
- satostr(&bs->local_address));
-
- if (bs->shop.ifindex)
- snprintf(buf + pos, sizeof(buf) - pos, " ifindex:%u",
- bs->shop.ifindex);
- }
-
+ pos += snprintf(buf + pos, sizeof(buf) - pos, " peer:%s",
+ inet_ntop(bs->key.family, &bs->key.peer, addr_buf,
+ sizeof(addr_buf)));
+ pos += snprintf(buf + pos, sizeof(buf) - pos, " local:%s",
+ inet_ntop(bs->key.family, &bs->key.local, addr_buf,
+ sizeof(addr_buf)));
+ if (bs->key.vrfname[0])
+ pos += snprintf(buf + pos, sizeof(buf) - pos, " vrf:%s",
+ bs->key.vrfname);
+ if (bs->key.ifname[0])
+ pos += snprintf(buf + pos, sizeof(buf) - pos, " ifname:%s",
+ bs->key.ifname);
return buf;
}
@@ -1261,12 +1191,20 @@ int bs_observer_add(struct bfd_session *bs)
bso->bso_bs = bs;
bso->bso_isinterface = !BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH);
if (bso->bso_isinterface)
- strlcpy(bso->bso_entryname, bs->ifname,
+ strlcpy(bso->bso_entryname, bs->key.ifname,
sizeof(bso->bso_entryname));
else
- strlcpy(bso->bso_entryname, bs->vrfname,
+ strlcpy(bso->bso_entryname, bs->key.vrfname,
sizeof(bso->bso_entryname));
+ /* Handle socket binding failures caused by missing local addresses. */
+ if (bs->sock == -1) {
+ bso->bso_isaddress = true;
+ bso->bso_addr.family = bs->key.family;
+ memcpy(&bso->bso_addr.u.prefix, &bs->key.local,
+ sizeof(bs->key.local));
+ }
+
TAILQ_INSERT_TAIL(&bglobal.bg_obslist, bso, bso_entry);
return 0;
@@ -1278,21 +1216,59 @@ void bs_observer_del(struct bfd_session_observer *bso)
XFREE(MTYPE_BFDD_SESSION_OBSERVER, bso);
}
+void bs_to_bpc(struct bfd_session *bs, struct bfd_peer_cfg *bpc)
+{
+ memset(bpc, 0, sizeof(*bpc));
+
+ bpc->bpc_ipv4 = (bs->key.family == AF_INET);
+ bpc->bpc_mhop = bs->key.mhop;
+
+ switch (bs->key.family) {
+ case AF_INET:
+ bpc->bpc_peer.sa_sin.sin_family = AF_INET;
+ memcpy(&bpc->bpc_peer.sa_sin.sin_addr, &bs->key.peer,
+ sizeof(bpc->bpc_peer.sa_sin.sin_addr));
+
+ if (memcmp(&bs->key.local, &zero_addr, sizeof(bs->key.local))) {
+ bpc->bpc_local.sa_sin.sin_family = AF_INET6;
+ memcpy(&bpc->bpc_local.sa_sin.sin_addr, &bs->key.peer,
+ sizeof(bpc->bpc_local.sa_sin.sin_addr));
+ }
+ break;
+
+ case AF_INET6:
+ bpc->bpc_peer.sa_sin.sin_family = AF_INET6;
+ memcpy(&bpc->bpc_peer.sa_sin6.sin6_addr, &bs->key.peer,
+ sizeof(bpc->bpc_peer.sa_sin6.sin6_addr));
+
+ bpc->bpc_local.sa_sin6.sin6_family = AF_INET6;
+ memcpy(&bpc->bpc_local.sa_sin6.sin6_addr, &bs->key.peer,
+ sizeof(bpc->bpc_local.sa_sin6.sin6_addr));
+ break;
+ }
+
+ if (bs->key.ifname[0]) {
+ bpc->bpc_has_localif = true;
+ strlcpy(bpc->bpc_localif, bs->key.ifname,
+ sizeof(bpc->bpc_localif));
+ }
+
+ if (bs->key.vrfname[0]) {
+ bpc->bpc_has_vrfname = true;
+ strlcpy(bpc->bpc_vrfname, bs->key.vrfname,
+ sizeof(bpc->bpc_vrfname));
+ }
+}
+
/*
* BFD hash data structures to find sessions.
*/
static struct hash *bfd_id_hash;
-static struct hash *bfd_shop_hash;
-static struct hash *bfd_mhop_hash;
+static struct hash *bfd_key_hash;
static unsigned int bfd_id_hash_do(void *p);
-static unsigned int bfd_shop_hash_do(void *p);
-static unsigned int bfd_mhop_hash_do(void *p);
-
-static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop);
-static void _shop_key2(struct bfd_session *bs, const struct bfd_shop_key *shop);
-static void _mhop_key(struct bfd_session *bs, const struct bfd_mhop_key *mhop);
+static unsigned int bfd_key_hash_do(void *p);
static void _bfd_free(struct hash_bucket *hb,
void *arg __attribute__((__unused__)));
@@ -1313,73 +1289,20 @@ static bool bfd_id_hash_cmp(const void *n1, const void *n2)
}
/* BFD hash for single hop. */
-static unsigned int bfd_shop_hash_do(void *p)
-{
- struct bfd_session *bs = p;
-
- return jhash(&bs->shop, sizeof(bs->shop), 0);
-}
-
-static bool bfd_shop_hash_cmp(const void *n1, const void *n2)
-{
- const struct bfd_session *bs1 = n1, *bs2 = n2;
-
- return memcmp(&bs1->shop, &bs2->shop, sizeof(bs1->shop)) == 0;
-}
-
-/* BFD hash for multi hop. */
-static unsigned int bfd_mhop_hash_do(void *p)
+static unsigned int bfd_key_hash_do(void *p)
{
struct bfd_session *bs = p;
- return jhash(&bs->mhop, sizeof(bs->mhop), 0);
+ return jhash(&bs->key, sizeof(bs->key), 0);
}
-static bool bfd_mhop_hash_cmp(const void *n1, const void *n2)
+static bool bfd_key_hash_cmp(const void *n1, const void *n2)
{
const struct bfd_session *bs1 = n1, *bs2 = n2;
- return memcmp(&bs1->mhop, &bs2->mhop, sizeof(bs1->mhop)) == 0;
+ return memcmp(&bs1->key, &bs2->key, sizeof(bs1->key)) == 0;
}
-/* Helper functions */
-static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop)
-{
- bs->shop = *shop;
-
- /* Remove unused fields. */
- switch (bs->shop.peer.sa_sin.sin_family) {
- case AF_INET:
- bs->shop.peer.sa_sin.sin_port = 0;
- break;
- case AF_INET6:
- bs->shop.peer.sa_sin6.sin6_port = 0;
- break;
- }
-}
-
-static void _shop_key2(struct bfd_session *bs, const struct bfd_shop_key *shop)
-{
- _shop_key(bs, shop);
- bs->shop.ifindex = IFINDEX_INTERNAL;
-}
-
-static void _mhop_key(struct bfd_session *bs, const struct bfd_mhop_key *mhop)
-{
- bs->mhop = *mhop;
-
- /* Remove unused fields. */
- switch (bs->mhop.peer.sa_sin.sin_family) {
- case AF_INET:
- bs->mhop.peer.sa_sin.sin_port = 0;
- bs->mhop.local.sa_sin.sin_port = 0;
- break;
- case AF_INET6:
- bs->mhop.peer.sa_sin6.sin6_port = 0;
- bs->mhop.local.sa_sin6.sin6_port = 0;
- break;
- }
-}
/*
* Hash public interface / exported functions.
@@ -1395,32 +1318,33 @@ struct bfd_session *bfd_id_lookup(uint32_t id)
return hash_lookup(bfd_id_hash, &bs);
}
-struct bfd_session *bfd_shop_lookup(struct bfd_shop_key shop)
+struct bfd_session *bfd_key_lookup(struct bfd_key key)
{
struct bfd_session bs, *bsp;
- _shop_key(&bs, &shop);
+ bs.key = key;
+ bsp = hash_lookup(bfd_key_hash, &bs);
- bsp = hash_lookup(bfd_shop_hash, &bs);
- if (bsp == NULL && bs.shop.ifindex != 0) {
- /*
- * Since the local interface spec is optional, try
- * searching the key without it as well.
- */
- _shop_key2(&bs, &shop);
- bsp = hash_lookup(bfd_shop_hash, &bs);
+ /* Handle cases where local-address is optional. */
+ if (bsp == NULL && bs.key.family == AF_INET) {
+ memset(&bs.key.local, 0, sizeof(bs.key.local));
+ bsp = hash_lookup(bfd_key_hash, &bs);
}
- return bsp;
-}
-
-struct bfd_session *bfd_mhop_lookup(struct bfd_mhop_key mhop)
-{
- struct bfd_session bs;
+ /* Handle cases where ifname is optional. */
+ bs.key = key;
+ if (bsp == NULL && bs.key.ifname[0]) {
+ memset(bs.key.ifname, 0, sizeof(bs.key.ifname));
+ bsp = hash_lookup(bfd_key_hash, &bs);
- _mhop_key(&bs, &mhop);
+ /* Handle cases where local-address and ifname are optional. */
+ if (bsp == NULL && bs.key.family == AF_INET) {
+ memset(&bs.key.local, 0, sizeof(bs.key.local));
+ bsp = hash_lookup(bfd_key_hash, &bs);
+ }
+ }
- return hash_lookup(bfd_mhop_hash, &bs);
+ return bsp;
}
/*
@@ -1442,31 +1366,18 @@ struct bfd_session *bfd_id_delete(uint32_t id)
return hash_release(bfd_id_hash, &bs);
}
-struct bfd_session *bfd_shop_delete(struct bfd_shop_key shop)
+struct bfd_session *bfd_key_delete(struct bfd_key key)
{
struct bfd_session bs, *bsp;
- _shop_key(&bs, &shop);
- bsp = hash_release(bfd_shop_hash, &bs);
- if (bsp == NULL && shop.ifindex != 0) {
- /*
- * Since the local interface spec is optional, try
- * searching the key without it as well.
- */
- _shop_key2(&bs, &shop);
- bsp = hash_release(bfd_shop_hash, &bs);
+ bs.key = key;
+ bsp = hash_lookup(bfd_key_hash, &bs);
+ if (bsp == NULL && key.ifname[0]) {
+ memset(bs.key.ifname, 0, sizeof(bs.key.ifname));
+ bsp = hash_lookup(bfd_key_hash, &bs);
}
- return bsp;
-}
-
-struct bfd_session *bfd_mhop_delete(struct bfd_mhop_key mhop)
-{
- struct bfd_session bs;
-
- _mhop_key(&bs, &mhop);
-
- return hash_release(bfd_mhop_hash, &bs);
+ return hash_release(bfd_key_hash, bsp);
}
/* Iteration functions. */
@@ -1475,14 +1386,9 @@ void bfd_id_iterate(hash_iter_func hif, void *arg)
hash_iterate(bfd_id_hash, hif, arg);
}
-void bfd_shop_iterate(hash_iter_func hif, void *arg)
-{
- hash_iterate(bfd_shop_hash, hif, arg);
-}
-
-void bfd_mhop_iterate(hash_iter_func hif, void *arg)
+void bfd_key_iterate(hash_iter_func hif, void *arg)
{
- hash_iterate(bfd_mhop_hash, hif, arg);
+ hash_iterate(bfd_key_hash, hif, arg);
}
/*
@@ -1496,24 +1402,17 @@ bool bfd_id_insert(struct bfd_session *bs)
return (hash_get(bfd_id_hash, bs, hash_alloc_intern) == bs);
}
-bool bfd_shop_insert(struct bfd_session *bs)
-{
- return (hash_get(bfd_shop_hash, bs, hash_alloc_intern) == bs);
-}
-
-bool bfd_mhop_insert(struct bfd_session *bs)
+bool bfd_key_insert(struct bfd_session *bs)
{
- return (hash_get(bfd_mhop_hash, bs, hash_alloc_intern) == bs);
+ return (hash_get(bfd_key_hash, bs, hash_alloc_intern) == bs);
}
void bfd_initialize(void)
{
bfd_id_hash = hash_create(bfd_id_hash_do, bfd_id_hash_cmp,
- "BFD discriminator hash");
- bfd_shop_hash = hash_create(bfd_shop_hash_do, bfd_shop_hash_cmp,
- "BFD single hop hash");
- bfd_mhop_hash = hash_create(bfd_mhop_hash_do, bfd_mhop_hash_cmp,
- "BFD multihop hop hash");
+ "BFD session discriminator hash");
+ bfd_key_hash = hash_create(bfd_key_hash_do, bfd_key_hash_cmp,
+ "BFD session hash");
}
static void _bfd_free(struct hash_bucket *hb,
@@ -1534,11 +1433,9 @@ void bfd_shutdown(void)
* assert() here to make sure it really happened.
*/
bfd_id_iterate(_bfd_free, NULL);
- assert(bfd_shop_hash->count == 0);
- assert(bfd_mhop_hash->count == 0);
+ assert(bfd_key_hash->count == 0);
/* Now free the hashes themselves. */
hash_free(bfd_id_hash);
- hash_free(bfd_shop_hash);
- hash_free(bfd_mhop_hash);
+ hash_free(bfd_key_hash);
}
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 7451ca82a3..a69ff9a1a7 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -173,15 +173,13 @@ enum bfd_session_flags {
#define BFD_CHECK_FLAG(field, flag) (field & flag)
/* BFD session hash keys */
-struct bfd_shop_key {
- struct sockaddr_any peer;
- ifindex_t ifindex;
-};
-
-struct bfd_mhop_key {
- struct sockaddr_any peer;
- struct sockaddr_any local;
- vrf_id_t vrfid;
+struct bfd_key {
+ uint16_t family;
+ uint8_t mhop;
+ struct in6_addr peer;
+ struct in6_addr local;
+ char ifname[MAXNAMELEN];
+ char vrfname[MAXNAMELEN];
};
struct bfd_session_stats {
@@ -227,19 +225,14 @@ struct bfd_session {
uint8_t polling;
/* This and the localDiscr are the keys to state info */
+ struct bfd_key key;
struct peer_label *pl;
- union {
- struct bfd_shop_key shop;
- struct bfd_mhop_key mhop;
- };
- int sock;
struct sockaddr_any local_address;
- struct sockaddr_any local_ip;
struct interface *ifp;
struct vrf *vrf;
- char ifname[MAXNAMELEN];
- char vrfname[MAXNAMELEN];
+
+ int sock;
/* BFD session flags */
enum bfd_session_flags flags;
@@ -281,7 +274,11 @@ struct bfd_state_str_list {
struct bfd_session_observer {
struct bfd_session *bso_bs;
bool bso_isinterface;
- char bso_entryname[MAXNAMELEN];
+ bool bso_isaddress;
+ union {
+ char bso_entryname[MAXNAMELEN];
+ struct prefix bso_addr;
+ };
TAILQ_ENTRY(bfd_session_observer) bso_entry;
};
@@ -531,38 +528,28 @@ const char *satostr(struct sockaddr_any *sa);
const char *diag2str(uint8_t diag);
int strtosa(const char *addr, struct sockaddr_any *sa);
void integer2timestr(uint64_t time, char *buf, size_t buflen);
-const char *bs_to_string(struct bfd_session *bs);
+const char *bs_to_string(const struct bfd_session *bs);
int bs_observer_add(struct bfd_session *bs);
void bs_observer_del(struct bfd_session_observer *bso);
+void bs_to_bpc(struct bfd_session *bs, struct bfd_peer_cfg *bpc);
+
/* BFD hash data structures interface */
void bfd_initialize(void);
void bfd_shutdown(void);
struct bfd_session *bfd_id_lookup(uint32_t id);
-struct bfd_session *bfd_shop_lookup(struct bfd_shop_key shop);
-struct bfd_session *bfd_mhop_lookup(struct bfd_mhop_key mhop);
-struct bfd_vrf *bfd_vrf_lookup(int vrf_id);
-struct bfd_iface *bfd_iface_lookup(const char *ifname);
+struct bfd_session *bfd_key_lookup(struct bfd_key key);
struct bfd_session *bfd_id_delete(uint32_t id);
-struct bfd_session *bfd_shop_delete(struct bfd_shop_key shop);
-struct bfd_session *bfd_mhop_delete(struct bfd_mhop_key mhop);
-struct bfd_vrf *bfd_vrf_delete(int vrf_id);
-struct bfd_iface *bfd_iface_delete(const char *ifname);
+struct bfd_session *bfd_key_delete(struct bfd_key key);
bool bfd_id_insert(struct bfd_session *bs);
-bool bfd_shop_insert(struct bfd_session *bs);
-bool bfd_mhop_insert(struct bfd_session *bs);
-bool bfd_vrf_insert(struct bfd_vrf *vrf);
-bool bfd_iface_insert(struct bfd_iface *iface);
+bool bfd_key_insert(struct bfd_session *bs);
typedef void (*hash_iter_func)(struct hash_bucket *hb, void *arg);
void bfd_id_iterate(hash_iter_func hif, void *arg);
-void bfd_shop_iterate(hash_iter_func hif, void *arg);
-void bfd_mhop_iterate(hash_iter_func hif, void *arg);
-void bfd_vrf_iterate(hash_iter_func hif, void *arg);
-void bfd_iface_iterate(hash_iter_func hif, void *arg);
+void bfd_key_iterate(hash_iter_func hif, void *arg);
/* Export callback functions for `event.c`. */
extern struct thread_master *master;
@@ -572,6 +559,8 @@ int bfd_echo_recvtimer_cb(struct thread *t);
int bfd_xmt_cb(struct thread *t);
int bfd_echo_xmt_cb(struct thread *t);
+extern struct in6_addr zero_addr;
+
/*
* bfdd_vty.c
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 45c5f5dbdc..69d27ed698 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -79,7 +79,10 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) {
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = bs->shop.peer.sa_sin6.sin6_addr;
+ memcpy(&sin6.sin6_addr, &bs->key.peer, sizeof(sin6.sin6_addr));
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
+ sin6.sin6_scope_id = bs->ifp->ifindex;
+
sin6.sin6_port =
(port) ? *port
: (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
@@ -92,7 +95,7 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
} else {
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- sin.sin_addr = bs->shop.peer.sa_sin.sin_addr;
+ memcpy(&sin.sin_addr, &bs->key.peer, sizeof(sin.sin_addr));
sin.sin_port =
(port) ? *port
: (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
@@ -120,7 +123,7 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
void ptm_bfd_echo_snd(struct bfd_session *bfd)
{
- struct sockaddr_any *sa;
+ struct sockaddr *sa;
socklen_t salen;
int sd;
struct bfd_echo_pkt bep;
@@ -135,31 +138,34 @@ void ptm_bfd_echo_snd(struct bfd_session *bfd)
bep.len = BFD_ECHO_PKT_LEN;
bep.my_discr = htonl(bfd->discrs.my_discr);
- sa = BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MH) ? &bfd->mhop.peer
- : &bfd->shop.peer;
if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6)) {
sd = bglobal.bg_echov6;
- sin6 = sa->sa_sin6;
+ memset(&sin6, 0, sizeof(sin6));
+ memcpy(&sin6.sin6_addr, &bfd->key.peer, sizeof(sin6.sin6_addr));
+ if (bfd->ifp && IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
+ sin6.sin6_scope_id = bfd->ifp->ifindex;
+
sin6.sin6_port = htons(BFD_DEF_ECHO_PORT);
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin6.sin6_len = sizeof(sin6);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
- sa = (struct sockaddr_any *)&sin6;
+ sa = (struct sockaddr *)&sin6;
salen = sizeof(sin6);
} else {
sd = bglobal.bg_echo;
- sin = sa->sa_sin;
+ memset(&sin6, 0, sizeof(sin6));
+ memcpy(&sin.sin_addr, &bfd->key.peer, sizeof(sin.sin_addr));
sin.sin_port = htons(BFD_DEF_ECHO_PORT);
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin.sin_len = sizeof(sin);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
- sa = (struct sockaddr_any *)&sin;
+ sa = (struct sockaddr *)&sin;
salen = sizeof(sin);
}
- if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep),
- (struct sockaddr *)sa, salen)
+ if (bp_udp_send(sd, BFD_TTL_VAL, (uint8_t *)&bep, sizeof(bep), sa,
+ salen)
== -1)
return;
@@ -544,7 +550,7 @@ int bfd_recv_cb(struct thread *t)
}
/* Validate packet TTL. */
- if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
+ if ((!is_mhop) && (ttl != BFD_TTL_VAL)) {
cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"invalid TTL: %d expected %d", ttl, BFD_TTL_VAL);
return 0;
@@ -602,8 +608,8 @@ int bfd_recv_cb(struct thread *t)
bfd->mh_ttl, BFD_TTL_VAL);
return 0;
}
- } else if (bfd->local_ip.sa_sin.sin_family == AF_UNSPEC) {
- bfd->local_ip = local;
+ } else if (bfd->local_address.sa_sin.sin_family == AF_UNSPEC) {
+ bfd->local_address = local;
}
/*
@@ -917,25 +923,26 @@ int bp_peer_socket(const struct bfd_session *bs)
return -1;
}
- if (bs->shop.ifindex != IFINDEX_INTERNAL) {
- if (bp_bind_dev(sd, bs->ifp->name) != 0) {
+ if (bs->key.ifname[0]) {
+ if (bp_bind_dev(sd, bs->key.ifname) != 0) {
close(sd);
return -1;
}
- } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) &&
- bs->mhop.vrfid != VRF_DEFAULT) {
- if (bp_bind_dev(sd, bs->vrf->name) != 0) {
+ } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)
+ && bs->key.vrfname[0]) {
+ if (bp_bind_dev(sd, bs->key.vrfname) != 0) {
close(sd);
return -1;
}
}
/* Find an available source port in the proper range */
- sin = bs->local_ip.sa_sin;
+ memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin.sin_len = sizeof(sin);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+ memcpy(&sin.sin_addr, &bs->key.local, sizeof(sin.sin_addr));
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) == 0)
sin.sin_addr.s_addr = INADDR_ANY;
@@ -987,20 +994,23 @@ int bp_peer_socketv6(const struct bfd_session *bs)
}
/* Find an available source port in the proper range */
- sin6 = bs->local_ip.sa_sin6;
+ memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin6.sin6_len = sizeof(sin6);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+ memcpy(&sin6.sin6_addr, &bs->key.local, sizeof(sin6.sin6_addr));
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
+ sin6.sin6_scope_id = bs->ifp->ifindex;
- if (bs->shop.ifindex != IFINDEX_INTERNAL) {
- if (bp_bind_dev(sd, bs->ifp->name) != 0) {
+ if (bs->key.ifname[0]) {
+ if (bp_bind_dev(sd, bs->key.ifname) != 0) {
close(sd);
return -1;
}
- } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) &&
- bs->mhop.vrfid != VRF_DEFAULT) {
- if (bp_bind_dev(sd, bs->vrf->name) != 0) {
+ } else if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)
+ && bs->key.vrfname[0]) {
+ if (bp_bind_dev(sd, bs->key.vrfname) != 0) {
close(sd);
return -1;
}
diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c
index 0041f9cc2e..c139492076 100644
--- a/bfdd/bfdd_vty.c
+++ b/bfdd/bfdd_vty.c
@@ -79,7 +79,6 @@ _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv,
const char *local_str, const char *ifname,
const char *vrfname);
-
/*
* Commands definition.
*/
@@ -369,22 +368,25 @@ DEFPY(bfd_no_peer, bfd_no_peer_cmd,
*/
static void _display_peer_header(struct vty *vty, struct bfd_session *bs)
{
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
- vty_out(vty, "\tpeer %s", satostr(&bs->mhop.peer));
+ char addr_buf[INET6_ADDRSTRLEN];
+
+ vty_out(vty, "\tpeer %s",
+ inet_ntop(bs->key.family, &bs->key.peer, addr_buf,
+ sizeof(addr_buf)));
+
+ if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
vty_out(vty, " multihop");
- vty_out(vty, " local-address %s", satostr(&bs->mhop.local));
- if (bs->vrfname[0])
- vty_out(vty, " vrf %s", bs->vrfname);
- vty_out(vty, "\n");
- } else {
- vty_out(vty, "\tpeer %s", satostr(&bs->shop.peer));
- if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
- vty_out(vty, " local-address %s",
- satostr(&bs->local_address));
- if (bs->ifname[0])
- vty_out(vty, " interface %s", bs->ifname);
- vty_out(vty, "\n");
- }
+
+ if (memcmp(&bs->key.local, &zero_addr, sizeof(bs->key.local)))
+ vty_out(vty, " local-address %s",
+ inet_ntop(bs->key.family, &bs->key.local, addr_buf,
+ sizeof(addr_buf)));
+
+ if (bs->key.vrfname[0])
+ vty_out(vty, " vrf %s", bs->key.vrfname);
+ if (bs->key.ifname[0])
+ vty_out(vty, " interface %s", bs->key.ifname);
+ vty_out(vty, "\n");
if (bs->pl)
vty_out(vty, "\t\tlabel: %s\n", bs->pl->pl_label);
@@ -453,22 +455,25 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs)
static struct json_object *_peer_json_header(struct bfd_session *bs)
{
struct json_object *jo = json_object_new_object();
+ char addr_buf[INET6_ADDRSTRLEN];
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
+ if (bs->key.mhop)
json_object_boolean_true_add(jo, "multihop");
- json_object_string_add(jo, "peer", satostr(&bs->mhop.peer));
- json_object_string_add(jo, "local", satostr(&bs->mhop.local));
- if (bs->vrfname[0])
- json_object_string_add(jo, "vrf", bs->vrfname);
- } else {
+ else
json_object_boolean_false_add(jo, "multihop");
- json_object_string_add(jo, "peer", satostr(&bs->shop.peer));
- if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
- json_object_string_add(jo, "local",
- satostr(&bs->local_address));
- if (bs->ifname[0])
- json_object_string_add(jo, "interface", bs->ifname);
- }
+
+ json_object_string_add(jo, "peer",
+ inet_ntop(bs->key.family, &bs->key.peer,
+ addr_buf, sizeof(addr_buf)));
+ if (memcmp(&bs->key.local, &zero_addr, sizeof(bs->key.local)))
+ json_object_string_add(jo, "local",
+ inet_ntop(bs->key.family, &bs->key.local,
+ addr_buf, sizeof(addr_buf)));
+
+ if (bs->key.vrfname[0])
+ json_object_string_add(jo, "vrf", bs->key.vrfname);
+ if (bs->key.ifname[0])
+ json_object_string_add(jo, "interface", bs->key.ifname);
if (bs->pl)
json_object_string_add(jo, "label", bs->pl->pl_label);
@@ -564,7 +569,7 @@ static void _display_all_peers(struct vty *vty, bool use_json)
{
struct json_object *jo;
- if (use_json == false) {
+ if (!use_json) {
vty_out(vty, "BFD Peers:\n");
bfd_id_iterate(_display_peer_iter, vty);
return;
@@ -647,7 +652,7 @@ static void _display_peers_counter(struct vty *vty, bool use_json)
{
struct json_object *jo;
- if (use_json == false) {
+ if (!use_json) {
vty_out(vty, "BFD Peers:\n");
bfd_id_iterate(_display_peer_counter_iter, vty);
return;
@@ -916,25 +921,29 @@ static int bfdd_write_config(struct vty *vty)
static void _bfdd_peer_write_config(struct vty *vty, struct bfd_session *bs)
{
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
- vty_out(vty, " peer %s", satostr(&bs->mhop.peer));
+ char addr_buf[INET6_ADDRSTRLEN];
+
+ vty_out(vty, " peer %s",
+ inet_ntop(bs->key.family, &bs->key.peer, addr_buf,
+ sizeof(addr_buf)));
+
+ if (bs->key.mhop)
vty_out(vty, " multihop");
- vty_out(vty, " local-address %s", satostr(&bs->mhop.local));
- if (bs->vrfname[0])
- vty_out(vty, " vrf %s", bs->vrfname);
- vty_out(vty, "\n");
- } else {
- vty_out(vty, " peer %s", satostr(&bs->shop.peer));
- if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
- vty_out(vty, " local-address %s",
- satostr(&bs->local_address));
- if (bs->ifname[0])
- vty_out(vty, " interface %s", bs->ifname);
- vty_out(vty, "\n");
- }
+
+ if (memcmp(&bs->key.local, &zero_addr, sizeof(bs->key.local)))
+ vty_out(vty, " local-address %s",
+ inet_ntop(bs->key.family, &bs->key.local, addr_buf,
+ sizeof(addr_buf)));
+
+ if (bs->key.vrfname[0])
+ vty_out(vty, " vrf %s", bs->key.vrfname);
+ if (bs->key.ifname[0])
+ vty_out(vty, " interface %s", bs->key.ifname);
+ vty_out(vty, "\n");
if (bs->sock == -1)
- vty_out(vty, " ! vrf or interface doesn't exist\n");
+ vty_out(vty,
+ " ! vrf, interface or local-address doesn't exist\n");
if (bs->detect_mult != BPC_DEF_DETECTMULTIPLIER)
vty_out(vty, " detect-multiplier %d\n", bs->detect_mult);
@@ -980,16 +989,7 @@ static void _bfdd_peer_write_config_iter(struct hash_bucket *hb, void *arg)
static int bfdd_peer_write_config(struct vty *vty)
{
- struct bfd_session_observer *bso;
-
bfd_id_iterate(_bfdd_peer_write_config_iter, vty);
- TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) {
- /* Only print disabled sessions here. */
- if (bso->bso_bs->sock != -1)
- continue;
-
- _bfdd_peer_write_config(vty, bso->bso_bs);
- }
return 1;
}
diff --git a/bfdd/config.c b/bfdd/config.c
index d1342eff1e..cd57ea9fe3 100644
--- a/bfdd/config.c
+++ b/bfdd/config.c
@@ -309,24 +309,7 @@ static int parse_peer_label_config(struct json_object *jo,
log_debug("\tpeer-label: %s", sval);
/* Translate the label into BFD address keys. */
- bpc->bpc_ipv4 = !BFD_CHECK_FLAG(pl->pl_bs->flags, BFD_SESS_FLAG_IPV6);
- bpc->bpc_mhop = BFD_CHECK_FLAG(pl->pl_bs->flags, BFD_SESS_FLAG_MH);
- if (bpc->bpc_mhop) {
- bpc->bpc_peer = pl->pl_bs->mhop.peer;
- bpc->bpc_local = pl->pl_bs->mhop.local;
- if (pl->pl_bs->mhop.vrfid != VRF_DEFAULT) {
- bpc->bpc_has_vrfname = true;
- strlcpy(bpc->bpc_vrfname, pl->pl_bs->vrf->name,
- sizeof(bpc->bpc_vrfname));
- }
- } else {
- bpc->bpc_peer = pl->pl_bs->shop.peer;
- if (pl->pl_bs->ifname[0]) {
- bpc->bpc_has_localif = true;
- strlcpy(bpc->bpc_localif, pl->pl_bs->ifname,
- sizeof(bpc->bpc_localif));
- }
- }
+ bs_to_bpc(pl->pl_bs, bpc);
return 0;
}
@@ -519,6 +502,8 @@ int config_notify_request(struct bfd_control_socket *bcs, const char *jsonstr,
static int json_object_add_peer(struct json_object *jo, struct bfd_session *bs)
{
+ char addr_buf[INET6_ADDRSTRLEN];
+
/* Add peer 'key' information. */
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6))
json_object_boolean_true_add(jo, "ipv6");
@@ -528,21 +513,26 @@ static int json_object_add_peer(struct json_object *jo, struct bfd_session *bs)
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
json_object_boolean_true_add(jo, "multihop");
json_object_string_add(jo, "peer-address",
- satostr(&bs->mhop.peer));
+ inet_ntop(bs->key.family, &bs->key.peer,
+ addr_buf, sizeof(addr_buf)));
json_object_string_add(jo, "local-address",
- satostr(&bs->mhop.local));
- if (bs->vrfname[0])
- json_object_string_add(jo, "vrf-name", bs->vrfname);
+ inet_ntop(bs->key.family, &bs->key.local,
+ addr_buf, sizeof(addr_buf)));
+ if (bs->key.vrfname[0])
+ json_object_string_add(jo, "vrf-name", bs->key.vrfname);
} else {
json_object_boolean_false_add(jo, "multihop");
json_object_string_add(jo, "peer-address",
- satostr(&bs->shop.peer));
- if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
- json_object_string_add(jo, "local-address",
- satostr(&bs->local_address));
- if (bs->ifname[0])
+ inet_ntop(bs->key.family, &bs->key.peer,
+ addr_buf, sizeof(addr_buf)));
+ if (memcmp(&bs->key.local, &zero_addr, sizeof(bs->key.local)))
+ json_object_string_add(
+ jo, "local-address",
+ inet_ntop(bs->key.family, &bs->key.local,
+ addr_buf, sizeof(addr_buf)));
+ if (bs->key.ifname[0])
json_object_string_add(jo, "local-interface",
- bs->ifname);
+ bs->key.ifname);
}
if (bs->pl)
@@ -574,8 +564,6 @@ struct peer_label *pl_new(const char *label, struct bfd_session *bs)
struct peer_label *pl;
pl = XCALLOC(MTYPE_BFDD_LABEL, sizeof(*pl));
- if (pl == NULL)
- return NULL;
if (strlcpy(pl->pl_label, label, sizeof(pl->pl_label))
> sizeof(pl->pl_label))
diff --git a/bfdd/control.c b/bfdd/control.c
index 40f4f4d3be..c308d647d8 100644
--- a/bfdd/control.c
+++ b/bfdd/control.c
@@ -186,8 +186,6 @@ struct bfd_control_socket *control_new(int sd)
struct bfd_control_socket *bcs;
bcs = XCALLOC(MTYPE_BFDD_CONTROL, sizeof(*bcs));
- if (bcs == NULL)
- return NULL;
/* Disable notifications by default. */
bcs->bcs_notify = 0;
@@ -247,10 +245,6 @@ struct bfd_notify_peer *control_notifypeer_new(struct bfd_control_socket *bcs,
return bnp;
bnp = XCALLOC(MTYPE_BFDD_CONTROL, sizeof(*bnp));
- if (bnp == NULL) {
- log_warning("%s: calloc: %s", __func__, strerror(errno));
- return NULL;
- }
TAILQ_INSERT_TAIL(&bcs->bcs_bnplist, bnp, bnp_entry);
bnp->bnp_bs = bs;
@@ -285,10 +279,6 @@ struct bfd_control_queue *control_queue_new(struct bfd_control_socket *bcs)
struct bfd_control_queue *bcq;
bcq = XCALLOC(MTYPE_BFDD_NOTIFICATION, sizeof(*bcq));
- if (bcq == NULL) {
- log_warning("%s: calloc: %s", __func__, strerror(errno));
- return NULL;
- }
control_reset_buf(&bcq->bcq_bcb);
TAILQ_INSERT_TAIL(&bcs->bcs_bcqueue, bcq, bcq_entry);
@@ -743,11 +733,6 @@ static void control_response(struct bfd_control_socket *bcs, uint16_t id,
jsonstrlen = strlen(jsonstr);
bcm = XMALLOC(MTYPE_BFDD_NOTIFICATION,
sizeof(struct bfd_control_msg) + jsonstrlen);
- if (bcm == NULL) {
- log_warning("%s: malloc: %s", __func__, strerror(errno));
- XFREE(MTYPE_BFDD_NOTIFICATION, jsonstr);
- return;
- }
bcm->bcm_length = htonl(jsonstrlen);
bcm->bcm_ver = BMV_VERSION_1;
@@ -778,11 +763,6 @@ static void _control_notify(struct bfd_control_socket *bcs,
jsonstrlen = strlen(jsonstr);
bcm = XMALLOC(MTYPE_BFDD_NOTIFICATION,
sizeof(struct bfd_control_msg) + jsonstrlen);
- if (bcm == NULL) {
- log_warning("%s: malloc: %s", __func__, strerror(errno));
- XFREE(MTYPE_BFDD_NOTIFICATION, jsonstr);
- return;
- }
bcm->bcm_length = htonl(jsonstrlen);
bcm->bcm_ver = BMV_VERSION_1;
@@ -846,11 +826,6 @@ static void _control_notify_config(struct bfd_control_socket *bcs,
jsonstrlen = strlen(jsonstr);
bcm = XMALLOC(MTYPE_BFDD_NOTIFICATION,
sizeof(struct bfd_control_msg) + jsonstrlen);
- if (bcm == NULL) {
- log_warning("%s: malloc: %s", __func__, strerror(errno));
- XFREE(MTYPE_BFDD_NOTIFICATION, jsonstr);
- return;
- }
bcm->bcm_length = htonl(jsonstrlen);
bcm->bcm_ver = BMV_VERSION_1;
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 3f1512d8e7..b44d13f132 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -55,7 +55,7 @@ static struct zclient *zclient;
/*
* Prototypes
*/
-static int _ptm_msg_address(struct stream *msg, struct sockaddr_any *sa);
+static int _ptm_msg_address(struct stream *msg, int family, const void *addr);
static void _ptm_msg_read_address(struct stream *msg, struct sockaddr_any *sa);
static int _ptm_msg_read(struct stream *msg, int command,
@@ -127,24 +127,24 @@ static void debug_printbpc(const char *func, unsigned int line,
#define DEBUG_PRINTBPC(bpc)
#endif /* BFD_DEBUG */
-static int _ptm_msg_address(struct stream *msg, struct sockaddr_any *sa)
+static int _ptm_msg_address(struct stream *msg, int family, const void *addr)
{
- switch (sa->sa_sin.sin_family) {
+ stream_putc(msg, family);
+
+ switch (family) {
case AF_INET:
- stream_putc(msg, sa->sa_sin.sin_family);
- stream_put_in_addr(msg, &sa->sa_sin.sin_addr);
+ stream_put(msg, addr, sizeof(struct in_addr));
stream_putc(msg, 32);
break;
case AF_INET6:
- stream_putc(msg, sa->sa_sin6.sin6_family);
- stream_put(msg, &sa->sa_sin6.sin6_addr,
- sizeof(sa->sa_sin6.sin6_addr));
+ stream_put(msg, addr, sizeof(struct in6_addr));
stream_putc(msg, 128);
break;
default:
- return -1;
+ assert(0);
+ break;
}
return 0;
@@ -153,7 +153,6 @@ static int _ptm_msg_address(struct stream *msg, struct sockaddr_any *sa)
int ptm_bfd_notify(struct bfd_session *bs)
{
struct stream *msg;
- struct sockaddr_any sac;
bs->stats.znotification++;
@@ -195,10 +194,7 @@ int ptm_bfd_notify(struct bfd_session *bs)
stream_putl(msg, IFINDEX_INTERNAL);
/* BFD destination prefix information. */
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
- _ptm_msg_address(msg, &bs->mhop.peer);
- else
- _ptm_msg_address(msg, &bs->shop.peer);
+ _ptm_msg_address(msg, bs->key.family, &bs->key.peer);
/* BFD status */
switch (bs->ses_state) {
@@ -218,34 +214,7 @@ int ptm_bfd_notify(struct bfd_session *bs)
}
/* BFD source prefix information. */
- if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) {
- _ptm_msg_address(msg, &bs->mhop.local);
- } else {
- if (bs->local_address.sa_sin.sin_family)
- _ptm_msg_address(msg, &bs->local_address);
- else if (bs->local_address.sa_sin.sin_family)
- _ptm_msg_address(msg, &bs->local_ip);
- else {
- sac = bs->shop.peer;
- switch (sac.sa_sin.sin_family) {
- case AF_INET:
- memset(&sac.sa_sin.sin_addr, 0,
- sizeof(sac.sa_sin.sin_family));
- break;
- case AF_INET6:
- memset(&sac.sa_sin6.sin6_addr, 0,
- sizeof(sac.sa_sin6.sin6_family));
- break;
-
- default:
- assert(false);
- break;
- }
-
- /* No local address found yet, so send zeroes. */
- _ptm_msg_address(msg, &sac);
- }
- }
+ _ptm_msg_address(msg, bs->key.family, &bs->key.local);
/* Write packet size. */
stream_putw_at(msg, 0, stream_get_endp(msg));
@@ -290,7 +259,6 @@ stream_failure:
static int _ptm_msg_read(struct stream *msg, int command,
struct bfd_peer_cfg *bpc, struct ptm_client **pc)
{
- struct interface *ifp;
uint32_t pid;
uint8_t ttl __attribute__((unused));
size_t ifnamelen;
@@ -385,31 +353,6 @@ static int _ptm_msg_read(struct stream *msg, int command,
if (bpc->bpc_has_localif) {
STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
bpc->bpc_localif[ifnamelen] = 0;
-
- /*
- * IPv6 link-local addresses must use scope id,
- * otherwise the session lookup will always fail
- * and we'll have multiple sessions showing up.
- *
- * This problem only happens with single hop
- * since it is not possible to have link-local
- * address for multi hop sessions.
- */
- if (bpc->bpc_ipv4 == false
- && IN6_IS_ADDR_LINKLOCAL(
- &bpc->bpc_peer.sa_sin6.sin6_addr)) {
- ifp = if_lookup_by_name_all_vrf(
- bpc->bpc_localif);
- if (ifp == NULL) {
- log_error(
- "ptm-read: interface %s doesn't exists",
- bpc->bpc_localif);
- return -1;
- }
-
- bpc->bpc_peer.sa_sin6.sin6_scope_id =
- ifp->ifindex;
- }
}
}
@@ -608,7 +551,7 @@ static void bfdd_sessions_enable_interface(struct interface *ifp)
/* Interface name mismatch. */
bs = bso->bso_bs;
- if (strcmp(ifp->name, bs->ifname))
+ if (strcmp(ifp->name, bs->key.ifname))
continue;
/* Skip enabled sessions. */
if (bs->sock != -1)
@@ -630,7 +573,7 @@ static void bfdd_sessions_disable_interface(struct interface *ifp)
/* Interface name mismatch. */
bs = bso->bso_bs;
- if (strcmp(ifp->name, bs->ifname))
+ if (strcmp(ifp->name, bs->key.ifname))
continue;
/* Skip disabled sessions. */
if (bs->sock == -1)
@@ -691,6 +634,48 @@ static int bfdd_interface_vrf_update(int command __attribute__((__unused__)),
return 0;
}
+static void bfdd_sessions_enable_address(struct connected *ifc)
+{
+ struct bfd_session_observer *bso;
+ struct bfd_session *bs;
+ struct prefix prefix;
+
+ TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) {
+ if (bso->bso_isaddress == false)
+ continue;
+
+ /* Skip enabled sessions. */
+ bs = bso->bso_bs;
+ if (bs->sock != -1)
+ continue;
+
+ /* Check address. */
+ prefix = bso->bso_addr;
+ prefix.prefixlen = ifc->address->prefixlen;
+ if (prefix_cmp(&prefix, ifc->address))
+ continue;
+
+ /* Try to enable it. */
+ bfd_session_enable(bs);
+ }
+}
+
+static int bfdd_interface_address_update(int cmd, struct zclient *zc,
+ zebra_size_t len
+ __attribute__((__unused__)),
+ vrf_id_t vrfid)
+{
+ struct connected *ifc;
+
+ ifc = zebra_interface_address_read(cmd, zc->ibuf, vrfid);
+ if (ifc == NULL)
+ return 0;
+
+ bfdd_sessions_enable_address(ifc);
+
+ return 0;
+}
+
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
zclient = zclient_new(master, &zclient_options_default);
@@ -713,6 +698,10 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
/* Learn about interface VRF. */
zclient->interface_vrf_update = bfdd_interface_vrf_update;
+
+ /* Learn about new addresses being registered. */
+ zclient->interface_address_add = bfdd_interface_address_update;
+ zclient->interface_address_delete = bfdd_interface_address_update;
}
void bfdd_zclient_stop(void)
@@ -752,8 +741,6 @@ static struct ptm_client *pc_new(uint32_t pid)
/* Allocate the client data and save it. */
pc = XCALLOC(MTYPE_BFDD_CONTROL, sizeof(*pc));
- if (pc == NULL)
- return NULL;
pc->pc_pid = pid;
TAILQ_INSERT_HEAD(&pcqueue, pc, pc_entry);
@@ -799,8 +786,6 @@ static struct ptm_client_notification *pcn_new(struct ptm_client *pc,
/* Save the client notification data. */
pcn = XCALLOC(MTYPE_BFDD_NOTIFICATION, sizeof(*pcn));
- if (pcn == NULL)
- return NULL;
TAILQ_INSERT_HEAD(&pc->pc_pcnqueue, pcn, pcn_entry);
pcn->pcn_pc = pc;
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index 208a2947ef..05eeeca156 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -45,8 +45,8 @@
peer. */
struct bgp_advertise_attr *baa_new(void)
{
- return (struct bgp_advertise_attr *)XCALLOC(
- MTYPE_BGP_ADVERTISE_ATTR, sizeof(struct bgp_advertise_attr));
+ return XCALLOC(MTYPE_BGP_ADVERTISE_ATTR,
+ sizeof(struct bgp_advertise_attr));
}
static void baa_free(struct bgp_advertise_attr *baa)
@@ -84,8 +84,7 @@ bool baa_hash_cmp(const void *p1, const void *p2)
information. */
struct bgp_advertise *bgp_advertise_new(void)
{
- return (struct bgp_advertise *)XCALLOC(MTYPE_BGP_ADVERTISE,
- sizeof(struct bgp_advertise));
+ return XCALLOC(MTYPE_BGP_ADVERTISE, sizeof(struct bgp_advertise));
}
void bgp_advertise_free(struct bgp_advertise *adv)
@@ -255,8 +254,7 @@ void bgp_sync_delete(struct peer *peer)
safi_t safi;
FOREACH_AFI_SAFI (afi, safi) {
- if (peer->sync[afi][safi])
- XFREE(MTYPE_BGP_SYNCHRONISE, peer->sync[afi][safi]);
+ XFREE(MTYPE_BGP_SYNCHRONISE, peer->sync[afi][safi]);
peer->sync[afi][safi] = NULL;
}
}
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 3bd3de031c..92c37fabd2 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -312,8 +312,7 @@ void aspath_free(struct aspath *aspath)
return;
if (aspath->segments)
assegment_free_all(aspath->segments);
- if (aspath->str)
- XFREE(MTYPE_AS_STR, aspath->str);
+ XFREE(MTYPE_AS_STR, aspath->str);
if (aspath->json) {
json_object_free(aspath->json);
@@ -623,8 +622,7 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
void aspath_str_update(struct aspath *as, bool make_json)
{
- if (as->str)
- XFREE(MTYPE_AS_STR, as->str);
+ XFREE(MTYPE_AS_STR, as->str);
if (as->json) {
json_object_free(as->json);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 4c6da724b1..226bf99d2c 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -159,8 +159,7 @@ static bool cluster_hash_cmp(const void *p1, const void *p2)
static void cluster_free(struct cluster_list *cluster)
{
- if (cluster->list)
- XFREE(MTYPE_CLUSTER_VAL, cluster->list);
+ XFREE(MTYPE_CLUSTER_VAL, cluster->list);
XFREE(MTYPE_CLUSTER, cluster);
}
@@ -401,8 +400,7 @@ static struct hash *transit_hash;
static void transit_free(struct transit *transit)
{
- if (transit->val)
- XFREE(MTYPE_TRANSIT_VAL, transit->val);
+ XFREE(MTYPE_TRANSIT_VAL, transit->val);
XFREE(MTYPE_TRANSIT, transit);
}
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c
index 208a9d4705..15fa322159 100644
--- a/bgpd/bgp_attr_evpn.c
+++ b/bgpd/bgp_attr_evpn.c
@@ -84,8 +84,8 @@ char *esi2str(struct eth_segment_id *id)
return NULL;
val = id->val;
- ptr = (char *)XMALLOC(MTYPE_TMP,
- (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
+ ptr = XMALLOC(MTYPE_TMP,
+ (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char));
snprintf(ptr, (ESI_LEN * 2 + ESI_LEN - 1 + 1),
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", val[0],
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index 84a00488c1..7b64f349d2 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -100,16 +100,14 @@ static void community_entry_free(struct community_entry *entry)
case EXTCOMMUNITY_LIST_STANDARD:
/* In case of standard extcommunity-list, configuration string
is made by ecommunity_ecom2str(). */
- if (entry->config)
- XFREE(MTYPE_ECOMMUNITY_STR, entry->config);
+ XFREE(MTYPE_ECOMMUNITY_STR, entry->config);
if (entry->u.ecom)
ecommunity_free(&entry->u.ecom);
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
case LARGE_COMMUNITY_LIST_EXPANDED:
- if (entry->config)
- XFREE(MTYPE_COMMUNITY_LIST_CONFIG, entry->config);
+ XFREE(MTYPE_COMMUNITY_LIST_CONFIG, entry->config);
if (entry->reg)
bgp_regex_free(entry->reg);
default:
@@ -127,8 +125,7 @@ static struct community_list *community_list_new(void)
/* Free community-list. */
static void community_list_free(struct community_list *list)
{
- if (list->name)
- XFREE(MTYPE_COMMUNITY_LIST_NAME, list->name);
+ XFREE(MTYPE_COMMUNITY_LIST_NAME, list->name);
XFREE(MTYPE_COMMUNITY_LIST, list);
}
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index 2e28c30950..67cd2be214 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -34,17 +34,14 @@ static struct hash *comhash;
/* Allocate a new communities value. */
static struct community *community_new(void)
{
- return (struct community *)XCALLOC(MTYPE_COMMUNITY,
- sizeof(struct community));
+ return XCALLOC(MTYPE_COMMUNITY, sizeof(struct community));
}
/* Free communities value. */
void community_free(struct community **com)
{
- if ((*com)->val)
- XFREE(MTYPE_COMMUNITY_VAL, (*com)->val);
- if ((*com)->str)
- XFREE(MTYPE_COMMUNITY_STR, (*com)->str);
+ XFREE(MTYPE_COMMUNITY_VAL, (*com)->val);
+ XFREE(MTYPE_COMMUNITY_STR, (*com)->str);
if ((*com)->json) {
json_object_free((*com)->json);
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index fcfaa388d9..8ef398952d 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -48,8 +48,7 @@ static struct hash *ecomhash;
/* Allocate a new ecommunities. */
struct ecommunity *ecommunity_new(void)
{
- return (struct ecommunity *)XCALLOC(MTYPE_ECOMMUNITY,
- sizeof(struct ecommunity));
+ return XCALLOC(MTYPE_ECOMMUNITY, sizeof(struct ecommunity));
}
void ecommunity_strfree(char **s)
@@ -60,10 +59,8 @@ void ecommunity_strfree(char **s)
/* Allocate ecommunities. */
void ecommunity_free(struct ecommunity **ecom)
{
- if ((*ecom)->val)
- XFREE(MTYPE_ECOMMUNITY_VAL, (*ecom)->val);
- if ((*ecom)->str)
- XFREE(MTYPE_ECOMMUNITY_STR, (*ecom)->str);
+ XFREE(MTYPE_ECOMMUNITY_VAL, (*ecom)->val);
+ XFREE(MTYPE_ECOMMUNITY_STR, (*ecom)->str);
XFREE(MTYPE_ECOMMUNITY, *ecom);
}
diff --git a/bgpd/bgp_encap_tlv.c b/bgpd/bgp_encap_tlv.c
index 30a08098e8..964adec9b6 100644
--- a/bgpd/bgp_encap_tlv.c
+++ b/bgpd/bgp_encap_tlv.c
@@ -401,8 +401,7 @@ void bgp_encap_type_vxlan_to_tlv(
if (bet == NULL || !bet->vnid)
return;
- if (attr->encap_subtlvs)
- XFREE(MTYPE_ENCAP_TLV, attr->encap_subtlvs);
+ XFREE(MTYPE_ENCAP_TLV, attr->encap_subtlvs);
tlv = XCALLOC(MTYPE_ENCAP_TLV,
sizeof(struct bgp_attr_encap_subtlv) + 12);
tlv->type = 1; /* encapsulation type */
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index f123b7f8ec..84f3649758 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -184,8 +184,6 @@ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt)
irt = XCALLOC(MTYPE_BGP_EVPN_VRF_IMPORT_RT,
sizeof(struct vrf_irt_node));
- if (!irt)
- return NULL;
irt->rt = *rt;
irt->vrfs = list_new();
@@ -296,8 +294,6 @@ static struct irt_node *import_rt_new(struct bgp *bgp,
return NULL;
irt = XCALLOC(MTYPE_BGP_EVPN_IMPORT_RT, sizeof(struct irt_node));
- if (!irt)
- return NULL;
irt->rt = *rt;
irt->vnis = list_new();
@@ -968,8 +964,6 @@ static struct in_addr *es_vtep_new(struct in_addr vtep)
struct in_addr *ip;
ip = XCALLOC(MTYPE_BGP_EVPN_ES_VTEP, sizeof(struct in_addr));
- if (!ip)
- return NULL;
ip->s_addr = vtep.s_addr;
return ip;
@@ -5100,8 +5094,6 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
return NULL;
vpn = XCALLOC(MTYPE_BGP_EVPN, sizeof(struct bgpevpn));
- if (!vpn)
- return NULL;
/* Set values - RD and RT set to defaults. */
vpn->vni = vni;
@@ -5181,8 +5173,6 @@ struct evpnes *bgp_evpn_es_new(struct bgp *bgp,
return NULL;
es = XCALLOC(MTYPE_BGP_EVPN_ES, sizeof(struct evpnes));
- if (!es)
- return NULL;
/* set the ESI and originator_ip */
memcpy(&es->esi, esi, sizeof(esi_t));
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 8437c4024e..fb2d9da533 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -3358,7 +3358,8 @@ DEFUN (bgp_evpn_advertise_type5,
}
/* advertise type-5 routes */
- bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
+ if (advertise_type5_routes(bgp_vrf, afi))
+ bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
return CMD_SUCCESS;
}
diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c
index 1ccb8fb245..80cfb97436 100644
--- a/bgpd/bgp_filter.c
+++ b/bgpd/bgp_filter.c
@@ -95,8 +95,7 @@ static void as_filter_free(struct as_filter *asfilter)
{
if (asfilter->reg)
bgp_regex_free(asfilter->reg);
- if (asfilter->reg_str)
- XFREE(MTYPE_AS_FILTER_STR, asfilter->reg_str);
+ XFREE(MTYPE_AS_FILTER_STR, asfilter->reg_str);
XFREE(MTYPE_AS_FILTER, asfilter);
}
@@ -338,8 +337,7 @@ static void as_list_filter_delete(struct as_list *aslist,
/* Run hook function. */
if (as_list_master.delete_hook)
(*as_list_master.delete_hook)(name);
- if (name)
- XFREE(MTYPE_AS_STR, name);
+ XFREE(MTYPE_AS_STR, name);
}
static int as_filter_match(struct as_filter *asfilter, struct aspath *aspath)
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index b70c8bbd63..447d8da613 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -310,7 +310,8 @@ void bgp_timer_set(struct peer *peer)
status start timer is on unless peer is shutdown or peer is
inactive. All other timer must be turned off */
if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
- || peer->bgp->vrf_id == VRF_UNKNOWN) {
+ || (peer->bgp->inst_type != BGP_INSTANCE_TYPE_VIEW &&
+ peer->bgp->vrf_id == VRF_UNKNOWN)) {
BGP_TIMER_OFF(peer->t_start);
} else {
BGP_TIMER_ON(peer->t_start, bgp_start_timer,
@@ -1422,7 +1423,8 @@ int bgp_start(struct peer *peer)
return 0;
}
- if (peer->bgp->vrf_id == VRF_UNKNOWN) {
+ if (peer->bgp->inst_type != BGP_INSTANCE_TYPE_VIEW &&
+ peer->bgp->vrf_id == VRF_UNKNOWN) {
if (bgp_debug_neighbor_events(peer))
flog_err(
EC_BGP_FSM,
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index 181f864575..69dd0f9dac 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -180,14 +180,12 @@ static void lp_cbq_item_free(struct work_queue *wq, void *data)
static void lp_lcb_free(void *goner)
{
- if (goner)
- XFREE(MTYPE_BGP_LABEL_CB, goner);
+ XFREE(MTYPE_BGP_LABEL_CB, goner);
}
static void lp_chunk_free(void *goner)
{
- if (goner)
- XFREE(MTYPE_BGP_LABEL_CHUNK, goner);
+ XFREE(MTYPE_BGP_LABEL_CHUNK, goner);
}
void bgp_lp_init(struct thread_master *master, struct labelpool *pool)
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index 1e45897192..44766c9b6e 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -38,17 +38,14 @@ static struct hash *lcomhash;
/* Allocate a new lcommunities. */
static struct lcommunity *lcommunity_new(void)
{
- return (struct lcommunity *)XCALLOC(MTYPE_LCOMMUNITY,
- sizeof(struct lcommunity));
+ return XCALLOC(MTYPE_LCOMMUNITY, sizeof(struct lcommunity));
}
/* Allocate lcommunities. */
void lcommunity_free(struct lcommunity **lcom)
{
- if ((*lcom)->val)
- XFREE(MTYPE_LCOMMUNITY_VAL, (*lcom)->val);
- if ((*lcom)->str)
- XFREE(MTYPE_LCOMMUNITY_STR, (*lcom)->str);
+ XFREE(MTYPE_LCOMMUNITY_VAL, (*lcom)->val);
+ XFREE(MTYPE_LCOMMUNITY_STR, (*lcom)->str);
XFREE(MTYPE_LCOMMUNITY, *lcom);
}
@@ -180,7 +177,7 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
{
int i;
int len;
- bool first = 1;
+ bool first = true;
char *str_buf;
char *str_pnt;
uint8_t *pnt;
@@ -218,7 +215,7 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
for (i = 0; i < lcom->size; i++) {
if (first)
- first = 0;
+ first = false;
else
*str_pnt++ = ' ';
@@ -319,10 +316,10 @@ bool lcommunity_cmp(const void *arg1, const void *arg2)
const struct lcommunity *lcom2 = arg2;
if (lcom1 == NULL && lcom2 == NULL)
- return 1;
+ return true;
if (lcom1 == NULL || lcom2 == NULL)
- return 0;
+ return false;
return (lcom1->size == lcom2->size
&& memcmp(lcom1->val, lcom2->val, lcom_length(lcom1)) == 0);
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 241146e451..d5b3d6b197 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -671,7 +671,7 @@ void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best)
bgp_path_info_mpath_count_set(dmed_best, 0);
UNSET_FLAG(dmed_best->flags, BGP_PATH_MULTIPATH_CHG);
- assert(bgp_path_info_mpath_first(dmed_best) == 0);
+ assert(bgp_path_info_mpath_first(dmed_best) == NULL);
}
/*
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 4c51db8e14..c0be36ed3f 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -333,7 +333,7 @@ static bool bgp_pbr_extract_enumerate_unary(struct bgp_pbr_match_val list[],
unary_operator, and_valmask,
or_valmask, list[i].value,
type_entry);
- if (ret == false)
+ if (!ret)
return ret;
continue;
}
@@ -441,7 +441,7 @@ static bool bgp_pbr_extract(struct bgp_pbr_match_val list[],
range->min_port = list[i].value;
exact_match = true;
}
- if (exact_match == true && i > 0)
+ if (exact_match && i > 0)
return false;
if (list[i].compare_operator ==
(OPERATOR_COMPARE_GREATER_THAN +
@@ -545,7 +545,7 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
"too complex. ignoring.");
return 0;
} else if (api->match_icmp_type_num > 1 &&
- enumerate_icmp == false) {
+ !enumerate_icmp) {
if (BGP_DEBUG(pbr, PBR))
zlog_debug("BGP: match icmp code is enumerate"
", and icmp type is not."
diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c
index 77f5aade5f..571139a49a 100644
--- a/bgpd/bgp_rd.c
+++ b/bgpd/bgp_rd.c
@@ -155,8 +155,7 @@ int str2prefix_rd(const char *str, struct prefix_rd *prd)
out:
if (s)
stream_free(s);
- if (half)
- XFREE(MTYPE_TMP, half);
+ XFREE(MTYPE_TMP, half);
return lret;
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a83e4419e4..90a8f8cec5 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4468,12 +4468,10 @@ static struct bgp_static *bgp_static_new(void)
static void bgp_static_free(struct bgp_static *bgp_static)
{
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
route_map_counter_decrement(bgp_static->rmap.map);
- if (bgp_static->eth_s_id)
- XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
+ XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
XFREE(MTYPE_BGP_STATIC, bgp_static);
}
@@ -5033,9 +5031,8 @@ static int bgp_static_set(struct vty *vty, const char *negate,
bgp_static->backdoor = backdoor;
if (rmap) {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
route_map_counter_decrement(
bgp_static->rmap.map);
bgp_static->rmap.name =
@@ -5045,9 +5042,8 @@ static int bgp_static_set(struct vty *vty, const char *negate,
route_map_counter_increment(
bgp_static->rmap.map);
} else {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
route_map_counter_decrement(
bgp_static->rmap.map);
bgp_static->rmap.name = NULL;
@@ -5065,9 +5061,8 @@ static int bgp_static_set(struct vty *vty, const char *negate,
bgp_static->label_index = label_index;
if (rmap) {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
route_map_counter_decrement(
bgp_static->rmap.map);
bgp_static->rmap.name =
@@ -5351,9 +5346,7 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
bgp_static->prd = prd;
if (rmap_str) {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
route_map_counter_decrement(bgp_static->rmap.map);
bgp_static->rmap.name =
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
@@ -5460,15 +5453,13 @@ static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
rmap = &bgp->table_map[afi][safi];
if (rmap_name) {
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
route_map_counter_decrement(rmap->map);
rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
rmap->map = route_map_lookup_by_name(rmap_name);
route_map_counter_increment(rmap->map);
} else {
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
route_map_counter_decrement(rmap->map);
rmap->name = NULL;
rmap->map = NULL;
@@ -5487,8 +5478,7 @@ static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
struct bgp_rmap *rmap;
rmap = &bgp->table_map[afi][safi];
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
route_map_counter_decrement(rmap->map);
rmap->name = NULL;
rmap->map = NULL;
@@ -11461,8 +11451,7 @@ static int bgp_distance_unset(struct vty *vty, const char *distance_str,
return CMD_WARNING_CONFIG_FAILED;
}
- if (bdistance->access_list)
- XFREE(MTYPE_AS_LIST, bdistance->access_list);
+ XFREE(MTYPE_AS_LIST, bdistance->access_list);
bgp_distance_free(bdistance);
bgp_node_set_bgp_path_info(rn, NULL);
@@ -12049,10 +12038,8 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
decode_label(&bgp_static->label), esi, buf2,
macrouter);
- if (macrouter)
- XFREE(MTYPE_TMP, macrouter);
- if (esi)
- XFREE(MTYPE_TMP, esi);
+ XFREE(MTYPE_TMP, macrouter);
+ XFREE(MTYPE_TMP, esi);
}
}
}
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 17109281bc..c276f5ef7b 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -197,8 +197,6 @@ static void *route_value_compile(const char *arg)
}
rv = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
- if (!rv)
- return NULL;
rv->action = action;
rv->variable = var;
@@ -324,8 +322,7 @@ static void route_match_peer_free(void *rule)
{
struct bgp_match_peer_compiled *pc = rule;
- if (pc->interface)
- XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface);
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface);
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
@@ -837,8 +834,6 @@ static void *route_match_vni_compile(const char *arg)
char *end = NULL;
vni = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(vni_t));
- if (!vni)
- return NULL;
*vni = strtoul(arg, &end, 10);
if (*end != '\0') {
@@ -998,9 +993,6 @@ static void *route_match_local_pref_compile(const char *arg)
local_pref = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
- if (!local_pref)
- return local_pref;
-
*local_pref = tmpval;
return local_pref;
}
@@ -1555,8 +1547,7 @@ static void route_set_ip_nexthop_free(void *rule)
{
struct rmap_ip_nexthop_set *rins = rule;
- if (rins->address)
- XFREE(MTYPE_ROUTE_MAP_COMPILED, rins->address);
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rins->address);
XFREE(MTYPE_ROUTE_MAP_COMPILED, rins);
}
@@ -2046,22 +2037,12 @@ static route_map_result_t route_set_lcommunity_delete(void *rule,
static void *route_set_lcommunity_delete_compile(const char *arg)
{
struct rmap_community *rcom;
- char *p;
- char *str;
- int len;
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
- p = strchr(arg, ' ');
- if (p) {
- len = p - arg;
- str = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
- memcpy(str, arg, len);
- } else
- str = NULL;
-
- rcom->name = str;
+ rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
rcom->name_hash = bgp_clist_hash_key(rcom->name);
+
return rcom;
}
@@ -2141,22 +2122,12 @@ static route_map_result_t route_set_community_delete(
static void *route_set_community_delete_compile(const char *arg)
{
struct rmap_community *rcom;
- char *p;
- char *str;
- int len;
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
- p = strchr(arg, ' ');
- if (p) {
- len = p - arg;
- str = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
- memcpy(str, arg, len);
- } else
- str = NULL;
-
- rcom->name = str;
+ rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
rcom->name_hash = bgp_clist_hash_key(rcom->name);
+
return rcom;
}
@@ -3105,10 +3076,8 @@ static int bgp_route_match_delete(struct vty *vty, const char *command,
break;
}
- if (dep_name)
- XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
- if (rmap_name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
return retval;
}
@@ -3399,7 +3368,7 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
"Processing route_map %s update on advertise type5 route command",
rmap_name);
- if (route_update) {
+ if (route_update && advertise_type5_routes(bgp, afi)) {
bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
bgp_evpn_advertise_type5_routes(bgp, afi, safi);
}
@@ -4351,17 +4320,10 @@ DEFUN (set_community_delete,
"Delete matching communities\n")
{
int idx_comm_list = 2;
- char *str;
-
- str = XCALLOC(MTYPE_TMP,
- strlen(argv[idx_comm_list]->arg) + strlen(" delete") + 1);
- strcpy(str, argv[idx_comm_list]->arg);
- strcpy(str + strlen(argv[idx_comm_list]->arg), " delete");
generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), "comm-list",
- str);
+ argv[idx_comm_list]->arg);
- XFREE(MTYPE_TMP, str);
return CMD_SUCCESS;
}
@@ -4450,16 +4412,9 @@ DEFUN (set_lcommunity_delete,
"Large Community-list name\n"
"Delete matching large communities\n")
{
- char *str;
-
- str = XCALLOC(MTYPE_TMP, strlen(argv[2]->arg) + strlen(" delete") + 1);
- strcpy(str, argv[2]->arg);
- strcpy(str + strlen(argv[2]->arg), " delete");
-
generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
- "large-comm-list", str);
+ "large-comm-list", argv[2]->arg);
- XFREE(MTYPE_TMP, str);
return CMD_SUCCESS;
}
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index c1321dd7dc..44cbeabd69 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -900,11 +900,10 @@ static int bgpTrapEstablished(struct peer *peer)
oid_copy_addr(index, &addr, IN_ADDR_SIZE);
- smux_trap(bgp_variables, sizeof bgp_variables / sizeof(struct variable),
- bgp_trap_oid, sizeof bgp_trap_oid / sizeof(oid), bgp_oid,
+ smux_trap(bgp_variables, array_size(bgp_variables), bgp_trap_oid,
+ array_size(bgp_trap_oid), bgp_oid,
sizeof bgp_oid / sizeof(oid), index, IN_ADDR_SIZE,
- bgpTrapList, sizeof bgpTrapList / sizeof(struct trap_object),
- BGPESTABLISHED);
+ bgpTrapList, array_size(bgpTrapList), BGPESTABLISHED);
return 0;
}
@@ -920,11 +919,10 @@ static int bgpTrapBackwardTransition(struct peer *peer)
oid_copy_addr(index, &addr, IN_ADDR_SIZE);
- smux_trap(bgp_variables, sizeof bgp_variables / sizeof(struct variable),
- bgp_trap_oid, sizeof bgp_trap_oid / sizeof(oid), bgp_oid,
+ smux_trap(bgp_variables, array_size(bgp_variables), bgp_trap_oid,
+ array_size(bgp_trap_oid), bgp_oid,
sizeof bgp_oid / sizeof(oid), index, IN_ADDR_SIZE,
- bgpTrapList, sizeof bgpTrapList / sizeof(struct trap_object),
- BGPBACKWARDTRANSITION);
+ bgpTrapList, array_size(bgpTrapList), BGPBACKWARDTRANSITION);
return 0;
}
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index b74dc33ea4..49a435120d 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -110,8 +110,7 @@ static void sync_init(struct update_subgroup *subgrp)
static void sync_delete(struct update_subgroup *subgrp)
{
- if (subgrp->sync)
- XFREE(MTYPE_BGP_SYNCHRONISE, subgrp->sync);
+ XFREE(MTYPE_BGP_SYNCHRONISE, subgrp->sync);
subgrp->sync = NULL;
if (subgrp->hash)
hash_free(subgrp->hash);
@@ -144,8 +143,7 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi,
dst->v_routeadv = src->v_routeadv;
dst->flags = src->flags;
dst->af_flags[afi][safi] = src->af_flags[afi][safi];
- if (dst->host)
- XFREE(MTYPE_BGP_PEER_HOST, dst->host);
+ XFREE(MTYPE_BGP_PEER_HOST, dst->host);
dst->host = XSTRDUP(MTYPE_BGP_PEER_HOST, src->host);
dst->cap = src->cap;
@@ -208,27 +206,19 @@ static void conf_release(struct peer *src, afi_t afi, safi_t safi)
srcfilter = &src->filter[afi][safi];
- if (src->default_rmap[afi][safi].name)
- XFREE(MTYPE_ROUTE_MAP_NAME, src->default_rmap[afi][safi].name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, src->default_rmap[afi][safi].name);
- if (srcfilter->dlist[FILTER_OUT].name)
- XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->dlist[FILTER_OUT].name);
+ XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->dlist[FILTER_OUT].name);
- if (srcfilter->plist[FILTER_OUT].name)
- XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->plist[FILTER_OUT].name);
+ XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->plist[FILTER_OUT].name);
- if (srcfilter->aslist[FILTER_OUT].name)
- XFREE(MTYPE_BGP_FILTER_NAME,
- srcfilter->aslist[FILTER_OUT].name);
+ XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->aslist[FILTER_OUT].name);
- if (srcfilter->map[RMAP_OUT].name)
- XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->map[RMAP_OUT].name);
+ XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->map[RMAP_OUT].name);
- if (srcfilter->usmap.name)
- XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->usmap.name);
+ XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->usmap.name);
- if (src->host)
- XFREE(MTYPE_BGP_PEER_HOST, src->host);
+ XFREE(MTYPE_BGP_PEER_HOST, src->host);
src->host = NULL;
}
@@ -440,7 +430,7 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2)
return false;
if (pe1->addpath_type[afi][safi] != pe2->addpath_type[afi][safi])
- return 0;
+ return false;
if ((pe1->cap & PEER_UPDGRP_CAP_FLAGS)
!= (pe2->cap & PEER_UPDGRP_CAP_FLAGS))
@@ -741,12 +731,10 @@ static void update_group_delete(struct update_group *updgrp)
hash_release(updgrp->bgp->update_groups[updgrp->afid], updgrp);
conf_release(updgrp->conf, updgrp->afi, updgrp->safi);
- if (updgrp->conf->host)
- XFREE(MTYPE_BGP_PEER_HOST, updgrp->conf->host);
+ XFREE(MTYPE_BGP_PEER_HOST, updgrp->conf->host);
updgrp->conf->host = NULL;
- if (updgrp->conf->ifname)
- XFREE(MTYPE_BGP_PEER_IFNAME, updgrp->conf->ifname);
+ XFREE(MTYPE_BGP_PEER_IFNAME, updgrp->conf->ifname);
XFREE(MTYPE_BGP_PEER, updgrp->conf);
XFREE(MTYPE_BGP_UPDGRP, updgrp);
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index cbbf8b2302..66e306cba2 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -69,8 +69,7 @@ struct bpacket *bpacket_alloc(void)
{
struct bpacket *pkt;
- pkt = (struct bpacket *)XCALLOC(MTYPE_BGP_PACKET,
- sizeof(struct bpacket));
+ pkt = XCALLOC(MTYPE_BGP_PACKET, sizeof(struct bpacket));
return pkt;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index f111ad3c7f..3e100f2f0a 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2841,18 +2841,23 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
as = strtoul(as_str, NULL, 10);
}
- /* If peer is peer group, call proper function. */
+ /* If peer is peer group or interface peer, call proper function. */
ret = str2sockunion(peer_str, &su);
if (ret < 0) {
- /* Check for peer by interface */
+ struct peer *peer;
+
+ /* Check if existing interface peer */
+ peer = peer_lookup_by_conf_if(bgp, peer_str);
+
ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi,
safi);
- if (ret < 0) {
+
+ /* if not interface peer, check peer-group settings */
+ if (ret < 0 && !peer) {
ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
if (ret < 0) {
vty_out(vty,
- "%% Create the peer-group or interface first or specify \"interface\" keyword\n");
- vty_out(vty, "%% if using an unnumbered interface neighbor\n");
+ "%% Create the peer-group or interface first\n");
return CMD_WARNING_CONFIG_FAILED;
}
return CMD_SUCCESS;
@@ -3251,7 +3256,7 @@ DEFUN (no_neighbor_interface_peer_group_remote_as,
/* look up for neighbor by interface name config. */
peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
if (peer) {
- peer_as_change(peer, 0, AS_SPECIFIED);
+ peer_as_change(peer, 0, AS_UNSPECIFIED);
return CMD_SUCCESS;
}
@@ -8522,7 +8527,7 @@ const char *afi_safi_json(afi_t afi, safi_t safi)
}
/* Show BGP peer's information. */
-enum show_type { show_all, show_peer };
+enum show_type { show_all, show_peer, show_ipv4_all, show_ipv6_all, show_ipv4_peer, show_ipv6_peer };
static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
afi_t afi, safi_t safi,
@@ -10945,6 +10950,14 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
struct peer *peer;
int find = 0;
bool nbr_output = false;
+ afi_t afi = AFI_MAX;
+ safi_t safi = SAFI_MAX;
+
+ if (type == show_ipv4_peer || type == show_ipv4_all) {
+ afi = AFI_IP;
+ } else if (type == show_ipv6_peer || type == show_ipv6_all) {
+ afi = AFI_IP6;
+ }
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
@@ -10973,17 +10986,54 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
}
}
break;
+ case show_ipv4_peer:
+ case show_ipv6_peer:
+ FOREACH_SAFI (safi) {
+ if (peer->afc[afi][safi]) {
+ if (conf_if) {
+ if ((peer->conf_if
+ && !strcmp(peer->conf_if, conf_if))
+ || (peer->hostname
+ && !strcmp(peer->hostname, conf_if))) {
+ find = 1;
+ bgp_show_peer(vty, peer, use_json,
+ json);
+ break;
+ }
+ } else {
+ if (sockunion_same(&peer->su, su)) {
+ find = 1;
+ bgp_show_peer(vty, peer, use_json,
+ json);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case show_ipv4_all:
+ case show_ipv6_all:
+ FOREACH_SAFI (safi) {
+ if (peer->afc[afi][safi]) {
+ bgp_show_peer(vty, peer, use_json, json);
+ nbr_output = true;
+ break;
+ }
+ }
+ break;
}
}
- if (type == show_peer && !find) {
+ if ((type == show_peer || type == show_ipv4_peer ||
+ type == show_ipv6_peer) && !find) {
if (use_json)
json_object_boolean_true_add(json, "bgpNoSuchNeighbor");
else
vty_out(vty, "%% No such neighbor in this view/vrf\n");
}
- if (type != show_peer && !nbr_output && !use_json)
+ if (type != show_peer && type != show_ipv4_peer &&
+ type != show_ipv6_peer && !nbr_output && !use_json)
vty_out(vty, "%% No BGP neighbors found\n");
if (use_json) {
@@ -11049,7 +11099,8 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
: bgp->name);
}
- if (type == show_peer) {
+ if (type == show_peer || type == show_ipv4_peer ||
+ type == show_ipv6_peer) {
ret = str2sockunion(ip_str, &su);
if (ret < 0)
bgp_show_neighbor(vty, bgp, type, NULL, ip_str,
@@ -11058,7 +11109,7 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
bgp_show_neighbor(vty, bgp, type, &su, NULL,
use_json, json);
} else {
- bgp_show_neighbor(vty, bgp, show_all, NULL, NULL,
+ bgp_show_neighbor(vty, bgp, type, NULL, NULL,
use_json, json);
}
json_object_free(json);
@@ -11151,6 +11202,7 @@ DEFUN (show_ip_bgp_neighbors,
char *vrf = NULL;
char *sh_arg = NULL;
enum show_type sh_type;
+ afi_t afi = AFI_MAX;
bool uj = use_json(argc, argv);
@@ -11166,13 +11218,29 @@ DEFUN (show_ip_bgp_neighbors,
vrf = argv[idx + 1]->arg;
idx++;
+
+ if (argv_find(argv, argc, "ipv4", &idx)) {
+ sh_type = show_ipv4_all;
+ afi = AFI_IP;
+ } else if (argv_find(argv, argc, "ipv6", &idx)) {
+ sh_type = show_ipv6_all;
+ afi = AFI_IP6;
+ } else {
+ sh_type = show_all;
+ }
+
if (argv_find(argv, argc, "A.B.C.D", &idx)
|| argv_find(argv, argc, "X:X::X:X", &idx)
|| argv_find(argv, argc, "WORD", &idx)) {
sh_type = show_peer;
sh_arg = argv[idx]->arg;
- } else
- sh_type = show_all;
+ }
+
+ if (sh_type == show_peer && afi == AFI_IP) {
+ sh_type = show_ipv4_peer;
+ } else if (sh_type == show_peer && afi == AFI_IP6) {
+ sh_type = show_ipv6_peer;
+ }
return bgp_show_neighbor_vty(vty, vrf, sh_type, sh_arg, uj);
}
@@ -11267,8 +11335,9 @@ DEFUN (show_ip_bgp_attr_info,
return CMD_SUCCESS;
}
-static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
- safi_t safi, bool use_json)
+static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
+ afi_t afi, safi_t safi,
+ bool use_json, json_object *json)
{
struct bgp *bgp;
struct listnode *node;
@@ -11277,13 +11346,10 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
char *ecom_str;
vpn_policy_direction_t dir;
- if (use_json) {
- json_object *json = NULL;
+ if (json) {
json_object *json_import_vrfs = NULL;
json_object *json_export_vrfs = NULL;
- json = json_object_new_object();
-
bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
if (!bgp) {
@@ -11354,11 +11420,12 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
}
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(json,
+ if (use_json) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(json,
JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
-
+ json_object_free(json);
+ }
} else {
bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
@@ -11422,6 +11489,54 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
return CMD_SUCCESS;
}
+static int bgp_show_all_instance_route_leak_vty(struct vty *vty, afi_t afi,
+ safi_t safi, bool use_json)
+{
+ struct listnode *node, *nnode;
+ struct bgp *bgp;
+ char *vrf_name = NULL;
+ json_object *json = NULL;
+ json_object *json_vrf = NULL;
+ json_object *json_vrfs = NULL;
+
+ if (use_json) {
+ json = json_object_new_object();
+ json_vrfs = json_object_new_object();
+ }
+
+ for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+
+ if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
+ vrf_name = bgp->name;
+
+ if (use_json) {
+ json_vrf = json_object_new_object();
+ } else {
+ vty_out(vty, "\nInstance %s:\n",
+ (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+ ? VRF_DEFAULT_NAME : bgp->name);
+ }
+ bgp_show_route_leak_vty(vty, vrf_name, afi, safi, 0, json_vrf);
+ if (use_json) {
+ if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+ json_object_object_add(json_vrfs,
+ VRF_DEFAULT_NAME, json_vrf);
+ else
+ json_object_object_add(json_vrfs, vrf_name,
+ json_vrf);
+ }
+ }
+
+ if (use_json) {
+ json_object_object_add(json, "vrfs", json_vrfs);
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+
+ return CMD_SUCCESS;
+}
+
/* "show [ip] bgp route-leak" command. */
DEFUN (show_ip_bgp_route_leak,
show_ip_bgp_route_leak_cmd,
@@ -11441,6 +11556,7 @@ DEFUN (show_ip_bgp_route_leak,
bool uj = use_json(argc, argv);
int idx = 0;
+ json_object *json = NULL;
/* show [ip] bgp */
if (argv_find(argv, argc, "ip", &idx)) {
@@ -11470,7 +11586,13 @@ DEFUN (show_ip_bgp_route_leak,
return CMD_WARNING;
}
- return bgp_show_route_leak_vty(vty, vrf, afi, safi, uj);
+ if (vrf && strmatch(vrf, "all"))
+ return bgp_show_all_instance_route_leak_vty(vty, afi, safi, uj);
+
+ if (uj)
+ json = json_object_new_object();
+
+ return bgp_show_route_leak_vty(vty, vrf, afi, safi, uj, json);
}
static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
@@ -14456,8 +14578,7 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc,
/* Free temporary community list string allocated by
argv_concat(). */
- if (str)
- XFREE(MTYPE_TMP, str);
+ XFREE(MTYPE_TMP, str);
if (ret < 0) {
community_list_perror(vty, ret);
@@ -14508,8 +14629,7 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
/* Free temporary community list string allocated by
argv_concat(). */
- if (str)
- XFREE(MTYPE_TMP, str);
+ XFREE(MTYPE_TMP, str);
if (ret < 0) {
community_list_perror(vty, ret);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index f833ab89d7..5f0b20e029 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1586,8 +1586,7 @@ struct bgp_redist *bgp_redist_add(struct bgp *bgp, afi_t afi, uint8_t type,
bgp->redist[afi][type] = list_new();
red_list = bgp->redist[afi][type];
- red = (struct bgp_redist *)XCALLOC(MTYPE_BGP_REDIST,
- sizeof(struct bgp_redist));
+ red = XCALLOC(MTYPE_BGP_REDIST, sizeof(struct bgp_redist));
red->instance = instance;
listnode_add(red_list, red);
@@ -1694,8 +1693,7 @@ int bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
if (red->rmap.name && (strcmp(red->rmap.name, name) == 0))
return 0;
- if (red->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
/* Decrement the count for existing routemap and
* increment the count for new route map.
*/
@@ -1808,8 +1806,7 @@ int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type,
bgp_redistribute_unreg(bgp, afi, type, instance);
/* Unset route-map. */
- if (red->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
route_map_counter_decrement(red->rmap.map);
red->rmap.name = NULL;
red->rmap.map = NULL;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index e7361ca0c6..54e8f5f369 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -116,7 +116,7 @@ static int bgp_check_main_socket(bool create, struct bgp *bgp)
{
static int bgp_server_main_created;
- if (create == true) {
+ if (create) {
if (bgp_server_main_created)
return 0;
if (bgp_socket(bgp, bm->port, bm->address) < 0)
@@ -1108,8 +1108,7 @@ static void peer_free(struct peer *peer)
peer->update_if = NULL;
}
- if (peer->notify.data)
- XFREE(MTYPE_TMP, peer->notify.data);
+ XFREE(MTYPE_TMP, peer->notify.data);
memset(&peer->notify, 0, sizeof(struct bgp_notify));
if (peer->clear_node_queue)
@@ -1331,8 +1330,7 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
peer_dst->update_source =
sockunion_dup(peer_src->update_source);
} else if (peer_src->update_if) {
- if (peer_dst->update_if)
- XFREE(MTYPE_PEER_UPDATE_SOURCE, peer_dst->update_if);
+ XFREE(MTYPE_PEER_UPDATE_SOURCE, peer_dst->update_if);
if (peer_dst->update_source) {
sockunion_free(peer_dst->update_source);
peer_dst->update_source = NULL;
@@ -1342,8 +1340,7 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
}
if (peer_src->ifname) {
- if (peer_dst->ifname)
- XFREE(MTYPE_BGP_PEER_IFNAME, peer_dst->ifname);
+ XFREE(MTYPE_BGP_PEER_IFNAME, peer_dst->ifname);
peer_dst->ifname =
XSTRDUP(MTYPE_BGP_PEER_IFNAME, peer_src->ifname);
@@ -1550,14 +1547,12 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
peer->su = *su;
else
bgp_peer_conf_if_to_su_update(peer);
- if (peer->host)
- XFREE(MTYPE_BGP_PEER_HOST, peer->host);
+ XFREE(MTYPE_BGP_PEER_HOST, peer->host);
peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if);
} else if (su) {
peer->su = *su;
sockunion2str(su, buf, SU_ADDRSTRLEN);
- if (peer->host)
- XFREE(MTYPE_BGP_PEER_HOST, peer->host);
+ XFREE(MTYPE_BGP_PEER_HOST, peer->host);
peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf);
}
peer->local_as = local_as;
@@ -2393,8 +2388,7 @@ static int peer_group_cmp(struct peer_group *g1, struct peer_group *g2)
/* Peer group cofiguration. */
static struct peer_group *peer_group_new(void)
{
- return (struct peer_group *)XCALLOC(MTYPE_PEER_GROUP,
- sizeof(struct peer_group));
+ return XCALLOC(MTYPE_PEER_GROUP, sizeof(struct peer_group));
}
static void peer_group_free(struct peer_group *group)
@@ -2425,8 +2419,7 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
group = peer_group_new();
group->bgp = bgp;
- if (group->name)
- XFREE(MTYPE_PEER_GROUP_HOST, group->name);
+ XFREE(MTYPE_PEER_GROUP_HOST, group->name);
group->name = XSTRDUP(MTYPE_PEER_GROUP_HOST, name);
group->peer = list_new();
for (afi = AFI_IP; afi < AFI_MAX; afi++)
@@ -2434,8 +2427,7 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
group->conf = peer_new(bgp);
if (!bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
- if (group->conf->host)
- XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
+ XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name);
group->conf->group = group;
group->conf->as = 0;
@@ -2731,7 +2723,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
peer->sort = group->conf->sort;
}
- if (!group->conf->as) {
+ if (!group->conf->as && peer_sort(peer)) {
if (peer_sort(group->conf) != BGP_PEER_INTERNAL
&& peer_sort(group->conf) != peer_sort(peer)) {
if (as)
@@ -2895,8 +2887,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
: VRF_UNKNOWN;
bgp->peer_self = peer_new(bgp);
- if (bgp->peer_self->host)
- XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
+ XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
bgp->peer_self->host =
XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
if (bgp->peer_self->hostname != NULL) {
@@ -3413,8 +3404,7 @@ void bgp_free(struct bgp *bgp)
if (bgp->rib[afi][safi])
bgp_table_finish(&bgp->rib[afi][safi]);
rmap = &bgp->table_map[afi][safi];
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
}
bgp_scan_finish(bgp);
@@ -3444,10 +3434,8 @@ void bgp_free(struct bgp *bgp)
ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
}
- if (bgp->name)
- XFREE(MTYPE_BGP, bgp->name);
- if (bgp->name_pretty)
- XFREE(MTYPE_BGP, bgp->name_pretty);
+ XFREE(MTYPE_BGP, bgp->name);
+ XFREE(MTYPE_BGP, bgp->name_pretty);
XFREE(MTYPE_BGP, bgp);
}
@@ -4377,8 +4365,7 @@ int peer_ebgp_multihop_unset(struct peer *peer)
/* Neighbor description. */
int peer_description_set(struct peer *peer, const char *desc)
{
- if (peer->desc)
- XFREE(MTYPE_PEER_DESC, peer->desc);
+ XFREE(MTYPE_PEER_DESC, peer->desc);
peer->desc = XSTRDUP(MTYPE_PEER_DESC, desc);
@@ -4387,8 +4374,7 @@ int peer_description_set(struct peer *peer, const char *desc)
int peer_description_unset(struct peer *peer)
{
- if (peer->desc)
- XFREE(MTYPE_PEER_DESC, peer->desc);
+ XFREE(MTYPE_PEER_DESC, peer->desc);
peer->desc = NULL;
@@ -5134,15 +5120,13 @@ int peer_advertise_interval_unset(struct peer *peer)
/* neighbor interface */
void peer_interface_set(struct peer *peer, const char *str)
{
- if (peer->ifname)
- XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
+ XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
peer->ifname = XSTRDUP(MTYPE_BGP_PEER_IFNAME, str);
}
void peer_interface_unset(struct peer *peer)
{
- if (peer->ifname)
- XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
+ XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
peer->ifname = NULL;
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 8f8696438b..7a77c8b3ee 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -99,6 +99,9 @@ enum bgp_af_index {
for (afi = AFI_IP; afi < AFI_MAX; afi++) \
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+#define FOREACH_SAFI(safi) \
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+
extern struct frr_pthread *bgp_pth_io;
extern struct frr_pthread *bgp_pth_ka;
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index d621d58e48..2220f0ed9a 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -3457,8 +3457,7 @@ static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */
ecommunity_free(&rfg->rt_export_list);
if (rfg->labels)
list_delete(&rfg->labels);
- if (rfg->rfp_cfg)
- XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
+ XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
listnode_delete(bgp->rfapi_cfg->l2_groups, rfg);
rfapi_l2_group_del(rfg);
@@ -3815,8 +3814,7 @@ struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
struct rfapi_cfg *h;
afi_t afi;
- h = (struct rfapi_cfg *)XCALLOC(MTYPE_RFAPI_CFG,
- sizeof(struct rfapi_cfg));
+ h = XCALLOC(MTYPE_RFAPI_CFG, sizeof(struct rfapi_cfg));
assert(h);
h->nve_groups_sequential = list_new();
@@ -3878,8 +3876,7 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
ecommunity_free(&h->default_rt_export_list);
if (h->default_rt_import_list)
ecommunity_free(&h->default_rt_import_list);
- if (h->default_rfp_cfg)
- XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
+ XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
agg_table_finish(h->nve_groups_vn[afi]);
agg_table_finish(h->nve_groups_un[afi]);
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index df2d404f69..93729c1476 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -4285,7 +4285,7 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp)
assert(bgp->rfapi_cfg == NULL);
- h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi));
+ h = XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi));
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
h->un[afi] = agg_table_init();
diff --git a/bgpd/rfapi/vnc_debug.c b/bgpd/rfapi/vnc_debug.c
index 2b08ea493c..cb9799870b 100644
--- a/bgpd/rfapi/vnc_debug.c
+++ b/bgpd/rfapi/vnc_debug.c
@@ -190,7 +190,7 @@ static int bgp_vnc_config_write_debug(struct vty *vty)
int write = 0;
size_t i;
- for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) {
+ for (i = 0; i < array_size(vncdebug); ++i) {
if (conf_vnc_debug & vncdebug[i].bit) {
vty_out(vty, "debug bgp vnc %s\n", vncdebug[i].name);
write++;
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index 98f719969c..b08e922962 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -608,10 +608,8 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp,
add);
}
- if (nhp_ary)
- XFREE(MTYPE_TMP, nhp_ary);
- if (nh_ary)
- XFREE(MTYPE_TMP, nh_ary);
+ XFREE(MTYPE_TMP, nhp_ary);
+ XFREE(MTYPE_TMP, nh_ary);
}
void vnc_zebra_add_prefix(struct bgp *bgp,
@@ -789,10 +787,8 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp,
}
}
}
- if (nhp_ary)
- XFREE(MTYPE_TMP, nhp_ary);
- if (nh_ary)
- XFREE(MTYPE_TMP, nh_ary);
+ XFREE(MTYPE_TMP, nhp_ary);
+ XFREE(MTYPE_TMP, nh_ary);
}
}
diff --git a/configure.ac b/configure.ac
index fcfc4bd2fb..9ae196fcb1 100755
--- a/configure.ac
+++ b/configure.ac
@@ -765,7 +765,7 @@ AC_DEFINE_UNQUOTED([CONFIGFILE_MASK], [${enable_configfile_mask}], [Mask for con
enable_logfile_mask=${enable_logfile_mask:-0600}
AC_DEFINE_UNQUOTED([LOGFILE_MASK], [${enable_logfile_mask}], [Mask for log files])
-MPATH_NUM=1
+MPATH_NUM=16
case "${enable_multipath}" in
0)
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 4e1582ccd8..e191ebd035 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -275,7 +275,8 @@ options from the list below.
For backwards compatability with older configure options when setting X = 0,
we will build FRR with 64 way ECMP. This is needed because there are
hardcoded arrays that FRR builds towards, so we need to know how big to
- make these arrays at build time.
+ make these arrays at build time. Additionally if this parameter is
+ not passed in FRR will default to 16 ECMP.
.. option:: --enable-shell-access
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
index 374114cf55..22f5a5ddb1 100644
--- a/eigrpd/eigrp_fsm.c
+++ b/eigrpd/eigrp_fsm.c
@@ -231,7 +231,7 @@ static const char *fsm_state2str(enum eigrp_fsm_events event)
return "Query from Successor while in active state";
case EIGRP_FSM_EVENT_LR_FCN:
return "Last Reply Event, Feasibility not satisfied";
- };
+ }
return "Unknown";
}
diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c
index b4d850be08..dacd5caeb5 100644
--- a/eigrpd/eigrp_hello.c
+++ b/eigrpd/eigrp_hello.c
@@ -577,8 +577,6 @@ static uint16_t eigrp_next_sequence_encode(struct stream *s)
static uint16_t eigrp_hello_parameter_encode(struct eigrp_interface *ei,
struct stream *s, uint8_t flags)
{
- uint16_t length = EIGRP_TLV_PARAMETER_LEN;
-
// add in the parameters TLV
stream_putw(s, EIGRP_TLV_PARAMETER);
stream_putw(s, EIGRP_TLV_PARAMETER_LEN);
@@ -605,7 +603,7 @@ static uint16_t eigrp_hello_parameter_encode(struct eigrp_interface *ei,
// and set hold time value..
stream_putw(s, ei->params.v_wait);
- return length;
+ return EIGRP_TLV_PARAMETER_LEN;
}
/**
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
index a9b103de47..fc5bdbdbc5 100644
--- a/eigrpd/eigrp_vty.c
+++ b/eigrpd/eigrp_vty.c
@@ -1499,8 +1499,6 @@ static int eigrp_config_write(struct vty *vty)
{
struct eigrp *eigrp;
- int write = 0;
-
eigrp = eigrp_lookup();
if (eigrp != NULL) {
/* Writes 'router eigrp' section to config */
@@ -1525,7 +1523,7 @@ static int eigrp_config_write(struct vty *vty)
// config_write_eigrp_distance (vty, eigrp)
}
- return write;
+ return 0;
}
void eigrp_vty_show_init(void)
diff --git a/isisd/dict.c b/isisd/dict.c
index 5d3e61e6d6..d91f05d254 100644
--- a/isisd/dict.c
+++ b/isisd/dict.c
@@ -1095,10 +1095,10 @@ void dict_load_end(dict_load_t *load)
baselevel = level = 1;
complete = tree[0];
- if (complete != 0) {
+ if (complete != NULL) {
tree[0] = 0;
complete->right = dictnil;
- while (tree[level] != 0) {
+ while (tree[level] != NULL) {
tree[level]->right = complete;
complete->parent = tree[level];
complete = tree[level];
@@ -1114,7 +1114,7 @@ void dict_load_end(dict_load_t *load)
complete = curr;
assert(level == baselevel);
- while (tree[level] != 0) {
+ while (tree[level] != NULL) {
tree[level]->right = complete;
complete->parent = tree[level];
complete = tree[level];
@@ -1134,7 +1134,7 @@ void dict_load_end(dict_load_t *load)
complete = dictnil;
for (i = 0; i < DICT_DEPTH_MAX; i++) {
- if (tree[i] != 0) {
+ if (tree[i] != NULL) {
tree[i]->right = complete;
complete->parent = tree[i];
complete = tree[i];
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index e1cdfc30ea..62814329ea 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -140,12 +140,9 @@ void isis_delete_adj(void *arg)
/* remove from SPF trees */
spftree_area_adj_del(adj->circuit->area, adj);
- if (adj->area_addresses)
- XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
- if (adj->ipv4_addresses)
- XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses);
- if (adj->ipv6_addresses)
- XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses);
+ XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
+ XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses);
+ XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses);
adj_mt_finish(adj);
diff --git a/isisd/isis_dlpi.c b/isisd/isis_dlpi.c
index 54a19ad239..148b438661 100644
--- a/isisd/isis_dlpi.c
+++ b/isisd/isis_dlpi.c
@@ -444,7 +444,7 @@ static int open_dlpi_dev(struct isis_circuit *circuit)
struct strioctl sioc;
pfil.Pf_Priority = 0;
- pfil.Pf_FilterLen = sizeof(pf_filter) / sizeof(unsigned short);
+ pfil.Pf_FilterLen = array_size(pf_filter);
memcpy(pfil.Pf_Filter, pf_filter, sizeof(pf_filter));
/* pfmod does not support transparent ioctls */
sioc.ic_cmd = PFIOCSETF;
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 9126e40d42..e74a9baadd 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -80,7 +80,7 @@ struct zebra_privs_t isisd_privs = {
.vty_group = VTY_GROUP,
#endif
.caps_p = _caps_p,
- .cap_num_p = sizeof(_caps_p) / sizeof(*_caps_p),
+ .cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
/* isisd options */
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 330da9b216..107de47f3d 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -2146,11 +2146,11 @@ int send_csnp(struct isis_circuit *circuit, int level)
* stop lsp_id in this current CSNP.
*/
memcpy(start, stop, ISIS_SYS_ID_LEN + 2);
- loop = 0;
+ loop = false;
for (int i = ISIS_SYS_ID_LEN + 1; i >= 0; --i) {
if (start[i] < (uint8_t)0xff) {
start[i] += 1;
- loop = 1;
+ loop = true;
break;
}
}
@@ -2164,7 +2164,6 @@ int send_csnp(struct isis_circuit *circuit, int level)
int send_l1_csnp(struct thread *thread)
{
struct isis_circuit *circuit;
- int retval = ISIS_OK;
circuit = THREAD_ARG(thread);
assert(circuit);
@@ -2181,13 +2180,12 @@ int send_l1_csnp(struct thread *thread)
isis_jitter(circuit->csnp_interval[0], CSNP_JITTER),
&circuit->t_send_csnp[0]);
- return retval;
+ return ISIS_OK;
}
int send_l2_csnp(struct thread *thread)
{
struct isis_circuit *circuit;
- int retval = ISIS_OK;
circuit = THREAD_ARG(thread);
assert(circuit);
@@ -2204,7 +2202,7 @@ int send_l2_csnp(struct thread *thread)
isis_jitter(circuit->csnp_interval[1], CSNP_JITTER),
&circuit->t_send_csnp[1]);
- return retval;
+ return ISIS_OK;
}
/*
@@ -2329,7 +2327,6 @@ int send_l1_psnp(struct thread *thread)
{
struct isis_circuit *circuit;
- int retval = ISIS_OK;
circuit = THREAD_ARG(thread);
assert(circuit);
@@ -2342,7 +2339,7 @@ int send_l1_psnp(struct thread *thread)
isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
&circuit->t_send_psnp[0]);
- return retval;
+ return ISIS_OK;
}
/*
@@ -2352,7 +2349,6 @@ int send_l1_psnp(struct thread *thread)
int send_l2_psnp(struct thread *thread)
{
struct isis_circuit *circuit;
- int retval = ISIS_OK;
circuit = THREAD_ARG(thread);
assert(circuit);
@@ -2366,7 +2362,7 @@ int send_l2_psnp(struct thread *thread)
isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
&circuit->t_send_psnp[1]);
- return retval;
+ return ISIS_OK;
}
/*
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 20f3e62a74..3a864fb356 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -504,8 +504,7 @@ void isis_redist_area_finish(struct isis_area *area)
redist = &area->redist_settings[protocol][type]
[level];
redist->redist = 0;
- if (redist->map_name)
- XFREE(MTYPE_ISIS, redist->map_name);
+ XFREE(MTYPE_ISIS, redist->map_name);
}
route_table_finish(area->ext_reach[protocol][level]);
}
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 5a6c7bc300..fbb1e5714c 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -1913,7 +1913,7 @@ static void format_item_auth(uint16_t mtid, struct isis_item *i,
default:
sbuf_push(buf, indent, " Unknown (%" PRIu8 ")\n", auth->type);
break;
- };
+ }
}
static void free_item_auth(struct isis_item *i)
@@ -3202,8 +3202,7 @@ void isis_tlvs_set_protocols_supported(struct isis_tlvs *tlvs,
struct nlpids *nlpids)
{
tlvs->protocols_supported.count = nlpids->count;
- if (tlvs->protocols_supported.protocols)
- XFREE(MTYPE_ISIS_TLV, tlvs->protocols_supported.protocols);
+ XFREE(MTYPE_ISIS_TLV, tlvs->protocols_supported.protocols);
if (nlpids->count) {
tlvs->protocols_supported.protocols =
XCALLOC(MTYPE_ISIS_TLV, nlpids->count);
diff --git a/lib/command.c b/lib/command.c
index b46241ac87..559457c119 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -1277,8 +1277,7 @@ int cmd_execute(struct vty *vty, const char *cmd,
hook_call(cmd_execute_done, vty, cmd_exec);
- if (cmd_out)
- XFREE(MTYPE_TMP, cmd_out);
+ XFREE(MTYPE_TMP, cmd_out);
return ret;
}
@@ -2408,8 +2407,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
ret = zlog_set_file(fullpath, loglevel);
- if (p)
- XFREE(MTYPE_TMP, p);
+ XFREE(MTYPE_TMP, p);
if (!ret) {
if (vty)
@@ -2417,8 +2415,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
return CMD_WARNING_CONFIG_FAILED;
}
- if (host.logfile)
- XFREE(MTYPE_HOST, host.logfile);
+ XFREE(MTYPE_HOST, host.logfile);
host.logfile = XSTRDUP(MTYPE_HOST, fname);
@@ -2487,8 +2484,7 @@ static void disable_log_file(void)
{
zlog_reset_file();
- if (host.logfile)
- XFREE(MTYPE_HOST, host.logfile);
+ XFREE(MTYPE_HOST, host.logfile);
host.logfile = NULL;
}
@@ -2637,8 +2633,7 @@ int cmd_banner_motd_file(const char *file)
return CMD_ERR_NO_FILE;
in = strstr(rpath, SYSCONFDIR);
if (in == rpath) {
- if (host.motdfile)
- XFREE(MTYPE_HOST, host.motdfile);
+ XFREE(MTYPE_HOST, host.motdfile);
host.motdfile = XSTRDUP(MTYPE_HOST, file);
} else
success = CMD_WARNING_CONFIG_FAILED;
@@ -2723,8 +2718,7 @@ DEFUN(find,
/* Set config filename. Called from vty.c */
void host_config_set(const char *filename)
{
- if (host.config)
- XFREE(MTYPE_HOST, host.config);
+ XFREE(MTYPE_HOST, host.config);
host.config = XSTRDUP(MTYPE_HOST, filename);
}
@@ -2904,24 +2898,15 @@ void cmd_terminate(void)
cmdvec = NULL;
}
- if (host.name)
- XFREE(MTYPE_HOST, host.name);
- if (host.domainname)
- XFREE(MTYPE_HOST, host.domainname);
- if (host.password)
- XFREE(MTYPE_HOST, host.password);
- if (host.password_encrypt)
- XFREE(MTYPE_HOST, host.password_encrypt);
- if (host.enable)
- XFREE(MTYPE_HOST, host.enable);
- if (host.enable_encrypt)
- XFREE(MTYPE_HOST, host.enable_encrypt);
- if (host.logfile)
- XFREE(MTYPE_HOST, host.logfile);
- if (host.motdfile)
- XFREE(MTYPE_HOST, host.motdfile);
- if (host.config)
- XFREE(MTYPE_HOST, host.config);
+ XFREE(MTYPE_HOST, host.name);
+ XFREE(MTYPE_HOST, host.domainname);
+ XFREE(MTYPE_HOST, host.password);
+ XFREE(MTYPE_HOST, host.password_encrypt);
+ XFREE(MTYPE_HOST, host.enable);
+ XFREE(MTYPE_HOST, host.enable_encrypt);
+ XFREE(MTYPE_HOST, host.logfile);
+ XFREE(MTYPE_HOST, host.motdfile);
+ XFREE(MTYPE_HOST, host.config);
list_delete(&varhandlers);
qobj_finish();
diff --git a/lib/command_graph.c b/lib/command_graph.c
index 0e8669c4b5..4757fd951f 100644
--- a/lib/command_graph.c
+++ b/lib/command_graph.c
@@ -471,7 +471,7 @@ void cmd_graph_node_print_cb(struct graph_node *gn, struct buffer *buf)
struct cmd_token *tok = gn->data;
const char *color;
- if (wasend == true) {
+ if (wasend) {
wasend = false;
return;
}
diff --git a/lib/distribute.c b/lib/distribute.c
index 7cc10a230d..fa8ac5242e 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -44,16 +44,15 @@ static void distribute_free(struct distribute *dist)
{
int i = 0;
- if (dist->ifname)
- XFREE(MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
+ XFREE(MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
- for (i = 0; i < DISTRIBUTE_MAX; i++)
- if (dist->list[i])
- XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[i]);
+ for (i = 0; i < DISTRIBUTE_MAX; i++) {
+ XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[i]);
+ }
- for (i = 0; i < DISTRIBUTE_MAX; i++)
- if (dist->prefix[i])
- XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[i]);
+ for (i = 0; i < DISTRIBUTE_MAX; i++) {
+ XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[i]);
+ }
XFREE(MTYPE_DISTRIBUTE, dist);
}
@@ -83,8 +82,7 @@ struct distribute *distribute_lookup(struct distribute_ctx *ctx,
dist = hash_lookup(ctx->disthash, &key);
- if (key.ifname)
- XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
+ XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
return dist;
}
@@ -128,8 +126,7 @@ static struct distribute *distribute_get(struct distribute_ctx *ctx,
ret = hash_get(ctx->disthash, &key,
(void *(*)(void *))distribute_hash_alloc);
- if (key.ifname)
- XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
+ XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
return ret;
}
@@ -163,8 +160,7 @@ static void distribute_list_set(struct distribute_ctx *ctx,
dist = distribute_get(ctx, ifname);
- if (dist->list[type])
- XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
+ XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
/* Apply this distribute-list to the interface. */
@@ -210,8 +206,7 @@ static void distribute_list_prefix_set(struct distribute_ctx *ctx,
dist = distribute_get(ctx, ifname);
- if (dist->prefix[type])
- XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
+ XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
/* Apply this distribute-list to the interface. */
diff --git a/lib/filter.c b/lib/filter.c
index 317c1b68b7..276df4b4d7 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -128,8 +128,7 @@ static struct access_master *access_master_get(afi_t afi)
/* Allocate new filter structure. */
static struct filter *filter_new(void)
{
- return (struct filter *)XCALLOC(MTYPE_ACCESS_FILTER,
- sizeof(struct filter));
+ return XCALLOC(MTYPE_ACCESS_FILTER, sizeof(struct filter));
}
static void filter_free(struct filter *filter)
@@ -202,8 +201,7 @@ static int filter_match_zebra(struct filter *mfilter, const struct prefix *p)
/* Allocate new access list structure. */
static struct access_list *access_list_new(void)
{
- return (struct access_list *)XCALLOC(MTYPE_ACCESS_LIST,
- sizeof(struct access_list));
+ return XCALLOC(MTYPE_ACCESS_LIST, sizeof(struct access_list));
}
/* Free allocated access_list. */
@@ -242,11 +240,9 @@ static void access_list_delete(struct access_list *access)
else
list->head = access->next;
- if (access->name)
- XFREE(MTYPE_ACCESS_LIST_STR, access->name);
+ XFREE(MTYPE_ACCESS_LIST_STR, access->name);
- if (access->remark)
- XFREE(MTYPE_TMP, access->remark);
+ XFREE(MTYPE_TMP, access->remark);
access_list_free(access);
}
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c
index d7f655271b..2a18e5cfc6 100644
--- a/lib/frr_pthread.c
+++ b/lib/frr_pthread.c
@@ -110,8 +110,7 @@ void frr_pthread_destroy(struct frr_pthread *fpt)
pthread_mutex_destroy(&fpt->mtx);
pthread_mutex_destroy(fpt->running_cond_mtx);
pthread_cond_destroy(fpt->running_cond);
- if (fpt->name)
- XFREE(MTYPE_FRR_PTHREAD, fpt->name);
+ XFREE(MTYPE_FRR_PTHREAD, fpt->name);
XFREE(MTYPE_PTHREAD_PRIM, fpt->running_cond_mtx);
XFREE(MTYPE_PTHREAD_PRIM, fpt->running_cond);
XFREE(MTYPE_FRR_PTHREAD, fpt);
diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c
index cfea238d95..7781beae5e 100644
--- a/lib/frr_zmq.c
+++ b/lib/frr_zmq.c
@@ -176,8 +176,6 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master,
cb = *cbp;
else {
cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb));
- if (!cb)
- return -1;
cb->write.cancelled = 1;
*cbp = cb;
@@ -286,8 +284,6 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master,
cb = *cbp;
else {
cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb));
- if (!cb)
- return -1;
cb->read.cancelled = 1;
*cbp = cb;
diff --git a/lib/frrstr.c b/lib/frrstr.c
index 85d968182b..fd337073f8 100644
--- a/lib/frrstr.c
+++ b/lib/frrstr.c
@@ -155,13 +155,13 @@ void frrstr_strvec_free(vector v)
bool begins_with(const char *str, const char *prefix)
{
if (!str || !prefix)
- return 0;
+ return false;
size_t lenstr = strlen(str);
size_t lenprefix = strlen(prefix);
if (lenprefix > lenstr)
- return 0;
+ return false;
return strncmp(str, prefix, lenprefix) == 0;
}
diff --git a/lib/hash.c b/lib/hash.c
index 9f9fc31d37..c02b81814c 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -95,8 +95,6 @@ static void hash_expand(struct hash *hash)
new_index = XCALLOC(MTYPE_HASH_INDEX,
sizeof(struct hash_bucket *) * new_size);
- if (new_index == NULL)
- return;
hash->stats.empty = new_size;
@@ -324,8 +322,7 @@ void hash_free(struct hash *hash)
}
pthread_mutex_unlock(&_hashes_mtx);
- if (hash->name)
- XFREE(MTYPE_HASH, hash->name);
+ XFREE(MTYPE_HASH, hash->name);
XFREE(MTYPE_HASH_INDEX, hash->index);
XFREE(MTYPE_HASH, hash);
diff --git a/lib/if.c b/lib/if.c
index 48841c7ee8..abcc6c5d3c 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -234,8 +234,7 @@ void if_delete(struct interface *ifp)
if_link_params_free(ifp);
- if (ifp->desc)
- XFREE(MTYPE_TMP, ifp->desc);
+ XFREE(MTYPE_TMP, ifp->desc);
XFREE(MTYPE_IF, ifp);
}
@@ -708,8 +707,7 @@ void connected_free(struct connected *connected)
if (connected->destination)
prefix_free(connected->destination);
- if (connected->label)
- XFREE(MTYPE_CONNECTED_LABEL, connected->label);
+ XFREE(MTYPE_CONNECTED_LABEL, connected->label);
XFREE(MTYPE_CONNECTED, connected);
}
@@ -1349,8 +1347,7 @@ static int lib_interface_description_modify(enum nb_event event,
return NB_OK;
ifp = yang_dnode_get_entry(dnode, true);
- if (ifp->desc)
- XFREE(MTYPE_TMP, ifp->desc);
+ XFREE(MTYPE_TMP, ifp->desc);
description = yang_dnode_get_string(dnode, NULL);
ifp->desc = XSTRDUP(MTYPE_TMP, description);
@@ -1366,8 +1363,7 @@ static int lib_interface_description_delete(enum nb_event event,
return NB_OK;
ifp = yang_dnode_get_entry(dnode, true);
- if (ifp->desc)
- XFREE(MTYPE_TMP, ifp->desc);
+ XFREE(MTYPE_TMP, ifp->desc);
return NB_OK;
}
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 53bbcbfe57..955c1417c4 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -44,13 +44,10 @@ static struct if_rmap *if_rmap_new(void)
static void if_rmap_free(struct if_rmap *if_rmap)
{
- if (if_rmap->ifname)
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->ifname);
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->ifname);
- if (if_rmap->routemap[IF_RMAP_IN])
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
- if (if_rmap->routemap[IF_RMAP_OUT])
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
XFREE(MTYPE_IF_RMAP, if_rmap);
}
@@ -65,8 +62,7 @@ struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx, const char *ifname)
if_rmap = hash_lookup(ctx->ifrmaphash, &key);
- if (key.ifname)
- XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
+ XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
return if_rmap;
}
@@ -106,8 +102,7 @@ static struct if_rmap *if_rmap_get(struct if_rmap_ctx *ctx, const char *ifname)
ret = hash_get(ctx->ifrmaphash, &key, if_rmap_hash_alloc);
- if (key.ifname)
- XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
+ XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
return ret;
}
@@ -136,16 +131,12 @@ static struct if_rmap *if_rmap_set(struct if_rmap_ctx *ctx,
if_rmap = if_rmap_get(ctx, ifname);
if (type == IF_RMAP_IN) {
- if (if_rmap->routemap[IF_RMAP_IN])
- XFREE(MTYPE_IF_RMAP_NAME,
- if_rmap->routemap[IF_RMAP_IN]);
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
if_rmap->routemap[IF_RMAP_IN] =
XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
}
if (type == IF_RMAP_OUT) {
- if (if_rmap->routemap[IF_RMAP_OUT])
- XFREE(MTYPE_IF_RMAP_NAME,
- if_rmap->routemap[IF_RMAP_OUT]);
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
if_rmap->routemap[IF_RMAP_OUT] =
XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
}
diff --git a/lib/imsg.c b/lib/imsg.c
index 935d137727..57e70617d2 100644
--- a/lib/imsg.c
+++ b/lib/imsg.c
@@ -18,6 +18,7 @@
#include <zebra.h>
+#include "memory.h"
#include "queue.h"
#include "imsg.h"
@@ -35,7 +36,7 @@ static int available_fds(unsigned int n)
unsigned int i;
int ret, fds[256];
- if (n > (sizeof(fds) / sizeof(fds[0])))
+ if (n > (unsigned int)array_size(fds))
return (1);
ret = 0;
diff --git a/lib/jhash.c b/lib/jhash.c
index cb6946f37e..0d561ef3a4 100644
--- a/lib/jhash.c
+++ b/lib/jhash.c
@@ -116,7 +116,7 @@ uint32_t jhash(const void *key, uint32_t length, uint32_t initval)
/* fallthru */
case 1:
a += k[0];
- };
+ }
__jhash_mix(a, b, c);
@@ -151,7 +151,7 @@ uint32_t jhash2(const uint32_t *k, uint32_t length, uint32_t initval)
/* fallthru */
case 1:
a += k[0];
- };
+ }
__jhash_mix(a, b, c);
diff --git a/lib/keychain.c b/lib/keychain.c
index 9aa3ef695f..0a96c4cf0e 100644
--- a/lib/keychain.c
+++ b/lib/keychain.c
@@ -116,8 +116,7 @@ static struct keychain *keychain_get(const char *name)
static void keychain_delete(struct keychain *keychain)
{
- if (keychain->name)
- XFREE(MTYPE_KEYCHAIN, keychain->name);
+ XFREE(MTYPE_KEYCHAIN, keychain->name);
list_delete(&keychain->key);
listnode_delete(keychain_list, keychain);
@@ -217,8 +216,7 @@ static void key_delete(struct keychain *keychain, struct key *key)
{
listnode_delete(keychain->key, key);
- if (key->string)
- XFREE(MTYPE_KEY, key->string);
+ XFREE(MTYPE_KEY, key->string);
key_free(key);
}
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 9119b04992..1afe30d618 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -61,7 +61,7 @@ static char dbfile_default[512];
#endif
static char vtypath_default[256];
-bool debug_memstats_at_exit = 0;
+bool debug_memstats_at_exit = false;
static bool nodetach_term, nodetach_daemon;
static char comb_optstr[256];
diff --git a/lib/log.c b/lib/log.c
index c424a5bc98..e98040eb06 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -851,8 +851,7 @@ void closezlog(void)
if (zl->fp != NULL)
fclose(zl->fp);
- if (zl->filename != NULL)
- XFREE(MTYPE_ZLOG, zl->filename);
+ XFREE(MTYPE_ZLOG, zl->filename);
XFREE(MTYPE_ZLOG, zl);
zlog_default = NULL;
@@ -911,8 +910,7 @@ int zlog_reset_file(void)
logfile_fd = -1;
zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED;
- if (zl->filename)
- XFREE(MTYPE_ZLOG, zl->filename);
+ XFREE(MTYPE_ZLOG, zl->filename);
zl->filename = NULL;
pthread_mutex_unlock(&loglock);
diff --git a/lib/module.c b/lib/module.c
index 6754b94579..098c550684 100644
--- a/lib/module.c
+++ b/lib/module.c
@@ -141,8 +141,7 @@ struct frrmod_runtime *frrmod_load(const char *spec, const char *dir, char *err,
return rtinfo;
out_fail:
- if (rtinfo->load_args)
- XFREE(MTYPE_MODULE_LOADARGS, rtinfo->load_args);
+ XFREE(MTYPE_MODULE_LOADARGS, rtinfo->load_args);
XFREE(MTYPE_MODULE_LOADNAME, rtinfo->load_name);
return NULL;
}
diff --git a/lib/netns_linux.c b/lib/netns_linux.c
index ef2f5dc953..55c66fdc3d 100644
--- a/lib/netns_linux.c
+++ b/lib/netns_linux.c
@@ -344,8 +344,7 @@ void ns_delete(struct ns *ns)
// if_terminate (&ns->iflist);
RB_REMOVE(ns_head, &ns_tree, ns);
- if (ns->name)
- XFREE(MTYPE_NS_NAME, ns->name);
+ XFREE(MTYPE_NS_NAME, ns->name);
XFREE(MTYPE_NS, ns);
}
diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c
index 23ea96f75c..f940418d83 100644
--- a/lib/nexthop_group.c
+++ b/lib/nexthop_group.c
@@ -205,11 +205,9 @@ static int nhgl_cmp(struct nexthop_hold *nh1, struct nexthop_hold *nh2)
static void nhgl_delete(struct nexthop_hold *nh)
{
- if (nh->intf)
- XFREE(MTYPE_TMP, nh->intf);
+ XFREE(MTYPE_TMP, nh->intf);
- if (nh->nhvrf_name)
- XFREE(MTYPE_TMP, nh->nhvrf_name);
+ XFREE(MTYPE_TMP, nh->nhvrf_name);
XFREE(MTYPE_TMP, nh);
}
diff --git a/lib/northbound.c b/lib/northbound.c
index 15139aa8d0..edf7e0eca6 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -348,39 +348,58 @@ static void nb_config_diff_del_changes(struct nb_config_cbs *changes)
* configurations. Given a new subtree, calculate all new YANG data nodes,
* excluding default leafs and leaf-lists. This is a recursive function.
*/
-static void nb_config_diff_new_subtree(const struct lyd_node *dnode,
- struct nb_config_cbs *changes)
+static void nb_config_diff_created(const struct lyd_node *dnode,
+ struct nb_config_cbs *changes)
{
+ enum nb_operation operation;
struct lyd_node *child;
- LY_TREE_FOR (dnode->child, child) {
- enum nb_operation operation;
+ switch (dnode->schema->nodetype) {
+ case LYS_LEAF:
+ case LYS_LEAFLIST:
+ if (lyd_wd_default((struct lyd_node_leaf_list *)dnode))
+ break;
- switch (child->schema->nodetype) {
- case LYS_LEAF:
- case LYS_LEAFLIST:
- if (lyd_wd_default((struct lyd_node_leaf_list *)child))
- break;
+ if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema))
+ operation = NB_OP_CREATE;
+ else if (nb_operation_is_valid(NB_OP_MODIFY, dnode->schema))
+ operation = NB_OP_MODIFY;
+ else
+ return;
- if (nb_operation_is_valid(NB_OP_CREATE, child->schema))
- operation = NB_OP_CREATE;
- else if (nb_operation_is_valid(NB_OP_MODIFY,
- child->schema))
- operation = NB_OP_MODIFY;
- else
- continue;
+ nb_config_diff_add_change(changes, operation, dnode);
+ break;
+ case LYS_CONTAINER:
+ case LYS_LIST:
+ if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema))
+ nb_config_diff_add_change(changes, NB_OP_CREATE, dnode);
- nb_config_diff_add_change(changes, operation, child);
- break;
- case LYS_CONTAINER:
- case LYS_LIST:
- if (nb_operation_is_valid(NB_OP_CREATE, child->schema))
- nb_config_diff_add_change(changes, NB_OP_CREATE,
- child);
- nb_config_diff_new_subtree(child, changes);
- break;
- default:
- break;
+ /* Process child nodes recursively. */
+ LY_TREE_FOR (dnode->child, child) {
+ nb_config_diff_created(child, changes);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void nb_config_diff_deleted(const struct lyd_node *dnode,
+ struct nb_config_cbs *changes)
+{
+ if (nb_operation_is_valid(NB_OP_DESTROY, dnode->schema))
+ nb_config_diff_add_change(changes, NB_OP_DESTROY, dnode);
+ else if (CHECK_FLAG(dnode->schema->nodetype, LYS_CONTAINER)) {
+ struct lyd_node *child;
+
+ /*
+ * Non-presence containers need special handling since they
+ * don't have "destroy" callbacks. In this case, what we need to
+ * do is to call the "destroy" callbacks of their child nodes
+ * when applicable (i.e. optional nodes).
+ */
+ LY_TREE_FOR (dnode->child, child) {
+ nb_config_diff_deleted(child, changes);
}
}
}
@@ -399,42 +418,27 @@ static void nb_config_diff(const struct nb_config *config1,
for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) {
LYD_DIFFTYPE type;
struct lyd_node *dnode;
- enum nb_operation operation;
type = diff->type[i];
switch (type) {
case LYD_DIFF_CREATED:
dnode = diff->second[i];
-
- if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema))
- operation = NB_OP_CREATE;
- else if (nb_operation_is_valid(NB_OP_MODIFY,
- dnode->schema))
- operation = NB_OP_MODIFY;
- else
- continue;
+ nb_config_diff_created(dnode, changes);
break;
case LYD_DIFF_DELETED:
dnode = diff->first[i];
- operation = NB_OP_DESTROY;
+ nb_config_diff_deleted(dnode, changes);
break;
case LYD_DIFF_CHANGED:
dnode = diff->second[i];
- operation = NB_OP_MODIFY;
+ nb_config_diff_add_change(changes, NB_OP_MODIFY, dnode);
break;
case LYD_DIFF_MOVEDAFTER1:
case LYD_DIFF_MOVEDAFTER2:
default:
continue;
}
-
- nb_config_diff_add_change(changes, operation, dnode);
-
- if (type == LYD_DIFF_CREATED
- && CHECK_FLAG(dnode->schema->nodetype,
- LYS_CONTAINER | LYS_LIST))
- nb_config_diff_new_subtree(dnode, changes);
}
lyd_free_diff(diff);
diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c
index a8e0017819..a499d48c12 100644
--- a/lib/northbound_confd.c
+++ b/lib/northbound_confd.c
@@ -1383,7 +1383,7 @@ error:
static int frr_confd_finish(void)
{
- if (confd_connected == false)
+ if (!confd_connected)
return 0;
frr_confd_finish_cdb();
diff --git a/lib/plist.c b/lib/plist.c
index 41c8e4f8c0..2a97e1e5b2 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -326,8 +326,7 @@ static void prefix_list_delete(struct prefix_list *plist)
else
list->head = plist->next;
- if (plist->desc)
- XFREE(MTYPE_TMP, plist->desc);
+ XFREE(MTYPE_TMP, plist->desc);
/* Make sure master's recent changed prefix-list information is
cleared. */
@@ -338,8 +337,7 @@ static void prefix_list_delete(struct prefix_list *plist)
if (master->delete_hook)
(*master->delete_hook)(plist);
- if (plist->name)
- XFREE(MTYPE_MPREFIX_LIST_STR, plist->name);
+ XFREE(MTYPE_MPREFIX_LIST_STR, plist->name);
XFREE(MTYPE_PREFIX_LIST_TRIE, plist->trie);
diff --git a/lib/pqueue.c b/lib/pqueue.c
index 1565de216e..87b54a681a 100644
--- a/lib/pqueue.c
+++ b/lib/pqueue.c
@@ -133,8 +133,6 @@ static int pqueue_expand(struct pqueue *queue)
newarray =
XCALLOC(MTYPE_PQUEUE_DATA, queue->array_size * DATA_SIZE * 2);
- if (newarray == NULL)
- return 0;
memcpy(newarray, queue->array, queue->array_size * DATA_SIZE);
diff --git a/lib/prefix.c b/lib/prefix.c
index 80a89cc3c7..52bb266f11 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -944,8 +944,7 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
ret = 1;
done:
- if (cp)
- XFREE(MTYPE_TMP, cp);
+ XFREE(MTYPE_TMP, cp);
return ret;
}
@@ -1503,8 +1502,7 @@ char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size)
if (!mac)
return NULL;
if (!buf)
- ptr = (char *)XMALLOC(MTYPE_TMP,
- ETHER_ADDR_STRLEN * sizeof(char));
+ ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char));
else {
assert(size >= ETHER_ADDR_STRLEN);
ptr = buf;
@@ -1585,8 +1583,7 @@ char *esi_to_str(const esi_t *esi, char *buf, int size)
if (!esi)
return NULL;
if (!buf)
- ptr = (char *)XMALLOC(MTYPE_TMP,
- ESI_STR_LEN * sizeof(char));
+ ptr = XMALLOC(MTYPE_TMP, ESI_STR_LEN * sizeof(char));
else {
assert(size >= ESI_STR_LEN);
ptr = buf;
diff --git a/lib/privs.c b/lib/privs.c
index 2932800070..3ce8e0d57a 100644
--- a/lib/privs.c
+++ b/lib/privs.c
@@ -706,6 +706,14 @@ struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs,
if (!privs)
return NULL;
+ /* If we're already elevated, just return */
+ pthread_mutex_lock(&(privs->mutex));
+ if (++privs->refcount > 1) {
+ pthread_mutex_unlock(&(privs->mutex));
+ return privs;
+ }
+ pthread_mutex_unlock(&(privs->mutex));
+
errno = 0;
if (privs->change(ZPRIVS_RAISE)) {
zlog_err("%s: Failed to raise privileges (%s)",
@@ -723,6 +731,14 @@ void _zprivs_lower(struct zebra_privs_t **privs)
if (!*privs)
return;
+ /* Don't lower privs if there's another caller */
+ pthread_mutex_lock(&(*privs)->mutex);
+ if (--((*privs)->refcount) > 0) {
+ pthread_mutex_unlock(&(*privs)->mutex);
+ return;
+ }
+ pthread_mutex_unlock(&(*privs)->mutex);
+
errno = 0;
if ((*privs)->change(ZPRIVS_LOWER)) {
zlog_err("%s: Failed to lower privileges (%s)",
@@ -743,6 +759,9 @@ void zprivs_preinit(struct zebra_privs_t *zprivs)
exit(1);
}
+ pthread_mutex_init(&(zprivs->mutex), NULL);
+ zprivs->refcount = 0;
+
if (zprivs->vty_group) {
/* in a "NULL" setup, this is allowed to fail too, but still
* try. */
diff --git a/lib/privs.h b/lib/privs.h
index 1fee423a95..01ddba4622 100644
--- a/lib/privs.h
+++ b/lib/privs.h
@@ -23,6 +23,8 @@
#ifndef _ZEBRA_PRIVS_H
#define _ZEBRA_PRIVS_H
+#include <pthread.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -59,6 +61,14 @@ struct zebra_privs_t {
zebra_capabilities_t *caps_i; /* caps to allow inheritance of */
int cap_num_p; /* number of caps in arrays */
int cap_num_i;
+
+ /* Mutex and counter used to avoid race conditions in multi-threaded
+ * processes. The privs elevation is process-wide, so we need to
+ * avoid changing the privilege status across threads.
+ */
+ pthread_mutex_t mutex;
+ uint32_t refcount;
+
const char *user; /* user and group to run as */
const char *group;
const char *vty_group; /* group to chown vty socket to */
diff --git a/lib/routemap.c b/lib/routemap.c
index 7c1ee2353c..4898a8d0fa 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -538,10 +538,8 @@ int generic_match_delete(struct vty *vty, struct route_map_index *index,
break;
}
- if (dep_name)
- XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
- if (rmap_name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
return retval;
}
@@ -1075,8 +1073,7 @@ static void route_map_index_delete(struct route_map_index *index, int notify)
index->map->head = index->next;
/* Free 'char *nextrm' if not NULL */
- if (index->nextrm)
- XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
+ XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
/* Execute event hook. */
if (route_map_master.event_hook && notify) {
@@ -1231,8 +1228,7 @@ static void route_map_rule_delete(struct route_map_rule_list *list,
if (rule->cmd->func_free)
(*rule->cmd->func_free)(rule->value);
- if (rule->rule_str)
- XFREE(MTYPE_ROUTE_MAP_RULE_STR, rule->rule_str);
+ XFREE(MTYPE_ROUTE_MAP_RULE_STR, rule->rule_str);
if (rule->next)
rule->next->prev = rule->prev;
@@ -1779,8 +1775,7 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name,
}
ret_map_name = (char *)hash_release(dep->dep_rmap_hash, rname);
- if (ret_map_name)
- XFREE(MTYPE_ROUTE_MAP_NAME, ret_map_name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, ret_map_name);
if (!dep->dep_rmap_hash->count) {
dep = hash_release(dephash, dname);
diff --git a/lib/thread.c b/lib/thread.c
index 055587434c..19ab409439 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -414,8 +414,6 @@ struct thread_master *thread_master_create(const char *name)
pthread_once(&init_once, &initializer);
rv = XCALLOC(MTYPE_THREAD_MASTER, sizeof(struct thread_master));
- if (rv == NULL)
- return NULL;
/* Initialize master mutex */
pthread_mutex_init(&rv->mtx, NULL);
@@ -484,8 +482,7 @@ void thread_master_set_name(struct thread_master *master, const char *name)
{
pthread_mutex_lock(&master->mtx);
{
- if (master->name)
- XFREE(MTYPE_THREAD_MASTER, master->name);
+ XFREE(MTYPE_THREAD_MASTER, master->name);
master->name = XSTRDUP(MTYPE_THREAD_MASTER, name);
}
pthread_mutex_unlock(&master->mtx);
@@ -649,8 +646,7 @@ void thread_master_free(struct thread_master *m)
hash_free(m->cpu_record);
m->cpu_record = NULL;
- if (m->name)
- XFREE(MTYPE_THREAD_MASTER, m->name);
+ XFREE(MTYPE_THREAD_MASTER, m->name);
XFREE(MTYPE_THREAD_MASTER, m->handler.pfds);
XFREE(MTYPE_THREAD_MASTER, m->handler.copy);
XFREE(MTYPE_THREAD_MASTER, m);
diff --git a/lib/vty.c b/lib/vty.c
index d6fda8cbb4..0bcee6a801 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -974,8 +974,7 @@ static void vty_complete_command(struct vty *vty)
default:
break;
}
- if (matched)
- XFREE(MTYPE_TMP, matched);
+ XFREE(MTYPE_TMP, matched);
}
static void vty_describe_fold(struct vty *vty, int cmd_width,
@@ -1169,8 +1168,7 @@ static void vty_hist_add(struct vty *vty)
}
/* Insert history entry. */
- if (vty->hist[vty->hindex])
- XFREE(MTYPE_VTY_HIST, vty->hist[vty->hindex]);
+ XFREE(MTYPE_VTY_HIST, vty->hist[vty->hindex]);
vty->hist[vty->hindex] = XSTRDUP(MTYPE_VTY_HIST, vty->buf);
/* History index rotation. */
@@ -2232,9 +2230,9 @@ void vty_close(struct vty *vty)
buffer_free(vty->lbuf);
/* Free command history. */
- for (i = 0; i < VTY_MAXHIST; i++)
- if (vty->hist[i])
- XFREE(MTYPE_VTY_HIST, vty->hist[i]);
+ for (i = 0; i < VTY_MAXHIST; i++) {
+ XFREE(MTYPE_VTY_HIST, vty->hist[i]);
+ }
/* Unset vector. */
if (vty->fd != -1)
@@ -2255,8 +2253,7 @@ void vty_close(struct vty *vty)
if (vty->fd == STDIN_FILENO)
was_stdio = true;
- if (vty->buf)
- XFREE(MTYPE_VTY, vty->buf);
+ XFREE(MTYPE_VTY, vty->buf);
if (vty->error) {
vty->error->del = vty_error_delete;
@@ -2546,8 +2543,7 @@ bool vty_read_config(struct nb_config *config, const char *config_file,
host_config_set(fullpath);
tmp_free_and_out:
- if (tmp)
- XFREE(MTYPE_TMP, tmp);
+ XFREE(MTYPE_TMP, tmp);
return read_success;
}
@@ -3163,8 +3159,7 @@ void vty_init(struct thread_master *master_thread)
void vty_terminate(void)
{
- if (vty_cwd)
- XFREE(MTYPE_TMP, vty_cwd);
+ XFREE(MTYPE_TMP, vty_cwd);
if (vtyvec && Vvty_serv_thread) {
vty_reset();
diff --git a/lib/workqueue.c b/lib/workqueue.c
index fa69ec600e..066d81f350 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -274,7 +274,7 @@ int work_queue_run(struct thread *thread)
wq->cycles.granularity = WORK_QUEUE_MIN_GRANULARITY;
STAILQ_FOREACH_SAFE (item, &wq->items, wq, titem) {
- assert(item && item->data);
+ assert(item->data);
/* dont run items which are past their allowed retries */
if (item->ran > wq->spec.max_retries) {
diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c
index 6273dff3ce..7ecea5f445 100644
--- a/lib/yang_wrappers.c
+++ b/lib/yang_wrappers.c
@@ -62,7 +62,7 @@ bool yang_str2bool(const char *value)
struct yang_data *yang_data_new_bool(const char *xpath, bool value)
{
- return yang_data_new(xpath, (value == true) ? "true" : "false");
+ return yang_data_new(xpath, (value) ? "true" : "false");
}
bool yang_dnode_get_bool(const struct lyd_node *dnode, const char *xpath_fmt,
diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c
index 4c6827cb3d..6666c6e96b 100644
--- a/nhrpd/netlink_arp.c
+++ b/nhrpd/netlink_arp.c
@@ -122,7 +122,7 @@ static int netlink_route_recv(struct thread *t)
zbuf_init(&zb, buf, sizeof(buf), 0);
while (zbuf_recv(&zb, fd) > 0) {
- while ((n = znl_nlmsg_pull(&zb, &payload)) != 0) {
+ while ((n = znl_nlmsg_pull(&zb, &payload)) != NULL) {
debugf(NHRP_DEBUG_KERNEL,
"Netlink: Received msg_type %u, msg_flags %u",
n->nlmsg_type, n->nlmsg_flags);
@@ -217,7 +217,7 @@ static int netlink_log_recv(struct thread *t)
zbuf_init(&zb, buf, sizeof(buf), 0);
while (zbuf_recv(&zb, fd) > 0) {
- while ((n = znl_nlmsg_pull(&zb, &payload)) != 0) {
+ while ((n = znl_nlmsg_pull(&zb, &payload)) != NULL) {
debugf(NHRP_DEBUG_KERNEL,
"Netlink-log: Received msg_type %u, msg_flags %u",
n->nlmsg_type, n->nlmsg_flags);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 83b9001fea..692c84ad08 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -177,8 +177,7 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
struct ospf6_interface *oi;
unsigned int iobuflen;
- oi = (struct ospf6_interface *)XCALLOC(MTYPE_OSPF6_IF,
- sizeof(struct ospf6_interface));
+ oi = XCALLOC(MTYPE_OSPF6_IF, sizeof(struct ospf6_interface));
oi->area = (struct ospf6_area *)NULL;
oi->neighbor_list = list_new();
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index 40b3522c3d..9acbd09b1a 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -518,16 +518,14 @@ struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header)
lsa_size = ntohs(header->length); /* XXX vulnerable */
/* allocate memory for this LSA */
- new_header = (struct ospf6_lsa_header *)XMALLOC(MTYPE_OSPF6_LSA_HEADER,
- lsa_size);
+ new_header = XMALLOC(MTYPE_OSPF6_LSA_HEADER, lsa_size);
/* copy LSA from original header */
memcpy(new_header, header, lsa_size);
/* LSA information structure */
/* allocate memory */
- lsa = (struct ospf6_lsa *)XCALLOC(MTYPE_OSPF6_LSA,
- sizeof(struct ospf6_lsa));
+ lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa));
lsa->header = (struct ospf6_lsa_header *)new_header;
@@ -546,16 +544,15 @@ struct ospf6_lsa *ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header)
struct ospf6_lsa_header *new_header = NULL;
/* allocate memory for this LSA */
- new_header = (struct ospf6_lsa_header *)XMALLOC(
- MTYPE_OSPF6_LSA_HEADER, sizeof(struct ospf6_lsa_header));
+ new_header = XMALLOC(MTYPE_OSPF6_LSA_HEADER,
+ sizeof(struct ospf6_lsa_header));
/* copy LSA from original header */
memcpy(new_header, header, sizeof(struct ospf6_lsa_header));
/* LSA information structure */
/* allocate memory */
- lsa = (struct ospf6_lsa *)XCALLOC(MTYPE_OSPF6_LSA,
- sizeof(struct ospf6_lsa));
+ lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa));
lsa->header = (struct ospf6_lsa_header *)new_header;
SET_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY);
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index 5e02c0c917..b551dbdfa6 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -39,10 +39,6 @@ struct ospf6_lsdb *ospf6_lsdb_create(void *data)
struct ospf6_lsdb *lsdb;
lsdb = XCALLOC(MTYPE_OSPF6_LSDB, sizeof(struct ospf6_lsdb));
- if (lsdb == NULL) {
- zlog_warn("Can't malloc lsdb");
- return NULL;
- }
memset(lsdb, 0, sizeof(struct ospf6_lsdb));
lsdb->data = data;
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index cd688bbf89..4acb5e3b2e 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -1505,10 +1505,8 @@ int ospf6_iobuf_size(unsigned int size)
recvnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size);
sendnew = XMALLOC(MTYPE_OSPF6_MESSAGE, size);
- if (recvbuf)
- XFREE(MTYPE_OSPF6_MESSAGE, recvbuf);
- if (sendbuf)
- XFREE(MTYPE_OSPF6_MESSAGE, sendbuf);
+ XFREE(MTYPE_OSPF6_MESSAGE, recvbuf);
+ XFREE(MTYPE_OSPF6_MESSAGE, sendbuf);
recvbuf = recvnew;
sendbuf = sendnew;
iobuflen = size;
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index bb451c239e..46dc621ae7 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -86,10 +86,7 @@ struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
struct ospf6_neighbor *on;
char buf[16];
- on = (struct ospf6_neighbor *)XMALLOC(MTYPE_OSPF6_NEIGHBOR,
- sizeof(struct ospf6_neighbor));
-
- memset(on, 0, sizeof(struct ospf6_neighbor));
+ on = XCALLOC(MTYPE_OSPF6_NEIGHBOR, sizeof(struct ospf6_neighbor));
inet_ntop(AF_INET, &router_id, buf, sizeof(buf));
snprintf(on->name, sizeof(on->name), "%s%%%s", buf,
oi->interface->name);
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 79e1a44392..b71b353e1f 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -174,8 +174,7 @@ struct ospf6_nexthop *ospf6_nexthop_create(void)
void ospf6_nexthop_delete(struct ospf6_nexthop *nh)
{
- if (nh)
- XFREE(MTYPE_OSPF6_NEXTHOP, nh);
+ XFREE(MTYPE_OSPF6_NEXTHOP, nh);
}
void ospf6_clear_nexthops(struct list *nh_list)
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index 376950e84a..fc7c6177d7 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -1358,13 +1358,10 @@ static int ospf6TrapNbrStateChange(struct ospf6_neighbor *on, int next_state,
index[1] = on->ospf6_if->instance_id;
index[2] = ntohl(on->router_id);
- smux_trap(ospfv3_variables,
- sizeof ospfv3_variables / sizeof(struct variable),
- ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof(oid),
- ospfv3_oid, sizeof ospfv3_oid / sizeof(oid), index, 3,
- ospf6NbrTrapList,
- sizeof ospf6NbrTrapList / sizeof(struct trap_object),
- NBRSTATECHANGE);
+ smux_trap(ospfv3_variables, array_size(ospfv3_variables),
+ ospfv3_trap_oid, array_size(ospfv3_trap_oid), ospfv3_oid,
+ sizeof ospfv3_oid / sizeof(oid), index, 3, ospf6NbrTrapList,
+ array_size(ospf6NbrTrapList), NBRSTATECHANGE);
return 0;
}
@@ -1383,13 +1380,10 @@ static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state,
index[0] = oi->interface->ifindex;
index[1] = oi->instance_id;
- smux_trap(ospfv3_variables,
- sizeof ospfv3_variables / sizeof(struct variable),
- ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof(oid),
- ospfv3_oid, sizeof ospfv3_oid / sizeof(oid), index, 2,
- ospf6IfTrapList,
- sizeof ospf6IfTrapList / sizeof(struct trap_object),
- IFSTATECHANGE);
+ smux_trap(ospfv3_variables, array_size(ospfv3_variables),
+ ospfv3_trap_oid, array_size(ospfv3_trap_oid), ospfv3_oid,
+ sizeof ospfv3_oid / sizeof(oid), index, 2, ospf6IfTrapList,
+ array_size(ospf6IfTrapList), IFSTATECHANGE);
return 0;
}
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index 2d271c1dab..d4f6f6f4ae 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -107,8 +107,7 @@ static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa)
{
struct ospf6_vertex *v;
- v = (struct ospf6_vertex *)XMALLOC(MTYPE_OSPF6_VERTEX,
- sizeof(struct ospf6_vertex));
+ v = XMALLOC(MTYPE_OSPF6_VERTEX, sizeof(struct ospf6_vertex));
/* type */
if (ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) {
@@ -1016,8 +1015,7 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area,
new_header = XMALLOC(MTYPE_OSPF6_LSA_HEADER, total_lsa_length);
/* LSA information structure */
- lsa = (struct ospf6_lsa *)XCALLOC(MTYPE_OSPF6_LSA,
- sizeof(struct ospf6_lsa));
+ lsa = XCALLOC(MTYPE_OSPF6_LSA, sizeof(struct ospf6_lsa));
lsa->header = (struct ospf6_lsa_header *)new_header;
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index ba2e04bf76..ea919017d3 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -79,8 +79,7 @@ struct external_info *ospf_external_info_new(uint8_t type,
{
struct external_info *new;
- new = (struct external_info *)XCALLOC(MTYPE_OSPF_EXTERNAL_INFO,
- sizeof(struct external_info));
+ new = XCALLOC(MTYPE_OSPF_EXTERNAL_INFO, sizeof(struct external_info));
new->type = type;
new->instance = instance;
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index 9fd9a70c78..419081fe59 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -380,12 +380,10 @@ static int ism_interface_up(struct ospf_interface *oi)
static int ism_loop_ind(struct ospf_interface *oi)
{
- int ret = 0;
-
/* call ism_interface_down. */
/* ret = ism_interface_down (oi); */
- return ret;
+ return 0;
}
/* Interface down event handler. */
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 755634a2f1..f068efc8db 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -2590,13 +2590,10 @@ static void ospfTrapNbrStateChange(struct ospf_neighbor *on)
oid_copy_addr(index, &(on->address.u.prefix4), IN_ADDR_SIZE);
index[IN_ADDR_SIZE] = 0;
- smux_trap(ospf_variables,
- sizeof ospf_variables / sizeof(struct variable),
- ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid,
+ smux_trap(ospf_variables, array_size(ospf_variables), ospf_trap_oid,
+ array_size(ospf_trap_oid), ospf_oid,
sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1,
- ospfNbrTrapList,
- sizeof ospfNbrTrapList / sizeof(struct trap_object),
- NBRSTATECHANGE);
+ ospfNbrTrapList, array_size(ospfNbrTrapList), NBRSTATECHANGE);
}
static void ospfTrapVirtNbrStateChange(struct ospf_neighbor *on)
@@ -2608,12 +2605,10 @@ static void ospfTrapVirtNbrStateChange(struct ospf_neighbor *on)
oid_copy_addr(index, &(on->address.u.prefix4), IN_ADDR_SIZE);
index[IN_ADDR_SIZE] = 0;
- smux_trap(ospf_variables,
- sizeof ospf_variables / sizeof(struct variable),
- ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid,
+ smux_trap(ospf_variables, array_size(ospf_variables), ospf_trap_oid,
+ array_size(ospf_trap_oid), ospf_oid,
sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1,
- ospfVirtNbrTrapList,
- sizeof ospfVirtNbrTrapList / sizeof(struct trap_object),
+ ospfVirtNbrTrapList, array_size(ospfVirtNbrTrapList),
VIRTNBRSTATECHANGE);
}
@@ -2649,13 +2644,10 @@ static void ospfTrapIfStateChange(struct ospf_interface *oi)
oid_copy_addr(index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
index[IN_ADDR_SIZE] = 0;
- smux_trap(ospf_variables,
- sizeof ospf_variables / sizeof(struct variable),
- ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid,
+ smux_trap(ospf_variables, array_size(ospf_variables), ospf_trap_oid,
+ array_size(ospf_trap_oid), ospf_oid,
sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1,
- ospfIfTrapList,
- sizeof ospfIfTrapList / sizeof(struct trap_object),
- IFSTATECHANGE);
+ ospfIfTrapList, array_size(ospfIfTrapList), IFSTATECHANGE);
}
static void ospfTrapVirtIfStateChange(struct ospf_interface *oi)
@@ -2667,12 +2659,10 @@ static void ospfTrapVirtIfStateChange(struct ospf_interface *oi)
oid_copy_addr(index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
index[IN_ADDR_SIZE] = 0;
- smux_trap(ospf_variables,
- sizeof ospf_variables / sizeof(struct variable),
- ospf_trap_oid, sizeof ospf_trap_oid / sizeof(oid), ospf_oid,
+ smux_trap(ospf_variables, array_size(ospf_variables), ospf_trap_oid,
+ array_size(ospf_trap_oid), ospf_oid,
sizeof ospf_oid / sizeof(oid), index, IN_ADDR_SIZE + 1,
- ospfVirtIfTrapList,
- sizeof ospfVirtIfTrapList / sizeof(struct trap_object),
+ ospfVirtIfTrapList, array_size(ospfVirtIfTrapList),
VIRTIFSTATECHANGE);
}
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index bb22f211a7..b5d8739fcb 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3029,13 +3029,13 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
if (ospf->stub_router_startup_time
!= OSPF_STUB_ROUTER_UNCONFIGURED)
json_object_int_add(
- json_vrf, "postStartEnabledMsecs",
- ospf->stub_router_startup_time / 1000);
+ json_vrf, "postStartEnabledSecs",
+ ospf->stub_router_startup_time);
if (ospf->stub_router_shutdown_time
!= OSPF_STUB_ROUTER_UNCONFIGURED)
json_object_int_add(
- json_vrf, "preShutdownEnabledMsecs",
- ospf->stub_router_shutdown_time / 1000);
+ json_vrf, "preShutdownEnabledSecs",
+ ospf->stub_router_shutdown_time);
} else {
vty_out(vty,
" Stub router advertisement is configured\n");
@@ -3511,8 +3511,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
json_object_int_add(json_interface_sub, "cost",
oi->output_cost);
json_object_int_add(
- json_interface_sub, "transmitDelayMsecs",
- 1000 / OSPF_IF_PARAM(oi, transmit_delay));
+ json_interface_sub, "transmitDelaySecs",
+ OSPF_IF_PARAM(oi, transmit_delay));
json_object_string_add(json_interface_sub, "state",
lookup_msg(ospf_ism_state_msg,
oi->state, NULL));
@@ -3616,20 +3616,20 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
if (OSPF_IF_PARAM(oi, fast_hello) == 0)
json_object_int_add(
json_interface_sub, "timerMsecs",
- 1000 / OSPF_IF_PARAM(oi, v_hello));
+ OSPF_IF_PARAM(oi, v_hello) * 1000);
else
json_object_int_add(
json_interface_sub, "timerMsecs",
1000 / OSPF_IF_PARAM(oi, fast_hello));
json_object_int_add(json_interface_sub,
- "timerDeadMsecs",
- 1000 / OSPF_IF_PARAM(oi, v_wait));
+ "timerDeadSecs",
+ OSPF_IF_PARAM(oi, v_wait));
json_object_int_add(json_interface_sub,
- "timerWaitMsecs",
- 1000 / OSPF_IF_PARAM(oi, v_wait));
+ "timerWaitSecs",
+ OSPF_IF_PARAM(oi, v_wait));
json_object_int_add(
- json_interface_sub, "timerRetransmit",
- 1000 / OSPF_IF_PARAM(oi, retransmit_interval));
+ json_interface_sub, "timerRetransmitSecs",
+ OSPF_IF_PARAM(oi, retransmit_interval));
} else {
vty_out(vty, " Timer intervals configured,");
vty_out(vty, " Hello ");
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index ea2c492e18..4cbd817ad8 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -560,8 +560,7 @@ struct ospf_external *ospf_external_add(struct ospf *ospf, uint8_t type,
ospf->external[type] = list_new();
ext_list = ospf->external[type];
- ext = (struct ospf_external *)XCALLOC(MTYPE_OSPF_EXTERNAL,
- sizeof(struct ospf_external));
+ ext = XCALLOC(MTYPE_OSPF_EXTERNAL, sizeof(struct ospf_external));
ext->instance = instance;
EXTERNAL_INFO(ext) = route_table_init();
@@ -621,8 +620,7 @@ struct ospf_redist *ospf_redist_add(struct ospf *ospf, uint8_t type,
ospf->redist[type] = list_new();
red_list = ospf->redist[type];
- red = (struct ospf_redist *)XCALLOC(MTYPE_OSPF_REDISTRIBUTE,
- sizeof(struct ospf_redist));
+ red = XCALLOC(MTYPE_OSPF_REDISTRIBUTE, sizeof(struct ospf_redist));
red->instance = instance;
red->dmetric.type = -1;
red->dmetric.value = -1;
diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c
index 8f8b6aeed1..5e67990d5e 100644
--- a/pbrd/pbr_map.c
+++ b/pbrd/pbr_map.c
@@ -71,8 +71,7 @@ static int pbr_map_sequence_compare(const struct pbr_map_sequence *pbrms1,
static void pbr_map_sequence_delete(struct pbr_map_sequence *pbrms)
{
- if (pbrms->internal_nhg_name)
- XFREE(MTYPE_TMP, pbrms->internal_nhg_name);
+ XFREE(MTYPE_TMP, pbrms->internal_nhg_name);
XFREE(MTYPE_PBR_MAP_SEQNO, pbrms);
}
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index 2cba657f65..6a025fd724 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -740,7 +740,7 @@ uint32_t pbr_nht_get_next_tableid(bool peek)
bool found = false;
for (i = pbr_nhg_low_table; i <= pbr_nhg_high_table; i++) {
- if (nhg_tableid[i] == false) {
+ if (!nhg_tableid[i]) {
found = true;
break;
}
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index eaec002a73..f521704f1b 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -5159,16 +5159,14 @@ static int pim_cmd_spt_switchover(struct pim_instance *pim,
switch (pim->spt.switchover) {
case PIM_SPT_IMMEDIATE:
- if (pim->spt.plist)
- XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
+ XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
pim_upstream_add_lhr_star_pimreg(pim);
break;
case PIM_SPT_INFINITY:
pim_upstream_remove_lhr_star_pimreg(pim, plist);
- if (pim->spt.plist)
- XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
+ XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
if (plist)
pim->spt.plist =
@@ -6353,8 +6351,8 @@ DEFUN (interface_ip_pim_drprio,
pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
if (old_dr_prio != pim_ifp->pim_dr_priority) {
- if (pim_if_dr_election(ifp))
- pim_hello_restart_now(ifp);
+ pim_if_dr_election(ifp);
+ pim_hello_restart_now(ifp);
}
return CMD_SUCCESS;
@@ -6379,8 +6377,8 @@ DEFUN (interface_no_ip_pim_drprio,
if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
- if (pim_if_dr_election(ifp))
- pim_hello_restart_now(ifp);
+ pim_if_dr_election(ifp);
+ pim_hello_restart_now(ifp);
}
return CMD_SUCCESS;
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 6933f4d5bd..92d21cf429 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -208,8 +208,7 @@ void pim_if_delete(struct interface *ifp)
list_delete(&pim_ifp->upstream_switch_list);
list_delete(&pim_ifp->sec_addr_list);
- if (pim_ifp->boundary_oil_plist)
- XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
+ XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index dc42899c7b..5a8991c4c0 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -68,7 +68,7 @@ struct zebra_privs_t pimd_privs = {
.vty_group = VTY_GROUP,
#endif
.caps_p = _caps_p,
- .cap_num_p = sizeof(_caps_p) / sizeof(_caps_p[0]),
+ .cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
static const struct frr_yang_module_info *pimd_yang_modules[] = {
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index a4f87fa1a6..395c4af35f 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1256,8 +1256,7 @@ static void pim_msdp_mg_free(struct pim_instance *pim)
if (PIM_DEBUG_MSDP_EVENTS) {
zlog_debug("MSDP mesh-group %s deleted", mg->mesh_group_name);
}
- if (mg->mesh_group_name)
- XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name);
+ XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name);
if (mg->mbr_list)
list_delete(&mg->mbr_list);
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 08f2ffc4ea..308d5a5e06 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -65,8 +65,7 @@ void pim_rp_list_hash_clean(void *data)
static void pim_rp_info_free(struct rp_info *rp_info)
{
- if (rp_info->plist)
- XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist);
+ XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist);
XFREE(MTYPE_PIM_RP, rp_info);
}
diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c
index dfc7063fd0..6a70a73b45 100644
--- a/pimd/pim_ssm.c
+++ b/pimd/pim_ssm.c
@@ -151,8 +151,7 @@ void pim_ssm_terminate(struct pim_ssm *ssm)
if (!ssm)
return;
- if (ssm->plist_name)
- XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+ XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
XFREE(MTYPE_PIM_SSM_INFO, ssm);
}
diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c
index 6fbcdc059b..62aaad5d97 100644
--- a/ripd/rip_cli.c
+++ b/ripd/rip_cli.c
@@ -378,10 +378,19 @@ DEFPY (rip_passive_interface,
"Suppress routing updates on an interface\n"
"Interface name\n")
{
- nb_cli_enqueue_change(vty, "./passive-interface",
- no ? NB_OP_DESTROY : NB_OP_CREATE, ifname);
- nb_cli_enqueue_change(vty, "./non-passive-interface",
- no ? NB_OP_CREATE : NB_OP_DESTROY, ifname);
+ bool passive_default =
+ yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
+ VTY_CURR_XPATH, "/passive-default");
+
+ if (passive_default) {
+ nb_cli_enqueue_change(vty, "./non-passive-interface",
+ no ? NB_OP_CREATE : NB_OP_DESTROY,
+ ifname);
+ } else {
+ nb_cli_enqueue_change(vty, "./passive-interface",
+ no ? NB_OP_DESTROY : NB_OP_CREATE,
+ ifname);
+ }
return nb_cli_apply_changes(vty, NULL);
}
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 9575f6b8a8..8bad6b8b14 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -510,11 +510,9 @@ static void rip_interface_reset(struct rip_interface *ri)
ri->ri_receive = yang_get_default_enum("%s/version-receive", RIP_IFACE);
ri->v2_broadcast = yang_get_default_bool("%s/v2-broadcast", RIP_IFACE);
- if (ri->auth_str)
- XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
+ XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
- if (ri->key_chain)
- XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
+ XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
ri->list[RIP_FILTER_IN] = NULL;
ri->list[RIP_FILTER_OUT] = NULL;
diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c
index 1e5f86eff8..f3b5dc2dc3 100644
--- a/ripd/rip_northbound.c
+++ b/ripd/rip_northbound.c
@@ -937,8 +937,7 @@ lib_interface_rip_authentication_password_modify(enum nb_event event,
ifp = yang_dnode_get_entry(dnode, true);
ri = ifp->info;
- if (ri->auth_str)
- XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
+ XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
yang_dnode_get_string(dnode, NULL));
@@ -978,8 +977,7 @@ lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
ifp = yang_dnode_get_entry(dnode, true);
ri = ifp->info;
- if (ri->key_chain)
- XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
+ XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
yang_dnode_get_string(dnode, NULL));
diff --git a/sharpd/sharp_globals.h b/sharpd/sharp_globals.h
index 065fb092d4..4e5c933667 100644
--- a/sharpd/sharp_globals.h
+++ b/sharpd/sharp_globals.h
@@ -38,6 +38,7 @@ struct sharp_routes {
int32_t repeat;
uint8_t inst;
+ vrf_id_t vrf_id;
struct timeval t_start;
struct timeval t_end;
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 9018cfb359..fbcbbe3fdc 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -39,17 +39,28 @@
#endif
DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
- "sharp watch <nexthop$n|import$import> X:X::X:X$nhop [connected$connected]",
+ "sharp watch [vrf NAME$name] <nexthop$n|import$import> X:X::X:X$nhop [connected$connected]",
"Sharp routing Protocol\n"
"Watch for changes\n"
+ "The vrf we would like to watch if non-default\n"
+ "The NAME of the vrf\n"
"Watch for nexthop changes\n"
"Watch for import check changes\n"
"The v6 nexthop to signal for watching\n"
"Should the route be connected\n")
{
+ struct vrf *vrf;
struct prefix p;
bool type_import;
+ if (!name)
+ name = VRF_DEFAULT_NAME;
+ vrf = vrf_lookup_by_name(name);
+ if (!vrf) {
+ vty_out(vty, "The vrf NAME specified: %s does not exist\n",
+ name);
+ return CMD_WARNING;
+ }
if (n)
type_import = false;
@@ -63,23 +74,36 @@ DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
p.family = AF_INET6;
sharp_nh_tracker_get(&p);
- sharp_zebra_nexthop_watch(&p, type_import, true, !!connected);
+ sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
+ true, !!connected);
return CMD_SUCCESS;
}
DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
- "sharp watch <nexthop$n|import$import> A.B.C.D$nhop [connected$connected]",
+ "sharp watch [vrf NAME$name] <nexthop$n|import$import> A.B.C.D$nhop [connected$connected]",
"Sharp routing Protocol\n"
"Watch for changes\n"
+ "The vrf we would like to watch if non-default\n"
+ "The NAME of the vrf\n"
"Watch for nexthop changes\n"
"Watch for import check changes\n"
"The v4 nexthop to signal for watching\n"
"Should the route be connected\n")
{
+ struct vrf *vrf;
struct prefix p;
bool type_import;
+ if (!name)
+ name = VRF_DEFAULT_NAME;
+ vrf = vrf_lookup_by_name(name);
+ if (!vrf) {
+ vty_out(vty, "The vrf NAME specified: %s does not exist\n",
+ name);
+ return CMD_WARNING;
+ }
+
memset(&p, 0, sizeof(p));
if (n)
@@ -92,7 +116,8 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
p.family = AF_INET;
sharp_nh_tracker_get(&p);
- sharp_zebra_nexthop_watch(&p, type_import, true, !!connected);
+ sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
+ true, !!connected);
return CMD_SUCCESS;
}
@@ -132,10 +157,12 @@ DEFPY (install_routes_data_dump,
DEFPY (install_routes,
install_routes_cmd,
- "sharp install routes <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
+ "sharp install routes [vrf NAME$name] <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
"Sharp routing Protocol\n"
"install some routes\n"
"Routes to install\n"
+ "The vrf we would like to install into if non-default\n"
+ "The NAME of the vrf\n"
"v4 Address to start /32 generation at\n"
"v6 Address to start /32 generation at\n"
"Nexthop to use(Can be an IPv4 or IPv6 address)\n"
@@ -149,6 +176,7 @@ DEFPY (install_routes,
"Should we repeat this command\n"
"How many times to repeat this command\n")
{
+ struct vrf *vrf;
struct prefix prefix;
uint32_t rts;
@@ -176,6 +204,16 @@ DEFPY (install_routes,
}
sg.r.orig_prefix = prefix;
+ if (!name)
+ name = VRF_DEFAULT_NAME;
+
+ vrf = vrf_lookup_by_name(name);
+ if (!vrf) {
+ vty_out(vty, "The vrf NAME specified: %s does not exist\n",
+ name);
+ return CMD_WARNING;
+ }
+
if (nexthop_group) {
struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
if (!nhgc) {
@@ -195,12 +233,15 @@ DEFPY (install_routes,
sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
}
+ sg.r.nhop.vrf_id = vrf->vrf_id;
sg.r.nhop_group.nexthop = &sg.r.nhop;
}
sg.r.inst = instance;
+ sg.r.vrf_id = vrf->vrf_id;
rts = routes;
- sharp_install_routes_helper(&prefix, sg.r.inst, &sg.r.nhop_group, rts);
+ sharp_install_routes_helper(&prefix, sg.r.vrf_id,
+ sg.r.inst, &sg.r.nhop_group, rts);
return CMD_SUCCESS;
}
@@ -237,16 +278,19 @@ DEFPY(vrf_label, vrf_label_cmd,
DEFPY (remove_routes,
remove_routes_cmd,
- "sharp remove routes <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
+ "sharp remove routes [vrf NAME$name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
"Sharp Routing Protocol\n"
"Remove some routes\n"
"Routes to remove\n"
+ "The vrf we would like to remove from if non-default\n"
+ "The NAME of the vrf\n"
"v4 Starting spot\n"
"v6 Starting spot\n"
"Routes to uninstall\n"
"instance to use\n"
"Value of instance\n")
{
+ struct vrf *vrf;
struct prefix prefix;
sg.r.total_routes = routes;
@@ -265,9 +309,18 @@ DEFPY (remove_routes,
prefix.u.prefix6 = start6;
}
+ vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
+ if (!vrf) {
+ vty_out(vty, "The vrf NAME specified: %s does not exist\n",
+ name ? name : VRF_DEFAULT_NAME);
+ return CMD_WARNING;
+ }
+
sg.r.inst = instance;
+ sg.r.vrf_id = vrf->vrf_id;
rts = routes;
- sharp_remove_routes_helper(&prefix, sg.r.inst, rts);
+ sharp_remove_routes_helper(&prefix, sg.r.vrf_id,
+ sg.r.inst, rts);
return CMD_SUCCESS;
}
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 4682dbc73a..f1e83628c2 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -131,8 +131,8 @@ static int interface_state_down(int command, struct zclient *zclient,
return 0;
}
-void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
- struct nexthop_group *nhg,
+void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance, struct nexthop_group *nhg,
uint32_t routes)
{
uint32_t temp, i;
@@ -148,7 +148,7 @@ void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
monotime(&sg.r.t_start);
for (i = 0; i < routes; i++) {
- route_add(p, (uint8_t)instance, nhg);
+ route_add(p, vrf_id, (uint8_t)instance, nhg);
if (v4)
p->u.prefix4.s_addr = htonl(++temp);
else
@@ -156,8 +156,8 @@ void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
}
}
-void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
- uint32_t routes)
+void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance, uint32_t routes)
{
uint32_t temp, i;
bool v4 = false;
@@ -172,7 +172,7 @@ void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
monotime(&sg.r.t_start);
for (i = 0; i < routes; i++) {
- route_delete(p, (uint8_t)instance);
+ route_delete(p, vrf_id, (uint8_t)instance);
if (v4)
p->u.prefix4.s_addr = htonl(++temp);
else
@@ -190,12 +190,14 @@ static void handle_repeated(bool installed)
if (installed) {
sg.r.removed_routes = 0;
- sharp_remove_routes_helper(&p, sg.r.inst, sg.r.total_routes);
+ sharp_remove_routes_helper(&p, sg.r.vrf_id,
+ sg.r.inst, sg.r.total_routes);
}
if (installed) {
sg.r.installed_routes = 0;
- sharp_install_routes_helper(&p, sg.r.inst, &sg.r.nhop_group,
+ sharp_install_routes_helper(&p, sg.r.vrf_id, sg.r.inst,
+ &sg.r.nhop_group,
sg.r.total_routes);
}
}
@@ -255,7 +257,8 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
}
-void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
+void route_add(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance, struct nexthop_group *nhg)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
@@ -263,7 +266,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
int i = 0;
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = vrf_id;
api.type = ZEBRA_ROUTE_SHARP;
api.instance = instance;
api.safi = SAFI_UNICAST;
@@ -274,7 +277,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
for (ALL_NEXTHOPS_PTR(nhg, nh)) {
api_nh = &api.nexthops[i];
- api_nh->vrf_id = VRF_DEFAULT;
+ api_nh->vrf_id = nh->vrf_id;
api_nh->type = nh->type;
switch (nh->type) {
case NEXTHOP_TYPE_IPV4:
@@ -305,12 +308,12 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
-void route_delete(struct prefix *p, uint8_t instance)
+void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance)
{
struct zapi_route api;
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = vrf_id;
api.type = ZEBRA_ROUTE_SHARP;
api.safi = SAFI_UNICAST;
api.instance = instance;
@@ -320,7 +323,7 @@ void route_delete(struct prefix *p, uint8_t instance)
return;
}
-void sharp_zebra_nexthop_watch(struct prefix *p, bool import,
+void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import,
bool watch, bool connected)
{
int command;
@@ -337,7 +340,7 @@ void sharp_zebra_nexthop_watch(struct prefix *p, bool import,
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
}
- if (zclient_send_rnh(zclient, command, p, connected, VRF_DEFAULT) < 0)
+ if (zclient_send_rnh(zclient, command, p, connected, vrf_id) < 0)
zlog_warn("%s: Failure to send nexthop to zebra",
__PRETTY_FUNCTION__);
}
diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h
index b219022f02..57ffcc7690 100644
--- a/sharpd/sharp_zebra.h
+++ b/sharpd/sharp_zebra.h
@@ -25,15 +25,16 @@
extern void sharp_zebra_init(void);
extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
-extern void route_add(struct prefix *p, uint8_t instance,
+extern void route_add(struct prefix *p, vrf_id_t, uint8_t instance,
struct nexthop_group *nhg);
-extern void route_delete(struct prefix *p, uint8_t instance);
-extern void sharp_zebra_nexthop_watch(struct prefix *p, bool import,
- bool watch, bool connected);
+extern void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance);
+extern void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id,
+ bool import, bool watch, bool connected);
-extern void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
- struct nexthop_group *nhg,
- uint32_t routes);
-extern void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
- uint32_t routes);
+extern void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance,
+ struct nexthop_group *nhg,
+ uint32_t routes);
+extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
+ uint8_t instance, uint32_t routes);
#endif
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index f09c304359..3a9e4e8fa4 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -104,30 +104,18 @@ static int static_list_compare_helper(const char *s1, const char *s2)
static void static_list_delete(struct static_hold_route *shr)
{
- if (shr->vrf_name)
- XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name);
- if (shr->nhvrf_name)
- XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name);
- if (shr->dest_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->dest_str);
- if (shr->mask_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->mask_str);
- if (shr->src_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->src_str);
- if (shr->gate_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->gate_str);
- if (shr->ifname)
- XFREE(MTYPE_STATIC_ROUTE, shr->ifname);
- if (shr->flag_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->flag_str);
- if (shr->tag_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->tag_str);
- if (shr->distance_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->distance_str);
- if (shr->label_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->label_str);
- if (shr->table_str)
- XFREE(MTYPE_STATIC_ROUTE, shr->table_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name);
+ XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name);
+ XFREE(MTYPE_STATIC_ROUTE, shr->dest_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->mask_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->src_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->gate_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->ifname);
+ XFREE(MTYPE_STATIC_ROUTE, shr->flag_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->tag_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->distance_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->label_str);
+ XFREE(MTYPE_STATIC_ROUTE, shr->table_str);
XFREE(MTYPE_STATIC_ROUTE, shr);
}
diff --git a/tests/bgpd/test_bgp_table.c b/tests/bgpd/test_bgp_table.c
index 73243dcacf..7b38df5f66 100644
--- a/tests/bgpd/test_bgp_table.c
+++ b/tests/bgpd/test_bgp_table.c
@@ -158,7 +158,7 @@ static void test_range_lookup(void)
"1.16.160.0/19", "1.16.32.0/20",
"1.16.32.0/21", "16.0.0.0/16"};
- int num_prefixes = sizeof(prefixes) / sizeof(prefixes[0]);
+ int num_prefixes = array_size(prefixes);
for (int i = 0; i < num_prefixes; i++)
add_node(table, prefixes[i]);
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index 04fbda42eb..0ecd0fdfec 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -205,7 +205,7 @@ struct peer test_mp_list_peer[] = {
{.local_as = 1, .as = 2}, {.local_as = 1, .as = 2},
{.local_as = 1, .as = 2},
};
-int test_mp_list_peer_count = sizeof(test_mp_list_peer) / sizeof(struct peer);
+int test_mp_list_peer_count = array_size(test_mp_list_peer);
struct attr test_mp_list_attr[4];
struct bgp_path_info test_mp_list_info[] = {
{.peer = &test_mp_list_peer[0], .attr = &test_mp_list_attr[0]},
@@ -214,8 +214,7 @@ struct bgp_path_info test_mp_list_info[] = {
{.peer = &test_mp_list_peer[3], .attr = &test_mp_list_attr[2]},
{.peer = &test_mp_list_peer[4], .attr = &test_mp_list_attr[3]},
};
-int test_mp_list_info_count =
- sizeof(test_mp_list_info) / sizeof(struct bgp_path_info);
+int test_mp_list_info_count = array_size(test_mp_list_info);
static int setup_bgp_mp_list(testcase_t *t)
{
@@ -370,7 +369,7 @@ testcase_t *all_tests[] = {
&test_bgp_path_info_mpath_update,
};
-int all_tests_count = (sizeof(all_tests) / sizeof(testcase_t *));
+int all_tests_count = array_size(all_tests);
/*=========================================================
* Test Driver Functions
diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c
index e203da8f6e..fc3d908661 100644
--- a/tests/lib/test_privs.c
+++ b/tests/lib/test_privs.c
@@ -37,7 +37,7 @@ struct zebra_privs_t test_privs = {
.vty_group = VTY_GROUP,
#endif
.caps_p = _caps_p,
- .cap_num_p = sizeof(_caps_p) / sizeof(_caps_p[0]),
+ .cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
struct option longopts[] = {{"help", no_argument, NULL, 'h'},
diff --git a/tests/lib/test_srcdest_table.c b/tests/lib/test_srcdest_table.c
index 5c0e171778..19a40b2184 100644
--- a/tests/lib/test_srcdest_table.c
+++ b/tests/lib/test_srcdest_table.c
@@ -105,7 +105,7 @@ static unsigned int log_key(void *data)
static bool log_cmp(const void *a, const void *b)
{
if (a == NULL || b == NULL)
- return 0;
+ return false;
return !memcmp(a, b, 2 * sizeof(struct prefix));
}
diff --git a/tests/lib/test_table.c b/tests/lib/test_table.c
index 2b65040627..90d6c76bf1 100644
--- a/tests/lib/test_table.c
+++ b/tests/lib/test_table.c
@@ -478,7 +478,7 @@ static void test_iter_pause(void)
const char *prefixes[] = {"1.0.1.0/24", "1.0.1.0/25", "1.0.1.128/25",
"1.0.2.0/24", "2.0.0.0/8"};
- num_prefixes = sizeof(prefixes) / sizeof(prefixes[0]);
+ num_prefixes = array_size(prefixes);
printf("\n\nTesting that route_table_iter_pause() works as expected\n");
table = route_table_init();
diff --git a/tests/topotests/bfd-topo2/__init__.py b/tests/topotests/bfd-topo2/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bfd-topo2/__init__.py
diff --git a/tests/topotests/bfd-topo2/r1/bfdd.conf b/tests/topotests/bfd-topo2/r1/bfdd.conf
new file mode 100644
index 0000000000..5c2571bdbd
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r1/bfdd.conf
@@ -0,0 +1,5 @@
+bfd
+ peer 2001:db8:4::1 multihop local-address 2001:db8:1::1
+ no shutdown
+ !
+!
diff --git a/tests/topotests/bfd-topo2/r1/bgpd.conf b/tests/topotests/bfd-topo2/r1/bgpd.conf
new file mode 100644
index 0000000000..1623b4578b
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r1/bgpd.conf
@@ -0,0 +1,13 @@
+router bgp 101
+ bgp router-id 10.254.254.1
+ neighbor r2g peer-group
+ neighbor r2g remote-as external
+ neighbor r2g bfd
+ neighbor r1-eth0 interface peer-group r2g
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+ address-family ipv6 unicast
+ neighbor r2g activate
+ exit-address-family
+!
diff --git a/tests/topotests/bfd-topo2/r1/ipv4_routes.json b/tests/topotests/bfd-topo2/r1/ipv4_routes.json
new file mode 100644
index 0000000000..8a2ec25baa
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r1/ipv4_routes.json
@@ -0,0 +1,68 @@
+{
+ "10.0.3.0/24": [
+ {
+ "distance": 20,
+ "protocol": "bgp",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.0.3.0/24",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r1-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ],
+ "10.254.254.2/32": [
+ {
+ "distance": 20,
+ "protocol": "bgp",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.2/32",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r1-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ],
+ "10.254.254.1/32": [
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.1/32",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "lo",
+ "interfaceIndex": 1,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r1/ipv6_routes.json b/tests/topotests/bfd-topo2/r1/ipv6_routes.json
new file mode 100644
index 0000000000..618853bd42
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r1/ipv6_routes.json
@@ -0,0 +1,63 @@
+{
+ "2001:db8:4::/64": [
+ {
+ "distance": 20,
+ "protocol": "bgp",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "2001:db8:4::/64",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r1-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ],
+ "2001:db8:1::/64": [
+ {
+ "distance": 20,
+ "protocol": "bgp",
+ "internalFlags": 0,
+ "metric": 0,
+ "internalStatus": 2,
+ "prefix": "2001:db8:1::/64",
+ "nexthops": [
+ {
+ "interfaceName": "r1-eth0",
+ "interfaceIndex": 2,
+ "flags": 1,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ },
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "2001:db8:1::/64",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "r1-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r1/peers.json b/tests/topotests/bfd-topo2/r1/peers.json
new file mode 100644
index 0000000000..b14351cd81
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r1/peers.json
@@ -0,0 +1,29 @@
+[
+ {
+ "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
+ },
+ {
+ "multihop":false,
+ "interface":"r1-eth0",
+ "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-topo2/r1/zebra.conf b/tests/topotests/bfd-topo2/r1/zebra.conf
new file mode 100644
index 0000000000..7fe5eb218f
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r1/zebra.conf
@@ -0,0 +1,6 @@
+interface lo
+ ip address 10.254.254.1/32
+!
+interface r1-eth0
+ ipv6 address 2001:db8:1::1/64
+!
diff --git a/tests/topotests/bfd-topo2/r2/bgpd.conf b/tests/topotests/bfd-topo2/r2/bgpd.conf
new file mode 100644
index 0000000000..bf42d21812
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/bgpd.conf
@@ -0,0 +1,16 @@
+router bgp 102
+ bgp router-id 10.254.254.2
+ neighbor r2g peer-group
+ neighbor r2g remote-as external
+ neighbor r2g bfd
+ neighbor r2-eth0 interface peer-group r2g
+ !
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+ !
+ address-family ipv6 unicast
+ redistribute connected
+ neighbor r2g activate
+ exit-address-family
+!
diff --git a/tests/topotests/bfd-topo2/r2/ipv4_routes.json b/tests/topotests/bfd-topo2/r2/ipv4_routes.json
new file mode 100644
index 0000000000..b9d8afb430
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/ipv4_routes.json
@@ -0,0 +1,108 @@
+{
+ "10.0.3.0/24": [
+ {
+ "distance": 110,
+ "protocol": "ospf",
+ "internalFlags": 0,
+ "metric": 10,
+ "internalStatus": 2,
+ "prefix": "10.0.3.0/24",
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "flags": 1,
+ "interfaceIndex": 3,
+ "interfaceName": "r2-eth1"
+ }
+ ]
+ },
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.0.3.0/24",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "r2-eth1",
+ "interfaceIndex": 3,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "10.254.254.3/32": [
+ {
+ "distance": 110,
+ "protocol": "ospf",
+ "internalFlags": 8,
+ "metric": 20,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.3/32",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r2-eth1",
+ "ip": "10.0.3.1",
+ "interfaceIndex": 3,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv4"
+ }
+ ]
+ }
+ ],
+ "10.254.254.2/32": [
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.2/32",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "lo",
+ "interfaceIndex": 1,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "10.254.254.1/32": [
+ {
+ "distance": 20,
+ "protocol": "bgp",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.1/32",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r2-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r2/ipv6_routes.json b/tests/topotests/bfd-topo2/r2/ipv6_routes.json
new file mode 100644
index 0000000000..004e7588aa
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/ipv6_routes.json
@@ -0,0 +1,63 @@
+{
+ "2001:db8:4::/64": [
+ {
+ "distance": 110,
+ "protocol": "ospf6",
+ "internalFlags": 0,
+ "metric": 10,
+ "internalStatus": 2,
+ "prefix": "2001:db8:4::/64",
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "flags": 1,
+ "interfaceIndex": 4,
+ "interfaceName": "r2-eth2"
+ }
+ ]
+ },
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "2001:db8:4::/64",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "r2-eth2",
+ "interfaceIndex": 4,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1::/64": [
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "2001:db8:1::/64",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "r2-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r2/ospf6d.conf b/tests/topotests/bfd-topo2/r2/ospf6d.conf
new file mode 100644
index 0000000000..f1cdb50285
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/ospf6d.conf
@@ -0,0 +1,9 @@
+interface r2-eth2
+ ipv6 ospf6 bfd
+!
+router ospf6
+ ospf6 router-id 10.254.254.2
+ redistribute connected
+ redistribute bgp
+ interface r2-eth2 area 0.0.0.1
+!
diff --git a/tests/topotests/bfd-topo2/r2/ospfd.conf b/tests/topotests/bfd-topo2/r2/ospfd.conf
new file mode 100644
index 0000000000..8e0c45980d
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/ospfd.conf
@@ -0,0 +1,9 @@
+interface r2-eth1
+ ip ospf area 0.0.0.1
+ ip ospf bfd
+!
+router ospf
+ ospf router-id 10.254.254.2
+ redistribute connected
+ redistribute bgp
+!
diff --git a/tests/topotests/bfd-topo2/r2/peers.json b/tests/topotests/bfd-topo2/r2/peers.json
new file mode 100644
index 0000000000..29075fcc80
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/peers.json
@@ -0,0 +1,42 @@
+[
+ {
+ "status": "up",
+ "transmit-interval": 300,
+ "remote-receive-interval": 300,
+ "echo-interval": 0,
+ "diagnostic": "ok",
+ "multihop": false,
+ "interface": "r2-eth0",
+ "remote-transmit-interval": 300,
+ "receive-interval": 300,
+ "remote-echo-interval": 50,
+ "remote-diagnostic": "ok"
+ },
+ {
+ "status": "up",
+ "transmit-interval": 300,
+ "remote-receive-interval": 300,
+ "echo-interval": 0,
+ "diagnostic": "ok",
+ "multihop": false,
+ "interface": "r2-eth2",
+ "remote-transmit-interval": 300,
+ "receive-interval": 300,
+ "remote-echo-interval": 50,
+ "remote-diagnostic": "ok"
+ },
+ {
+ "status": "up",
+ "transmit-interval": 300,
+ "remote-receive-interval": 300,
+ "echo-interval": 0,
+ "diagnostic": "ok",
+ "multihop": false,
+ "interface": "r2-eth1",
+ "remote-transmit-interval": 300,
+ "receive-interval": 300,
+ "remote-echo-interval": 50,
+ "remote-diagnostic": "ok",
+ "peer": "10.0.3.1"
+ }
+]
diff --git a/tests/topotests/bfd-topo2/r2/zebra.conf b/tests/topotests/bfd-topo2/r2/zebra.conf
new file mode 100644
index 0000000000..cccbf6574a
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r2/zebra.conf
@@ -0,0 +1,15 @@
+ip forwarding
+ipv6 forwarding
+!
+interface lo
+ ip address 10.254.254.2/32
+!
+interface r2-eth0
+ ipv6 address 2001:db8:1::2/64
+!
+interface r2-eth1
+ ip address 10.0.3.2/24
+!
+interface r2-eth2
+ ipv6 address 2001:db8:4::2/64
+!
diff --git a/tests/topotests/bfd-topo2/r3/ipv4_routes.json b/tests/topotests/bfd-topo2/r3/ipv4_routes.json
new file mode 100644
index 0000000000..14dfc692fe
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r3/ipv4_routes.json
@@ -0,0 +1,109 @@
+{
+ "10.0.3.0/24": [
+ {
+ "distance": 110,
+ "protocol": "ospf",
+ "internalFlags": 0,
+ "metric": 10,
+ "internalStatus": 0,
+ "prefix": "10.0.3.0/24",
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "flags": 1,
+ "interfaceIndex": 2,
+ "interfaceName": "r3-eth0"
+ }
+ ]
+ },
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.0.3.0/24",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "r3-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "10.254.254.3/32": [
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.3/32",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "lo",
+ "interfaceIndex": 1,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "10.254.254.2/32": [
+ {
+ "distance": 110,
+ "protocol": "ospf",
+ "internalFlags": 8,
+ "metric": 20,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.2/32",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r3-eth0",
+ "ip": "10.0.3.2",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv4"
+ }
+ ]
+ }
+ ],
+ "10.254.254.1/32": [
+ {
+ "distance": 110,
+ "protocol": "ospf",
+ "internalFlags": 8,
+ "metric": 20,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.1/32",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r3-eth0",
+ "ip": "10.0.3.2",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv4"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r3/ipv6_routes.json b/tests/topotests/bfd-topo2/r3/ipv6_routes.json
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r3/ipv6_routes.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/tests/topotests/bfd-topo2/r3/ospfd.conf b/tests/topotests/bfd-topo2/r3/ospfd.conf
new file mode 100644
index 0000000000..cf2a1bdf76
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r3/ospfd.conf
@@ -0,0 +1,8 @@
+interface r3-eth0
+ ip ospf area 0.0.0.1
+ ip ospf bfd
+!
+router ospf
+ ospf router-id 10.254.254.3
+ redistribute connected
+!
diff --git a/tests/topotests/bfd-topo2/r3/peers.json b/tests/topotests/bfd-topo2/r3/peers.json
new file mode 100644
index 0000000000..6698bff201
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r3/peers.json
@@ -0,0 +1,16 @@
+[
+ {
+ "status": "up",
+ "transmit-interval": 300,
+ "remote-receive-interval": 300,
+ "echo-interval": 0,
+ "diagnostic": "ok",
+ "multihop": false,
+ "interface": "r3-eth0",
+ "remote-transmit-interval": 300,
+ "receive-interval": 300,
+ "remote-echo-interval": 50,
+ "remote-diagnostic": "ok",
+ "peer": "10.0.3.2"
+ }
+]
diff --git a/tests/topotests/bfd-topo2/r3/zebra.conf b/tests/topotests/bfd-topo2/r3/zebra.conf
new file mode 100644
index 0000000000..96fd08c729
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r3/zebra.conf
@@ -0,0 +1,6 @@
+interface lo
+ ip address 10.254.254.3/32
+!
+interface r3-eth0
+ ip address 10.0.3.1/24
+!
diff --git a/tests/topotests/bfd-topo2/r4/bfdd.conf b/tests/topotests/bfd-topo2/r4/bfdd.conf
new file mode 100644
index 0000000000..fdb4412446
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r4/bfdd.conf
@@ -0,0 +1,5 @@
+bfd
+ peer 2001:db8:1::1 multihop local-address 2001:db8:4::1
+ no shutdown
+ !
+!
diff --git a/tests/topotests/bfd-topo2/r4/ipv4_routes.json b/tests/topotests/bfd-topo2/r4/ipv4_routes.json
new file mode 100644
index 0000000000..ae1e97b017
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r4/ipv4_routes.json
@@ -0,0 +1,24 @@
+{
+ "10.254.254.4/32": [
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "10.254.254.4/32",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "lo",
+ "interfaceIndex": 1,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r4/ipv6_routes.json b/tests/topotests/bfd-topo2/r4/ipv6_routes.json
new file mode 100644
index 0000000000..33608b45aa
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r4/ipv6_routes.json
@@ -0,0 +1,63 @@
+{
+ "2001:db8:4::/64": [
+ {
+ "distance": 110,
+ "protocol": "ospf6",
+ "internalFlags": 0,
+ "metric": 10,
+ "internalStatus": 2,
+ "prefix": "2001:db8:4::/64",
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "flags": 1,
+ "interfaceIndex": 2,
+ "interfaceName": "r4-eth0"
+ }
+ ]
+ },
+ {
+ "distance": 0,
+ "protocol": "connected",
+ "internalFlags": 8,
+ "metric": 0,
+ "selected": true,
+ "installed": true,
+ "prefix": "2001:db8:4::/64",
+ "internalStatus": 32,
+ "nexthops": [
+ {
+ "directlyConnected": true,
+ "interfaceName": "r4-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1::/64": [
+ {
+ "distance": 110,
+ "protocol": "ospf6",
+ "internalFlags": 8,
+ "metric": 10,
+ "selected": true,
+ "installed": true,
+ "prefix": "2001:db8:1::/64",
+ "internalStatus": 34,
+ "nexthops": [
+ {
+ "interfaceName": "r4-eth0",
+ "interfaceIndex": 2,
+ "fib": true,
+ "flags": 3,
+ "active": true,
+ "afi": "ipv6"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bfd-topo2/r4/ospf6d.conf b/tests/topotests/bfd-topo2/r4/ospf6d.conf
new file mode 100644
index 0000000000..756597d6f8
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r4/ospf6d.conf
@@ -0,0 +1,8 @@
+interface r4-eth0
+ ipv6 ospf6 bfd
+!
+router ospf6
+ ospf6 router-id 10.254.254.4
+ redistribute connected
+ interface r4-eth0 area 0.0.0.1
+!
diff --git a/tests/topotests/bfd-topo2/r4/peers.json b/tests/topotests/bfd-topo2/r4/peers.json
new file mode 100644
index 0000000000..83101eb47f
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r4/peers.json
@@ -0,0 +1,29 @@
+[
+ {
+ "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
+ },
+ {
+ "multihop":false,
+ "interface":"r4-eth0",
+ "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-topo2/r4/zebra.conf b/tests/topotests/bfd-topo2/r4/zebra.conf
new file mode 100644
index 0000000000..e4f8fd8514
--- /dev/null
+++ b/tests/topotests/bfd-topo2/r4/zebra.conf
@@ -0,0 +1,6 @@
+interface lo
+ ip address 10.254.254.4/32
+!
+interface r4-eth0
+ ipv6 address 2001:db8:4::1/64
+!
diff --git a/tests/topotests/bfd-topo2/test_bfd_topo2.dot b/tests/topotests/bfd-topo2/test_bfd_topo2.dot
new file mode 100644
index 0000000000..6b68fb398f
--- /dev/null
+++ b/tests/topotests/bfd-topo2/test_bfd_topo2.dot
@@ -0,0 +1,73 @@
+## 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="r3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r4 [
+ 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,
+ ];
+ sw3 [
+ shape=oval,
+ label="sw3\n2001:db8:4::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+
+ # Connections
+ r1 -- sw1 [label="eth0"];
+ r2 -- sw1 [label="eth0"];
+
+ r2 -- sw2 [label="eth1"];
+ r3 -- sw2 [label="eth0"];
+
+ r2 -- sw3 [label="eth2"];
+ r4 -- sw3 [label="eth0"];
+}
diff --git a/tests/topotests/bfd-topo2/test_bfd_topo2.jpg b/tests/topotests/bfd-topo2/test_bfd_topo2.jpg
new file mode 100644
index 0000000000..35fe562a80
--- /dev/null
+++ b/tests/topotests/bfd-topo2/test_bfd_topo2.jpg
Binary files differ
diff --git a/tests/topotests/bfd-topo2/test_bfd_topo2.py b/tests/topotests/bfd-topo2/test_bfd_topo2.py
new file mode 100644
index 0000000000..773db129f0
--- /dev/null
+++ b/tests/topotests/bfd-topo2/test_bfd_topo2.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+#
+# test_bfd_topo2.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2019 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# 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_topo2.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, 5):
+ 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'])
+
+ switch = tgen.add_switch('s3')
+ switch.add_link(tgen.gears['r2'])
+ switch.add_link(tgen.gears['r4'])
+
+
+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))
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF,
+ os.path.join(CWD, '{}/ospfd.conf'.format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF6,
+ os.path.join(CWD, '{}/ospf6d.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 IPv4 routing tables.
+ logger.info("Checking IPv4 routes for convergence")
+ for router in tgen.routers().values():
+ json_file = '{}/{}/ipv4_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 ip route json', expected)
+ _, result = topotest.run_and_expect(test_func, None, count=160,
+ wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+ # Check IPv6 routing tables.
+ logger.info("Checking IPv6 routes for convergence")
+ for router in tgen.routers().values():
+ 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=160,
+ 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():
+ 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/tools/coccinelle/alloc_cast.cocci b/tools/coccinelle/alloc_cast.cocci
new file mode 100644
index 0000000000..b1497c750f
--- /dev/null
+++ b/tools/coccinelle/alloc_cast.cocci
@@ -0,0 +1,101 @@
+/// Remove casting the values returned by memory allocation functions
+/// like XMALLOC and XCALLOC.
+///
+// This makes an effort to find cases of casting of values returned by #
+// XMALLOC and XCALLOC and removes the casting as it is not required. The
+// result in the patch case may need some reformatting.
+//
+// Confidence: High
+// Copyright: (C) 2014 Himangi Saraogi GPLv2.
+// Copyright: (C) 2017 Himanshu Jha GPLv2.
+// Copyright: (C) 2019 Quentin Young GPLv2.
+// Comments:
+// Options: --no-includes --include-headers
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+@initialize:python@
+@@
+import re
+pattern = '__'
+m = re.compile(pattern)
+
+@r1 depends on context || patch@
+type T;
+@@
+
+ (T *)
+ \(XMALLOC\|XCALLOC\)(...)
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@script:python depends on context@
+t << r1.T;
+@@
+
+if m.search(t) != None:
+ cocci.include_match(False)
+
+@depends on context && r1@
+type r1.T;
+@@
+
+* (T *)
+ \(XMALLOC\|XCALLOC\)(...)
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@script:python depends on patch@
+t << r1.T;
+@@
+
+if m.search(t) != None:
+ cocci.include_match(False)
+
+@depends on patch && r1@
+type r1.T;
+@@
+
+- (T *)
+ \(XMALLOC\|XCALLOC\)(...)
+
+//----------------------------------------------------------
+// For org and report mode
+//----------------------------------------------------------
+
+@r2 depends on org || report@
+type T;
+position p;
+@@
+
+ (T@p *)
+ \(XMALLOC\|XCALLOC\)(...)
+
+@script:python depends on org@
+p << r2.p;
+t << r2.T;
+@@
+
+if m.search(t) != None:
+ cocci.include_match(False)
+else:
+ coccilib.org.print_safe_todo(p[0], t)
+
+@script:python depends on report@
+p << r2.p;
+t << r2.T;
+@@
+
+if m.search(t) != None:
+ cocci.include_match(False)
+else:
+ msg="WARNING: casting value returned by memory allocation function to (%s *) is useless." % (t)
+ coccilib.report.print_report(p[0], msg)
diff --git a/tools/coccinelle/array_size.cocci b/tools/coccinelle/array_size.cocci
new file mode 100644
index 0000000000..f977b8aef2
--- /dev/null
+++ b/tools/coccinelle/array_size.cocci
@@ -0,0 +1,83 @@
+/// Use array_size instead of dividing sizeof array with sizeof an element
+///
+//# This makes an effort to find cases where array_size can be used such as
+//# where there is a division of sizeof the array by the sizeof its first
+//# element or by any indexed element or the element type. It replaces the
+//# division of the two sizeofs by array_size.
+//
+// Confidence: High
+// Copyright: (C) 2014 Himangi Saraogi. GPLv2.
+// Copyright: (C) 2019 Quentin Young. GPLv2.
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context@
+type T;
+T[] E;
+@@
+(
+* (sizeof(E)/sizeof(*E))
+|
+* (sizeof(E)/sizeof(E[...]))
+|
+* (sizeof(E)/sizeof(T))
+)
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+type T;
+T[] E;
+@@
+(
+- (sizeof(E)/sizeof(*E))
++ array_size(E)
+|
+- (sizeof(E)/sizeof(E[...]))
++ array_size(E)
+|
+- (sizeof(E)/sizeof(T))
++ array_size(E)
+)
+
+//----------------------------------------------------------
+// For org and report mode
+//----------------------------------------------------------
+
+@r depends on (org || report)@
+type T;
+T[] E;
+position p;
+@@
+(
+ (sizeof(E)@p /sizeof(*E))
+|
+ (sizeof(E)@p /sizeof(E[...]))
+|
+ (sizeof(E)@p /sizeof(T))
+)
+
+@script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING should use array_size")
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg="WARNING: Use array_size"
+coccilib.report.print_report(p[0], msg)
+
diff --git a/tools/coccinelle/badty.cocci b/tools/coccinelle/badty.cocci
new file mode 100644
index 0000000000..481cf301cc
--- /dev/null
+++ b/tools/coccinelle/badty.cocci
@@ -0,0 +1,76 @@
+/// Use ARRAY_SIZE instead of dividing sizeof array with sizeof an element
+///
+//# This makes an effort to find cases where the argument to sizeof is wrong
+//# in memory allocation functions by checking the type of the allocated memory
+//# when it is a double pointer and ensuring the sizeof argument takes a pointer
+//# to the the memory being allocated. There are false positives in cases the
+//# sizeof argument is not used in constructing the return value. The result
+//# may need some reformatting.
+//
+// Confidence: Moderate
+// Copyright: (C) 2014 Himangi Saraogi. GPLv2.
+// Comments:
+// Options:
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context disable sizeof_type_expr@
+type T;
+T **x;
+@@
+
+ x =
+ <+...sizeof(
+* T
+ )...+>
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch disable sizeof_type_expr@
+type T;
+T **x;
+@@
+
+ x =
+ <+...sizeof(
+- T
++ *x
+ )...+>
+
+//----------------------------------------------------------
+// For org and report mode
+//----------------------------------------------------------
+
+@r depends on (org || report) disable sizeof_type_expr@
+type T;
+T **x;
+position p;
+@@
+
+ x =
+ <+...sizeof(
+ T@p
+ )...+>
+
+@script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING sizeof argument should be pointer type, not structure type")
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg="WARNING: Use correct pointer type argument for sizeof"
+coccilib.report.print_report(p[0], msg)
+
diff --git a/tools/coccinelle/badzero.cocci b/tools/coccinelle/badzero.cocci
new file mode 100644
index 0000000000..f597c8007b
--- /dev/null
+++ b/tools/coccinelle/badzero.cocci
@@ -0,0 +1,238 @@
+/// Compare pointer-typed values to NULL rather than 0
+///
+//# This makes an effort to choose between !x and x == NULL. !x is used
+//# if it has previously been used with the function used to initialize x.
+//# This relies on type information. More type information can be obtained
+//# using the option -all_includes and the option -I to specify an
+//# include path.
+//
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Requires: 1.0.0
+// Options:
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@initialize:ocaml@
+@@
+let negtable = Hashtbl.create 101
+
+@depends on patch@
+expression *E;
+identifier f;
+@@
+
+(
+ (E = f(...)) ==
+- 0
++ NULL
+|
+ (E = f(...)) !=
+- 0
++ NULL
+|
+- 0
++ NULL
+ == (E = f(...))
+|
+- 0
++ NULL
+ != (E = f(...))
+)
+
+
+@t1 depends on !patch@
+expression *E;
+identifier f;
+position p;
+@@
+
+(
+ (E = f(...)) ==
+* 0@p
+|
+ (E = f(...)) !=
+* 0@p
+|
+* 0@p
+ == (E = f(...))
+|
+* 0@p
+ != (E = f(...))
+)
+
+@script:python depends on org@
+p << t1.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
+
+@script:python depends on report@
+p << t1.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
+
+// Tests of returned values
+
+@s@
+identifier f;
+expression E,E1;
+@@
+
+ E = f(...)
+ ... when != E = E1
+ !E
+
+@script:ocaml depends on s@
+f << s.f;
+@@
+
+try let _ = Hashtbl.find negtable f in ()
+with Not_found -> Hashtbl.add negtable f ()
+
+@ r disable is_zero,isnt_zero exists @
+expression *E;
+identifier f;
+@@
+
+E = f(...)
+...
+(E == 0
+|E != 0
+|0 == E
+|0 != E
+)
+
+@script:ocaml@
+f << r.f;
+@@
+
+try let _ = Hashtbl.find negtable f in ()
+with Not_found -> include_match false
+
+// This rule may lead to inconsistent path problems, if E is defined in two
+// places
+@ depends on patch disable is_zero,isnt_zero @
+expression *E;
+expression E1;
+identifier r.f;
+@@
+
+E = f(...)
+<...
+(
+- E == 0
++ !E
+|
+- E != 0
++ E
+|
+- 0 == E
++ !E
+|
+- 0 != E
++ E
+)
+...>
+?E = E1
+
+@t2 depends on !patch disable is_zero,isnt_zero @
+expression *E;
+expression E1;
+identifier r.f;
+position p1;
+position p2;
+@@
+
+E = f(...)
+<...
+(
+* E == 0@p1
+|
+* E != 0@p2
+|
+* 0@p1 == E
+|
+* 0@p1 != E
+)
+...>
+?E = E1
+
+@script:python depends on org@
+p << t2.p1;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")
+
+@script:python depends on org@
+p << t2.p2;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
+
+@script:python depends on report@
+p << t2.p1;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")
+
+@script:python depends on report@
+p << t2.p2;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
+
+@ depends on patch disable is_zero,isnt_zero @
+expression *E;
+@@
+
+(
+ E ==
+- 0
++ NULL
+|
+ E !=
+- 0
++ NULL
+|
+- 0
++ NULL
+ == E
+|
+- 0
++ NULL
+ != E
+)
+
+@ t3 depends on !patch disable is_zero,isnt_zero @
+expression *E;
+position p;
+@@
+
+(
+* E == 0@p
+|
+* E != 0@p
+|
+* 0@p == E
+|
+* 0@p != E
+)
+
+@script:python depends on org@
+p << t3.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
+
+@script:python depends on report@
+p << t3.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
diff --git a/tools/coccinelle/boolconv.cocci b/tools/coccinelle/boolconv.cocci
new file mode 100644
index 0000000000..33c464d6bc
--- /dev/null
+++ b/tools/coccinelle/boolconv.cocci
@@ -0,0 +1,90 @@
+/// Remove unneeded conversion to bool
+///
+//# Relational and logical operators evaluate to bool,
+//# explicit conversion is overly verbose and unneeded.
+//
+// Copyright: (C) 2016 Andrew F. Davis <afd@ti.com> GPLv2.
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+expression A, B;
+symbol true, false;
+@@
+
+(
+ A == B
+|
+ A != B
+|
+ A > B
+|
+ A < B
+|
+ A >= B
+|
+ A <= B
+|
+ A && B
+|
+ A || B
+)
+- ? true : false
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@r depends on !patch@
+expression A, B;
+symbol true, false;
+position p;
+@@
+
+(
+ A == B
+|
+ A != B
+|
+ A > B
+|
+ A < B
+|
+ A >= B
+|
+ A <= B
+|
+ A && B
+|
+ A || B
+)
+* ? true : false@p
+
+//----------------------------------------------------------
+// For org mode
+//----------------------------------------------------------
+
+@script:python depends on r&&org@
+p << r.p;
+@@
+
+msg = "WARNING: conversion to bool not needed here"
+coccilib.org.print_todo(p[0], msg)
+
+//----------------------------------------------------------
+// For report mode
+//----------------------------------------------------------
+
+@script:python depends on r&&report@
+p << r.p;
+@@
+
+msg = "WARNING: conversion to bool not needed here"
+coccilib.report.print_report(p[0], msg)
diff --git a/tools/coccinelle/boolinit.cocci b/tools/coccinelle/boolinit.cocci
new file mode 100644
index 0000000000..aabb581fab
--- /dev/null
+++ b/tools/coccinelle/boolinit.cocci
@@ -0,0 +1,194 @@
+/// Bool initializations should use true and false. Bool tests don't need
+/// comparisons. Based on contributions from Joe Perches, Rusty Russell
+/// and Bruce W Allan.
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@boolok@
+symbol true,false;
+@@
+(
+true
+|
+false
+)
+
+@depends on patch@
+bool t;
+@@
+
+(
+- t == true
++ t
+|
+- true == t
++ t
+|
+- t != true
++ !t
+|
+- true != t
++ !t
+|
+- t == false
++ !t
+|
+- false == t
++ !t
+|
+- t != false
++ t
+|
+- false != t
++ t
+)
+
+@depends on patch disable is_zero, isnt_zero@
+bool t;
+@@
+
+(
+- t == 1
++ t
+|
+- t != 1
++ !t
+|
+- t == 0
++ !t
+|
+- t != 0
++ t
+)
+
+@depends on patch && boolok@
+bool b;
+@@
+(
+ b =
+- 0
++ false
+|
+ b =
+- 1
++ true
+)
+
+// ---------------------------------------------------------------------
+
+@r1 depends on !patch@
+bool t;
+position p;
+@@
+
+(
+* t@p == true
+|
+* true == t@p
+|
+* t@p != true
+|
+* true != t@p
+|
+* t@p == false
+|
+* false == t@p
+|
+* t@p != false
+|
+* false != t@p
+)
+
+@r2 depends on !patch disable is_zero, isnt_zero@
+bool t;
+position p;
+@@
+
+(
+* t@p == 1
+|
+* t@p != 1
+|
+* t@p == 0
+|
+* t@p != 0
+)
+
+@r3 depends on !patch && boolok@
+bool b;
+position p1;
+@@
+(
+*b@p1 = 0
+|
+*b@p1 = 1
+)
+
+@r4 depends on !patch@
+bool b;
+position p2;
+identifier i;
+constant c != {0,1};
+@@
+(
+ b = i
+|
+*b@p2 = c
+)
+
+@script:python depends on org@
+p << r1.p;
+@@
+
+cocci.print_main("WARNING: Comparison to bool",p)
+
+@script:python depends on org@
+p << r2.p;
+@@
+
+cocci.print_main("WARNING: Comparison of 0/1 to bool variable",p)
+
+@script:python depends on org@
+p1 << r3.p1;
+@@
+
+cocci.print_main("WARNING: Assignment of 0/1 to bool variable",p1)
+
+@script:python depends on org@
+p2 << r4.p2;
+@@
+
+cocci.print_main("ERROR: Assignment of non-0/1 constant to bool variable",p2)
+
+@script:python depends on report@
+p << r1.p;
+@@
+
+coccilib.report.print_report(p[0],"WARNING: Comparison to bool")
+
+@script:python depends on report@
+p << r2.p;
+@@
+
+coccilib.report.print_report(p[0],"WARNING: Comparison of 0/1 to bool variable")
+
+@script:python depends on report@
+p1 << r3.p1;
+@@
+
+coccilib.report.print_report(p1[0],"WARNING: Assignment of 0/1 to bool variable")
+
+@script:python depends on report@
+p2 << r4.p2;
+@@
+
+coccilib.report.print_report(p2[0],"ERROR: Assignment of non-0/1 constant to bool variable")
diff --git a/tools/coccinelle/boolreturn.cocci b/tools/coccinelle/boolreturn.cocci
new file mode 100644
index 0000000000..29d2bf41e9
--- /dev/null
+++ b/tools/coccinelle/boolreturn.cocci
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/// Return statements in functions returning bool should use
+/// true/false instead of 1/0.
+//
+// Confidence: High
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+virtual context
+
+@r1 depends on patch@
+identifier fn;
+typedef bool;
+symbol false;
+symbol true;
+@@
+
+bool fn ( ... )
+{
+<...
+return
+(
+- 0
++ false
+|
+- 1
++ true
+)
+ ;
+...>
+}
+
+@r2 depends on report || context@
+identifier fn;
+position p;
+@@
+
+bool fn ( ... )
+{
+<...
+return
+(
+* 0@p
+|
+* 1@p
+)
+ ;
+...>
+}
+
+
+@script:python depends on report@
+p << r2.p;
+fn << r2.fn;
+@@
+
+msg = "WARNING: return of 0/1 in function '%s' with return type bool" % fn
+coccilib.report.print_report(p[0], msg)
diff --git a/tools/coccinelle/cond_no_effect.cocci b/tools/coccinelle/cond_no_effect.cocci
new file mode 100644
index 0000000000..8467dbd1c4
--- /dev/null
+++ b/tools/coccinelle/cond_no_effect.cocci
@@ -0,0 +1,64 @@
+///Find conditions where if and else branch are functionally
+// identical.
+//
+// There can be false positives in cases where the positional
+// information is used (as with lockdep) or where the identity
+// is a placeholder for not yet handled cases.
+// Unfortunately there also seems to be a tendency to use
+// the last if else/else as a "default behavior" - which some
+// might consider a legitimate coding pattern. From discussion
+// on kernelnewbies though it seems that this is not really an
+// accepted pattern and if at all it would need to be commented
+//
+// In the Linux kernel it does not seem to actually report
+// false positives except for those that were documented as
+// being intentional.
+// the two known cases are:
+// arch/sh/kernel/traps_64.c:read_opcode()
+// } else if ((pc & 1) == 0) {
+// /* SHcompact */
+// /* TODO : provide handling for this. We don't really support
+// user-mode SHcompact yet, and for a kernel fault, this would
+// have to come from a module built for SHcompact. */
+// return -EFAULT;
+// } else {
+// /* misaligned */
+// return -EFAULT;
+// }
+// fs/kernfs/file.c:kernfs_fop_open()
+// * Both paths of the branch look the same. They're supposed to
+// * look that way and give @of->mutex different static lockdep keys.
+// */
+// if (has_mmap)
+// mutex_init(&of->mutex);
+// else
+// mutex_init(&of->mutex);
+//
+// All other cases look like bugs or at least lack of documentation
+//
+// Confidence: Moderate
+// Copyright: (C) 2016 Nicholas Mc Guire, OSADL. GPLv2.
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+@cond@
+statement S1;
+position p;
+@@
+
+* if@p (...) S1 else S1
+
+@script:python depends on org@
+p << cond.p;
+@@
+
+cocci.print_main("WARNING: possible condition with no effect (if == else)",p)
+
+@script:python depends on report@
+p << cond.p;
+@@
+
+coccilib.report.print_report(p[0],"WARNING: possible condition with no effect (if == else)")
diff --git a/tools/coccinelle/deref_null.cocci b/tools/coccinelle/deref_null.cocci
new file mode 100644
index 0000000000..cbc6184e69
--- /dev/null
+++ b/tools/coccinelle/deref_null.cocci
@@ -0,0 +1,282 @@
+///
+/// A variable is dereferenced under a NULL test.
+/// Even though it is known to be NULL.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: -I ... -all_includes can give more complete results
+// Options:
+
+virtual context
+virtual org
+virtual report
+
+// The following two rules are separate, because both can match a single
+// expression in different ways
+@pr1 expression@
+expression E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
+
+@pr2 expression@
+expression E;
+identifier f;
+position p2;
+@@
+
+(
+ (E != NULL) && ... && <+...E->f@p2...+>
+|
+ (E == NULL) || ... || <+...E->f@p2...+>
+|
+ sizeof(<+...E->f@p2...+>)
+)
+
+@ifm@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...) S1 else S2
+
+// For org and report modes
+
+@r depends on !context && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f@p // bad use
+)
+ ... when any
+ return ...;
+}
+else S3
+
+@script:python depends on !context && !org && report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+cocci.include_match(False)
+
+@script:python depends on !context && org && !report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+cocci.include_match(False)
+
+@s depends on !context && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f@p // bad use
+)
+ ... when any
+}
+else S3
+
+@script:python depends on !context && !org && report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+
+@script:python depends on !context && org && !report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+
+// For context mode
+
+@depends on context && !org && !report exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f@p // bad use
+)
+ ... when any
+ return ...;
+}
+else S3
+
+// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
+// It is need because the previous rule as already made a "change".
+
+@pr11 depends on context && !org && !report expression@
+expression E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
+
+@pr12 depends on context && !org && !report expression@
+expression E;
+identifier f;
+position p2;
+@@
+
+(
+ (E != NULL) && ... && <+...E->f@p2...+>
+|
+ (E == NULL) || ... || <+...E->f@p2...+>
+|
+ sizeof(<+...E->f@p2...+>)
+)
+
+@ifm1 depends on context && !org && !report@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...) S1 else S2
+
+@depends on context && !org && !report exists@
+expression subE <= ifm1.E;
+expression *ifm1.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr11.p1,pr12.p2};
+position ifm1.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f@p // bad use
+)
+ ... when any
+}
+else S3
diff --git a/tools/coccinelle/double_lock.cocci b/tools/coccinelle/double_lock.cocci
new file mode 100644
index 0000000000..002752f97d
--- /dev/null
+++ b/tools/coccinelle/double_lock.cocci
@@ -0,0 +1,92 @@
+/// Find double locks. False positives may occur when some paths cannot
+/// occur at execution, due to the values of variables, and when there is
+/// an intervening function call that releases the lock.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+@locked@
+position p1;
+expression E1;
+position p;
+@@
+
+(
+mutex_lock@p1
+|
+mutex_trylock@p1
+|
+spin_lock@p1
+|
+spin_trylock@p1
+|
+read_lock@p1
+|
+read_trylock@p1
+|
+write_lock@p1
+|
+write_trylock@p1
+) (E1@p,...);
+
+@balanced@
+position p1 != locked.p1;
+position locked.p;
+identifier lock,unlock;
+expression x <= locked.E1;
+expression E,locked.E1;
+expression E2;
+@@
+
+if (E) {
+ <+... when != E1
+ lock(E1@p,...)
+ ...+>
+}
+... when != E1
+ when != \(x = E2\|&x\)
+ when forall
+if (E) {
+ <+... when != E1
+ unlock@p1(E1,...)
+ ...+>
+}
+
+@r depends on !balanced exists@
+expression x <= locked.E1;
+expression locked.E1;
+expression E2;
+identifier lock;
+position locked.p,p1,p2;
+@@
+
+lock@p1 (E1@p,...);
+... when != E1
+ when != \(x = E2\|&x\)
+lock@p2 (E1,...);
+
+@script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+lock << r.lock;
+@@
+
+cocci.print_main(lock,p1)
+cocci.print_secs("second lock",p2)
+
+@script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+lock << r.lock;
+@@
+
+msg = "second lock on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/tools/coccinelle/doublebitand.cocci b/tools/coccinelle/doublebitand.cocci
new file mode 100644
index 0000000000..72f1572aae
--- /dev/null
+++ b/tools/coccinelle/doublebitand.cocci
@@ -0,0 +1,54 @@
+/// Find bit operations that include the same argument more than once
+//# One source of false positives is when the argument performs a side
+//# effect. Another source of false positives is when a neutral value
+//# such as 0 for | is used to indicate no information, to maintain the
+//# same structure as other similar expressions
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+@r expression@
+expression E;
+position p;
+@@
+
+(
+* E@p
+ & ... & E
+|
+* E@p
+ | ... | E
+|
+* E@p
+ & ... & !E
+|
+* E@p
+ | ... | !E
+|
+* !E@p
+ & ... & E
+|
+* !E@p
+ | ... | E
+)
+
+@script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("duplicated argument to & or |",p)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0],"duplicated argument to & or |")
diff --git a/tools/coccinelle/doubleinit.cocci b/tools/coccinelle/doubleinit.cocci
new file mode 100644
index 0000000000..c0c3371d25
--- /dev/null
+++ b/tools/coccinelle/doubleinit.cocci
@@ -0,0 +1,53 @@
+/// Find duplicate field initializations. This has a high rate of false
+/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
+/// initialization.
+///
+// Confidence: Low
+// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+@r@
+identifier I, s, fld;
+position p0,p;
+expression E;
+@@
+
+struct I s =@p0 { ..., .fld@p = E, ...};
+
+@s@
+identifier I, s, r.fld;
+position r.p0,p;
+expression E;
+@@
+
+struct I s =@p0 { ..., .fld@p = E, ...};
+
+@script:python depends on org@
+p0 << r.p0;
+fld << r.fld;
+ps << s.p;
+pr << r.p;
+@@
+
+if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
+ cocci.print_main(fld,p0)
+ cocci.print_secs("s",ps)
+ cocci.print_secs("r",pr)
+
+@script:python depends on report@
+p0 << r.p0;
+fld << r.fld;
+ps << s.p;
+pr << r.p;
+@@
+
+if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
+ msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
+ coccilib.report.print_report(p0[0],msg)
diff --git a/tools/coccinelle/doubletest.cocci b/tools/coccinelle/doubletest.cocci
new file mode 100644
index 0000000000..7af2ce7eb9
--- /dev/null
+++ b/tools/coccinelle/doubletest.cocci
@@ -0,0 +1,58 @@
+/// Find &&/|| operations that include the same argument more than once
+//# A common source of false positives is when the expression, or
+//# another expresssion in the same && or || operation, performs a
+//# side effect.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+@r expression@
+expression E;
+position p;
+@@
+
+(
+ E@p || ... || E
+|
+ E@p && ... && E
+)
+
+@bad@
+expression r.E,e1,e2,fn;
+position r.p;
+assignment operator op;
+@@
+
+(
+E@p
+&
+ <+... \(fn(...)\|e1 op e2\|e1++\|e1--\|++e1\|--e1\) ...+>
+)
+
+@depends on context && !bad@
+expression r.E;
+position r.p;
+@@
+
+*E@p
+
+@script:python depends on org && !bad@
+p << r.p;
+@@
+
+cocci.print_main("duplicated argument to && or ||",p)
+
+@script:python depends on report && !bad@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0],"duplicated argument to && or ||")
diff --git a/tools/coccinelle/ifaddr.cocci b/tools/coccinelle/ifaddr.cocci
new file mode 100644
index 0000000000..c2663c677a
--- /dev/null
+++ b/tools/coccinelle/ifaddr.cocci
@@ -0,0 +1,34 @@
+/// The address of a variable or field is likely always to be non-zero.
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+@r@
+expression x;
+statement S1,S2;
+position p;
+@@
+
+*if@p (&x)
+ S1 else S2
+
+@script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("test of a variable/field address",p)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg = "ERROR: test of a variable/field address"
+coccilib.report.print_report(p[0],msg)
diff --git a/tools/coccinelle/ifnullxfree.cocci b/tools/coccinelle/ifnullxfree.cocci
new file mode 100644
index 0000000000..85fc23e394
--- /dev/null
+++ b/tools/coccinelle/ifnullxfree.cocci
@@ -0,0 +1,15 @@
+/// NULL check before some freeing functions is not needed.
+///
+// Copyright: (C) 2014 Fabian Frederick. GPLv2.
+// Copyright: (C) 2019 Quentin Young. GPLv2.
+// Comments: -
+// Options: --no-includes --include-headers
+
+virtual patch
+
+@r2 depends on patch@
+expression E;
+expression Y;
+@@
+- if (E != NULL)
+XFREE(Y, E);
diff --git a/tools/coccinelle/itnull.cocci b/tools/coccinelle/itnull.cocci
new file mode 100644
index 0000000000..f58732b56a
--- /dev/null
+++ b/tools/coccinelle/itnull.cocci
@@ -0,0 +1,94 @@
+/// Many iterators have the property that the first argument is always bound
+/// to a real list element, never NULL.
+//# False positives arise for some iterators that do not have this property,
+//# or in cases when the loop cursor is reassigned. The latter should only
+//# happen when the matched code is on the way to a loop exit (break, goto,
+//# or return).
+///
+// Confidence: Moderate
+// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@depends on patch@
+iterator I;
+expression x,E,E1,E2;
+statement S,S1,S2;
+@@
+
+I(x,...) { <...
+(
+- if (x == NULL && ...) S
+|
+- if (x != NULL || ...)
+ S
+|
+- (x == NULL) ||
+ E
+|
+- (x != NULL) &&
+ E
+|
+- (x == NULL && ...) ? E1 :
+ E2
+|
+- (x != NULL || ...) ?
+ E1
+- : E2
+|
+- if (x == NULL && ...) S1 else
+ S2
+|
+- if (x != NULL || ...)
+ S1
+- else S2
+|
++ BAD(
+ x == NULL
++ )
+|
++ BAD(
+ x != NULL
++ )
+)
+ ...> }
+
+@r depends on !patch exists@
+iterator I;
+expression x,E;
+position p1,p2;
+@@
+
+*I@p1(x,...)
+{ ... when != x = E
+(
+* x@p2 == NULL
+|
+* x@p2 != NULL
+)
+ ... when any
+}
+
+@script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("iterator-bound variable",p1)
+cocci.print_secs("useless NULL test",p2)
+
+@script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
diff --git a/tools/coccinelle/mini_lock.cocci b/tools/coccinelle/mini_lock.cocci
new file mode 100644
index 0000000000..19c6ee5b98
--- /dev/null
+++ b/tools/coccinelle/mini_lock.cocci
@@ -0,0 +1,98 @@
+/// Find missing unlocks. This semantic match considers the specific case
+/// where the unlock is missing from an if branch, and there is a lock
+/// before the if and an unlock after the if. False positives are due to
+/// cases where the if branch represents a case where the function is
+/// supposed to exit with the lock held, or where there is some preceding
+/// function call that releases the lock.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+@prelocked@
+position p1,p;
+expression E1;
+@@
+
+(
+mutex_lock@p1
+|
+mutex_trylock@p1
+|
+spin_lock@p1
+|
+spin_trylock@p1
+|
+read_lock@p1
+|
+read_trylock@p1
+|
+write_lock@p1
+|
+write_trylock@p1
+|
+read_lock_irq@p1
+|
+write_lock_irq@p1
+|
+read_lock_irqsave@p1
+|
+write_lock_irqsave@p1
+|
+spin_lock_irq@p1
+|
+spin_lock_irqsave@p1
+) (E1@p,...);
+
+@looped@
+position r;
+@@
+
+for(...;...;...) { <+... return@r ...; ...+> }
+
+@err exists@
+expression E1;
+position prelocked.p;
+position up != prelocked.p1;
+position r!=looped.r;
+identifier lock,unlock;
+@@
+
+*lock(E1@p,...);
+... when != E1
+ when any
+if (...) {
+ ... when != E1
+* return@r ...;
+}
+... when != E1
+ when any
+*unlock@up(E1,...);
+
+@script:python depends on org@
+p << prelocked.p1;
+lock << err.lock;
+unlock << err.unlock;
+p2 << err.r;
+@@
+
+cocci.print_main(lock,p)
+cocci.print_secs(unlock,p2)
+
+@script:python depends on report@
+p << prelocked.p1;
+lock << err.lock;
+unlock << err.unlock;
+p2 << err.r;
+@@
+
+msg = "preceding lock on line %s" % (p[0].line)
+coccilib.report.print_report(p2[0],msg)
diff --git a/tools/coccinelle/noderef.cocci b/tools/coccinelle/noderef.cocci
new file mode 100644
index 0000000000..ca289d5741
--- /dev/null
+++ b/tools/coccinelle/noderef.cocci
@@ -0,0 +1,81 @@
+/// sizeof when applied to a pointer typed expression gives the size of
+/// the pointer
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+virtual patch
+
+@depends on patch@
+expression *x;
+expression f;
+expression i;
+type T;
+@@
+
+(
+x = <+... sizeof(
+- x
++ *x
+ ) ...+>
+|
+f(...,(T)(x),...,sizeof(
+- x
++ *x
+ ),...)
+|
+f(...,sizeof(
+- x
++ *x
+ ),...,(T)(x),...)
+|
+f(...,(T)(x),...,i*sizeof(
+- x
++ *x
+ ),...)
+|
+f(...,i*sizeof(
+- x
++ *x
+ ),...,(T)(x),...)
+)
+
+@r depends on !patch@
+expression *x;
+expression f;
+expression i;
+position p;
+type T;
+@@
+
+(
+*x = <+... sizeof@p(x) ...+>
+|
+*f(...,(T)(x),...,sizeof@p(x),...)
+|
+*f(...,sizeof@p(x),...,(T)(x),...)
+|
+*f(...,(T)(x),...,i*sizeof@p(x),...)
+|
+*f(...,i*sizeof@p(x),...,(T)(x),...)
+)
+
+@script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("application of sizeof to pointer",p)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg = "ERROR: application of sizeof to pointer"
+coccilib.report.print_report(p[0],msg)<Paste>
diff --git a/tools/coccinelle/replace-strncpy.cocci b/tools/coccinelle/replace-strncpy.cocci
new file mode 100644
index 0000000000..18ff1314b0
--- /dev/null
+++ b/tools/coccinelle/replace-strncpy.cocci
@@ -0,0 +1,8 @@
+@@
+type T;
+T[] E;
+expression buf, srclen;
+@@
+
+- strncpy(E, src, srclen)
++ strlcpy(E, src, sizeof(E))
diff --git a/tools/coccinelle/returnvar.cocci b/tools/coccinelle/returnvar.cocci
new file mode 100644
index 0000000000..d8286ef530
--- /dev/null
+++ b/tools/coccinelle/returnvar.cocci
@@ -0,0 +1,66 @@
+///
+/// Remove unneeded variable used to store return value.
+///
+// Confidence: Moderate
+// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: Comments on code can be deleted if near code that is removed.
+// "when strict" can be removed to get more hits, but adds false
+// positives
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+virtual context
+virtual org
+
+@depends on patch@
+type T;
+constant C;
+identifier ret;
+@@
+- T ret = C;
+... when != ret
+ when strict
+return
+- ret
++ C
+;
+
+@depends on context@
+type T;
+constant C;
+identifier ret;
+@@
+* T ret = C;
+... when != ret
+ when strict
+* return ret;
+
+@r1 depends on report || org@
+type T;
+constant C;
+identifier ret;
+position p1, p2;
+@@
+T ret@p1 = C;
+... when != ret
+ when strict
+return ret@p2;
+
+@script:python depends on report@
+p1 << r1.p1;
+p2 << r1.p2;
+C << r1.C;
+ret << r1.ret;
+@@
+coccilib.report.print_report(p1[0], "Unneeded variable: \"" + ret + "\". Return \"" + C + "\" on line " + p2[0].line)
+
+@script:python depends on org@
+p1 << r1.p1;
+p2 << r1.p2;
+C << r1.C;
+ret << r1.ret;
+@@
+cocci.print_main("unneeded \"" + ret + "\" variable", p1)
+cocci.print_sec("return " + C + " here", p2)
diff --git a/tools/coccinelle/semicolon.cocci b/tools/coccinelle/semicolon.cocci
new file mode 100644
index 0000000000..6740c659a2
--- /dev/null
+++ b/tools/coccinelle/semicolon.cocci
@@ -0,0 +1,83 @@
+///
+/// Remove unneeded semicolon.
+///
+// Confidence: Moderate
+// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: Some false positives on empty default cases in switch statements.
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual report
+virtual context
+virtual org
+
+@r_default@
+position p;
+@@
+switch (...)
+{
+default: ...;@p
+}
+
+@r_case@
+position p;
+@@
+(
+switch (...)
+{
+case ...:;@p
+}
+|
+switch (...)
+{
+case ...:...
+case ...:;@p
+}
+|
+switch (...)
+{
+case ...:...
+case ...:
+case ...:;@p
+}
+)
+
+@r1@
+statement S;
+position p1;
+position p != {r_default.p, r_case.p};
+identifier label;
+@@
+(
+label:;
+|
+S@p1;@p
+)
+
+@script:python@
+p << r1.p;
+p1 << r1.p1;
+@@
+if p[0].line != p1[0].line_end:
+ cocci.include_match(False)
+
+@depends on patch@
+position r1.p;
+@@
+-;@p
+
+@script:python depends on report@
+p << r1.p;
+@@
+coccilib.report.print_report(p[0],"Unneeded semicolon")
+
+@depends on context@
+position r1.p;
+@@
+*;@p
+
+@script:python depends on org@
+p << r1.p;
+@@
+cocci.print_main("Unneeded semicolon",p)
diff --git a/tools/coccinelle/strncpy_truncation.cocci b/tools/coccinelle/strncpy_truncation.cocci
new file mode 100644
index 0000000000..28b5c2a290
--- /dev/null
+++ b/tools/coccinelle/strncpy_truncation.cocci
@@ -0,0 +1,41 @@
+/// Use strlcpy rather than strncpy(dest,..,sz) + dest[sz-1] = '\0'
+///
+// Confidence: High
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual report
+virtual org
+
+@r@
+expression dest, src, sz;
+position p;
+@@
+
+strncpy@p(dest, src, sz);
+dest[sz - 1] = '\0';
+
+@script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("strncpy followed by truncation can be strlcpy",p)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg = "SUGGESTION: strncpy followed by truncation can be strlcpy"
+coccilib.report.print_report(p[0],msg)
+
+@ok depends on patch@
+expression r.dest, r.src, r.sz;
+position r.p;
+@@
+
+-strncpy@p(
++strlcpy(
+ dest, src, sz);
+-dest[sz - 1] = '\0';
diff --git a/tools/coccinelle/unsigned_lesser_than_zero.cocci b/tools/coccinelle/unsigned_lesser_than_zero.cocci
new file mode 100644
index 0000000000..8fa5a3c7b7
--- /dev/null
+++ b/tools/coccinelle/unsigned_lesser_than_zero.cocci
@@ -0,0 +1,75 @@
+/// Unsigned expressions cannot be lesser than zero. Presence of
+/// comparisons 'unsigned (<|<=|>|>=) 0' often indicates a bug,
+/// usually wrong type of variable.
+///
+/// To reduce number of false positives following tests have been added:
+/// - parts of range checks are skipped, eg. "if (u < 0 || u > 15) ...",
+/// developers prefer to keep such code,
+/// - comparisons "<= 0" and "> 0" are performed only on results of
+/// signed functions/macros,
+/// - hardcoded list of signed functions/macros with always non-negative
+/// result is used to avoid false positives difficult to detect by other ways
+///
+// Confidence: Average
+// Copyright: (C) 2015 Andrzej Hajda, Samsung Electronics Co., Ltd. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --all-includes
+
+virtual context
+virtual org
+virtual report
+
+@r_cmp@
+position p;
+typedef bool, u8, u16, u32, u64;
+{unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long,
+ size_t, bool, u8, u16, u32, u64} v;
+expression e;
+@@
+
+ \( v = e \| &v \)
+ ...
+ (\( v@p < 0 \| v@p <= 0 \| v@p >= 0 \| v@p > 0 \))
+
+@r@
+position r_cmp.p;
+typedef s8, s16, s32, s64;
+{char, short, int, long, long long, ssize_t, s8, s16, s32, s64} vs;
+expression c, e, v;
+identifier f !~ "^(ata_id_queue_depth|btrfs_copy_from_user|dma_map_sg|dma_map_sg_attrs|fls|fls64|gameport_time|get_write_extents|nla_len|ntoh24|of_flat_dt_match|of_get_child_count|uart_circ_chars_pending|[A-Z0-9_]+)$";
+@@
+
+(
+ v = f(...)@vs;
+ ... when != v = e;
+* (\( v@p <=@e 0 \| v@p >@e 0 \))
+ ... when any
+|
+(
+ (\( v@p < 0 \| v@p <= 0 \)) || ... || (\( v >= c \| v > c \))
+|
+ (\( v >= c \| v > c \)) || ... || (\( v@p < 0 \| v@p <= 0 \))
+|
+ (\( v@p >= 0 \| v@p > 0 \)) && ... && (\( v < c \| v <= c \))
+|
+ ((\( v < c \| v <= c \) && ... && \( v@p >= 0 \| v@p > 0 \)))
+|
+* (\( v@p <@e 0 \| v@p >=@e 0 \))
+)
+)
+
+@script:python depends on org@
+p << r_cmp.p;
+e << r.e;
+@@
+
+msg = "WARNING: Unsigned expression compared with zero: %s" % (e)
+coccilib.org.print_todo(p[0], msg)
+
+@script:python depends on report@
+p << r_cmp.p;
+e << r.e;
+@@
+
+msg = "WARNING: Unsigned expression compared with zero: %s" % (e)
+coccilib.report.print_report(p[0], msg)
diff --git a/tools/vty_check.cocci b/tools/coccinelle/vty_check.cocci
index 7e5fcc405b..7e5fcc405b 100644
--- a/tools/vty_check.cocci
+++ b/tools/coccinelle/vty_check.cocci
diff --git a/tools/vty_index.cocci b/tools/coccinelle/vty_index.cocci
index eabbaa1aa5..eabbaa1aa5 100644
--- a/tools/vty_index.cocci
+++ b/tools/coccinelle/vty_index.cocci
diff --git a/tools/coccinelle/xcalloc-simple.cocci b/tools/coccinelle/xcalloc-simple.cocci
new file mode 100644
index 0000000000..5be4dafb2b
--- /dev/null
+++ b/tools/coccinelle/xcalloc-simple.cocci
@@ -0,0 +1,52 @@
+///
+/// Use zeroing allocator rather than allocator followed by memset with 0
+///
+/// This considers some simple cases that are common and easy to validate
+/// Note in particular that there are no ...s in the rule, so all of the
+/// matched code has to be contiguous
+///
+// Confidence: High
+// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// Copyright: (C) 2017 Himanshu Jha GPLv2.
+// Copyright: (C) 2019 Quentin Young. GPLv2.
+// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
+// Options: --no-includes --include-headers
+//
+// Keywords: XMALLOC, XCALLOC
+// Version min: < 2.6.12 kmalloc
+// Version min: 2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context@
+type T, T2;
+expression x;
+expression E1;
+expression t;
+@@
+
+* x = (T)XMALLOC(t, E1);
+* memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+type T, T2;
+expression x;
+expression E1;
+expression t;
+@@
+
+- x = (T)XMALLOC(t, E1);
++ x = (T)XCALLOC(t, E1);
+- memset((T2)x,0,E1);
+
diff --git a/tools/coccinelle/xfree.cocci b/tools/coccinelle/xfree.cocci
new file mode 100644
index 0000000000..eb38f0d5a8
--- /dev/null
+++ b/tools/coccinelle/xfree.cocci
@@ -0,0 +1,122 @@
+/// Find a use after free.
+//# Values of variables may imply that some
+//# execution paths are not possible, resulting in false positives.
+//# Another source of false positives are macros such as
+//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
+///
+// Confidence: Moderate
+// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
+// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
+// Copyright: (C) 2019 Quentin Young. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+
+@free@
+expression E, t;
+position p1;
+@@
+
+* XFREE@p1(t, E)
+
+@print expression@
+constant char [] c;
+expression free.E,E2;
+type T;
+position p;
+identifier f;
+@@
+
+(
+ f(...,c,...,(T)E@p,...)
+|
+ E@p == E2
+|
+ E@p != E2
+|
+ E2 == E@p
+|
+ E2 != E@p
+|
+ !E@p
+|
+ E@p || ...
+)
+
+@sz@
+expression free.E;
+position p;
+@@
+
+ sizeof(<+...E@p...+>)
+
+@loop exists@
+expression E, t;
+identifier l;
+position ok;
+@@
+
+while (1) { ...
+* XFREE@ok(t, E)
+ ... when != break;
+ when != goto l;
+ when forall
+}
+
+@r exists@
+expression free.E, subE<=free.E, E2;
+expression E1;
+iterator iter;
+statement S;
+position free.p1!=loop.ok,p2!={print.p,sz.p};
+@@
+
+* XFREE@p1(t, E)
+...
+(
+ iter(...,subE,...) S // no use
+|
+ list_remove_head(E1,subE,...)
+|
+ subE = E2
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ BUG(...)
+|
+ BUG_ON(...)
+|
+ return_VALUE(...)
+|
+ return_ACPI_STATUS(...)
+|
+ E@p2 // bad use
+)
+
+@script:python depends on org@
+p1 << free.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("kfree",p1)
+cocci.print_secs("ref",p2)
+
+@script:python depends on report@
+p1 << free.p1;
+p2 << r.p2;
+@@
+
+msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
+coccilib.report.print_report(p2[0],msg)
diff --git a/tools/coccinelle/xfreeaddr.cocci b/tools/coccinelle/xfreeaddr.cocci
new file mode 100644
index 0000000000..c99c7ac3f5
--- /dev/null
+++ b/tools/coccinelle/xfreeaddr.cocci
@@ -0,0 +1,33 @@
+/// Free of a structure field
+///
+// Confidence: High
+// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6. GPLv2.
+// Copyright: (C) 2019 Quentin Young. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: --no-includes --include-headers
+
+virtual org
+virtual report
+virtual context
+
+@r depends on context || report || org @
+expression e, t;
+identifier f;
+position p;
+@@
+
+* XFREE@p(t, &e->f)
+
+@script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("XFREE",p)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg = "ERROR: invalid free of structure field"
+coccilib.report.print_report(p[0],msg)
diff --git a/tools/coccinelle/xmalloc_returnval.cocci b/tools/coccinelle/xmalloc_returnval.cocci
new file mode 100644
index 0000000000..8e0ad1027d
--- /dev/null
+++ b/tools/coccinelle/xmalloc_returnval.cocci
@@ -0,0 +1,37 @@
+/// XMALLOC, XCALLOC etc either return non-null, or abort the program.
+/// Never nullcheck these.
+//
+// Copyright: (C) 2019 Quentin Young. GPLv2.
+
+virtual patch
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+identifier alloc;
+@@
+
+alloc = XMALLOC(...);
+
+...
+
+- if (alloc == NULL)
+- {
+- ...
+- }
+
+@depends on patch@
+identifier alloc;
+@@
+
+alloc = XCALLOC(...);
+
+...
+
+- if (alloc == NULL)
+- {
+- ...
+- }
+
diff --git a/tools/zprivs.cocci b/tools/coccinelle/zprivs.cocci
index 76d13c3f0d..76d13c3f0d 100644
--- a/tools/zprivs.cocci
+++ b/tools/coccinelle/zprivs.cocci
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 91e49c45c1..7ca3ed9c5e 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -74,8 +74,7 @@ static int config_cmp(struct config *c1, struct config *c2)
static void config_del(struct config *config)
{
list_delete(&config->line);
- if (config->name)
- XFREE(MTYPE_VTYSH_CONFIG_LINE, config->name);
+ XFREE(MTYPE_VTYSH_CONFIG_LINE, config->name);
XFREE(MTYPE_VTYSH_CONFIG, config);
}
diff --git a/vtysh/vtysh_user.c b/vtysh/vtysh_user.c
index dcf8ca0470..aaf70ab08b 100644
--- a/vtysh/vtysh_user.c
+++ b/vtysh/vtysh_user.c
@@ -204,7 +204,7 @@ char *vtysh_get_home(void)
struct passwd *passwd;
char *homedir;
- if ((homedir = getenv("HOME")) != 0)
+ if ((homedir = getenv("HOME")) != NULL)
return homedir;
/* Fallback if HOME is undefined */
diff --git a/zebra/connected.c b/zebra/connected.c
index c449855f6d..128f397552 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -594,5 +594,5 @@ int connected_is_unnumbered(struct interface *ifp)
return CHECK_FLAG(connected->flags,
ZEBRA_IFA_UNNUMBERED);
}
- return 0;
+ return 1;
}
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 3583d63d31..b2f470bc8d 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1194,8 +1194,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ifp = if_lookup_by_name_per_ns(zns, name);
if (ifp) {
- if (ifp->desc)
- XFREE(MTYPE_TMP, ifp->desc);
+ XFREE(MTYPE_TMP, ifp->desc);
if (desc)
ifp->desc = XSTRDUP(MTYPE_TMP, desc);
}
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 18cf389d5e..c56e2f316d 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -927,7 +927,7 @@ static void _netlink_route_nl_add_gateway_info(uint8_t route_family,
uint8_t gw_family,
struct nlmsghdr *nlmsg,
size_t req_size, int bytelen,
- struct nexthop *nexthop)
+ const struct nexthop *nexthop)
{
if (route_family == AF_MPLS) {
struct gw_family_t gw_fam;
@@ -954,7 +954,7 @@ static void _netlink_route_rta_add_gateway_info(uint8_t route_family,
struct rtattr *rta,
struct rtnexthop *rtnh,
size_t req_size, int bytelen,
- struct nexthop *nexthop)
+ const struct nexthop *nexthop)
{
if (route_family == AF_MPLS) {
struct gw_family_t gw_fam;
@@ -990,7 +990,7 @@ static void _netlink_route_rta_add_gateway_info(uint8_t route_family,
* @param req_size: The size allocated for the message.
*/
static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
- struct nexthop *nexthop,
+ const struct nexthop *nexthop,
struct nlmsghdr *nlmsg,
struct rtmsg *rtmsg,
size_t req_size, int cmd)
@@ -1009,7 +1009,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
label_buf[0] = '\0';
assert(nexthop);
- for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
+ for (const struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
char label_buf1[20];
nh_label = nh->nh_label;
@@ -1175,11 +1175,11 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
* the prefsrc should be stored.
*/
static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
- struct nexthop *nexthop,
+ const struct nexthop *nexthop,
struct rtattr *rta,
struct rtnexthop *rtnh,
struct rtmsg *rtmsg,
- union g_addr **src)
+ const union g_addr **src)
{
struct mpls_label_stack *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS];
@@ -1200,7 +1200,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
label_buf[0] = '\0';
assert(nexthop);
- for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
+ for (const struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
char label_buf1[20];
nh_label = nh->nh_label;
@@ -1342,7 +1342,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
}
static inline void _netlink_mpls_build_singlepath(const char *routedesc,
- zebra_nhlfe_t *nhlfe,
+ const zebra_nhlfe_t *nhlfe,
struct nlmsghdr *nlmsg,
struct rtmsg *rtmsg,
size_t req_size, int cmd)
@@ -1358,9 +1358,9 @@ static inline void _netlink_mpls_build_singlepath(const char *routedesc,
static inline void
-_netlink_mpls_build_multipath(const char *routedesc, zebra_nhlfe_t *nhlfe,
+_netlink_mpls_build_multipath(const char *routedesc, const zebra_nhlfe_t *nhlfe,
struct rtattr *rta, struct rtnexthop *rtnh,
- struct rtmsg *rtmsg, union g_addr **src)
+ struct rtmsg *rtmsg, const union g_addr **src)
{
int bytelen;
uint8_t family;
@@ -1438,7 +1438,6 @@ static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla,
static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
{
int bytelen;
- struct sockaddr_nl snl;
struct nexthop *nexthop = NULL;
unsigned int nexthop_num;
int family;
@@ -1656,7 +1655,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
char buf[NL_PKT_BUF_SIZE];
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
- union g_addr *src1 = NULL;
+ const union g_addr *src1 = NULL;
rta->rta_type = RTA_MULTIPATH;
rta->rta_len = RTA_LENGTH(0);
@@ -1747,11 +1746,6 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
}
skip:
-
- /* Destination netlink address. */
- memset(&snl, 0, sizeof(snl));
- snl.nl_family = AF_NETLINK;
-
/* Talk to netlink socket. */
return netlink_talk_info(netlink_talk_filter, &req.n,
dplane_ctx_get_ns(ctx), 0);
@@ -1971,23 +1965,38 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
/* The interface should exist. */
ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
ndm->ndm_ifindex);
- if (!ifp || !ifp->info)
+ if (!ifp || !ifp->info) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("\t%s without associated interface: %u",
+ __PRETTY_FUNCTION__, ndm->ndm_ifindex);
return 0;
+ }
/* The interface should be something we're interested in. */
- if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
+ if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("\t%s Not interested in %s, not a slave",
+ __PRETTY_FUNCTION__, ifp->name);
return 0;
+ }
/* Drop "permanent" entries. */
- if (ndm->ndm_state & NUD_PERMANENT)
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("\t%s Entry is PERMANENT, dropping",
+ __PRETTY_FUNCTION__);
return 0;
+ }
zif = (struct zebra_if *)ifp->info;
if ((br_if = zif->brslave_info.br_if) == NULL) {
- zlog_debug("%s family %s IF %s(%u) brIF %u - no bridge master",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "%s family %s IF %s(%u) brIF %u - no bridge master",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex,
+ zif->brslave_info.bridge_ifindex);
return 0;
}
@@ -1996,20 +2005,24 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
if (!tb[NDA_LLADDR]) {
- zlog_debug("%s family %s IF %s(%u) brIF %u - no LLADDR",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex);
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s family %s IF %s(%u) brIF %u - no LLADDR",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex,
+ zif->brslave_info.bridge_ifindex);
return 0;
}
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
- zlog_debug(
- "%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex, zif->brslave_info.bridge_ifindex,
- (unsigned long)RTA_PAYLOAD(tb[NDA_LLADDR]));
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu",
+ nl_msg_type_to_str(h->nlmsg_type),
+ nl_family_to_str(ndm->ndm_family), ifp->name,
+ ndm->ndm_ifindex,
+ zif->brslave_info.bridge_ifindex,
+ (unsigned long)RTA_PAYLOAD(tb[NDA_LLADDR]));
return 0;
}
@@ -2042,8 +2055,12 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
prefix_mac2str(&mac, buf, sizeof(buf)),
dst_present ? dst_buf : "");
- if (filter_vlan && vid != filter_vlan)
+ if (filter_vlan && vid != filter_vlan) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("\tFiltered due to filter vlan: %d",
+ filter_vlan);
return 0;
+ }
/* If add or update, do accordingly if learnt on a "local" interface; if
* the notification is over VxLAN, this has to be related to
@@ -2051,10 +2068,6 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
* so perform an implicit delete of any local entry (if it exists).
*/
if (h->nlmsg_type == RTM_NEWNEIGH) {
- /* Drop "permanent" entries. */
- if (ndm->ndm_state & NUD_PERMANENT)
- return 0;
-
if (IS_ZEBRA_IF_VXLAN(ifp))
return zebra_vxlan_check_del_local_mac(ifp, br_if, &mac,
vid);
@@ -2071,8 +2084,11 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
* Ignore the notification from VxLan driver as it is also generated
* when mac moves from remote to local.
*/
- if (dst_present)
+ if (dst_present) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("\tNo Destination Present");
return 0;
+ }
if (IS_ZEBRA_IF_VXLAN(ifp))
return zebra_vxlan_check_readd_remote_mac(ifp, br_if, &mac,
@@ -2385,6 +2401,9 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
/* if kernel deletes our rfc5549 neighbor entry, re-install it */
if (h->nlmsg_type == RTM_DELNEIGH && (ndm->ndm_state & NUD_PERMANENT)) {
netlink_handle_5549(ndm, zif, ifp, &ip);
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "\tNeighbor Entry Received is a 5549 entry, finished");
return 0;
}
@@ -2410,20 +2429,27 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
return 0;
} else if (IS_ZEBRA_IF_BRIDGE(ifp))
link_if = ifp;
- else
+ else {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "\tNeighbor Entry received is not on a VLAN or a BRIDGE, ignoring");
return 0;
+ }
memset(&mac, 0, sizeof(struct ethaddr));
if (h->nlmsg_type == RTM_NEWNEIGH) {
if (tb[NDA_LLADDR]) {
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
- zlog_debug(
- "%s family %s IF %s(%u) - LLADDR is not MAC, len %lu",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family),
- ifp->name, ndm->ndm_ifindex,
- (unsigned long)RTA_PAYLOAD(
- tb[NDA_LLADDR]));
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "%s family %s IF %s(%u) - LLADDR is not MAC, len %lu",
+ nl_msg_type_to_str(
+ h->nlmsg_type),
+ nl_family_to_str(
+ ndm->ndm_family),
+ ifp->name, ndm->ndm_ifindex,
+ (unsigned long)RTA_PAYLOAD(
+ tb[NDA_LLADDR]));
return 0;
}
@@ -2750,7 +2776,7 @@ int kernel_upd_neigh(struct interface *ifp, struct ipaddr *ip,
int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
{
mpls_lse_t lse;
- zebra_nhlfe_t *nhlfe;
+ const zebra_nhlfe_t *nhlfe;
struct nexthop *nexthop = NULL;
unsigned int nexthop_num;
const char *routedesc;
@@ -2853,7 +2879,7 @@ int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
char buf[NL_PKT_BUF_SIZE];
struct rtattr *rta = (void *)buf;
struct rtnexthop *rtnh;
- union g_addr *src1 = NULL;
+ const union g_addr *src1 = NULL;
rta->rta_type = RTA_MULTIPATH;
rta->rta_len = RTA_LENGTH(0);
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 928169a862..df26a8534c 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -111,10 +111,13 @@ struct dplane_pw_info {
int af;
int status;
uint32_t flags;
- union g_addr nexthop;
+ union g_addr dest;
mpls_label_t local_label;
mpls_label_t remote_label;
+ /* Nexthops */
+ struct nexthop_group nhg;
+
union pw_protocol_fields fields;
};
@@ -386,6 +389,15 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
case DPLANE_OP_PW_INSTALL:
case DPLANE_OP_PW_UNINSTALL:
+ /* Free allocated nexthops */
+ if ((*pctx)->u.pw.nhg.nexthop) {
+ /* This deals with recursive nexthops too */
+ nexthops_free((*pctx)->u.pw.nhg.nexthop);
+
+ (*pctx)->u.pw.nhg.nexthop = NULL;
+ }
+ break;
+
case DPLANE_OP_NONE:
break;
}
@@ -520,7 +532,7 @@ const char *dplane_op2str(enum dplane_op_e op)
ret = "PW_UNINSTALL";
break;
- };
+ }
return ret;
}
@@ -539,7 +551,7 @@ const char *dplane_res2str(enum zebra_dplane_result res)
case ZEBRA_DPLANE_REQUEST_SUCCESS:
ret = "SUCCESS";
break;
- };
+ }
return ret;
}
@@ -744,14 +756,15 @@ uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx)
return ctx->u.lsp.flags;
}
-zebra_nhlfe_t *dplane_ctx_get_nhlfe(struct zebra_dplane_ctx *ctx)
+const zebra_nhlfe_t *dplane_ctx_get_nhlfe(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
return ctx->u.lsp.nhlfe_list;
}
-zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(struct zebra_dplane_ctx *ctx)
+const zebra_nhlfe_t *
+dplane_ctx_get_best_nhlfe(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
@@ -814,12 +827,12 @@ int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx)
return ctx->u.pw.status;
}
-const union g_addr *dplane_ctx_get_pw_nexthop(
+const union g_addr *dplane_ctx_get_pw_dest(
const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return &(ctx->u.pw.nexthop);
+ return &(ctx->u.pw.dest);
}
const union pw_protocol_fields *dplane_ctx_get_pw_proto(
@@ -830,6 +843,14 @@ const union pw_protocol_fields *dplane_ctx_get_pw_proto(
return &(ctx->u.pw.fields);
}
+const struct nexthop_group *
+dplane_ctx_get_pw_nhg(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return &(ctx->u.pw.nhg);
+}
+
/*
* End of dplane context accessors
*/
@@ -1039,7 +1060,11 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
enum dplane_op_e op,
struct zebra_pw *pw)
{
- int ret = AOK;
+ struct prefix p;
+ afi_t afi;
+ struct route_table *table;
+ struct route_node *rn;
+ struct route_entry *re;
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug("init dplane ctx %s: pw '%s', loc %u, rem %u",
@@ -1058,6 +1083,7 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
/* This name appears to be c-string, so we use string copy. */
strlcpy(ctx->u.pw.ifname, pw->ifname, sizeof(ctx->u.pw.ifname));
+
ctx->zd_vrf_id = pw->vrf_id;
ctx->u.pw.ifindex = pw->ifindex;
ctx->u.pw.type = pw->type;
@@ -1066,11 +1092,38 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
ctx->u.pw.remote_label = pw->remote_label;
ctx->u.pw.flags = pw->flags;
- ctx->u.pw.nexthop = pw->nexthop;
+ ctx->u.pw.dest = pw->nexthop;
ctx->u.pw.fields = pw->data;
- return ret;
+ /* Capture nexthop info for the pw destination. We need to look
+ * up and use zebra datastructs, but we're running in the zebra
+ * pthread here so that should be ok.
+ */
+ memcpy(&p.u, &pw->nexthop, sizeof(pw->nexthop));
+ p.family = pw->af;
+ p.prefixlen = ((pw->af == AF_INET) ?
+ IPV4_MAX_PREFIXLEN : IPV6_MAX_PREFIXLEN);
+
+ afi = (pw->af == AF_INET) ? AFI_IP : AFI_IP6;
+ table = zebra_vrf_table(afi, SAFI_UNICAST, pw->vrf_id);
+ if (table) {
+ rn = route_node_match(table, &p);
+ if (rn) {
+ RNODE_FOREACH_RE(rn, re) {
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
+
+ if (re)
+ copy_nexthops(&(ctx->u.pw.nhg.nexthop),
+ re->ng.nexthop, NULL);
+
+ route_unlock_node(rn);
+ }
+ }
+
+ return AOK;
}
/*
@@ -1476,10 +1529,6 @@ int dplane_provider_register(const char *name,
/* Allocate and init new provider struct */
p = XCALLOC(MTYPE_DP_PROV, sizeof(struct zebra_dplane_provider));
- if (p == NULL) {
- ret = ENOMEM;
- goto done;
- }
pthread_mutex_init(&(p->dp_mutex), NULL);
TAILQ_INIT(&(p->dp_ctx_in_q));
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 81226961e8..149ff8dc60 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -203,8 +203,9 @@ const struct nexthop_group *dplane_ctx_get_old_ng(
mpls_label_t dplane_ctx_get_in_label(const struct zebra_dplane_ctx *ctx);
uint8_t dplane_ctx_get_addr_family(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_get_lsp_flags(const struct zebra_dplane_ctx *ctx);
-zebra_nhlfe_t *dplane_ctx_get_nhlfe(struct zebra_dplane_ctx *ctx);
-zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(struct zebra_dplane_ctx *ctx);
+const zebra_nhlfe_t *dplane_ctx_get_nhlfe(const struct zebra_dplane_ctx *ctx);
+const zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(
+ const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_get_lsp_num_ecmp(const struct zebra_dplane_ctx *ctx);
/* Accessors for pseudowire information */
@@ -215,10 +216,12 @@ int dplane_ctx_get_pw_type(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_get_pw_af(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_get_pw_flags(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_get_pw_status(const struct zebra_dplane_ctx *ctx);
-const union g_addr *dplane_ctx_get_pw_nexthop(
+const union g_addr *dplane_ctx_get_pw_dest(
const struct zebra_dplane_ctx *ctx);
const union pw_protocol_fields *dplane_ctx_get_pw_proto(
const struct zebra_dplane_ctx *ctx);
+const struct nexthop_group *dplane_ctx_get_pw_nhg(
+ const struct zebra_dplane_ctx *ctx);
/* Namespace info - esp. for netlink communication */
const struct zebra_dplane_info *dplane_ctx_get_ns(
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index a06e15d90d..5c375a6bef 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -249,8 +249,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
lsp->ile.in_label, lsp->flags);
lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
+ XFREE(MTYPE_LSP, lsp);
}
return 0;
@@ -313,8 +312,7 @@ static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label)
lsp->ile.in_label, lsp->flags);
lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
+ XFREE(MTYPE_LSP, lsp);
}
return 0;
@@ -1048,8 +1046,7 @@ static void lsp_processq_del(struct work_queue *wq, void *data)
lsp->ile.in_label, lsp->flags);
lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
+ XFREE(MTYPE_LSP, lsp);
}
}
@@ -1335,8 +1332,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
lsp->ile.in_label, lsp->flags);
lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
+ XFREE(MTYPE_LSP, lsp);
}
return 0;
@@ -1659,8 +1655,7 @@ static int snhlfe_del(zebra_snhlfe_t *snhlfe)
slsp->snhlfe_list = snhlfe->next;
snhlfe->prev = snhlfe->next = NULL;
- if (snhlfe->ifname)
- XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
+ XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
XFREE(MTYPE_SNHLFE, snhlfe);
return 0;
@@ -2539,8 +2534,7 @@ int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
lsp->ile.in_label, lsp->flags);
lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
+ XFREE(MTYPE_LSP, lsp);
}
}
return 0;
@@ -2784,8 +2778,7 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
* above. */
if (!slsp->snhlfe_list) {
slsp = hash_release(slsp_table, &tmp_ile);
- if (slsp)
- XFREE(MTYPE_SLSP, slsp);
+ XFREE(MTYPE_SLSP, slsp);
}
return 0;
diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c
index 72c8f73522..977a8eaf3c 100644
--- a/zebra/zebra_mpls_openbsd.c
+++ b/zebra/zebra_mpls_openbsd.c
@@ -43,7 +43,7 @@ struct {
} kr_state;
static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
- zebra_nhlfe_t *nhlfe)
+ const zebra_nhlfe_t *nhlfe)
{
struct iovec iov[5];
struct rt_msghdr hdr;
@@ -135,7 +135,7 @@ static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
#endif
static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
- zebra_nhlfe_t *nhlfe)
+ const zebra_nhlfe_t *nhlfe)
{
struct iovec iov[5];
struct rt_msghdr hdr;
@@ -238,7 +238,7 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
{
- zebra_nhlfe_t *nhlfe;
+ const zebra_nhlfe_t *nhlfe;
struct nexthop *nexthop = NULL;
unsigned int nexthop_num = 0;
int action;
@@ -342,7 +342,7 @@ static enum zebra_dplane_result kmpw_install(struct zebra_dplane_ctx *ctx)
/* pseudowire nexthop */
memset(&ss, 0, sizeof(ss));
- gaddr = dplane_ctx_get_pw_nexthop(ctx);
+ gaddr = dplane_ctx_get_pw_dest(ctx);
switch (dplane_ctx_get_pw_af(ctx)) {
case AF_INET:
sa_in->sin_family = AF_INET;
@@ -415,7 +415,7 @@ enum zebra_dplane_result kernel_pw_update(struct zebra_dplane_ctx *ctx)
break;
default:
break;
- };
+ }
return result;
}
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 348bdeb9fc..73db567eac 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -388,7 +388,7 @@ bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
r2 = (const struct zebra_pbr_iptable *)arg2;
if (r1->vrf_id != r2->vrf_id)
- return 0;
+ return false;
if (r1->type != r2->type)
return false;
if (r1->unique != r2->unique)
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 1e942d6433..cc5e38e690 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -1215,8 +1215,6 @@ static struct ptm_process *pp_new(pid_t pid, struct zserv *zs)
/* Allocate and register new process. */
pp = XCALLOC(MTYPE_ZEBRA_PTM_BFD_PROCESS, sizeof(*pp));
- if (pp == NULL)
- return NULL;
pp->pp_pid = pid;
pp->pp_zs = zs;
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index de1aa7d6d8..2014aa3bed 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3235,7 +3235,6 @@ void rib_close_table(struct route_table *table)
*/
static int handle_pw_result(struct zebra_dplane_ctx *ctx)
{
- int ret = 0;
struct zebra_pw *pw;
struct zebra_vrf *vrf;
@@ -3254,7 +3253,7 @@ static int handle_pw_result(struct zebra_dplane_ctx *ctx)
done:
- return ret;
+ return 0;
}
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 7d72583dd8..5d1cbbe781 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -127,10 +127,8 @@ static int zebra_route_match_delete(struct vty *vty, const char *command,
break;
}
- if (dep_name)
- XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
- if (rmap_name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
return retval;
}
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index c3b861c242..cabc8be8dd 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -168,10 +168,31 @@ static void zebra_router_free_table(struct zebra_router_table *zrt)
table_info = route_table_get_info(zrt->table);
route_table_finish(zrt->table);
+ RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
+
XFREE(MTYPE_RIB_TABLE_INFO, table_info);
XFREE(MTYPE_ZEBRA_NS, zrt);
}
+void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
+ afi_t afi, safi_t safi)
+{
+ struct zebra_router_table finder;
+ struct zebra_router_table *zrt;
+
+ memset(&finder, 0, sizeof(finder));
+ finder.afi = afi;
+ finder.safi = safi;
+ finder.tableid = tableid;
+ finder.ns_id = zvrf->zns->ns_id;
+ zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
+
+ if (!zrt)
+ return;
+
+ zebra_router_free_table(zrt);
+}
+
uint32_t zebra_router_get_next_sequence(void)
{
return 1
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index fb28495917..e5043f38ae 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -117,6 +117,8 @@ extern struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
uint32_t tableid, afi_t afi,
safi_t safi);
+extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
+ afi_t afi, safi_t safi);
extern int zebra_router_config_write(struct vty *vty);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index d18305495b..1300ca24f3 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -208,8 +208,11 @@ static int zebra_vrf_disable(struct vrf *vrf)
* table, see rib_close_table above
* we no-longer need this pointer.
*/
- for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
+ for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
+ zebra_router_release_table(zvrf, zvrf->table_id, afi,
+ safi);
zvrf->table[afi][safi] = NULL;
+ }
route_table_finish(zvrf->rnh_table[afi]);
zvrf->rnh_table[afi] = NULL;
@@ -256,14 +259,12 @@ static int zebra_vrf_delete(struct vrf *vrf)
/* release allocated memory */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
- void *table_info;
-
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
table = zvrf->table[afi][safi];
if (table) {
- table_info = route_table_get_info(table);
- route_table_finish(table);
- XFREE(MTYPE_RIB_TABLE_INFO, table_info);
+ zebra_router_release_table(zvrf, zvrf->table_id,
+ afi, safi);
+ zvrf->table[afi][safi] = NULL;
}
}
@@ -351,8 +352,7 @@ void zebra_rtable_node_cleanup(struct route_table *table,
rib_unlink(node, re);
}
- if (node->info)
- XFREE(MTYPE_RIB_DEST, node->info);
+ XFREE(MTYPE_RIB_DEST, node->info);
}
static void zebra_rnhtable_node_cleanup(struct route_table *table,
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 537820f7ea..b0884f22cf 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -383,6 +383,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object *json_labels = NULL;
time_t uptime;
struct tm *tm;
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
uptime = time(NULL);
uptime -= re->uptime;
@@ -407,6 +408,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
json_object_boolean_true_add(json_route, "selected");
+ if (dest->selected_fib == re)
+ json_object_boolean_true_add(json_route,
+ "destSelected");
+
json_object_int_add(json_route, "distance",
re->distance);
json_object_int_add(json_route, "metric", re->metric);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 4cd70381c7..00fc230851 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -2213,8 +2213,7 @@ static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
/* Free the VNI hash entry and allocated memory. */
tmp_n = hash_release(zvni->neigh_table, n);
- if (tmp_n)
- XFREE(MTYPE_NEIGH, tmp_n);
+ XFREE(MTYPE_NEIGH, tmp_n);
return 0;
}
@@ -2987,8 +2986,12 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
}
zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
+ if (!zvrf) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("\tUnable to find vrf for: %d",
+ zvni->vxlan_if->vrf_id);
return -1;
+ }
/* Check if the neighbor exists. */
n = zvni_neigh_lookup(zvni, ip);
@@ -3018,6 +3021,9 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
cur_is_router = !!CHECK_FLAG(n->flags,
ZEBRA_NEIGH_ROUTER_FLAG);
if (!mac_different && is_router == cur_is_router) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "\tIgnoring entry mac is the same and is_router == cur_is_router");
n->ifindex = ifp->ifindex;
return 0;
}
@@ -3046,6 +3052,11 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
return zvni_neigh_send_add_to_client(
zvni->vni, ip, macaddr,
n->flags, n->loc_seq);
+ else {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "\tNeighbor active and frozen");
+ }
return 0;
}
@@ -3186,6 +3197,10 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
if (!neigh_on_hold)
return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
n->flags, n->loc_seq);
+ else {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("\tNeighbor on hold not sending");
+ }
return 0;
}
@@ -3309,8 +3324,7 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
/* Free the VNI hash entry and allocated memory. */
tmp_mac = hash_release(zvni->mac_table, mac);
- if (tmp_mac)
- XFREE(MTYPE_MAC, tmp_mac);
+ XFREE(MTYPE_MAC, tmp_mac);
return 0;
}
@@ -3862,8 +3876,7 @@ static int zvni_del(zebra_vni_t *zvni)
/* Free the VNI hash entry and allocated memory. */
tmp_zvni = hash_release(zvrf->vni_table, zvni);
- if (tmp_zvni)
- XFREE(MTYPE_ZVNI, tmp_zvni);
+ XFREE(MTYPE_ZVNI, tmp_zvni);
return 0;
}
@@ -4299,8 +4312,7 @@ static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
}
tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
- if (tmp_rmac)
- XFREE(MTYPE_MAC, tmp_rmac);
+ XFREE(MTYPE_MAC, tmp_rmac);
return 0;
}
@@ -4476,8 +4488,7 @@ static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n)
}
tmp_n = hash_release(zl3vni->nh_table, n);
- if (tmp_n)
- XFREE(MTYPE_NEIGH, tmp_n);
+ XFREE(MTYPE_NEIGH, tmp_n);
return 0;
}
@@ -4709,8 +4720,7 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni)
/* Free the VNI hash entry and allocated memory. */
tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni);
- if (tmp_zl3vni)
- XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
+ XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
return 0;
}
@@ -7585,7 +7595,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
if (!zvni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
+ "\tAdd/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
sticky ? "sticky " : "",
prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, vid);
@@ -7593,15 +7603,20 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
}
if (!zvni->vxlan_if) {
- zlog_debug(
- "VNI %u hash %p doesn't have intf upon local MAC ADD",
- zvni->vni, zvni);
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "\tVNI %u hash %p doesn't have intf upon local MAC ADD",
+ zvni->vni, zvni);
return -1;
}
zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
+ if (!zvrf) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("\tNo Vrf found for vrf_id: %d",
+ zvni->vxlan_if->vrf_id);
return -1;
+ }
/* Check if we need to create or update or it is a NO-OP. */
mac = zvni_mac_lookup(zvni, macaddr);
@@ -7651,7 +7666,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
&& mac->fwd_info.local.vid == vid) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
+ "\tAdd/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
"entry exists and has not changed ",
sticky ? "sticky " : "",
prefix_mac2str(macaddr, buf,
@@ -9163,16 +9178,16 @@ static int zebra_vxlan_dad_ip_auto_recovery_exp(struct thread *t)
nbr = THREAD_ARG(t);
/* since this is asynchronous we need sanity checks*/
- nbr = zvni_neigh_lookup(zvni, &nbr->ip);
- if (!nbr)
+ zvrf = vrf_info_lookup(nbr->zvni->vrf_id);
+ if (!zvrf)
return 0;
zvni = zvni_lookup(nbr->zvni->vni);
if (!zvni)
return 0;
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
+ nbr = zvni_neigh_lookup(zvni, &nbr->ip);
+ if (!nbr)
return 0;
if (IS_ZEBRA_DEBUG_VXLAN)
@@ -9213,16 +9228,16 @@ static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t)
mac = THREAD_ARG(t);
/* since this is asynchronous we need sanity checks*/
- mac = zvni_mac_lookup(zvni, &mac->macaddr);
- if (!mac)
+ zvrf = vrf_info_lookup(mac->zvni->vrf_id);
+ if (!zvrf)
return 0;
zvni = zvni_lookup(mac->zvni->vni);
if (!zvni)
return 0;
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
+ mac = zvni_mac_lookup(zvni, &mac->macaddr);
+ if (!mac)
return 0;
if (IS_ZEBRA_DEBUG_VXLAN)