summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dockerignore6
-rw-r--r--bfdd/bfd_packet.c11
-rw-r--r--bgpd/bgp_ecommunity.c20
-rw-r--r--bgpd/bgp_ecommunity.h4
-rw-r--r--bgpd/bgp_flowspec_util.c13
-rw-r--r--bgpd/bgp_flowspec_vty.c3
-rw-r--r--bgpd/bgp_mplsvpn.c2
-rw-r--r--bgpd/bgp_pbr.c54
-rw-r--r--bgpd/bgp_rpki.c2
-rw-r--r--isisd/isis_main.c1
-rw-r--r--isisd/isis_pdu.c6
-rw-r--r--isisd/isis_tlvs.c9
-rw-r--r--ldpd/ldpd.c1
-rw-r--r--lib/command.c18
-rw-r--r--lib/command_py.c8
-rw-r--r--lib/northbound_cli.c30
-rw-r--r--lib/vty.c54
-rw-r--r--lib/vty.h12
-rw-r--r--ospfd/ospf_packet.c2
-rw-r--r--pbrd/pbr_nht.c8
-rw-r--r--pbrd/pbr_zebra.c5
-rw-r--r--python/clidef.py10
-rw-r--r--ripd/rip_main.c2
-rw-r--r--sharpd/sharp_zebra.c4
-rw-r--r--tests/topotests/Dockerfile2
-rw-r--r--tests/topotests/README.md10
-rw-r--r--tests/topotests/docker/README.md39
-rwxr-xr-xtests/topotests/docker/build.sh3
-rwxr-xr-xtests/topotests/docker/inner/entrypoint.sh5
-rw-r--r--zebra/main.c1
30 files changed, 204 insertions, 141 deletions
diff --git a/.dockerignore b/.dockerignore
index 6b8710a711..f2fc34583d 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1 +1,7 @@
.git
+**/*.a
+**/*.o
+**/*.la
+**/*.lo
+**/*.so
+**/.libs
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 1ba5ee826f..606f739b46 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -304,6 +304,9 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
local->sa_sin.sin_family = AF_INET;
local->sa_sin.sin_addr = pi->ipi_addr;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ local->sa_sin.sin_len = sizeof(local->sa_sin);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
fetch_portname_from_ifindex(pi->ipi_ifindex, port,
portlen);
break;
@@ -321,6 +324,9 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
memcpy(&ia, CMSG_DATA(cm), sizeof(ia));
local->sa_sin.sin_family = AF_INET;
local->sa_sin.sin_addr = ia;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ local->sa_sin.sin_len = sizeof(local->sa_sin);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break;
}
#endif /* BFD_BSD */
@@ -402,8 +408,11 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
} else if (cm->cmsg_type == IPV6_PKTINFO) {
pi6 = (struct in6_pktinfo *)CMSG_DATA(cm);
if (pi6) {
- local->sa_sin.sin_family = AF_INET6;
+ local->sa_sin6.sin6_family = AF_INET6;
local->sa_sin6.sin6_addr = pi6->ipi6_addr;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ local->sa_sin6.sin6_len = sizeof(local->sa_sin6);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
fetch_portname_from_ifindex(pi6->ipi6_ifindex,
port, portlen);
ifindex = pi6->ipi6_ifindex;
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 8029164184..ed0900a721 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -688,9 +688,23 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
/* Low-order octet of type. */
sub_type = *pnt++;
if (sub_type != ECOMMUNITY_ROUTE_TARGET
- && sub_type != ECOMMUNITY_SITE_ORIGIN)
- unk_ecom = 1;
- else
+ && sub_type != ECOMMUNITY_SITE_ORIGIN) {
+ if (sub_type ==
+ ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4 &&
+ type == ECOMMUNITY_ENCODE_IP) {
+ struct in_addr *ipv4 =
+ (struct in_addr *)pnt;
+ char ipv4str[INET_ADDRSTRLEN];
+
+ inet_ntop(AF_INET, ipv4,
+ ipv4str,
+ INET_ADDRSTRLEN);
+ len = sprintf(str_buf + str_pnt,
+ "NH:%s:%d",
+ ipv4str, pnt[5]);
+ } else
+ unk_ecom = 1;
+ } else
len = ecommunity_rt_soo_str(str_buf + str_pnt,
pnt, type, sub_type,
format);
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index d43403ed8d..519991da5a 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -41,6 +41,10 @@
#define ECOMMUNITY_REDIRECT_VRF 0x08
#define ECOMMUNITY_TRAFFIC_MARKING 0x09
#define ECOMMUNITY_REDIRECT_IP_NH 0x00
+/* from IANA: bgp-extended-communities/bgp-extended-communities.xhtml
+ * 0x0c Flow-spec Redirect to IPv4 - draft-ietf-idr-flowspec-redirect
+ */
+#define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4 0x0c
/* Low-order octet of the Extended Communities type field for EVPN types */
#define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY 0x00
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index cb71a64a85..c6386dcdb5 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -449,8 +449,17 @@ int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
flog_err(EC_BGP_FLOWSPEC_PACKET,
"%s: flowspec_ip_address error %d",
__func__, error);
- else
- bpem->match_bitmask |= bitmask;
+ else {
+ /* if src or dst address is 0.0.0.0,
+ * ignore that rule
+ */
+ if (prefix->family == AF_INET
+ && prefix->u.prefix4.s_addr == 0)
+ memset(prefix, 0,
+ sizeof(struct prefix));
+ else
+ bpem->match_bitmask |= bitmask;
+ }
offset += ret;
break;
case FLOWSPEC_IP_PROTOCOL:
diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c
index 4fb055bcc3..9c230d1126 100644
--- a/bgpd/bgp_flowspec_vty.c
+++ b/bgpd/bgp_flowspec_vty.c
@@ -315,7 +315,8 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
}
if (attr->nexthop.s_addr != 0 &&
display == NLRI_STRING_FORMAT_LARGE)
- vty_out(vty, "\tNH %-16s\n", inet_ntoa(attr->nexthop));
+ vty_out(vty, "\tNLRI NH %-16s\n",
+ inet_ntoa(attr->nexthop));
XFREE(MTYPE_ECOMMUNITY_STR, s);
}
peer_uptime(path->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL);
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 6668823d64..baf2c1e029 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -578,7 +578,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
return bpi;
}
- new = info_make(bpi_ultimate->type, bpi_ultimate->sub_type, 0,
+ new = info_make(bpi_ultimate->type, BGP_ROUTE_IMPORTED, 0,
bgp->peer_self, new_attr, bn);
if (nexthop_self_flag)
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 4e050df3e5..f0a0e615e6 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -638,6 +638,7 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
struct prefix *src = NULL, *dst = NULL;
int valid_prefix = 0;
afi_t afi = AFI_IP;
+ struct bgp_pbr_entry_action *api_action_redirect_ip = NULL;
/* extract match from flowspec entries */
ret = bgp_flowspec_match_rules_fill((uint8_t *)p->u.prefix_flowspec.ptr,
@@ -688,10 +689,55 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
(char)ECOMMUNITY_ENCODE_REDIRECT_IP_NH) &&
(ecom_eval->val[1] ==
(char)ECOMMUNITY_REDIRECT_IP_NH)) {
- api_action->action = ACTION_REDIRECT_IP;
- api_action->u.zr.redirect_ip_v4.s_addr =
- path->attr->nexthop.s_addr;
- api_action->u.zr.duplicate = ecom_eval->val[7];
+ /* in case the 2 ecom present,
+ * do not overwrite
+ * draft-ietf-idr-flowspec-redirect
+ */
+ if (api_action_redirect_ip) {
+ if (api_action_redirect_ip->u
+ .zr.redirect_ip_v4.s_addr)
+ continue;
+ if (!path->attr->nexthop.s_addr)
+ continue;
+ api_action_redirect_ip->u
+ .zr.redirect_ip_v4.s_addr =
+ path->attr->nexthop.s_addr;
+ api_action_redirect_ip->u.zr.duplicate
+ = ecom_eval->val[7];
+ continue;
+ } else {
+ api_action->action = ACTION_REDIRECT_IP;
+ api_action->u.zr.redirect_ip_v4.s_addr =
+ path->attr->nexthop.s_addr;
+ api_action->u.zr.duplicate =
+ ecom_eval->val[7];
+ api_action_redirect_ip = api_action;
+ }
+ } else if ((ecom_eval->val[0] ==
+ (char)ECOMMUNITY_ENCODE_IP) &&
+ (ecom_eval->val[1] ==
+ (char)ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4)) {
+ /* in case the 2 ecom present,
+ * overwrite simpson draft
+ * update redirect ip fields
+ */
+ if (api_action_redirect_ip) {
+ memcpy(&(api_action_redirect_ip->u
+ .zr.redirect_ip_v4.s_addr),
+ (ecom_eval->val+2), 4);
+ api_action_redirect_ip->u
+ .zr.duplicate =
+ ecom_eval->val[7];
+ continue;
+ } else {
+ api_action->action = ACTION_REDIRECT_IP;
+ memcpy(&(api_action->u
+ .zr.redirect_ip_v4.s_addr),
+ (ecom_eval->val+2), 4);
+ api_action->u.zr.duplicate =
+ ecom_eval->val[7];
+ api_action_redirect_ip = api_action;
+ }
} else {
if (ecom_eval->val[0] !=
(char)ECOMMUNITY_ENCODE_TRANS_EXP)
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 77bd2eaefa..c5d38f3009 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -1282,7 +1282,7 @@ DEFUN_NOSH (rpki_end,
{
int ret = reset(false);
- vty_config_unlock(vty);
+ vty_config_exit(vty);
vty->node = ENABLE_NODE;
return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
}
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index c325a3d6fe..2d540348e4 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -203,7 +203,6 @@ int main(int argc, char **argv, char **envp)
}
}
- vty_config_lockless();
/* thread master */
master = frr_init();
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 7df152f1fa..2f18b98d3f 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -747,7 +747,7 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
stream_get_endp(circuit->rcv_stream));
}
- struct isis_lsp_hdr hdr = {0};
+ struct isis_lsp_hdr hdr = {};
hdr.pdu_len = stream_getw(circuit->rcv_stream);
hdr.rem_lifetime = stream_getw(circuit->rcv_stream);
@@ -1126,8 +1126,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
stream_get(rem_sys_id, circuit->rcv_stream, ISIS_SYS_ID_LEN);
stream_forward_getp(circuit->rcv_stream, 1); /* Circuit ID - unused */
- uint8_t start_lsp_id[ISIS_SYS_ID_LEN + 2] = {0};
- uint8_t stop_lsp_id[ISIS_SYS_ID_LEN + 2] = {0};
+ uint8_t start_lsp_id[ISIS_SYS_ID_LEN + 2] = {};
+ uint8_t stop_lsp_id[ISIS_SYS_ID_LEN + 2] = {};
if (is_csnp) {
stream_get(start_lsp_id, circuit->rcv_stream,
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 5e73baa841..87d8273350 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -171,7 +171,8 @@ static int unpack_item_prefix_sid(uint16_t mtid, uint8_t len, struct stream *s,
struct sbuf *log, void *dest, int indent)
{
struct isis_subtlvs *subtlvs = dest;
- struct isis_prefix_sid sid = {0};
+ struct isis_prefix_sid sid = {
+ };
sbuf_push(log, indent, "Unpacking SR Prefix-SID...\n");
@@ -2051,7 +2052,7 @@ static int unpack_tlv_purge_originator(enum isis_tlv_context context,
void *dest, int indent)
{
struct isis_tlvs *tlvs = dest;
- struct isis_purge_originator poi = {0};
+ struct isis_purge_originator poi = {};
sbuf_push(log, indent, "Unpacking Purge Originator Identification TLV...\n");
if (tlv_len < 7) {
@@ -3130,7 +3131,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
[ISIS_TLV_IPV6_REACH] = &tlv_ipv6_reach_ops,
[ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops,
},
- [ISIS_CONTEXT_SUBTLV_NE_REACH] = {0},
+ [ISIS_CONTEXT_SUBTLV_NE_REACH] = {},
[ISIS_CONTEXT_SUBTLV_IP_REACH] = {
[ISIS_SUBTLV_PREFIX_SID] = &tlv_prefix_sid_ops,
},
@@ -3396,7 +3397,7 @@ static void tlvs_protocols_supported_to_adj(struct isis_tlvs *tlvs,
ipv6_supported = true;
}
- struct nlpids reduced = {0};
+ struct nlpids reduced = {};
if (ipv4_supported && ipv6_supported) {
reduced.count = 2;
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index 1280567f83..771d3b7459 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -335,7 +335,6 @@ main(int argc, char *argv[])
master = frr_init();
- vty_config_lockless();
vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init();
ldp_vty_init();
diff --git a/lib/command.c b/lib/command.c
index a01aabcc2a..d1dafa3a1a 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -1391,19 +1391,7 @@ DEFUN (config_terminal,
"Configuration from vty interface\n"
"Configuration terminal\n")
{
- if (vty_config_lock(vty))
- vty->node = CONFIG_NODE;
- else {
- vty_out(vty, "VTY configuration is locked by other VTY\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vty->private_config = false;
- vty->candidate_config = vty_shared_candidate_config;
- if (frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL)
- vty->candidate_config_base = nb_config_dup(running_config);
-
- return CMD_SUCCESS;
+ return vty_config_enter(vty, false, false);
}
/* Enable command */
@@ -1455,7 +1443,7 @@ void cmd_exit(struct vty *vty)
break;
case CONFIG_NODE:
vty->node = ENABLE_NODE;
- vty_config_unlock(vty);
+ vty_config_exit(vty);
break;
case INTERFACE_NODE:
case PW_NODE:
@@ -1599,7 +1587,7 @@ DEFUN (config_end,
case LINK_PARAMS_NODE:
case BFD_NODE:
case BFD_PEER_NODE:
- vty_config_unlock(vty);
+ vty_config_exit(vty);
vty->node = ENABLE_NODE;
break;
default:
diff --git a/lib/command_py.c b/lib/command_py.c
index ca0c8be79d..58b7982665 100644
--- a/lib/command_py.c
+++ b/lib/command_py.c
@@ -92,7 +92,7 @@ static PyMemberDef members_graph_node[] = {
member(deprecated, T_BOOL), member(hidden, T_BOOL),
member(text, T_STRING), member(desc, T_STRING),
member(min, T_LONGLONG), member(max, T_LONGLONG),
- member(varname, T_STRING), {0},
+ member(varname, T_STRING), {},
};
#undef member
@@ -137,7 +137,7 @@ static PyObject *graph_node_join(PyObject *self, PyObject *args)
static PyMethodDef methods_graph_node[] = {
{"next", graph_node_next, METH_NOARGS, "outbound graph edge list"},
{"join", graph_node_join, METH_NOARGS, "outbound join node"},
- {0}};
+ {}};
static void graph_node_wrap_free(void *arg)
{
@@ -228,7 +228,7 @@ static PyObject *graph_to_pyobj(struct wrap_graph *wgraph,
}
static PyMemberDef members_graph[] = {
member(definition, T_STRING),
- {0},
+ {},
};
#undef member
@@ -242,7 +242,7 @@ static PyObject *graph_first(PyObject *self, PyObject *args)
static PyMethodDef methods_graph[] = {
{"first", graph_first, METH_NOARGS, "first graph node"},
- {0}};
+ {}};
static PyObject *graph_parse(PyTypeObject *type, PyObject *args,
PyObject *kwds);
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index a3006264f1..2cacc6b1dc 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -519,20 +519,7 @@ DEFUN (config_exclusive,
"Configuration from vty interface\n"
"Configure exclusively from this terminal\n")
{
- if (vty_config_exclusive_lock(vty))
- vty->node = CONFIG_NODE;
- else {
- vty_out(vty, "VTY configuration is locked by other VTY\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vty->private_config = true;
- vty->candidate_config = nb_config_dup(running_config);
- vty->candidate_config_base = nb_config_dup(running_config);
- vty_out(vty,
- "Warning: uncommitted changes will be discarded on exit.\n\n");
-
- return CMD_SUCCESS;
+ return vty_config_enter(vty, true, true);
}
/* Configure using a private candidate configuration. */
@@ -542,20 +529,7 @@ DEFUN (config_private,
"Configuration from vty interface\n"
"Configure using a private candidate configuration\n")
{
- if (vty_config_lock(vty))
- vty->node = CONFIG_NODE;
- else {
- vty_out(vty, "VTY configuration is locked by other VTY\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vty->private_config = true;
- vty->candidate_config = nb_config_dup(running_config);
- vty->candidate_config_base = nb_config_dup(running_config);
- vty_out(vty,
- "Warning: uncommitted changes will be discarded on exit.\n\n");
-
- return CMD_SUCCESS;
+ return vty_config_enter(vty, true, false);
}
DEFPY (config_commit,
diff --git a/lib/vty.c b/lib/vty.c
index 811c23c218..9908ada7f0 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -86,10 +86,6 @@ static vector Vvty_serv_thread;
/* Current directory. */
char *vty_cwd = NULL;
-/* Configure lock. */
-static int vty_config;
-static int vty_config_is_lockless = 0;
-
/* Exclusive configuration lock. */
struct vty *vty_exclusive_lock;
@@ -824,7 +820,7 @@ static void vty_end_config(struct vty *vty)
case BGP_EVPN_VNI_NODE:
case BFD_NODE:
case BFD_PEER_NODE:
- vty_config_unlock(vty);
+ vty_config_exit(vty);
vty->node = ENABLE_NODE;
break;
default:
@@ -1225,7 +1221,7 @@ static void vty_stop_input(struct vty *vty)
case VTY_NODE:
case BFD_NODE:
case BFD_PEER_NODE:
- vty_config_unlock(vty);
+ vty_config_exit(vty);
vty->node = ENABLE_NODE;
break;
default:
@@ -2351,7 +2347,7 @@ void vty_close(struct vty *vty)
}
/* Check configure. */
- vty_config_unlock(vty);
+ vty_config_exit(vty);
/* OK free vty. */
XFREE(MTYPE_VTY, vty);
@@ -2690,18 +2686,33 @@ void vty_log_fixed(char *buf, size_t len)
}
}
-int vty_config_lock(struct vty *vty)
+int vty_config_enter(struct vty *vty, bool private_config, bool exclusive)
{
- if (vty_config_is_lockless)
- return 1;
- if (vty_config == 0) {
- vty->config = 1;
- vty_config = 1;
+ if (exclusive && !vty_config_exclusive_lock(vty)) {
+ vty_out(vty, "VTY configuration is locked by other VTY\n");
+ return CMD_WARNING;
+ }
+
+ vty->node = CONFIG_NODE;
+ vty->config = true;
+ vty->private_config = private_config;
+
+ if (private_config) {
+ vty->candidate_config = nb_config_dup(running_config);
+ vty->candidate_config_base = nb_config_dup(running_config);
+ vty_out(vty,
+ "Warning: uncommitted changes will be discarded on exit.\n\n");
+ } else {
+ vty->candidate_config = vty_shared_candidate_config;
+ if (frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL)
+ vty->candidate_config_base =
+ nb_config_dup(running_config);
}
- return vty->config;
+
+ return CMD_SUCCESS;
}
-int vty_config_unlock(struct vty *vty)
+void vty_config_exit(struct vty *vty)
{
vty_config_exclusive_unlock(vty);
@@ -2714,19 +2725,6 @@ int vty_config_unlock(struct vty *vty)
nb_config_free(vty->candidate_config_base);
vty->candidate_config_base = NULL;
}
-
- if (vty_config_is_lockless)
- return 0;
- if (vty_config == 1 && vty->config == 1) {
- vty->config = 0;
- vty_config = 0;
- }
- return vty->config;
-}
-
-void vty_config_lockless(void)
-{
- vty_config_is_lockless = 1;
}
int vty_config_exclusive_lock(struct vty *vty)
diff --git a/lib/vty.h b/lib/vty.h
index 5cc077523f..ae6c4bae96 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -114,6 +114,9 @@ struct vty {
int xpath_index;
char xpath[VTY_MAXDEPTH][XPATH_MAXLEN];
+ /* In configure mode. */
+ bool config;
+
/* Private candidate configuration mode. */
bool private_config;
@@ -161,9 +164,6 @@ struct vty {
/* Terminal monitor. */
int monitor;
- /* In configure mode. */
- int config;
-
/* Read and write thread. */
struct thread *t_read;
struct thread *t_write;
@@ -311,9 +311,9 @@ extern void vty_close(struct vty *);
extern char *vty_get_cwd(void);
extern void vty_log(const char *level, const char *proto, const char *fmt,
struct timestamp_control *, va_list);
-extern int vty_config_lock(struct vty *);
-extern int vty_config_unlock(struct vty *);
-extern void vty_config_lockless(void);
+extern int vty_config_enter(struct vty *vty, bool private_config,
+ bool exclusive);
+extern void vty_config_exit(struct vty *);
extern int vty_config_exclusive_lock(struct vty *vty);
extern void vty_config_exclusive_unlock(struct vty *vty);
extern int vty_shell(struct vty *);
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 27a94f2310..3bb3b79a6a 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -655,7 +655,7 @@ static int ospf_write(struct thread *thread)
int pkt_count = 0;
#ifdef GNU_LINUX
- unsigned char cmsgbuf[64] = {0};
+ unsigned char cmsgbuf[64] = {};
struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
struct in_pktinfo *pi;
#endif
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index db958e833f..6103bd7db5 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -232,9 +232,9 @@ void pbr_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
const struct nexthop *nhop)
{
char debugstr[256];
- struct pbr_nexthop_group_cache pnhgc_find = {0};
+ struct pbr_nexthop_group_cache pnhgc_find = {};
struct pbr_nexthop_group_cache *pnhgc;
- struct pbr_nexthop_cache pnhc_find = {0};
+ struct pbr_nexthop_cache pnhc_find = {};
struct pbr_nexthop_cache *pnhc;
if (!pbr_nht_get_next_tableid(true)) {
@@ -270,9 +270,9 @@ void pbr_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
const struct nexthop *nhop)
{
char debugstr[256];
- struct pbr_nexthop_group_cache pnhgc_find = {0};
+ struct pbr_nexthop_group_cache pnhgc_find = {};
struct pbr_nexthop_group_cache *pnhgc;
- struct pbr_nexthop_cache pnhc_find = {0};
+ struct pbr_nexthop_cache pnhc_find = {};
struct pbr_nexthop_cache *pnhc;
enum nexthop_types_t nh_afi = nhop->type;
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 9db3edacb9..7974bbfb4e 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -361,7 +361,10 @@ static int pbr_zebra_nexthop_update(int command, struct zclient *zclient,
char buf[PREFIX2STR_BUFFER];
uint32_t i;
- zapi_nexthop_update_decode(zclient->ibuf, &nhr);
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ zlog_warn("Failure to decode Nexthop update message");
+ return 0;
+ }
if (DEBUG_MODE_CHECK(&pbr_dbg_zebra, DEBUG_MODE_ALL)) {
diff --git a/python/clidef.py b/python/clidef.py
index b6eb490b67..a140ce3d54 100644
--- a/python/clidef.py
+++ b/python/clidef.py
@@ -67,19 +67,19 @@ class PrefixBase(RenderHandler):
deref = '&'
class Prefix4Handler(PrefixBase):
argtype = 'const struct prefix_ipv4 *'
- decl = Template('struct prefix_ipv4 $varname = {0};')
+ decl = Template('struct prefix_ipv4 $varname = { };')
code = Template('_fail = !str2prefix_ipv4(argv[_i]->arg, &$varname);')
class Prefix6Handler(PrefixBase):
argtype = 'const struct prefix_ipv6 *'
- decl = Template('struct prefix_ipv6 $varname = {0};')
+ decl = Template('struct prefix_ipv6 $varname = { };')
code = Template('_fail = !str2prefix_ipv6(argv[_i]->arg, &$varname);')
class PrefixEthHandler(PrefixBase):
argtype = 'struct prefix_eth *'
- decl = Template('struct prefix_eth $varname = {0};')
+ decl = Template('struct prefix_eth $varname = { };')
code = Template('_fail = !str2prefix_eth(argv[_i]->arg, &$varname);')
class PrefixGenHandler(PrefixBase):
argtype = 'const struct prefix *'
- decl = Template('struct prefix $varname = {0};')
+ decl = Template('struct prefix $varname = { };')
code = Template('_fail = !str2prefix(argv[_i]->arg, &$varname);')
# same for IP addresses. result is union sockunion.
@@ -96,7 +96,7 @@ class IP4Handler(IPBase):
code = Template('_fail = !inet_aton(argv[_i]->arg, &$varname);')
class IP6Handler(IPBase):
argtype = 'struct in6_addr'
- decl = Template('struct in6_addr $varname = {0};')
+ decl = Template('struct in6_addr $varname = {};')
code = Template('_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);')
class IPGenHandler(IPBase):
argtype = 'const union sockunion *'
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index 4ee5994a9d..5db9c4b7e9 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -165,8 +165,6 @@ int main(int argc, char **argv)
}
}
- vty_config_lockless();
-
/* Prepare master thread. */
master = frr_init();
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 12bab73c5e..f752009eb8 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -223,7 +223,9 @@ void sharp_zebra_nexthop_watch(struct prefix *p, bool watch)
if (!watch)
command = ZEBRA_NEXTHOP_UNREGISTER;
- zclient_send_rnh(zclient, command, p, true, VRF_DEFAULT);
+ if (zclient_send_rnh(zclient, command, p, true, VRF_DEFAULT) < 0)
+ zlog_warn("%s: Failure to send nexthop to zebra",
+ __PRETTY_FUNCTION__);
}
static int sharp_nexthop_update(int command, struct zclient *zclient,
diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile
index 72a876ed83..3613e23a6e 100644
--- a/tests/topotests/Dockerfile
+++ b/tests/topotests/Dockerfile
@@ -70,7 +70,7 @@ RUN echo "" >> /etc/security/limits.conf; \
echo "root hard core unlimited" >> /etc/security/limits.conf
# Copy run scripts to facilitate users wanting to run the tests
-COPY docker/inner /opt/topotests
+COPY tests/topotests/docker/inner /opt/topotests
WORKDIR /root/topotests
ENV PATH "$PATH:/opt/topotests"
diff --git a/tests/topotests/README.md b/tests/topotests/README.md
index 3f1323c218..a495675ee9 100644
--- a/tests/topotests/README.md
+++ b/tests/topotests/README.md
@@ -1,5 +1,10 @@
# FRRouting Topology Tests with Mininet
+## Running tests with docker
+
+There is a docker image which allows to run topotests. Instructions can be
+found [here](docker/README.md).
+
## Guidelines
Instructions for use, write or debug topologies can be found in the
@@ -11,11 +16,6 @@ that does what you need. If nothing is similar, then you may create a
new topology, preferably, using the newest
[template](example-test/test_template.py).
-## Running tests with docker
-
-There is a docker image which allows to run topotests. Instructions can be
-found [here](docker/README.md).
-
## Installation of Mininet for running tests
Only tested with Ubuntu 16.04 and Ubuntu 18.04 (which uses Mininet 2.2.x)
diff --git a/tests/topotests/docker/README.md b/tests/topotests/docker/README.md
index 918594e6a3..cdc41fad52 100644
--- a/tests/topotests/docker/README.md
+++ b/tests/topotests/docker/README.md
@@ -3,34 +3,43 @@
## Quickstart
If you have Docker installed, you can run the topotests in Docker.
-The easiest way to do this, is to use the `frr-topotests.sh` script
-from this repository:
+The easiest way to do this, is to use the make targets from this
+repository.
+
+Your current user needs to have access to the Docker daemon. Alternatively
+you can run these commands as root.
```console
-wget -O /usr/local/bin/frr-topotests \
- https://raw.githubusercontent.com/frrouting/topotests/master/docker/frr-topotests.sh
-chmod +x /usr/local/bin/frr-topotests
+make topotests-build
+make topotests
```
-Once this script is in place, simply run it while you are inside your FRR repository:
+The first command will build a docker image with all the dependencies needed
+to run the topotests.
-```console
-frr-topotests
-```
+The second command will spawn an instance of this image, compile FRR inside
+of it, and run the topotests.
## Advanced Usage
-There are several environtment variables which can be used to modify the behavior of
-the image. Those can be listed using `frr-topotests -h`.
+Internally, the topotests make target uses a shell script to spawn the docker
+container.
+
+There are several environment variables which can be used to modify the behavior
+of the script, these can be listed by calling it with `-h`:
+
+```console
+./tests/topotests/docker/frr-topotests.sh -h
+```
For example, a volume is used to cache build artifacts between multiple runs
of the image. If you need to force a complete recompile, you can set `TOPOTEST_CLEAN`:
```console
-TOPOTEST_CLEAN=1 frr-topotests
+TOPOTEST_CLEAN=1 ./tests/topotests/docker/frr-topotests.sh
```
-By default, `frr-topotests` will build frr and run pytest. If you append
+By default, `frr-topotests.sh` will build frr and run pytest. If you append
arguments and the first one starts with `/` or `./`, they will replace the call to
pytest. If the appended arguments do not match this patttern, they will be provided to
pytest as arguments.
@@ -38,11 +47,11 @@ pytest as arguments.
So, to run a specific test with more verbose logging:
```console
-frr-topotests -vv -s all-protocol-startup/test_all_protocol_startup.py
+./tests/topotests/docker/frr-topotests.sh -vv -s all-protocol-startup/test_all_protocol_startup.py
```
And to compile FRR but drop into a shell instead of running pytest:
```console
-frr-topotests /bin/bash
+./tests/topotests/docker/frr-topotests.sh /bin/bash
```
diff --git a/tests/topotests/docker/build.sh b/tests/topotests/docker/build.sh
index 344fb2ffcb..3bb6dbaad8 100755
--- a/tests/topotests/docker/build.sh
+++ b/tests/topotests/docker/build.sh
@@ -22,9 +22,10 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-cd "$(dirname "$0")"/..
+cd "$(dirname "$0")"/../../..
exec docker build --pull \
--compress \
-t frrouting/frr:topotests-latest \
+ -f tests/topotests/Dockerfile \
.
diff --git a/tests/topotests/docker/inner/entrypoint.sh b/tests/topotests/docker/inner/entrypoint.sh
index f491d15f79..3050ec86d0 100755
--- a/tests/topotests/docker/inner/entrypoint.sh
+++ b/tests/topotests/docker/inner/entrypoint.sh
@@ -40,7 +40,10 @@ chmod 1777 /tmp
if [ $# -eq 0 ] || ([[ "$1" != /* ]] && [[ "$1" != ./* ]]); then
export TOPOTESTS_CHECK_MEMLEAK=/tmp/memleak_
export TOPOTESTS_CHECK_STDERR=Yes
- set -- pytest --junitxml /tmp/topotests.xml "$@"
+ set -- pytest \
+ --junitxml /tmp/topotests.xml \
+ -o cache_dir=/tmp \
+ "$@"
fi
exec "$@"
diff --git a/zebra/main.c b/zebra/main.c
index 5b5ee8259a..0f1e14821b 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -390,7 +390,6 @@ int main(int argc, char **argv)
}
}
- vty_config_lockless();
zebrad.master = frr_init();
/* Initialize pthread library */