diff options
| -rw-r--r-- | .dockerignore | 6 | ||||
| -rw-r--r-- | bfdd/bfd_packet.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_ecommunity.c | 20 | ||||
| -rw-r--r-- | bgpd/bgp_ecommunity.h | 4 | ||||
| -rw-r--r-- | bgpd/bgp_flowspec_util.c | 13 | ||||
| -rw-r--r-- | bgpd/bgp_flowspec_vty.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_pbr.c | 54 | ||||
| -rw-r--r-- | bgpd/bgp_rpki.c | 2 | ||||
| -rw-r--r-- | isisd/isis_main.c | 1 | ||||
| -rw-r--r-- | isisd/isis_pdu.c | 6 | ||||
| -rw-r--r-- | isisd/isis_tlvs.c | 9 | ||||
| -rw-r--r-- | ldpd/ldpd.c | 1 | ||||
| -rw-r--r-- | lib/command.c | 18 | ||||
| -rw-r--r-- | lib/command_py.c | 8 | ||||
| -rw-r--r-- | lib/northbound_cli.c | 30 | ||||
| -rw-r--r-- | lib/vty.c | 54 | ||||
| -rw-r--r-- | lib/vty.h | 12 | ||||
| -rw-r--r-- | ospfd/ospf_packet.c | 2 | ||||
| -rw-r--r-- | pbrd/pbr_nht.c | 8 | ||||
| -rw-r--r-- | pbrd/pbr_zebra.c | 5 | ||||
| -rw-r--r-- | python/clidef.py | 10 | ||||
| -rw-r--r-- | ripd/rip_main.c | 2 | ||||
| -rw-r--r-- | sharpd/sharp_zebra.c | 4 | ||||
| -rw-r--r-- | tests/topotests/Dockerfile | 2 | ||||
| -rw-r--r-- | tests/topotests/README.md | 10 | ||||
| -rw-r--r-- | tests/topotests/docker/README.md | 39 | ||||
| -rwxr-xr-x | tests/topotests/docker/build.sh | 3 | ||||
| -rwxr-xr-x | tests/topotests/docker/inner/entrypoint.sh | 5 | ||||
| -rw-r--r-- | zebra/main.c | 1 |
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, @@ -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) @@ -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 */ |
