summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alpine/APKBUILD.in1
-rw-r--r--bfdd/dplane.c2
-rw-r--r--bgpd/bgp_aspath.c3
-rw-r--r--bgpd/bgp_attr.c32
-rw-r--r--bgpd/bgp_evpn_mh.c8
-rw-r--r--bgpd/bgp_fsm.c1
-rw-r--r--bgpd/bgp_mpath.c3
-rw-r--r--bgpd/bgp_nht.c15
-rw-r--r--bgpd/bgp_route.c16
-rw-r--r--bgpd/bgp_routemap_nb_config.c4
-rw-r--r--bgpd/bgp_updgrp.c5
-rw-r--r--bgpd/bgp_updgrp_adv.c3
-rw-r--r--bgpd/bgp_vty.c11
-rw-r--r--bgpd/bgpd.c14
-rw-r--r--configure.ac15
-rw-r--r--debian/README.Debian8
-rw-r--r--debian/control1
-rwxr-xr-xdebian/rules13
-rw-r--r--doc/developer/building-frr-for-archlinux.rst4
-rw-r--r--doc/developer/building-frr-for-centos7.rst3
-rw-r--r--doc/developer/building-frr-for-centos8.rst3
-rw-r--r--doc/developer/building-frr-for-debian8.rst2
-rw-r--r--doc/developer/building-frr-for-debian9.rst2
-rw-r--r--doc/developer/building-frr-for-fedora.rst2
-rw-r--r--doc/developer/building-frr-for-opensuse.rst2
-rw-r--r--doc/developer/building-frr-for-ubuntu1604.rst4
-rw-r--r--doc/developer/building-frr-for-ubuntu1804.rst4
-rw-r--r--doc/developer/building-frr-for-ubuntu2004.rst4
-rw-r--r--doc/developer/include-compile.rst5
-rw-r--r--doc/developer/packaging-debian.rst10
-rw-r--r--doc/developer/packaging-redhat.rst4
-rw-r--r--doc/user/installation.rst11
-rw-r--r--doc/user/ospf6d.rst55
-rw-r--r--docker/centos-7/Dockerfile2
-rw-r--r--docker/centos-8/Dockerfile2
-rw-r--r--docker/ubuntu18-ci/Dockerfile4
-rw-r--r--docker/ubuntu20-ci/Dockerfile4
-rw-r--r--lib/buffer.c24
-rw-r--r--lib/csv.c3
-rw-r--r--lib/libfrr.c6
-rw-r--r--lib/link_state.c12
-rw-r--r--lib/network.c3
-rw-r--r--lib/ntop.c14
-rw-r--r--lib/prefix.c3
-rw-r--r--lib/prefix.h32
-rw-r--r--lib/sockopt.c16
-rw-r--r--lib/stream.c8
-rw-r--r--lib/systemd.c173
-rw-r--r--lib/systemd.h10
-rw-r--r--lib/zclient.c6
-rw-r--r--ospf6d/ospf6_asbr.c57
-rw-r--r--ospf6d/ospf6_flood.c29
-rw-r--r--ospf6d/ospf6_interface.c2
-rw-r--r--ospf6d/ospf6_message.c58
-rw-r--r--ospf6d/ospf6_spf.c28
-rw-r--r--ospf6d/ospf6_zebra.c12
-rw-r--r--ospfd/ospf_asbr.c4
-rw-r--r--ospfd/ospf_flood.c12
-rw-r--r--ospfd/ospf_lsa.c20
-rw-r--r--ospfd/ospf_lsa.h1
-rw-r--r--ospfd/ospf_vty.c8
-rw-r--r--ospfd/ospf_zebra.c14
-rw-r--r--pathd/path_pcep_config.c2
-rw-r--r--pathd/path_pcep_pcc.c53
-rw-r--r--redhat/frr.spec.in5
-rw-r--r--staticd/static_routes.c7
-rw-r--r--tests/bgpd/test_aspath.c58
-rw-r--r--tests/topotests/bgp_aspath_zero/__init__.py0
-rw-r--r--tests/topotests/bgp_aspath_zero/exabgp.env53
-rw-r--r--tests/topotests/bgp_aspath_zero/peer1/exabgp.cfg17
-rw-r--r--tests/topotests/bgp_aspath_zero/r1/bgpd.conf6
-rw-r--r--tests/topotests/bgp_aspath_zero/r1/zebra.conf6
-rw-r--r--tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py121
-rw-r--r--tests/topotests/lib/common_config.py30
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py7
-rw-r--r--tools/coccinelle/xcalloc-xmalloc.cocci17
-rwxr-xr-xtools/generate_support_bundle.py186
-rw-r--r--vtysh/vtysh.c10
-rw-r--r--vtysh/vtysh.h2
-rw-r--r--vtysh/vtysh_config.c6
-rw-r--r--vtysh/vtysh_main.c11
-rw-r--r--watchfrr/watchfrr.c10
-rw-r--r--zebra/zebra_vty.c14
83 files changed, 936 insertions, 522 deletions
diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in
index dfedf0b52b..e6776cb3a2 100644
--- a/alpine/APKBUILD.in
+++ b/alpine/APKBUILD.in
@@ -41,7 +41,6 @@ build() {
--sysconfdir=$_sysconfdir \
--libdir=$_libdir \
--localstatedir=$_localstatedir \
- --enable-systemd=no \
--enable-rpki \
--enable-vtysh \
--enable-multipath=64 \
diff --git a/bfdd/dplane.c b/bfdd/dplane.c
index 6fb301d46a..4b7f9ba7ac 100644
--- a/bfdd/dplane.c
+++ b/bfdd/dplane.c
@@ -651,8 +651,6 @@ static struct bfd_dplane_ctx *bfd_dplane_ctx_new(int sock)
struct bfd_dplane_ctx *bdc;
bdc = XCALLOC(MTYPE_BFDD_DPLANE_CTX, sizeof(*bdc));
- if (bdc == NULL)
- return NULL;
bdc->sock = sock;
bdc->inbuf = stream_new(BFD_DPLANE_CLIENT_BUF_SIZE);
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 25109e030b..3c67017dc7 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -193,7 +193,8 @@ static struct assegment *assegment_prepend_asns(struct assegment *seg,
if (num >= AS_SEGMENT_MAX)
return seg; /* we don't do huge prepends */
- if ((newas = assegment_data_new(seg->length + num)) == NULL)
+ newas = assegment_data_new(seg->length + num);
+ if (newas == NULL)
return seg;
for (i = 0; i < num; i++)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 2f0751a5f0..24b48178d2 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1509,16 +1509,6 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
0);
}
- /* Codification of AS 0 Processing */
- if (aspath_check_as_zero(attr->aspath)) {
- flog_err(
- EC_BGP_ATTR_MAL_AS_PATH,
- "Malformed AS path, AS number is 0 in the path from %s",
- peer->host);
- return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
- 0);
- }
-
/* Set aspath attribute flag. */
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
@@ -1558,6 +1548,15 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer,
}
}
+ /* Codification of AS 0 Processing */
+ if (peer->sort == BGP_PEER_EBGP && aspath_check_as_zero(attr->aspath)) {
+ flog_err(
+ EC_BGP_ATTR_MAL_AS_PATH,
+ "Malformed AS path, AS number is 0 in the path from %s",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
+
/* local-as prepend */
if (peer->change_local_as
&& !CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) {
@@ -1590,16 +1589,6 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
0);
}
- /* Codification of AS 0 Processing */
- if (aspath_check_as_zero(*as4_path)) {
- flog_err(
- EC_BGP_ATTR_MAL_AS_PATH,
- "Malformed AS path, AS number is 0 in the path from %s",
- peer->host);
- return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
- 0);
- }
-
/* Set aspath attribute flag. */
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH);
@@ -3317,7 +3306,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
}
/* Check all mandatory well-known attributes are present */
- if ((ret = bgp_attr_check(peer, attr)) < 0)
+ ret = bgp_attr_check(peer, attr);
+ if (ret < 0)
goto done;
/*
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c
index 4b90937f62..34094a0bde 100644
--- a/bgpd/bgp_evpn_mh.c
+++ b/bgpd/bgp_evpn_mh.c
@@ -1311,7 +1311,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
bool old_active;
bool new_active;
- old_active = !!CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
+ old_active = CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
/* currently we need an active EVI reference to use the VTEP as
* a nexthop. this may change...
*/
@@ -1320,7 +1320,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
else
UNSET_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
- new_active = !!CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
+ new_active = CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
if ((old_active != new_active) || (new_active && param_change)) {
@@ -3119,7 +3119,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
bool new_active;
uint32_t ead_activity_flags;
- old_active = !!CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
+ old_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
if (bgp_mh_info->ead_evi_rx)
/* Both EAD-per-ES and EAD-per-EVI routes must be rxed from a PE
@@ -3135,7 +3135,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
else
UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
- new_active = !!CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
+ new_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
if (old_active == new_active)
return;
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 4cc096d8e7..79dc0aec9d 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -256,6 +256,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
from_peer->last_major_event = last_maj_evt;
peer->remote_id = from_peer->remote_id;
peer->last_reset = from_peer->last_reset;
+ peer->max_packet_size = from_peer->max_packet_size;
peer->peer_gr_present_state = from_peer->peer_gr_present_state;
peer->peer_gr_new_status_flag = from_peer->peer_gr_new_status_flag;
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index d5fce115de..8127428bc7 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -411,7 +411,8 @@ static void bgp_path_info_mpath_lb_update(struct bgp_path_info *path, bool set,
{
struct bgp_path_info_mpath *mpath;
- if ((mpath = path->mpath) == NULL) {
+ mpath = path->mpath;
+ if (mpath == NULL) {
if (!set || (cum_bw == 0 && !all_paths_lb))
return;
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 742ef217d9..eb00a4641c 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -793,7 +793,18 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
|| IN6_IS_ADDR_LINKLOCAL(
&pi->attr->mp_nexthop_global)))
p->u.prefix6 = pi->attr->mp_nexthop_local;
- else
+ /* If we receive MR_REACH with (GA)::(LL)
+ * then check for route-map to choose GA or LL
+ */
+ else if (pi->attr->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ if (pi->attr->mp_nexthop_prefer_global)
+ p->u.prefix6 =
+ pi->attr->mp_nexthop_global;
+ else
+ p->u.prefix6 =
+ pi->attr->mp_nexthop_local;
+ } else
p->u.prefix6 = pi->attr->mp_nexthop_global;
p->prefixlen = IPV6_MAX_BITLEN;
}
@@ -1042,7 +1053,7 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
|| path->attr->srte_color != 0)
SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED);
- path_valid = !!CHECK_FLAG(path->flags, BGP_PATH_VALID);
+ path_valid = CHECK_FLAG(path->flags, BGP_PATH_VALID);
if (path_valid != bnc_is_valid_nexthop) {
if (path_valid) {
/* No longer valid, clear flag; also for EVPN
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4637cef3eb..bd45314350 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6052,6 +6052,7 @@ int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
&& (label_index != bgp_static->label_index)) {
snprintf(errmsg, errmsg_len,
"label-index doesn't match static route\n");
+ bgp_dest_unlock_node(dest);
return -1;
}
@@ -6059,6 +6060,7 @@ int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
&& strcmp(rmap, bgp_static->rmap.name)) {
snprintf(errmsg, errmsg_len,
"route-map name doesn't match static route\n");
+ bgp_dest_unlock_node(dest);
return -1;
}
@@ -11643,7 +11645,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
if (!table)
continue;
- if ((rm = bgp_node_match(table, &match)) == NULL)
+ rm = bgp_node_match(table, &match);
+ if (rm == NULL)
continue;
const struct prefix *rm_p = bgp_dest_get_prefix(rm);
@@ -11735,7 +11738,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
json_object_free(json_paths);
}
} else {
- if ((dest = bgp_node_match(rib, &match)) != NULL) {
+ dest = bgp_node_match(rib, &match);
+ if (dest != NULL) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
if (!prefix_check
|| dest_p->prefixlen == match.prefixlen) {
@@ -14377,6 +14381,7 @@ int bgp_distance_unset(uint8_t distance, const char *ip_str,
if (bdistance->distance != distance) {
snprintf(errmsg, errmsg_len,
"Distance does not match configured\n");
+ bgp_dest_unlock_node(dest);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -14758,7 +14763,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
table = bgp_dest_get_bgp_table_info(dest);
if (!table)
continue;
- if ((rm = bgp_node_match(table, &match)) == NULL)
+ rm = bgp_node_match(table, &match);
+ if (rm == NULL)
continue;
const struct prefix *rm_p = bgp_dest_get_prefix(dest);
@@ -14782,8 +14788,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
bgp_dest_unlock_node(rm);
}
} else {
- if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
- != NULL) {
+ dest = bgp_node_match(bgp->rib[afi][safi], &match);
+ if (dest != NULL) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
if (!prefix_check
diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c
index e541d117be..88e3f6438f 100644
--- a/bgpd/bgp_routemap_nb_config.c
+++ b/bgpd/bgp_routemap_nb_config.c
@@ -70,8 +70,8 @@ static int bgp_route_match_delete(struct route_map_index *index,
if (type != RMAP_EVENT_MATCH_DELETED) {
/* ignore the mundane, the types without any dependency */
if (arg == NULL) {
- if ((tmpstr = route_map_get_match_arg(index, command))
- != NULL)
+ tmpstr = route_map_get_match_arg(index, command);
+ if (tmpstr != NULL)
dep_name =
XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
} else {
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index b8545188a4..dd3309dad9 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -339,6 +339,7 @@ static unsigned int updgrp_hash_key_make(const void *p)
key);
key = jhash_1word(peer->v_routeadv, key);
key = jhash_1word(peer->change_local_as, key);
+ key = jhash_1word(peer->max_packet_size, key);
if (peer->group)
key = jhash_1word(jhash(peer->group->name,
@@ -572,6 +573,7 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
struct update_subgroup *subgrp;
struct peer_af *paf;
struct bgp_filter *filter;
+ struct peer *peer = UPDGRP_PEER(updgrp);
int match = 0;
if (!ctx)
@@ -663,6 +665,9 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH)
? "R"
: "");
+ if (peer)
+ vty_out(vty, " Max packet size: %d\n",
+ peer->max_packet_size);
if (subgrp->peer_count > 0) {
vty_out(vty, " Peers:\n");
SUBGRP_FOREACH_PEER (subgrp, paf)
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index 18829aa747..9c2288cba3 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -572,7 +572,8 @@ void bgp_adj_out_unset_subgroup(struct bgp_dest *dest,
return;
/* Lookup existing adjacency */
- if ((adj = adj_lookup(dest, subgrp, addpath_tx_id)) != NULL) {
+ adj = adj_lookup(dest, subgrp, addpath_tx_id);
+ if (adj != NULL) {
/* Clean up previous advertisement. */
if (adj->adv)
bgp_advertise_clean_subgroup(subgrp, adj);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index e713894eb1..9d7e88bb1c 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1857,9 +1857,8 @@ void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode,
uint32_t med_admin_val;
vty_out(vty, " bgp max-med administrative");
- if ((med_admin_val =
- yang_dnode_get_uint32(dnode, "./max-med-admin"))
- != BGP_MAXMED_VALUE_DEFAULT)
+ med_admin_val = yang_dnode_get_uint32(dnode, "./max-med-admin");
+ if (med_admin_val != BGP_MAXMED_VALUE_DEFAULT)
vty_out(vty, " %u", med_admin_val);
vty_out(vty, "\n");
}
@@ -10196,7 +10195,8 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
if (table == NULL)
continue;
- if ((rm = bgp_node_match(table, &match)) != NULL) {
+ rm = bgp_node_match(table, &match);
+ if (rm != NULL) {
const struct prefix *rm_p =
bgp_dest_get_prefix(rm);
@@ -10209,7 +10209,8 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
}
}
} else {
- if ((dest = bgp_node_match(rib, &match)) != NULL) {
+ dest = bgp_node_match(rib, &match);
+ if (dest != NULL) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
if (dest_p->prefixlen == match.prefixlen) {
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 197133cbb4..01ea300557 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1369,7 +1369,7 @@ struct peer *peer_new(struct bgp *bgp)
peer->bgp = bgp_lock(bgp);
peer = peer_lock(peer); /* initial reference */
peer->password = NULL;
- peer->max_packet_size = BGP_MAX_PACKET_SIZE;
+ peer->max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
/* Set default flags. */
FOREACH_AFI_SAFI (afi, safi) {
@@ -1466,6 +1466,8 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
(void)peer_sort(peer_dst);
peer_dst->rmap_type = peer_src->rmap_type;
+ peer_dst->max_packet_size = peer_src->max_packet_size;
+
/* Timers */
peer_dst->holdtime = peer_src->holdtime;
peer_dst->keepalive = peer_src->keepalive;
@@ -2315,13 +2317,6 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
peer->afc[afi][safi] = 0;
group = peer->group;
- if (peer_af_delete(peer, afi, safi) != 0) {
- flog_err(
- EC_BGP_PEER_DELETE,
- "couldn't delete af structure for peer %s(%s, %s)",
- peer->host, afi2str(afi), safi2str(safi));
- }
-
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
ret |= non_peergroup_deactivate_af(tmp_peer, afi, safi);
}
@@ -3097,8 +3092,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
afi_t afi;
safi_t safi;
- if ((bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp))) == NULL)
- return NULL;
+ bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp));
if (BGP_DEBUG(zebra, ZEBRA)) {
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
diff --git a/configure.ac b/configure.ac
index 2a8411d122..564588cca7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -672,8 +672,6 @@ AC_ARG_ENABLE([fpm],
AS_HELP_STRING([--enable-fpm], [enable Forwarding Plane Manager support]))
AC_ARG_ENABLE([pcep],
AS_HELP_STRING([--enable-pcep], [enable PCEP support for pathd]))
-AC_ARG_ENABLE([systemd],
- AS_HELP_STRING([--enable-systemd], [enable Systemd support]))
AC_ARG_ENABLE([werror],
AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
AC_ARG_ENABLE([cumulus],
@@ -768,19 +766,6 @@ case "${enable_cpu_time}" in
;;
esac
-case "${enable_systemd}" in
- "no") ;;
- "yes")
- AC_CHECK_LIB([systemd], [sd_notify], [LIBS="$LIBS -lsystemd"])
- if test "$ac_cv_lib_systemd_sd_notify" = "no"; then
- AC_MSG_ERROR([enable systemd has been specified but systemd development env not found on your system])
- else
- AC_DEFINE([HAVE_SYSTEMD], [1], [Compile systemd support in])
- fi
- ;;
- "*") ;;
-esac
-
if test "$enable_rr_semantics" != "no" ; then
AC_DEFINE([HAVE_V6_RR_SEMANTICS], [1], [Compile in v6 Route Replacement Semantics])
fi
diff --git a/debian/README.Debian b/debian/README.Debian
index a23a0efcac..53fb6c9d0e 100644
--- a/debian/README.Debian
+++ b/debian/README.Debian
@@ -31,10 +31,6 @@ The following Build Profiles have been added:
controls whether the RPKI module is built.
Will be enabled by default at some point, adds some extra dependencies.
-- pkg.frr.nosystemd
- Disables both systemd unit file installation as well as watchfrr sd_notify
- support at startup. Removes libsystemd dependency.
-
Note that all options have a "no" form; if you want to have your decision
be sticky regardless of changes to what it defaults to, then always use one
of the two. For example, all occurrences of <pkg.frr.rtrlib> will at some
@@ -43,10 +39,6 @@ point be replaced with <!pkg.frr.nortrlib>.
The main frr package has the exact same contents regardless of rtrlib or snmp
choices. The options only control frr-snmp and frr-rpki-rtrlib packages.
-The main frr package does NOT have the same contents if pkg.frr.nosystemd is
-used. This option should only be used for systems that do not have systemd,
-e.g. Ubuntu 14.04.
-
* Debian Policy compliance notes
================================
diff --git a/debian/control b/debian/control
index 0bbe99b312..0e67ff3730 100644
--- a/debian/control
+++ b/debian/control
@@ -22,7 +22,6 @@ Build-Depends: bison,
librtr-dev <!pkg.frr.nortrlib>,
libsnmp-dev,
libssh-dev <!pkg.frr.nortrlib>,
- libsystemd-dev <!pkg.frr.nosystemd>,
libyang2-dev,
lsb-base,
pkg-config,
diff --git a/debian/rules b/debian/rules
index 93d0cdb2a0..0fa9c3a3b0 100755
--- a/debian/rules
+++ b/debian/rules
@@ -21,14 +21,6 @@ else
CONF_RPKI=--disable-rpki
endif
-ifeq ($(filter pkg.frr.nosystemd,$(DEB_BUILD_PROFILES)),)
- DH_WITHOUT_SYSTEMD=
- CONF_SYSTEMD=--enable-systemd=yes
-else
- DH_WITHOUT_SYSTEMD=--without=systemd
- CONF_SYSTEMD=--enable-systemd=no
-endif
-
ifeq ($(filter pkg.frr.lua,$(DEB_BUILD_PROFILES)),)
CONF_LUA=--disable-scripting
else
@@ -38,7 +30,7 @@ endif
export PYTHON=python3
%:
- dh $@ $(DH_WITHOUT_SYSTEMD)
+ dh $@
override_dh_auto_configure:
$(shell dpkg-buildflags --export=sh); \
@@ -52,7 +44,6 @@ override_dh_auto_configure:
LIBTOOLFLAGS="-rpath /usr/lib/$(DEB_HOST_MULTIARCH)/frr" \
--disable-dependency-tracking \
\
- $(CONF_SYSTEMD) \
$(CONF_RPKI) \
$(CONF_LUA) \
--with-libpam \
@@ -80,9 +71,7 @@ override_dh_auto_install:
sed -e '1c #!/usr/bin/python3' -i debian/tmp/usr/lib/frr/generate_support_bundle.py
# let dh_systemd_* and dh_installinit do their thing automatically
-ifeq ($(filter pkg.frr.nosystemd,$(DEB_BUILD_PROFILES)),)
cp tools/frr.service debian/frr.service
-endif
cp tools/frrinit.sh debian/frr.init
-rm -f debian/tmp/usr/lib/frr/frr
diff --git a/doc/developer/building-frr-for-archlinux.rst b/doc/developer/building-frr-for-archlinux.rst
index e589a9f724..af1677e89e 100644
--- a/doc/developer/building-frr-for-archlinux.rst
+++ b/doc/developer/building-frr-for-archlinux.rst
@@ -10,8 +10,8 @@ Installing Dependencies
sudo pacman -S \
git autoconf automake libtool make cmake pcre readline texinfo \
pkg-config pam json-c bison flex python-pytest \
- c-ares python systemd python2-ipaddress python-sphinx \
- systemd-libs net-snmp perl libcap libelf
+ c-ares python python2-ipaddress python-sphinx \
+ net-snmp perl libcap libelf
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst
index 93b9993a38..ce11126f70 100644
--- a/doc/developer/building-frr-for-centos7.rst
+++ b/doc/developer/building-frr-for-centos7.rst
@@ -21,7 +21,7 @@ Add packages:
sudo yum install git autoconf automake libtool make \
readline-devel texinfo net-snmp-devel groff pkgconfig \
json-c-devel pam-devel bison flex pytest c-ares-devel \
- python-devel systemd-devel python-sphinx libcap-devel \
+ python-devel python-sphinx libcap-devel \
elfutils-libelf-devel
.. include:: building-libyang.rst
@@ -66,7 +66,6 @@ an example.)
--enable-user=frr \
--enable-group=frr \
--enable-vty-group=frrvty \
- --enable-systemd=yes \
--disable-ldpd \
--enable-fpm \
--with-pkg-git-version \
diff --git a/doc/developer/building-frr-for-centos8.rst b/doc/developer/building-frr-for-centos8.rst
index 65c93286b7..109a7866d9 100644
--- a/doc/developer/building-frr-for-centos8.rst
+++ b/doc/developer/building-frr-for-centos8.rst
@@ -14,7 +14,7 @@ Add packages:
sudo dnf install --enablerepo=PowerTools git autoconf pcre-devel \
automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \
groff pkgconfig json-c-devel pam-devel bison flex python2-pytest \
- c-ares-devel python2-devel systemd-devel libcap-devel \
+ c-ares-devel python2-devel libcap-devel \
elfutils-libelf-devel
.. include:: building-libyang.rst
@@ -59,7 +59,6 @@ an example.)
--enable-user=frr \
--enable-group=frr \
--enable-vty-group=frrvty \
- --enable-systemd=yes \
--disable-ldpd \
--enable-fpm \
--with-pkg-git-version \
diff --git a/doc/developer/building-frr-for-debian8.rst b/doc/developer/building-frr-for-debian8.rst
index 475e0303fc..5e58854ed7 100644
--- a/doc/developer/building-frr-for-debian8.rst
+++ b/doc/developer/building-frr-for-debian8.rst
@@ -17,7 +17,7 @@ Add packages:
sudo apt-get install git autoconf automake libtool make \
libreadline-dev texinfo libjson-c-dev pkg-config bison flex python3-pip \
- libc-ares-dev python3-dev python3-sphinx build-essential libsystemd-dev \
+ libc-ares-dev python3-dev python3-sphinx build-essential \
libsnmp-dev libcap-dev libelf-dev
Install newer pytest (>3.0) from pip
diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst
index 1981127b3d..f8d8025f62 100644
--- a/doc/developer/building-frr-for-debian9.rst
+++ b/doc/developer/building-frr-for-debian9.rst
@@ -11,7 +11,7 @@ Add packages:
sudo apt-get install git autoconf automake libtool make \
libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
libc-ares-dev python3-dev python3-pytest python3-sphinx build-essential \
- libsnmp-dev libsystemd-dev libcap-dev libelf-dev
+ libsnmp-dev libcap-dev libelf-dev
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-fedora.rst b/doc/developer/building-frr-for-fedora.rst
index 5fecd8a826..6ce76ba158 100644
--- a/doc/developer/building-frr-for-fedora.rst
+++ b/doc/developer/building-frr-for-fedora.rst
@@ -14,7 +14,7 @@ Installing Dependencies
sudo dnf install git autoconf automake libtool make \
readline-devel texinfo net-snmp-devel groff pkgconfig json-c-devel \
pam-devel python3-pytest bison flex c-ares-devel python3-devel \
- python3-sphinx perl-core patch systemd-devel libcap-devel \
+ python3-sphinx perl-core patch libcap-devel \
elfutils-libelf-devel
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-opensuse.rst b/doc/developer/building-frr-for-opensuse.rst
index 4e886e9c25..ee6a36a14b 100644
--- a/doc/developer/building-frr-for-opensuse.rst
+++ b/doc/developer/building-frr-for-opensuse.rst
@@ -13,7 +13,7 @@ Installing Dependencies
zypper in git autoconf automake libtool make \
readline-devel texinfo net-snmp-devel groff pkgconfig libjson-c-devel\
pam-devel python3-pytest bison flex c-ares-devel python3-devel\
- python3-Sphinx perl patch systemd-devel libcap-devel libyang-devel \
+ python3-Sphinx perl patch libcap-devel libyang-devel \
libelf-devel
Building & Installing FRR
diff --git a/doc/developer/building-frr-for-ubuntu1604.rst b/doc/developer/building-frr-for-ubuntu1604.rst
index 2cb9536f9b..d79545c859 100644
--- a/doc/developer/building-frr-for-ubuntu1604.rst
+++ b/doc/developer/building-frr-for-ubuntu1604.rst
@@ -13,8 +13,8 @@ Installing Dependencies
apt-get install \
git autoconf automake libtool make libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddress python3-sphinx \
- install-info build-essential libsystemd-dev libsnmp-dev perl libcap-dev \
+ libc-ares-dev python3-dev python-ipaddress python3-sphinx \
+ install-info build-essential libsnmp-dev perl libcap-dev \
libelf-dev
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst
index eb3991c139..39a17fc01c 100644
--- a/doc/developer/building-frr-for-ubuntu1804.rst
+++ b/doc/developer/building-frr-for-ubuntu1804.rst
@@ -13,8 +13,8 @@ Installing Dependencies
sudo apt-get install \
git autoconf automake libtool make libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddress python3-sphinx \
- install-info build-essential libsystemd-dev libsnmp-dev perl libcap-dev \
+ libc-ares-dev python3-dev python-ipaddress python3-sphinx \
+ install-info build-essential libsnmp-dev perl libcap-dev \
libelf-dev
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-ubuntu2004.rst b/doc/developer/building-frr-for-ubuntu2004.rst
index 58d72e2891..92ddead4a5 100644
--- a/doc/developer/building-frr-for-ubuntu2004.rst
+++ b/doc/developer/building-frr-for-ubuntu2004.rst
@@ -13,8 +13,8 @@ Installing Dependencies
sudo apt-get install \
git autoconf automake libtool make libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddress python3-sphinx \
- install-info build-essential libsystemd-dev libsnmp-dev perl \
+ libc-ares-dev python3-dev python-ipaddress python3-sphinx \
+ install-info build-essential libsnmp-dev perl \
libcap-dev python2 libelf-dev
Note that Ubuntu 20 no longer installs python 2.x, so it must be
diff --git a/doc/developer/include-compile.rst b/doc/developer/include-compile.rst
index d9fa260221..513cac6179 100644
--- a/doc/developer/include-compile.rst
+++ b/doc/developer/include-compile.rst
@@ -2,11 +2,6 @@ Clone the FRR git repo and use the included ``configure`` script to configure
FRR's build time options to your liking. The full option listing can be
obtained by running ``./configure -h``. The options shown below are examples.
-.. note::
-
- If your platform uses ``systemd``, please make sure to add
- ``--enable-systemd=yes`` to your configure options.
-
.. code-block:: console
git clone https://github.com/frrouting/frr.git frr
diff --git a/doc/developer/packaging-debian.rst b/doc/developer/packaging-debian.rst
index 968e960267..a81e052490 100644
--- a/doc/developer/packaging-debian.rst
+++ b/doc/developer/packaging-debian.rst
@@ -53,7 +53,7 @@ buster.)
Where `$options` may contain any or all of the following items:
* build profiles specified with ``-P``, e.g.
- ``-Ppkg.frr.nortrlib,pkg.frr.nosystemd``.
+ ``-Ppkg.frr.nortrlib,pkg.frr.rtrlib``.
Multiple values are separated by commas and there must not be a space
after the ``-P``.
@@ -64,14 +64,6 @@ buster.)
+================+===================+=========================================+
| pkg.frr.rtrlib | pkg.frr.nortrlib | builds frr-rpki-rtrlib package (or not) |
+----------------+-------------------+-----------------------------------------+
- | n/a | pkg.frr.nosystemd | removes libsystemd dependency and |
- | | | disables unit file installation |
- +----------------+-------------------+-----------------------------------------+
-
- .. note::
-
- The ``pkg.frr.nosystemd`` option is only intended to support Ubuntu
- 14.04 (and should be enabled when building for that.)
* the ``-uc -us`` options to disable signing the packages with your GPG key
diff --git a/doc/developer/packaging-redhat.rst b/doc/developer/packaging-redhat.rst
index 458cfa0ad4..9e64b912f3 100644
--- a/doc/developer/packaging-redhat.rst
+++ b/doc/developer/packaging-redhat.rst
@@ -18,10 +18,6 @@ Tested on CentOS 6, CentOS 7, CentOS 8 and Fedora 24.
yum install rpm-build net-snmp-devel pam-devel libcap-devel
- If your platform uses systemd::
-
- yum install systemd-devel
-
For CentOS 7 and CentOS 8, the package will be built using python3
and requires additional python3 packages::
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 63254555d9..fdf5bab9c9 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -146,11 +146,6 @@ options from the list below.
software available on your machine. This is needed for systemd integration, if you
disable watchfrr you cannot have any systemd integration.
-.. option:: --enable-systemd
-
- Build watchfrr with systemd integration, this will allow FRR to communicate with
- systemd to tell systemd if FRR has come up properly.
-
.. option:: --enable-werror
Build with all warnings converted to errors as a compile option. This
@@ -404,6 +399,12 @@ options to the configuration script.
Set StrongSWAN vici interface socket path [/var/run/charon.vici].
+.. note::
+
+ The former ``--enable-systemd`` option does not exist anymore. Support for
+ systemd is now always available through built-in functions, without
+ depending on libsystemd.
+
Python dependency, documentation and tests
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst
index 04ee1643d8..c4a1bc381e 100644
--- a/doc/user/ospf6d.rst
+++ b/doc/user/ospf6d.rst
@@ -85,6 +85,61 @@ OSPF6 router
change to take effect, user can use this cli instead of restarting the
ospf6d daemon.
+.. _ospf6-debugging:
+
+OSPFv3 Debugging
+================
+
+The following debug commands are supported:
+
+.. clicmd:: debug ospf6 abr
+
+ Toggle OSPFv3 ABR debugging messages.
+
+.. clicmd:: debug ospf6 asbr
+
+ Toggle OSPFv3 ASBR debugging messages.
+
+.. clicmd:: debug ospf6 border-routers
+
+ Toggle OSPFv3 border router debugging messages.
+
+.. clicmd:: debug ospf6 flooding
+
+ Toggle OSPFv3 flooding debugging messages.
+
+.. clicmd:: debug ospf6 interface
+
+ Toggle OSPFv3 interface related debugging messages.
+
+.. clicmd:: debug ospf6 lsa
+
+ Toggle OSPFv3 Link State Advertisements debugging messages.
+
+.. clicmd:: debug ospf6 message
+
+ Toggle OSPFv3 message exchange debugging messages.
+
+.. clicmd:: debug ospf6 neighbor
+
+ Toggle OSPFv3 neighbor interaction debugging messages.
+
+.. clicmd:: debug ospf6 nssa
+
+ Toggle OSPFv3 Not So Stubby Area (NSSA) debugging messages.
+
+.. clicmd:: debug ospf6 route
+
+ Toggle OSPFv3 routes debugging messages.
+
+.. clicmd:: debug ospf6 spf
+
+ Toggle OSPFv3 Shortest Path calculation debugging messages.
+
+.. clicmd:: debug ospf6 zebra
+
+ Toggle OSPFv3 zebra interaction debugging messages.
+
.. _ospf6-area:
OSPF6 area
diff --git a/docker/centos-7/Dockerfile b/docker/centos-7/Dockerfile
index 303a33fe4a..73097df8fa 100644
--- a/docker/centos-7/Dockerfile
+++ b/docker/centos-7/Dockerfile
@@ -4,7 +4,7 @@ RUN yum install -y epel-release
RUN yum install -y rpm-build autoconf automake libtool make \
readline-devel texinfo net-snmp-devel groff pkgconfig \
json-c-devel pam-devel bison flex pytest c-ares-devel \
- python3-devel python3-sphinx systemd-devel libcap-devel \
+ python3-devel python3-sphinx libcap-devel \
https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \
https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \
https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm \
diff --git a/docker/centos-8/Dockerfile b/docker/centos-8/Dockerfile
index 8a0c28e13b..71378c2451 100644
--- a/docker/centos-8/Dockerfile
+++ b/docker/centos-8/Dockerfile
@@ -4,7 +4,7 @@ FROM centos:centos8 as centos-8-builder
RUN dnf install --enablerepo=powertools -y rpm-build git autoconf pcre-devel \
automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \
groff pkgconfig json-c-devel pam-devel bison flex python3-pytest \
- c-ares-devel python3-devel python3-sphinx systemd-devel libcap-devel platform-python-devel \
+ c-ares-devel python3-devel python3-sphinx libcap-devel platform-python-devel \
https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm \
diff --git a/docker/ubuntu18-ci/Dockerfile b/docker/ubuntu18-ci/Dockerfile
index 680b9172ad..766f06dfc2 100644
--- a/docker/ubuntu18-ci/Dockerfile
+++ b/docker/ubuntu18-ci/Dockerfile
@@ -7,8 +7,8 @@ RUN apt update && \
apt-get install -y \
git autoconf automake libtool make libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddress python3-sphinx \
- install-info build-essential libsystemd-dev libsnmp-dev perl libcap-dev \
+ libc-ares-dev python3-dev python-ipaddress python3-sphinx \
+ install-info build-essential libsnmp-dev perl libcap-dev \
libelf-dev \
sudo gdb iputils-ping time \
mininet python-pip iproute2 iperf && \
diff --git a/docker/ubuntu20-ci/Dockerfile b/docker/ubuntu20-ci/Dockerfile
index 47d5b81d3a..b5df98f23e 100644
--- a/docker/ubuntu20-ci/Dockerfile
+++ b/docker/ubuntu20-ci/Dockerfile
@@ -7,8 +7,8 @@ RUN apt update && \
apt-get install -y \
git autoconf automake libtool make libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddress python3-sphinx \
- install-info build-essential libsystemd-dev libsnmp-dev perl \
+ libc-ares-dev python3-dev python-ipaddress python3-sphinx \
+ install-info build-essential libsnmp-dev perl \
libcap-dev python2 libelf-dev \
sudo gdb curl iputils-ping time \
libgrpc++-dev libgrpc-dev protobuf-compiler-grpc \
diff --git a/lib/buffer.c b/lib/buffer.c
index 7929b3709d..41b1adc9fc 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -357,7 +357,8 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
iov_size =
((iov_index > IOV_MAX) ? IOV_MAX : iov_index);
- if ((nbytes = writev(fd, c_iov, iov_size)) < 0) {
+ nbytes = writev(fd, c_iov, iov_size);
+ if (nbytes < 0) {
flog_err(EC_LIB_SOCKET,
"%s: writev to fd %d failed: %s",
__func__, fd, safe_strerror(errno));
@@ -370,7 +371,8 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
}
}
#else /* IOV_MAX */
- if ((nbytes = writev(fd, iov, iov_index)) < 0)
+ nbytes = writev(fd, iov, iov_index);
+ if (nbytes < 0)
flog_err(EC_LIB_SOCKET, "%s: writev to fd %d failed: %s",
__func__, fd, safe_strerror(errno));
#endif /* IOV_MAX */
@@ -472,13 +474,17 @@ buffer_status_t buffer_write(struct buffer *b, int fd, const void *p,
/* Buffer is not empty, so do not attempt to write the new data.
*/
nbytes = 0;
- else if ((nbytes = write(fd, p, size)) < 0) {
- if (ERRNO_IO_RETRY(errno))
- nbytes = 0;
- else {
- flog_err(EC_LIB_SOCKET, "%s: write error on fd %d: %s",
- __func__, fd, safe_strerror(errno));
- return BUFFER_ERROR;
+ else {
+ nbytes = write(fd, p, size);
+ if (nbytes < 0) {
+ if (ERRNO_IO_RETRY(errno))
+ nbytes = 0;
+ else {
+ flog_err(EC_LIB_SOCKET,
+ "%s: write error on fd %d: %s",
+ __func__, fd, safe_strerror(errno));
+ return BUFFER_ERROR;
+ }
}
}
/* Add any remaining data to the buffer. */
diff --git a/lib/csv.c b/lib/csv.c
index b48b79792e..05b9dbe39e 100644
--- a/lib/csv.c
+++ b/lib/csv.c
@@ -641,7 +641,8 @@ static int get_memory_usage(pid_t pid)
char *vm;
snprintf(status_child, sizeof(status_child), "/proc/%d/status", pid);
- if ((fd = open(status_child, O_RDONLY)) < 0)
+ fd = open(status_child, O_RDONLY);
+ if (fd < 0)
return -1;
read(fd, buf, 4095);
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 0817182f7a..97dab74d9b 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -44,6 +44,7 @@
#include "frr_pthread.h"
#include "defaults.h"
#include "frrscript.h"
+#include "systemd.h"
DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
DEFINE_HOOK(frr_config_pre, (struct thread_master * tm), (tm));
@@ -363,6 +364,11 @@ void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
startup_fds |= UINT64_C(0x1) << (uint64_t)i;
}
+
+ /* note this doesn't do anything, it just grabs state, so doing it
+ * early in _preinit is perfect.
+ */
+ systemd_init_env();
}
bool frr_is_startup_fd(int fd)
diff --git a/lib/link_state.c b/lib/link_state.c
index e8a6b89f89..062384aac7 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -538,8 +538,6 @@ struct ls_edge *ls_edge_add(struct ls_ted *ted,
/* Create Edge and add it to the TED */
new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_edge));
- if (!new)
- return NULL;
new->attributes = attributes;
new->key = key;
@@ -804,8 +802,6 @@ struct ls_ted *ls_ted_new(const uint32_t key, const char *name,
struct ls_ted *new;
new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_ted));
- if (new == NULL)
- return new;
/* Set basic information for this ted */
new->key = key;
@@ -1005,8 +1001,6 @@ static struct ls_node *ls_parse_node(struct stream *s)
size_t len;
node = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_node));
- if (node == NULL)
- return NULL;
STREAM_GET(&node->adv, s, sizeof(struct ls_node_id));
STREAM_GETW(s, node->flags);
@@ -1051,8 +1045,6 @@ static struct ls_attributes *ls_parse_attributes(struct stream *s)
size_t len;
attr = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_attributes));
- if (attr == NULL)
- return NULL;
attr->srlgs = NULL;
STREAM_GET(&attr->adv, s, sizeof(struct ls_node_id));
@@ -1157,8 +1149,6 @@ static struct ls_prefix *ls_parse_prefix(struct stream *s)
size_t len;
ls_pref = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_prefix));
- if (ls_pref == NULL)
- return NULL;
STREAM_GET(&ls_pref->adv, s, sizeof(struct ls_node_id));
STREAM_GETW(s, ls_pref->flags);
@@ -1193,8 +1183,6 @@ struct ls_message *ls_parse_msg(struct stream *s)
struct ls_message *msg;
msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
- if (msg == NULL)
- return NULL;
/* Read LS Message header */
STREAM_GETC(s, msg->event);
diff --git a/lib/network.c b/lib/network.c
index 411661a5e1..b60ad9a57c 100644
--- a/lib/network.c
+++ b/lib/network.c
@@ -78,7 +78,8 @@ int set_nonblocking(int fd)
/* According to the Single UNIX Spec, the return value for F_GETFL
should
never be negative. */
- if ((flags = fcntl(fd, F_GETFL)) < 0) {
+ flags = fcntl(fd, F_GETFL);
+ if (flags < 0) {
flog_err(EC_LIB_SYSTEM_CALL,
"fcntl(F_GETFL) failed for fd %d: %s", fd,
safe_strerror(errno));
diff --git a/lib/ntop.c b/lib/ntop.c
index ccbf8793d3..1b2dd7a6d1 100644
--- a/lib/ntop.c
+++ b/lib/ntop.c
@@ -40,14 +40,18 @@ static inline void putbyte(uint8_t bytex, char **posx)
bool zero = false;
int byte = bytex, tmp, a, b;
- if ((tmp = byte - 200) >= 0) {
+ tmp = byte - 200;
+ if (tmp >= 0) {
*pos++ = '2';
zero = true;
byte = tmp;
- } else if ((tmp = byte - 100) >= 0) {
- *pos++ = '1';
- zero = true;
- byte = tmp;
+ } else {
+ tmp = byte - 100;
+ if (tmp >= 0) {
+ *pos++ = '1';
+ zero = true;
+ byte = tmp;
+ }
}
/* make sure the compiler knows the value range of "byte" */
diff --git a/lib/prefix.c b/lib/prefix.c
index 1c57715e8f..ef7d2e59da 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -1034,7 +1034,8 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
l = strlen(buf);
buf[l++] = '/';
byte = p->prefixlen;
- if ((tmp = p->prefixlen - 100) >= 0) {
+ tmp = p->prefixlen - 100;
+ if (tmp >= 0) {
buf[l++] = '1';
z = true;
byte = tmp;
diff --git a/lib/prefix.h b/lib/prefix.h
index bc4cb7f441..944c94f57f 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -537,20 +537,32 @@ static inline int ipv4_martian(struct in_addr *addr)
return 0;
}
-static inline int is_default_prefix(const struct prefix *p)
+static inline bool is_default_prefix4(const struct prefix_ipv4 *p)
{
- if (!p)
- return 0;
+ return p && p->family == AF_INET && p->prefixlen == 0
+ && p->prefix.s_addr == INADDR_ANY;
+}
- if ((p->family == AF_INET) && (p->u.prefix4.s_addr == INADDR_ANY)
- && (p->prefixlen == 0))
- return 1;
+static inline bool is_default_prefix6(const struct prefix_ipv6 *p)
+{
+ return p && p->family == AF_INET6 && p->prefixlen == 0
+ && memcmp(&p->prefix, &in6addr_any, sizeof(struct in6_addr))
+ == 0;
+}
- if ((p->family == AF_INET6) && (p->prefixlen == 0)
- && (!memcmp(&p->u.prefix6, &in6addr_any, sizeof(struct in6_addr))))
- return 1;
+static inline bool is_default_prefix(const struct prefix *p)
+{
+ if (p == NULL)
+ return false;
+
+ switch (p->family) {
+ case AF_INET:
+ return is_default_prefix4((const struct prefix_ipv4 *)p);
+ case AF_INET6:
+ return is_default_prefix6((const struct prefix_ipv6 *)p);
+ }
- return 0;
+ return false;
}
static inline int is_host_route(const struct prefix *p)
diff --git a/lib/sockopt.c b/lib/sockopt.c
index 98bfda5079..150736e00c 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -379,14 +379,14 @@ static int setsockopt_ipv4_ifindex(int sock, ifindex_t val)
int ret;
#if defined(IP_PKTINFO)
- if ((ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)))
- < 0)
+ ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
+ if (ret < 0)
flog_err(EC_LIB_SOCKET,
"Can't set IP_PKTINFO option for fd %d to %d: %s",
sock, val, safe_strerror(errno));
#elif defined(IP_RECVIF)
- if ((ret = setsockopt(sock, IPPROTO_IP, IP_RECVIF, &val, sizeof(val)))
- < 0)
+ ret = setsockopt(sock, IPPROTO_IP, IP_RECVIF, &val, sizeof(val));
+ if (ret < 0)
flog_err(EC_LIB_SOCKET,
"Can't set IP_RECVIF option for fd %d to %d: %s", sock,
val, safe_strerror(errno));
@@ -639,12 +639,8 @@ int sockopt_tcp_signature_ext(int sock, union sockunion *su, uint16_t prefixlen,
#endif /* GNU_LINUX */
- if ((ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig,
- sizeof(md5sig)))
- < 0) {
- /* ENOENT is harmless. It is returned when we clear a password
- for which
- one was not previously set. */
+ ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig, sizeof(md5sig));
+ if (ret < 0) {
if (ENOENT == errno)
ret = 0;
else
diff --git a/lib/stream.c b/lib/stream.c
index 904ee73b10..1557500c60 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -1097,7 +1097,8 @@ ssize_t stream_read_try(struct stream *s, int fd, size_t size)
return -1;
}
- if ((nbytes = read(fd, s->data + s->endp, size)) >= 0) {
+ nbytes = read(fd, s->data + s->endp, size);
+ if (nbytes >= 0) {
s->endp += nbytes;
return nbytes;
}
@@ -1126,9 +1127,8 @@ ssize_t stream_recvfrom(struct stream *s, int fd, size_t size, int flags,
return -1;
}
- if ((nbytes = recvfrom(fd, s->data + s->endp, size, flags, from,
- fromlen))
- >= 0) {
+ nbytes = recvfrom(fd, s->data + s->endp, size, flags, from, fromlen);
+ if (nbytes >= 0) {
s->endp += nbytes;
return nbytes;
}
diff --git a/lib/systemd.c b/lib/systemd.c
index c5cc3aa447..2238dc9f3d 100644
--- a/lib/systemd.c
+++ b/lib/systemd.c
@@ -20,68 +20,56 @@
*/
#include <zebra.h>
+#include <sys/un.h>
#include "thread.h"
#include "systemd.h"
+#include "lib_errors.h"
-#if defined HAVE_SYSTEMD
-#include <systemd/sd-daemon.h>
-#endif
+/* these are cleared from env so they don't "leak" into things we fork(),
+ * particularly for watchfrr starting individual daemons
+ *
+ * watchdog_pid is currently not used since watchfrr starts forking.
+ * (TODO: handle that better, somehow?)
+ */
+static pid_t watchdog_pid = -1;
+static intmax_t watchdog_msec;
+
+/* not used yet, but can trigger auto-switch to journald logging */
+bool sd_stdout_is_journal;
+bool sd_stderr_is_journal;
+
+static char *notify_socket;
-/*
- * Wrapper this silliness if we
- * don't have systemd
+/* talk to whatever entity claims to be systemd ;)
+ *
+ * refer to sd_notify docs for messages systemd accepts over this socket.
+ * This function should be functionally equivalent to sd_notify().
*/
static void systemd_send_information(const char *info)
{
-#if defined HAVE_SYSTEMD
- sd_notify(0, info);
-#else
- return;
-#endif
-}
+ int sock;
+ struct sockaddr_un sun;
-/*
- * A return of 0 means that we are not watchdoged
- */
-static int systemd_get_watchdog_time(int the_process)
-{
-#if defined HAVE_SYSTEMD
- uint64_t usec;
- char *watchdog = NULL;
- int ret;
-
- ret = sd_watchdog_enabled(0, &usec);
-
- /*
- * If return is 0 -> we don't want watchdog
- * if return is < 0, some sort of failure occurred
- */
- if (ret < 0)
- return 0;
-
- /*
- * systemd can return that this process
- * is not the expected sender of the watchdog timer
- * If we set the_process = 0 then we expect to
- * be able to send the watchdog to systemd
- * irrelevant of the pid of this process.
- */
- if (ret == 0 && the_process)
- return 0;
-
- if (ret == 0 && !the_process) {
- watchdog = getenv("WATCHDOG_USEC");
- if (!watchdog)
- return 0;
-
- usec = atol(watchdog);
- }
+ if (!notify_socket)
+ return;
+
+ sock = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (sock < 0)
+ return;
+
+ sun.sun_family = AF_UNIX;
+ strlcpy(sun.sun_path, notify_socket, sizeof(sun.sun_path));
- return (usec / 1000000) / 3;
-#else
- return 0;
-#endif
+ /* linux abstract unix socket namespace */
+ if (sun.sun_path[0] == '@')
+ sun.sun_path[0] = '\0';
+
+ /* nothing we can do if this errors out... */
+ (void)sendto(sock, info, strlen(info), 0, (struct sockaddr *)&sun,
+ sizeof(sun));
+
+ close(sock);
}
void systemd_send_stopping(void)
@@ -90,34 +78,27 @@ void systemd_send_stopping(void)
systemd_send_information("STOPPING=1");
}
-/*
- * How many seconds should we wait between watchdog sends
- */
-static int wsecs = 0;
static struct thread_master *systemd_master = NULL;
static int systemd_send_watchdog(struct thread *t)
{
systemd_send_information("WATCHDOG=1");
- thread_add_timer(systemd_master, systemd_send_watchdog, NULL, wsecs,
- NULL);
-
+ assert(watchdog_msec > 0);
+ thread_add_timer_msec(systemd_master, systemd_send_watchdog, NULL,
+ watchdog_msec, NULL);
return 1;
}
-void systemd_send_started(struct thread_master *m, int the_process)
+void systemd_send_started(struct thread_master *m)
{
assert(m != NULL);
- wsecs = systemd_get_watchdog_time(the_process);
systemd_master = m;
systemd_send_information("READY=1");
- if (wsecs != 0) {
- systemd_send_information("WATCHDOG=1");
- thread_add_timer(m, systemd_send_watchdog, m, wsecs, NULL);
- }
+ if (watchdog_msec > 0)
+ systemd_send_watchdog(NULL);
}
void systemd_send_status(const char *status)
@@ -127,3 +108,65 @@ void systemd_send_status(const char *status)
snprintf(buffer, sizeof(buffer), "STATUS=%s", status);
systemd_send_information(buffer);
}
+
+static intmax_t getenv_int(const char *varname, intmax_t dflt)
+{
+ char *val, *err;
+ intmax_t intval;
+
+ val = getenv(varname);
+ if (!val)
+ return dflt;
+
+ intval = strtoimax(val, &err, 0);
+ if (*err || !*val)
+ return dflt;
+ return intval;
+}
+
+void systemd_init_env(void)
+{
+ char *tmp;
+ uintmax_t dev, ino;
+ int len;
+ struct stat st;
+
+ notify_socket = getenv("NOTIFY_SOCKET");
+
+ /* no point in setting up watchdog w/o notify socket */
+ if (notify_socket) {
+ intmax_t watchdog_usec;
+
+ watchdog_pid = getenv_int("WATCHDOG_PID", -1);
+ if (watchdog_pid <= 0)
+ watchdog_pid = -1;
+
+ /* note this is the deadline, hence the divide by 3 */
+ watchdog_usec = getenv_int("WATCHDOG_USEC", 0);
+ if (watchdog_usec >= 3000)
+ watchdog_msec = watchdog_usec / 3000;
+ else {
+ if (watchdog_usec != 0)
+ flog_err(
+ EC_LIB_UNAVAILABLE,
+ "systemd expects a %jd microsecond watchdog timer, but FRR only supports millisecond resolution!",
+ watchdog_usec);
+ watchdog_msec = 0;
+ }
+ }
+
+ tmp = getenv("JOURNAL_STREAM");
+ if (tmp && sscanf(tmp, "%ju:%ju%n", &dev, &ino, &len) == 2
+ && (size_t)len == strlen(tmp)) {
+ if (fstat(1, &st) == 0 && st.st_dev == (dev_t)dev
+ && st.st_ino == (ino_t)ino)
+ sd_stdout_is_journal = true;
+ if (fstat(2, &st) == 0 && st.st_dev == (dev_t)dev
+ && st.st_ino == (ino_t)ino)
+ sd_stderr_is_journal = true;
+ }
+
+ /* these should *not* be passed to any other process we start */
+ unsetenv("WATCHDOG_PID");
+ unsetenv("WATCHDOG_USEC");
+}
diff --git a/lib/systemd.h b/lib/systemd.h
index d9885c5d9c..1933f4f688 100644
--- a/lib/systemd.h
+++ b/lib/systemd.h
@@ -28,9 +28,6 @@ extern "C" {
*
* Design point is that if systemd is not being used on this system
* then these functions becomes a no-op.
- *
- * To turn on systemd compilation, use --enable-systemd on
- * configure run.
*/
void systemd_send_stopping(void);
@@ -39,13 +36,18 @@ void systemd_send_stopping(void);
* the_process - Should we send watchdog if we are not the requested
* process?
*/
-void systemd_send_started(struct thread_master *master, int the_process);
+void systemd_send_started(struct thread_master *master);
/*
* status - A status string to send to systemd
*/
void systemd_send_status(const char *status);
+/*
+ * grab startup state from env vars
+ */
+void systemd_init_env(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/zclient.c b/lib/zclient.c
index 1b4ac080cd..0815e77d4e 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1537,7 +1537,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
STREAM_GETW(s, api->opaque.length);
- assert(api->opaque.length < ZAPI_MESSAGE_OPAQUE_LENGTH);
+ assert(api->opaque.length <= ZAPI_MESSAGE_OPAQUE_LENGTH);
STREAM_GET(api->opaque.data, s, api->opaque.length);
}
@@ -3812,7 +3812,8 @@ static int zclient_read(struct thread *thread)
zclient->t_read = NULL;
/* Read zebra header (if we don't have it already). */
- if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
+ already = stream_get_endp(zclient->ibuf);
+ if (already < ZEBRA_HEADER_SIZE) {
ssize_t nbyte;
if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
ZEBRA_HEADER_SIZE - already))
@@ -3825,7 +3826,6 @@ static int zclient_read(struct thread *thread)
return zclient_failed(zclient);
}
if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
- /* Try again later. */
zclient_event(ZCLIENT_READ, zclient);
return 0;
}
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index d4e52f0ede..3e911a743a 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -690,7 +690,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
if (ospf6_check_and_set_router_abr(ospf6))
oa = ospf6->backbone;
else
- oa = listgetdata(listhead(ospf6->area_list));
+ oa = listnode_head(ospf6->area_list);
}
if (oa == NULL) {
@@ -2568,36 +2568,41 @@ int config_write_ospf6_debug_asbr(struct vty *vty)
return 0;
}
-int ospf6_distribute_config_write(struct vty *vty, struct ospf6 *ospf6)
+static void ospf6_default_originate_write(struct vty *vty, struct ospf6 *o)
{
struct ospf6_redist *red;
- if (ospf6) {
- /* default-route print. */
- if (ospf6->default_originate != DEFAULT_ORIGINATE_NONE) {
- vty_out(vty, " default-information originate");
- if (ospf6->default_originate
- == DEFAULT_ORIGINATE_ALWAYS)
- vty_out(vty, " always");
-
- red = ospf6_redist_lookup(ospf6, DEFAULT_ROUTE, 0);
- if (red) {
- if (red->dmetric.value >= 0)
- vty_out(vty, " metric %d",
- red->dmetric.value);
-
- if (red->dmetric.type >= 0)
- vty_out(vty, " metric-type %d",
- red->dmetric.type);
-
- if (ROUTEMAP_NAME(red))
- vty_out(vty, " route-map %s",
- ROUTEMAP_NAME(red));
- }
+ vty_out(vty, " default-information originate");
+ if (o->default_originate == DEFAULT_ORIGINATE_ALWAYS)
+ vty_out(vty, " always");
- vty_out(vty, "\n");
- }
+ red = ospf6_redist_lookup(o, DEFAULT_ROUTE, 0);
+ if (red == NULL) {
+ vty_out(vty, "\n");
+ return;
}
+
+ if (red->dmetric.value >= 0)
+ vty_out(vty, " metric %d", red->dmetric.value);
+
+ if (red->dmetric.type >= 0)
+ vty_out(vty, " metric-type %d", red->dmetric.type);
+
+ if (ROUTEMAP_NAME(red))
+ vty_out(vty, " route-map %s", ROUTEMAP_NAME(red));
+
+ vty_out(vty, "\n");
+}
+
+int ospf6_distribute_config_write(struct vty *vty, struct ospf6 *o)
+{
+ if (o == NULL)
+ return 0;
+
+ /* Print default originate configuration. */
+ if (o->default_originate != DEFAULT_ORIGINATE_NONE)
+ ospf6_default_originate_write(vty, o);
+
return 0;
}
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index 05b43189e9..738c2218fa 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -299,7 +299,7 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
{
struct listnode *node, *nnode;
struct ospf6_neighbor *on;
- struct ospf6_lsa *req;
+ struct ospf6_lsa *req, *old;
int retrans_added = 0;
int is_debug = 0;
@@ -408,12 +408,27 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
if (is_debug)
zlog_debug("Add retrans-list of neighbor %s ",
on->name);
- ospf6_increment_retrans_count(lsa);
- ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
- thread_add_timer(master, ospf6_lsupdate_send_neighbor,
- on, on->ospf6_if->rxmt_interval,
- &on->thread_send_lsupdate);
- retrans_added++;
+
+ /* Do not increment the retrans count if the lsa is
+ * already present in the retrans list.
+ */
+ old = ospf6_lsdb_lookup(
+ lsa->header->type, lsa->header->id,
+ lsa->header->adv_router, on->retrans_list);
+ if (!old) {
+ if (is_debug)
+ zlog_debug(
+ "Increment %s from retrans_list of %s",
+ lsa->name, on->name);
+ ospf6_increment_retrans_count(lsa);
+ ospf6_lsdb_add(ospf6_lsa_copy(lsa),
+ on->retrans_list);
+ thread_add_timer(
+ master, ospf6_lsupdate_send_neighbor,
+ on, on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsupdate);
+ retrans_added++;
+ }
}
}
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 1e75fc60f6..92c88623a0 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -733,7 +733,7 @@ int interface_up(struct thread *thread)
/* If no area assigned, return */
if (oi->area == NULL) {
zlog_warn(
- "%s: Not scheduleing Hello for %s as there is no area assigned yet",
+ "%s: Not scheduling Hello for %s as there is no area assigned yet",
__func__, oi->interface->name);
return 0;
}
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 817e5372ea..1f2618ec83 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -444,9 +444,9 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
/* check latency against hello period */
if (on->hello_in)
latency = monotime_since(&on->last_hello, NULL)
- - (oi->hello_interval * 1000000);
+ - ((int64_t)oi->hello_interval * 1000000);
/* log if latency exceeds the hello period */
- if (latency > (oi->hello_interval * 1000000))
+ if (latency > ((int64_t)oi->hello_interval * 1000000))
zlog_warn("%s RX %pI4 high latency %" PRId64 "us.", __func__,
&on->router_id, latency);
on->last_hello = timestamp;
@@ -1897,7 +1897,6 @@ static int ospf6_write(struct thread *thread)
struct ospf6_header *oh;
struct ospf6_packet *op;
struct listnode *node;
- char srcname[64], dstname[64];
struct iovec iovector[2];
int pkt_count = 0;
int len;
@@ -1934,26 +1933,45 @@ static int ospf6_write(struct thread *thread)
flog_err(EC_LIB_DEVELOPMENT,
"Could not send entire message");
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)) {
- inet_ntop(AF_INET6, &op->dst, dstname, sizeof(dstname));
- inet_ntop(AF_INET6, oi->linklocal_addr, srcname,
- sizeof(srcname));
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND_HDR)) {
zlog_debug("%s send on %s",
lookup_msg(ospf6_message_type_str, oh->type,
NULL),
oi->interface->name);
- zlog_debug(" src: %s", srcname);
- zlog_debug(" dst: %s", dstname);
+ zlog_debug(" src: %pI6", oi->linklocal_addr);
+ zlog_debug(" dst: %pI6", &op->dst);
+ switch (oh->type) {
+ case OSPF6_MESSAGE_TYPE_HELLO:
+ ospf6_hello_print(oh, OSPF6_ACTION_SEND);
+ break;
+ case OSPF6_MESSAGE_TYPE_DBDESC:
+ ospf6_dbdesc_print(oh, OSPF6_ACTION_SEND);
+ break;
+ case OSPF6_MESSAGE_TYPE_LSREQ:
+ ospf6_lsreq_print(oh, OSPF6_ACTION_SEND);
+ break;
+ case OSPF6_MESSAGE_TYPE_LSUPDATE:
+ ospf6_lsupdate_print(oh, OSPF6_ACTION_SEND);
+ break;
+ case OSPF6_MESSAGE_TYPE_LSACK:
+ ospf6_lsack_print(oh, OSPF6_ACTION_SEND);
+ break;
+ default:
+ zlog_debug("Unknown message");
+ assert(0);
+ break;
+ }
}
switch (oh->type) {
case OSPF6_MESSAGE_TYPE_HELLO:
monotime(&timestamp);
if (oi->hello_out)
latency = monotime_since(&oi->last_hello, NULL)
- - (oi->hello_interval * 1000000);
+ - ((int64_t)oi->hello_interval
+ * 1000000);
/* log if latency exceeds the hello period */
- if (latency > (oi->hello_interval * 1000000))
+ if (latency > ((int64_t)oi->hello_interval * 1000000))
zlog_warn("%s hello TX high latency %" PRId64
"us.",
__func__, latency);
@@ -1963,19 +1981,15 @@ static int ospf6_write(struct thread *thread)
break;
case OSPF6_MESSAGE_TYPE_DBDESC:
oi->db_desc_out++;
- ospf6_dbdesc_print(oh, OSPF6_ACTION_SEND);
break;
case OSPF6_MESSAGE_TYPE_LSREQ:
oi->ls_req_out++;
- ospf6_lsreq_print(oh, OSPF6_ACTION_SEND);
break;
case OSPF6_MESSAGE_TYPE_LSUPDATE:
oi->ls_upd_out++;
- ospf6_lsupdate_print(oh, OSPF6_ACTION_SEND);
break;
case OSPF6_MESSAGE_TYPE_LSACK:
oi->ls_ack_out++;
- ospf6_lsack_print(oh, OSPF6_ACTION_SEND);
break;
default:
zlog_debug("Unknown message");
@@ -2356,7 +2370,19 @@ static void ospf6_send_lsupdate(struct ospf6_neighbor *on,
}
if (oi) {
ospf6_packet_add(oi, op);
- OSPF6_MESSAGE_WRITE_ON(oi);
+ /* If ospf instance is being deleted, send the packet
+ * immediately
+ */
+ if ((oi->area == NULL) || (oi->area->ospf6 == NULL))
+ return;
+ if (oi->area->ospf6->inst_shutdown) {
+ if (oi->on_write_q == 0) {
+ listnode_add(oi->area->ospf6->oi_write_q, oi);
+ oi->on_write_q = 1;
+ }
+ thread_execute(master, ospf6_write, oi->area->ospf6, 0);
+ } else
+ OSPF6_MESSAGE_WRITE_ON(oi);
}
}
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index 032484e288..051b3a63ef 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -225,21 +225,25 @@ static char *ospf6_lsdesc_backlink(struct ospf6_lsa *lsa, caddr_t lsdesc,
assert(!(OSPF6_LSA_IS_TYPE(NETWORK, lsa)
&& VERTEX_IS_TYPE(NETWORK, v)));
- if (OSPF6_LSA_IS_TYPE(NETWORK, lsa)
- && NETWORK_LSDESC_GET_NBR_ROUTERID(backlink)
- == v->lsa->header->adv_router)
- found = backlink;
- else if (VERTEX_IS_TYPE(NETWORK, v)
- && ROUTER_LSDESC_IS_TYPE(TRANSIT_NETWORK, backlink)
- && ROUTER_LSDESC_GET_NBR_ROUTERID(backlink)
- == v->lsa->header->adv_router
- && ROUTER_LSDESC_GET_NBR_IFID(backlink)
- == ntohl(v->lsa->header->id))
- found = backlink;
- else {
+ if (OSPF6_LSA_IS_TYPE(NETWORK, lsa)) {
+ if (NETWORK_LSDESC_GET_NBR_ROUTERID(backlink)
+ == v->lsa->header->adv_router)
+ found = backlink;
+ } else if (VERTEX_IS_TYPE(NETWORK, v)) {
+ if (ROUTER_LSDESC_IS_TYPE(TRANSIT_NETWORK, backlink)
+ && ROUTER_LSDESC_GET_NBR_ROUTERID(backlink)
+ == v->lsa->header->adv_router
+ && ROUTER_LSDESC_GET_NBR_IFID(backlink)
+ == ntohl(v->lsa->header->id))
+ found = backlink;
+ } else {
+ assert(OSPF6_LSA_IS_TYPE(ROUTER, lsa)
+ && VERTEX_IS_TYPE(ROUTER, v));
+
if (!ROUTER_LSDESC_IS_TYPE(POINTTOPOINT, backlink)
|| !ROUTER_LSDESC_IS_TYPE(POINTTOPOINT, lsdesc))
continue;
+
if (ROUTER_LSDESC_GET_NBR_IFID(backlink)
!= ROUTER_LSDESC_GET_IFID(lsdesc)
|| ROUTER_LSDESC_GET_NBR_IFID(lsdesc)
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index a7e15c68ae..72bc3a2f3a 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -194,16 +194,6 @@ static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int is_prefix_default(struct prefix_ipv6 *p)
-{
- struct prefix_ipv6 q = {};
-
- q.family = AF_INET6;
- q.prefixlen = 0;
-
- return prefix_same((struct prefix *)p, (struct prefix *)&q);
-}
-
static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
{
struct zapi_route api;
@@ -239,7 +229,7 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
ifindex, api.tag);
memcpy(&p, &api.prefix, sizeof(p));
- if (is_prefix_default(&p))
+ if (is_default_prefix6(&p))
api.type = DEFAULT_ROUTE;
if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 192dbe4fc8..53d2ec538c 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -334,7 +334,7 @@ void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type,
struct ospf_external_aggr_rt *aggr;
- if (is_prefix_default(&ei->p)
+ if (is_default_prefix4(&ei->p)
&& ospf->default_originate != DEFAULT_ORIGINATE_NONE)
continue;
@@ -862,7 +862,7 @@ static void ospf_handle_external_aggr_add(struct ospf *ospf)
continue;
ei = rn->info;
- if (is_prefix_default(&ei->p))
+ if (is_default_prefix4(&ei->p))
continue;
/* Check the AS-external-LSA
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index d11c441e37..7fddb65a86 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -98,14 +98,14 @@ struct external_info *ospf_external_info_check(struct ospf *ospf,
int redist_on = 0;
redist_on =
- is_prefix_default(&p)
+ is_default_prefix4(&p)
? vrf_bitmap_check(
- zclient->default_information[AFI_IP],
- ospf->vrf_id)
+ zclient->default_information[AFI_IP],
+ ospf->vrf_id)
: (zclient->mi_redist[AFI_IP][type].enabled
|| vrf_bitmap_check(
- zclient->redist[AFI_IP][type],
- ospf->vrf_id));
+ zclient->redist[AFI_IP][type],
+ ospf->vrf_id));
// Pending: check for MI above.
if (redist_on) {
ext_list = ospf->external[type];
@@ -128,7 +128,7 @@ struct external_info *ospf_external_info_check(struct ospf *ospf,
}
}
- if (is_prefix_default(&p) && ospf->external[DEFAULT_ROUTE]) {
+ if (is_default_prefix4(&p) && ospf->external[DEFAULT_ROUTE]) {
ext_list = ospf->external[DEFAULT_ROUTE];
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 723a54a771..9ef2a6520a 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -1583,8 +1583,8 @@ static void ospf_external_lsa_body_set(struct stream *s,
stream_put_ipv4(s, mask.s_addr);
/* If prefix is default, specify DEFAULT_ROUTE. */
- type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type;
- instance = is_prefix_default(&ei->p) ? 0 : ei->instance;
+ type = is_default_prefix4(&ei->p) ? DEFAULT_ROUTE : ei->type;
+ instance = is_default_prefix4(&ei->p) ? 0 : ei->instance;
mtype = (ROUTEMAP_METRIC_TYPE(ei) != -1)
? ROUTEMAP_METRIC_TYPE(ei)
@@ -1986,17 +1986,6 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
return new;
}
-int is_prefix_default(struct prefix_ipv4 *p)
-{
- struct prefix_ipv4 q;
-
- q.family = AF_INET;
- q.prefix.s_addr = INADDR_ANY;
- q.prefixlen = 0;
-
- return prefix_same((struct prefix *)p, (struct prefix *)&q);
-}
-
/* Originate an AS-external-LSA, install and flood. */
struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
struct external_info *ei)
@@ -2159,8 +2148,7 @@ void ospf_external_lsa_rid_change(struct ospf *ospf)
if (!ei)
continue;
- if (is_prefix_default(
- (struct prefix_ipv4 *)&ei->p))
+ if (is_default_prefix4(&ei->p))
continue;
lsa = ospf_external_info_find_lsa(ospf, &ei->p);
@@ -2330,7 +2318,7 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type,
rn = route_next(rn)) {
ei = rn->info;
if (ei) {
- if (!is_prefix_default(&ei->p)) {
+ if (!is_default_prefix4(&ei->p)) {
struct ospf_lsa *lsa;
struct ospf_external_aggr_rt *aggr;
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 3808700ccc..d01dc720ba 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -331,7 +331,6 @@ extern void ospf_lsa_maxage_delete(struct ospf *, struct ospf_lsa *);
extern void ospf_discard_from_db(struct ospf *, struct ospf_lsdb *,
struct ospf_lsa *);
-extern int is_prefix_default(struct prefix_ipv4 *);
extern int metric_type(struct ospf *, uint8_t, unsigned short);
extern int metric_value(struct ospf *, uint8_t, unsigned short);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index b230e066c4..2cb3ec0894 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -10027,7 +10027,7 @@ DEFUN (ospf_external_route_aggregation,
str2prefix_ipv4(argv[idx]->arg, &p);
- if (is_prefix_default(&p)) {
+ if (is_default_prefix4(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
@@ -10068,7 +10068,7 @@ DEFUN (no_ospf_external_route_aggregation,
str2prefix_ipv4(argv[idx]->arg, &p);
- if (is_prefix_default(&p)) {
+ if (is_default_prefix4(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
@@ -10361,7 +10361,7 @@ DEFUN (ospf_external_route_aggregation_no_adrvertise,
str2prefix_ipv4(argv[idx]->arg, &p);
- if (is_prefix_default(&p)) {
+ if (is_default_prefix4(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
@@ -10397,7 +10397,7 @@ DEFUN (no_ospf_external_route_aggregation_no_adrvertise,
str2prefix_ipv4(argv[idx]->arg, &p);
- if (is_prefix_default(&p)) {
+ if (is_default_prefix4(&p)) {
vty_out(vty,
"Default address shouldn't be configured as summary address.\n");
return CMD_SUCCESS;
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index de33c9732d..1298a17f55 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -965,7 +965,7 @@ static int ospf_external_lsa_originate_check(struct ospf *ospf,
}
/* Take care of default-originate. */
- if (is_prefix_default(&ei->p))
+ if (is_default_prefix4(&ei->p))
if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) {
zlog_info(
"LSA[Type5:0.0.0.0]: Not originate AS-external-LSA for default");
@@ -1121,8 +1121,8 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
struct route_map_set_values save_values;
struct prefix_ipv4 *p = &ei->p;
struct ospf_redist *red;
- uint8_t type = is_prefix_default(&ei->p) ? DEFAULT_ROUTE : ei->type;
- unsigned short instance = is_prefix_default(&ei->p) ? 0 : ei->instance;
+ uint8_t type = is_default_prefix4(&ei->p) ? DEFAULT_ROUTE : ei->type;
+ unsigned short instance = is_default_prefix4(&ei->p) ? 0 : ei->instance;
route_tag_t saved_tag = 0;
/* Default is handled differently. */
@@ -1275,7 +1275,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
* originate)ZEBRA_ROUTE_MAX is used to delete the ex-info.
* Resolved this inconsistency by maintaining same route type.
*/
- if (is_prefix_default(&p))
+ if (is_default_prefix4(&p))
rt_type = DEFAULT_ROUTE;
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
@@ -1314,7 +1314,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
return 0;
}
if (ospf->router_id.s_addr != INADDR_ANY) {
- if (is_prefix_default(&p))
+ if (is_default_prefix4(&p))
ospf_external_lsa_refresh_default(ospf);
else {
struct ospf_external_aggr_rt *aggr;
@@ -1436,7 +1436,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
ospf_external_info_delete(ospf, rt_type, api.instance,
p);
- if (is_prefix_default(&p))
+ if (is_default_prefix4(&p))
ospf_external_lsa_refresh_default(ospf);
else
ospf_external_lsa_flush(ospf, rt_type, &p,
@@ -1533,7 +1533,7 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
if (!ei)
continue;
- if (is_prefix_default(&ei->p))
+ if (is_default_prefix4(&ei->p))
default_refresh = 1;
else {
struct ospf_external_aggr_rt *aggr;
diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c
index 0349618304..4c16b83948 100644
--- a/pathd/path_pcep_config.c
+++ b/pathd/path_pcep_config.c
@@ -332,6 +332,7 @@ int path_pcep_config_initiate_path(struct path *path)
candidate = srte_candidate_add(
policy, path->nbkey.preference,
SRTE_ORIGIN_PCEP, path->originator);
+ candidate->policy->srp_id = path->srp_id;
strlcpy(candidate->name, path->name,
sizeof(candidate->name));
SET_FLAG(candidate->flags, F_CANDIDATE_NEW);
@@ -387,6 +388,7 @@ int path_pcep_config_update_path(struct path *path)
if (!candidate)
return 0;
+ candidate->policy->srp_id = path->srp_id;
// first clean up old segment list if present
if (candidate->lsp->segment_list) {
SET_FLAG(candidate->lsp->segment_list->flags,
diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c
index 81a338ac63..b72a536ef4 100644
--- a/pathd/path_pcep_pcc.c
+++ b/pathd/path_pcep_pcc.c
@@ -128,6 +128,8 @@ static struct req_entry *push_new_req(struct pcc_state *pcc_state,
struct path *path);
static void repush_req(struct pcc_state *pcc_state, struct req_entry *req);
static struct req_entry *pop_req(struct pcc_state *pcc_state, uint32_t reqid);
+static struct req_entry *pop_req_no_reqid(struct pcc_state *pcc_state,
+ uint32_t reqid);
static bool add_reqid_mapping(struct pcc_state *pcc_state, struct path *path);
static void remove_reqid_mapping(struct pcc_state *pcc_state,
struct path *path);
@@ -558,7 +560,6 @@ void pcep_pcc_send_report(struct ctrl_state *ctrl_state,
if (is_stable && (real_status != PCEP_LSP_OPERATIONAL_DOWN)) {
PCEP_DEBUG("(%s)%s Send report for candidate path (!DOWN) %s",
__func__, pcc_state->tag, path->name);
- path->srp_id = 0;
path->status = real_status;
send_report(pcc_state, path);
}
@@ -1340,7 +1341,11 @@ void handle_pcep_comp_reply(struct ctrl_state *ctrl_state,
struct path *path;
path = pcep_lib_parse_path(msg);
- req = pop_req(pcc_state, path->req_id);
+ if (path->no_path) {
+ req = pop_req_no_reqid(pcc_state, path->req_id);
+ } else {
+ req = pop_req(pcc_state, path->req_id);
+ }
if (req == NULL) {
/* TODO: check the rate of bad computation reply and close
* the connection if more that a given rate.
@@ -1372,6 +1377,9 @@ void handle_pcep_comp_reply(struct ctrl_state *ctrl_state,
if (path->no_path) {
PCEP_DEBUG("%s Computation for path %s did not find any result",
pcc_state->tag, path->name);
+ free_req_entry(req);
+ pcep_free_path(path);
+ return;
} else if (validate_incoming_path(pcc_state, path, err, sizeof(err))) {
/* Updating a dynamic path will automatically delegate it */
pcep_thread_update_path(ctrl_state, pcc_state->id, path);
@@ -1847,6 +1855,20 @@ struct req_entry *pop_req(struct pcc_state *pcc_state, uint32_t reqid)
return req;
}
+struct req_entry *pop_req_no_reqid(struct pcc_state *pcc_state, uint32_t reqid)
+{
+ struct path path = {.req_id = reqid};
+ struct req_entry key = {.path = &path};
+ struct req_entry *req;
+
+ req = RB_FIND(req_entry_head, &pcc_state->requests, &key);
+ if (req == NULL)
+ return NULL;
+ RB_REMOVE(req_entry_head, &pcc_state->requests, req);
+
+ return req;
+}
+
bool add_reqid_mapping(struct pcc_state *pcc_state, struct path *path)
{
struct req_map_data *mapping;
@@ -1883,6 +1905,33 @@ uint32_t lookup_reqid(struct pcc_state *pcc_state, struct path *path)
bool has_pending_req_for(struct pcc_state *pcc_state, struct path *path)
{
+ struct req_entry key = {.path = path};
+ struct req_entry *req;
+
+
+ PCEP_DEBUG_PATH("(%s) %s", format_path(path), __func__);
+ /* Looking for request without result */
+ if (path->no_path || !path->first_hop) {
+ PCEP_DEBUG_PATH("%s Path : no_path|!first_hop", __func__);
+ /* ...and already was handle */
+ req = RB_FIND(req_entry_head, &pcc_state->requests, &key);
+ if (!req) {
+ /* we must purge remaining reqid */
+ PCEP_DEBUG_PATH("%s Purge pending reqid: no_path(%s)",
+ __func__,
+ path->no_path ? "TRUE" : "FALSE");
+ if (lookup_reqid(pcc_state, path) != 0) {
+ PCEP_DEBUG_PATH("%s Purge pending reqid: DONE ",
+ __func__);
+ remove_reqid_mapping(pcc_state, path);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+
return lookup_reqid(pcc_state, path) != 0;
}
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index e24a84d1e4..fbe4c4a1f1 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -199,8 +199,6 @@ Requires: initscripts
BuildRequires: pam-devel
%endif
%if "%{initsystem}" == "systemd"
-BuildRequires: systemd
-BuildRequires: systemd-devel
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
@@ -396,9 +394,6 @@ routing state through standard SNMP MIBs.
--disable-bgp-vnc \
%endif
--enable-isisd \
-%if "%{initsystem}" == "systemd"
- --enable-systemd \
-%endif
--enable-rpki \
%if %{with_bfdd}
--enable-bfdd \
diff --git a/staticd/static_routes.c b/staticd/static_routes.c
index cdafc4a76a..58a29ad25b 100644
--- a/staticd/static_routes.c
+++ b/staticd/static_routes.c
@@ -278,6 +278,9 @@ static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
nh->type = type;
nh->color = color;
+ if (nh->type == STATIC_BLACKHOLE)
+ nh->bh_type = STATIC_BLACKHOLE_NULL;
+
nh->nh_vrf_id = nh_svrf ? nh_svrf->vrf->vrf_id : VRF_UNKNOWN;
strlcpy(nh->nh_vrfname, nh_vrf, sizeof(nh->nh_vrfname));
@@ -325,6 +328,7 @@ static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
switch (nh->type) {
case STATIC_IPV4_GATEWAY:
case STATIC_IPV6_GATEWAY:
+ case STATIC_BLACKHOLE:
break;
case STATIC_IPV4_GATEWAY_IFNAME:
case STATIC_IPV6_GATEWAY_IFNAME:
@@ -337,9 +341,6 @@ static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
ifname);
break;
- case STATIC_BLACKHOLE:
- nh->bh_type = STATIC_BLACKHOLE_NULL;
- break;
case STATIC_IFNAME:
ifp = if_lookup_by_name(ifname, nh->nh_vrf_id);
if (ifp && ifp->ifindex != IFINDEX_INTERNAL) {
diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c
index aaf3fd2aa4..c2d39752ab 100644
--- a/tests/bgpd/test_aspath.c
+++ b/tests/bgpd/test_aspath.c
@@ -469,7 +469,10 @@ static struct aspath_tests {
0,
0,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 10,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 10,
},
COMMON_ATTR_SIZE + 3,
},
@@ -482,7 +485,10 @@ static struct aspath_tests {
-1,
0,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 8,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 8,
},
COMMON_ATTR_SIZE + 3,
},
@@ -495,7 +501,10 @@ static struct aspath_tests {
-1,
0,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 12,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 12,
},
COMMON_ATTR_SIZE + 3,
},
@@ -510,7 +519,8 @@ static struct aspath_tests {
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS_PATH, 10,
+ BGP_ATTR_AS_PATH,
+ 10,
},
COMMON_ATTR_SIZE + 3,
},
@@ -525,7 +535,8 @@ static struct aspath_tests {
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH, 10,
+ BGP_ATTR_AS4_PATH,
+ 10,
},
COMMON_ATTR_SIZE + 3,
},
@@ -540,7 +551,8 @@ static struct aspath_tests {
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH, 10,
+ BGP_ATTR_AS4_PATH,
+ 10,
},
COMMON_ATTR_SIZE + 3,
},
@@ -553,7 +565,10 @@ static struct aspath_tests {
0,
PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 18,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 18,
},
COMMON_ATTR_SIZE + 3,
},
@@ -566,7 +581,10 @@ static struct aspath_tests {
-1,
PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 16,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 16,
},
COMMON_ATTR_SIZE + 3,
},
@@ -579,7 +597,10 @@ static struct aspath_tests {
-1,
PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 20,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 20,
},
COMMON_ATTR_SIZE + 3,
},
@@ -592,7 +613,10 @@ static struct aspath_tests {
-1,
PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
{
- COMMON_ATTRS, BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH, 22,
+ COMMON_ATTRS,
+ BGP_ATTR_FLAG_TRANS,
+ BGP_ATTR_AS_PATH,
+ 22,
},
COMMON_ATTR_SIZE + 3,
},
@@ -607,7 +631,8 @@ static struct aspath_tests {
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS_PATH, 18,
+ BGP_ATTR_AS_PATH,
+ 18,
},
COMMON_ATTR_SIZE + 3,
},
@@ -622,7 +647,8 @@ static struct aspath_tests {
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH, 14,
+ BGP_ATTR_AS4_PATH,
+ 14,
},
COMMON_ATTR_SIZE + 3,
},
@@ -637,7 +663,8 @@ static struct aspath_tests {
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH, 14,
+ BGP_ATTR_AS4_PATH,
+ 14,
},
COMMON_ATTR_SIZE + 3,
&test_segments[0],
@@ -648,12 +675,13 @@ static struct aspath_tests {
&test_segments[28],
"8466 3 52737 0 4096",
AS4_DATA,
- -1,
+ -2,
PEER_CAP_AS4_RCV | PEER_CAP_AS4_ADV,
{
COMMON_ATTRS,
BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
- BGP_ATTR_AS4_PATH, 22,
+ BGP_ATTR_AS4_PATH,
+ 22,
},
COMMON_ATTR_SIZE + 3,
},
diff --git a/tests/topotests/bgp_aspath_zero/__init__.py b/tests/topotests/bgp_aspath_zero/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_aspath_zero/__init__.py
diff --git a/tests/topotests/bgp_aspath_zero/exabgp.env b/tests/topotests/bgp_aspath_zero/exabgp.env
new file mode 100644
index 0000000000..28e642360a
--- /dev/null
+++ b/tests/topotests/bgp_aspath_zero/exabgp.env
@@ -0,0 +1,53 @@
+[exabgp.api]
+encoder = text
+highres = false
+respawn = false
+socket = ''
+
+[exabgp.bgp]
+openwait = 60
+
+[exabgp.cache]
+attributes = true
+nexthops = true
+
+[exabgp.daemon]
+daemonize = true
+pid = '/var/run/exabgp/exabgp.pid'
+user = 'exabgp'
+##daemonize = false
+
+[exabgp.log]
+all = false
+configuration = true
+daemon = true
+destination = '/var/log/exabgp.log'
+enable = true
+level = INFO
+message = false
+network = true
+packets = false
+parser = false
+processes = true
+reactor = true
+rib = false
+routes = false
+short = false
+timers = false
+
+[exabgp.pdb]
+enable = false
+
+[exabgp.profile]
+enable = false
+file = ''
+
+[exabgp.reactor]
+speed = 1.0
+
+[exabgp.tcp]
+acl = false
+bind = ''
+delay = 0
+once = false
+port = 179
diff --git a/tests/topotests/bgp_aspath_zero/peer1/exabgp.cfg b/tests/topotests/bgp_aspath_zero/peer1/exabgp.cfg
new file mode 100644
index 0000000000..fe9ea01eca
--- /dev/null
+++ b/tests/topotests/bgp_aspath_zero/peer1/exabgp.cfg
@@ -0,0 +1,17 @@
+neighbor 10.0.0.1 {
+ router-id 10.0.0.2;
+ local-address 10.0.0.2;
+ local-as 65001;
+ peer-as 65534;
+
+ static {
+ route 192.168.100.101/32 {
+ next-hop 10.0.0.2;
+ }
+
+ route 192.168.100.102/32 {
+ as-path [65000 0 65001];
+ next-hop 10.0.0.2;
+ }
+ }
+}
diff --git a/tests/topotests/bgp_aspath_zero/r1/bgpd.conf b/tests/topotests/bgp_aspath_zero/r1/bgpd.conf
new file mode 100644
index 0000000000..002a5c78c0
--- /dev/null
+++ b/tests/topotests/bgp_aspath_zero/r1/bgpd.conf
@@ -0,0 +1,6 @@
+!
+router bgp 65534
+ no bgp ebgp-requires-policy
+ neighbor 10.0.0.2 remote-as external
+ neighbor 10.0.0.2 timers 3 10
+!
diff --git a/tests/topotests/bgp_aspath_zero/r1/zebra.conf b/tests/topotests/bgp_aspath_zero/r1/zebra.conf
new file mode 100644
index 0000000000..22a26ac610
--- /dev/null
+++ b/tests/topotests/bgp_aspath_zero/r1/zebra.conf
@@ -0,0 +1,6 @@
+!
+interface r1-eth0
+ ip address 10.0.0.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py b/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py
new file mode 100644
index 0000000000..903ab12a13
--- /dev/null
+++ b/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2021 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# 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 if BGP UPDATE with AS-PATH attribute with value zero (0)
+is threated as withdrawal.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+pytestmark = [pytest.mark.bgpd]
+
+
+class BgpAggregatorAsnZero(Topo):
+ def build(self, *_args, **_opts):
+ tgen = get_topogen(self)
+
+ r1 = tgen.add_router("r1")
+ peer1 = tgen.add_exabgp_peer(
+ "peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1"
+ )
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(r1)
+ switch.add_link(peer1)
+
+
+def setup_module(mod):
+ tgen = Topogen(BgpAggregatorAsnZero, mod.__name__)
+ tgen.start_topology()
+
+ router = tgen.gears["r1"]
+ router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf"))
+ router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf"))
+ router.start()
+
+ peer = tgen.gears["peer1"]
+ peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env"))
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_aggregator_zero():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ def _bgp_converge():
+ output = json.loads(
+ tgen.gears["r1"].vtysh_cmd("show ip bgp neighbor 10.0.0.2 json")
+ )
+ expected = {
+ "10.0.0.2": {
+ "bgpState": "Established",
+ "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge)
+ success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "More than one prefix seen at r1, SHOULD be only one."
+
+ def _bgp_has_correct_routes_without_asn_0():
+ output = json.loads(tgen.gears["r1"].vtysh_cmd("show ip bgp json"))
+ expected = {"routes": {"192.168.100.101/32": [{"valid": True}]}}
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_has_correct_routes_without_asn_0)
+ success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Failed listing 192.168.100.101/32, SHOULD be accepted."
+
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index 2230fd756f..9e60e523d3 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -713,20 +713,36 @@ def generate_support_bundle():
tgen = get_topogen()
router_list = tgen.routers()
- test_name = sys._getframe(2).f_code.co_name
+ test_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
+
TMPDIR = os.path.join(LOGDIR, tgen.modname)
+ bundle_procs = {}
for rname, rnode in router_list.items():
- logger.info("Generating support bundle for {}".format(rname))
+ logger.info("Spawn collection of support bundle for %s", rname)
rnode.run("mkdir -p /var/log/frr")
+ bundle_procs[rname] = tgen.net[rname].popen(
+ "/usr/lib/frr/generate_support_bundle.py",
+ stdin=None,
+ stdout=SUB_PIPE,
+ stderr=SUB_PIPE,
+ )
- # Support only python3 going forward
- bundle_log = rnode.run("env python3 /usr/lib/frr/generate_support_bundle.py")
-
- logger.info(bundle_log)
-
+ for rname, rnode in router_list.items():
dst_bundle = "{}/{}/support_bundles/{}".format(TMPDIR, rname, test_name)
src_bundle = "/var/log/frr"
+
+ output, error = bundle_procs[rname].communicate()
+
+ logger.info("Saving support bundle for %s", rname)
+ if output:
+ logger.info(
+ "Output from collecting support bundle for %s:\n%s", rname, output
+ )
+ if error:
+ logger.warning(
+ "Error from collecting support bundle for %s:\n%s", rname, error
+ )
rnode.run("rm -rf {}".format(dst_bundle))
rnode.run("mkdir -p {}".format(dst_bundle))
rnode.run("mv -f {}/* {}".format(src_bundle, dst_bundle))
diff --git a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
index e55e30270d..b880e0e462 100755
--- a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
+++ b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
@@ -526,9 +526,14 @@ def test_multicast_data_traffic_static_RP_send_traffic_then_join_p0(request):
{"dut": "r2", "src_address": source, "iif": "r2-f1-eth0", "oil": "r2-l1-eth2"},
{"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"},
]
+ # On timeout change from default of 80 to 120: failures logs indicate times 90+
+ # seconds for success on the 2nd entry in the above table. Using 100s here restores
+ # previous 80 retries with 2s wait if we assume .5s per vtysh/show ip mroute runtime
+ # (41 * (2 + .5)) == 102.
for data in input_dict:
result = verify_ip_mroutes(
- tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"]
+ tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"],
+ retry_timeout=102
)
assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
diff --git a/tools/coccinelle/xcalloc-xmalloc.cocci b/tools/coccinelle/xcalloc-xmalloc.cocci
new file mode 100644
index 0000000000..2a091d4cd9
--- /dev/null
+++ b/tools/coccinelle/xcalloc-xmalloc.cocci
@@ -0,0 +1,17 @@
+// No need checking against NULL for XMALLOC/XCALLOC.
+// If that happens, we have more problems with memory.
+
+@@
+type T;
+T *ptr;
+@@
+
+ptr =
+(
+XCALLOC(...)
+|
+XMALLOC(...)
+)
+...
+- if (ptr == NULL)
+- return ...;
diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py
index 38fdbd46df..56b2872d1e 100755
--- a/tools/generate_support_bundle.py
+++ b/tools/generate_support_bundle.py
@@ -1,117 +1,89 @@
#!/usr/bin/env python3
+#
+# Copyright (c) 2021, LabN Consulting, L.L.C.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; see the file COPYING; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
########################################################
### Python Script to generate the FRR support bundle ###
########################################################
+import argparse
+import logging
import os
import subprocess
-import datetime
-
-ETC_DIR = "/etc/frr/"
-LOG_DIR = "/var/log/frr/"
-SUCCESS = 1
-FAIL = 0
-
-inputFile = ETC_DIR + "support_bundle_commands.conf"
-
-# Create the output file name
-def createOutputFile(procName):
- fileName = procName + "_support_bundle.log"
- oldFile = LOG_DIR + fileName
- cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev"
- rmFileCmd = "rm -rf " + oldFile
- print("Making backup of " + oldFile)
- os.system(cpFileCmd)
- print("Removing " + oldFile)
- os.system(rmFileCmd)
- return fileName
-
-
-# Open the output file for this process
-def openOutputFile(fileName):
- crt_file_cmd = LOG_DIR + fileName
- print(crt_file_cmd)
- try:
- outputFile = open(crt_file_cmd, "w")
- return outputFile
- except IOError:
- return ()
-
-
-# Close the output file for this process
-def closeOutputFile(f):
- try:
- f.close()
- return SUCCESS
- except IOError:
- return FAIL
-
-
-# Execute the command over vtysh and store in the
-# output file
-def executeCommand(cmd, outputFile):
- cmd_exec_str = 'vtysh -c "' + cmd + '" '
+import tempfile
+
+def open_with_backup(path):
+ if os.path.exists(path):
+ print("Making backup of " + path)
+ subprocess.check_call("mv {0} {0}.prev".format(path))
+ return open(path, "w")
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-c", "--config", default="/etc/frr/support_bundle_commands.conf", help="input config")
+ parser.add_argument("-l", "--log-dir", default="/var/log/frr", help="directory for logfiles")
+ args = parser.parse_args()
+
+ collecting = False # file format has sentinels (seem superfluous)
+ proc_cmds = {}
+ proc = None
+ temp = None
+
+ # Collect all the commands for each daemon
try:
- cmd_output = subprocess.check_output(cmd_exec_str, shell=True)
- try:
- dateTime = datetime.datetime.now()
- outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
- outputFile.write(str(cmd_output))
- outputFile.write(
- "########################################################\n"
- )
- outputFile.write("\n")
- except Exception as e:
- print("Writing to output file Failed: ", e)
- except subprocess.CalledProcessError as e:
- dateTime = datetime.datetime.now()
- outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
- outputFile.write(e.output)
- outputFile.write("########################################################\n")
- outputFile.write("\n")
- print("Error:" + e.output)
-
-
-# Process the support bundle configuration file
-# and call appropriate functions
-def processConfFile():
-
- lines = list()
- outputFile = None
-
- try:
- with open(inputFile, "r") as supportBundleConfFile:
- for l in supportBundleConfFile:
- lines.append(l.rstrip())
- except IOError:
- print("conf file {} not present".format(inputFile))
- return
-
- for line in lines:
- if len(line) == 0 or line[0] == "#":
- continue
-
- cmd_line = line.split(":")
- if cmd_line[0] == "PROC_NAME":
- outputFileName = createOutputFile(cmd_line[1])
- if outputFileName:
- print(outputFileName, "created for", cmd_line[1])
- elif cmd_line[0] == "CMD_LIST_START":
- outputFile = openOutputFile(outputFileName)
- if outputFile:
- print(outputFileName, "opened")
- else:
- print(outputFileName, "open failed")
- return FAIL
- elif cmd_line[0] == "CMD_LIST_END":
- if closeOutputFile(outputFile):
- print(outputFileName, "closed")
+ for line in open(args.config):
+ line = line.rstrip()
+ if len(line) == 0 or line[0] == "#":
+ continue
+
+ cmd_line = line.split(":")
+ if cmd_line[0] == "PROC_NAME":
+ proc = cmd_line[1]
+ temp = tempfile.NamedTemporaryFile("w+")
+ collecting = False
+ elif cmd_line[0] == "CMD_LIST_START":
+ collecting = True
+ elif cmd_line[0] == "CMD_LIST_END":
+ collecting = False
+ temp.flush()
+ proc_cmds[proc] = open(temp.name)
+ temp.close()
+ elif collecting:
+ temp.write(line + "\n")
else:
- print(outputFileName, "close failed")
- else:
- print("Execute:", cmd_line[0])
- executeCommand(cmd_line[0], outputFile)
-
+ print("Ignoring unexpected input " + line.rstrip())
+ except IOError as error:
+ logging.fatal("Cannot read config file: %s: %s", args.config, str(error))
+ return
-# Main Function
-processConfFile()
+ # Spawn a vtysh to fetch each set of commands
+ procs = []
+ for proc in proc_cmds:
+ ofn = os.path.join(args.log_dir, proc + "_support_bundle.log")
+ p = subprocess.Popen(
+ ["/usr/bin/env", "vtysh", "-t"],
+ stdin=proc_cmds[proc],
+ stdout=open_with_backup(ofn),
+ stderr=subprocess.STDOUT,
+ )
+ procs.append(p)
+
+ for p in procs:
+ p.wait()
+
+if __name__ == "__main__":
+ main()
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 507c6ce882..dd3f448674 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -56,6 +56,9 @@ struct vty *vty;
/* VTY shell pager name. */
char *vtysh_pager_name = NULL;
+/* VTY should add timestamp */
+bool vtysh_add_timestamp;
+
/* VTY shell client structure */
struct vtysh_client {
int fd;
@@ -483,6 +486,13 @@ static int vtysh_execute_func(const char *line, int pager)
}
}
+ if (vtysh_add_timestamp && strncmp(line, "exit", 4)) {
+ char ts[48];
+
+ (void)quagga_timestamp(3, ts, sizeof(ts));
+ vty_out(vty, "%% %s\n\n", ts);
+ }
+
saved_ret = ret = cmd_execute(vty, line, &cmd, 1);
saved_node = vty->node;
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 71f672554b..e56d482da2 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -113,4 +113,6 @@ extern struct vty *vty;
extern int user_mode;
+extern bool vtysh_add_timestamp;
+
#endif /* VTYSH_H */
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 6d80cf9d96..d22ec3113f 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -560,6 +560,7 @@ static int vtysh_read_file(FILE *confp, bool dry_run)
int vtysh_read_config(const char *config_default_dir, bool dry_run)
{
FILE *confp = NULL;
+ bool save;
int ret;
confp = fopen(config_default_dir, "r");
@@ -570,9 +571,14 @@ int vtysh_read_config(const char *config_default_dir, bool dry_run)
return CMD_ERR_NO_FILE;
}
+ save = vtysh_add_timestamp;
+ vtysh_add_timestamp = false;
+
ret = vtysh_read_file(confp, dry_run);
fclose(confp);
+ vtysh_add_timestamp = save;
+
return (ret);
}
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index fe33bed7f6..20be81b901 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -201,6 +201,7 @@ struct option longopts[] = {
{"writeconfig", no_argument, NULL, 'w'},
{"pathspace", required_argument, NULL, 'N'},
{"user", no_argument, NULL, 'u'},
+ {"timestamp", no_argument, NULL, 't'},
{0}};
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
@@ -308,6 +309,7 @@ int main(int argc, char **argv, char **env)
int opt;
int dryrun = 0;
int boot_flag = 0;
+ bool ts_flag = false;
const char *daemon_name = NULL;
const char *inputfile = NULL;
struct cmd_rec {
@@ -346,7 +348,7 @@ int main(int argc, char **argv, char **env)
/* Option handling. */
while (1) {
- opt = getopt_long(argc, argv, "be:c:d:nf:H:mEhCwN:u", longopts,
+ opt = getopt_long(argc, argv, "be:c:d:nf:H:mEhCwN:ut", longopts,
0);
if (opt == EOF)
@@ -408,6 +410,9 @@ int main(int argc, char **argv, char **env)
case 'u':
user_mode = 1;
break;
+ case 't':
+ ts_flag = true;
+ break;
case 'w':
writeconfig = 1;
break;
@@ -624,6 +629,8 @@ int main(int argc, char **argv, char **env)
if (!user_mode)
vtysh_execute("enable");
+ vtysh_add_timestamp = ts_flag;
+
while (cmd != NULL) {
char *eol;
@@ -712,6 +719,8 @@ int main(int argc, char **argv, char **env)
if (!user_mode)
vtysh_execute("enable");
+ vtysh_add_timestamp = ts_flag;
+
/* Preparation for longjmp() in sigtstp(). */
sigsetjmp(jmpbuf, 1);
jmpflag = 1;
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index faf1777d7f..d0b4be81d4 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -469,12 +469,10 @@ static int run_job(struct restart_info *restart, const char *cmdtype,
return -1;
}
-#if defined HAVE_SYSTEMD
char buffer[512];
snprintf(buffer, sizeof(buffer), "restarting %s", restart->name);
systemd_send_status(buffer);
-#endif
/* Note: time_elapsed test must come before the force test, since we
need
@@ -506,9 +504,8 @@ static int run_job(struct restart_info *restart, const char *cmdtype,
restart->pid = 0;
}
-#if defined HAVE_SYSTEMD
systemd_send_status("FRR Operational");
-#endif
+
/* Calculate the new restart interval. */
if (update_interval) {
if (delay.tv_sec > 2 * gs.max_restart_interval)
@@ -718,10 +715,9 @@ static void daemon_send_ready(int exitcode)
fp = fopen(started, "w");
if (fp)
fclose(fp);
-#if defined HAVE_SYSTEMD
- systemd_send_started(master, 0);
+
+ systemd_send_started(master);
systemd_send_status("FRR Operational");
-#endif
sent = 1;
}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 51f19a3c03..b204b30ca7 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -915,6 +915,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_string_add(json_route, "prefix",
srcdest_rnode2str(rn, buf, sizeof(buf)));
+ json_object_int_add(json_route, "prefixLen", rn->p.prefixlen);
json_object_string_add(json_route, "protocol",
zebra_route_string(re->type));
@@ -1121,8 +1122,10 @@ static void vty_show_ip_route_detail_json(struct vty *vty,
prefix2str(&rn->p, buf, sizeof(buf));
json_object_object_add(json, buf, json_prefix);
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY
+ | JSON_C_TO_STRING_NOSLASHESCAPE));
json_object_free(json);
}
@@ -1234,8 +1237,11 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
}
if (use_json) {
- vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
- JSON_C_TO_STRING_PRETTY));
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json,
+ JSON_C_TO_STRING_PRETTY
+ | JSON_C_TO_STRING_NOSLASHESCAPE));
json_object_free(json);
}
}