From de91006803f823a149b04738dd2bbfe18bfe9791 Mon Sep 17 00:00:00 2001 From: Dave Wallace Date: Tue, 20 Mar 2018 09:22:13 -0400 Subject: VCL: add IPv6 to socket_test.sh and make test Change-Id: If3827828062a46f1cce43642535333f677f06e62 Signed-off-by: Dave Wallace --- src/vcl/sock_test.h | 2 + src/vcl/sock_test_client.c | 77 +++++++++++++++++++++++------ src/vcl/sock_test_server.c | 120 +++++++++++++++++++++++++++++++++++++++------ src/vcl/vppcom.c | 30 +++++++----- src/vnet/ip/ip.c | 6 ++- 5 files changed, 192 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/vcl/sock_test.h b/src/vcl/sock_test.h index 0729c310f50..f9f5c7070b2 100644 --- a/src/vcl/sock_test.h +++ b/src/vcl/sock_test.h @@ -69,6 +69,8 @@ typedef struct __attribute__ ((packed)) uint32_t ctrl_handle; uint32_t num_test_sockets; uint32_t verbose; + uint32_t address_ip6; + uint32_t transport_udp; uint64_t rxbuf_size; uint64_t txbuf_size; uint64_t num_writes; diff --git a/src/vcl/sock_test_client.c b/src/vcl/sock_test_client.c index 7a735f5f3c0..3559c68562f 100644 --- a/src/vcl/sock_test_client.c +++ b/src/vcl/sock_test_client.c @@ -35,7 +35,8 @@ typedef struct int af_unix_echo_tx; int af_unix_echo_rx; #endif - struct sockaddr_in server_addr; + struct sockaddr_storage server_addr; + uint32_t server_addr_size; sock_test_socket_t ctrl_socket; sock_test_socket_t *test_socket; uint32_t num_test_sockets; @@ -605,15 +606,19 @@ sock_test_connect_test_sockets (uint32_t num_test_sockets) { tsock = &scm->test_socket[i]; #ifdef VCL_TEST - tsock->fd = - vppcom_session_create (VPPCOM_PROTO_TCP, 1 /* is_nonblocking */ ); + tsock->fd = vppcom_session_create (ctrl->cfg.transport_udp ? + VPPCOM_PROTO_UDP : + VPPCOM_PROTO_TCP, + 1 /* is_nonblocking */ ); if (tsock->fd < 0) { errno = -tsock->fd; tsock->fd = -1; } #else - tsock->fd = socket (AF_INET, SOCK_STREAM, 0); + tsock->fd = socket (ctrl->cfg.address_ip6 ? AF_INET6 : AF_INET, + ctrl->cfg.transport_udp ? + SOCK_DGRAM : SOCK_STREAM, 0); #endif if (tsock->fd < 0) { @@ -634,7 +639,7 @@ sock_test_connect_test_sockets (uint32_t num_test_sockets) #else rv = connect (tsock->fd, (struct sockaddr *) &scm->server_addr, - sizeof (scm->server_addr)); + scm->server_addr_size); #endif if (rv < 0) { @@ -838,6 +843,8 @@ print_usage_and_exit (void) "sock_test_client [OPTIONS] \n" " OPTIONS\n" " -h Print this message and exit.\n" + " -6 Use IPv6\n" + " -u Use UDP transport layer\n" " -c Print test config before test.\n" " -w Write test results to .\n" " -X Exit after running test.\n" @@ -863,7 +870,7 @@ main (int argc, char **argv) sock_test_socket_buf_alloc (ctrl); opterr = 0; - while ((c = getopt (argc, argv, "chn:w:XE:I:N:R:T:UBV")) != -1) + while ((c = getopt (argc, argv, "chn:w:XE:I:N:R:T:UBV6D")) != -1) switch (c) { case 'c': @@ -1000,6 +1007,14 @@ main (int argc, char **argv) ctrl->cfg.verbose = 1; break; + case '6': + ctrl->cfg.address_ip6 = 1; + break; + + case 'D': + ctrl->cfg.transport_udp = 1; + break; + case '?': switch (optopt) { @@ -1042,7 +1057,9 @@ main (int argc, char **argv) } else { - ctrl->fd = vppcom_session_create (VPPCOM_PROTO_TCP, + ctrl->fd = vppcom_session_create (ctrl->cfg.transport_udp ? + VPPCOM_PROTO_UDP : + VPPCOM_PROTO_TCP, 0 /* is_nonblocking */ ); if (ctrl->fd < 0) { @@ -1051,7 +1068,8 @@ main (int argc, char **argv) } } #else - ctrl->fd = socket (AF_INET, SOCK_STREAM, 0); + ctrl->fd = socket (ctrl->cfg.address_ip6 ? AF_INET6 : AF_INET, + ctrl->cfg.transport_udp ? SOCK_DGRAM : SOCK_STREAM, 0); #endif if (ctrl->fd < 0) @@ -1064,15 +1082,42 @@ main (int argc, char **argv) } memset (&scm->server_addr, 0, sizeof (scm->server_addr)); - - scm->server_addr.sin_family = AF_INET; - inet_pton (AF_INET, argv[optind++], &(scm->server_addr.sin_addr)); - scm->server_addr.sin_port = htons (atoi (argv[optind])); + if (ctrl->cfg.address_ip6) + { + struct sockaddr_in6 *server_addr = + (struct sockaddr_in6 *) &scm->server_addr; + scm->server_addr_size = sizeof (*server_addr); + server_addr->sin6_family = AF_INET6; + inet_pton (AF_INET6, argv[optind++], &(server_addr->sin6_addr)); + server_addr->sin6_port = htons (atoi (argv[optind])); + } + else + { + struct sockaddr_in *server_addr = + (struct sockaddr_in *) &scm->server_addr; + scm->server_addr_size = sizeof (*server_addr); + server_addr->sin_family = AF_INET; + inet_pton (AF_INET, argv[optind++], &(server_addr->sin_addr)); + server_addr->sin_port = htons (atoi (argv[optind])); + } #ifdef VCL_TEST - scm->server_endpt.is_ip4 = (scm->server_addr.sin_family == AF_INET); - scm->server_endpt.ip = (uint8_t *) & scm->server_addr.sin_addr; - scm->server_endpt.port = (uint16_t) scm->server_addr.sin_port; + if (ctrl->cfg.address_ip6) + { + struct sockaddr_in6 *server_addr = + (struct sockaddr_in6 *) &scm->server_addr; + scm->server_endpt.is_ip4 = 0; + scm->server_endpt.ip = (uint8_t *) & server_addr->sin6_addr; + scm->server_endpt.port = (uint16_t) server_addr->sin6_port; + } + else + { + struct sockaddr_in *server_addr = + (struct sockaddr_in *) &scm->server_addr; + scm->server_endpt.is_ip4 = 1; + scm->server_endpt.ip = (uint8_t *) & server_addr->sin_addr; + scm->server_endpt.port = (uint16_t) server_addr->sin_port; + } #endif do @@ -1089,7 +1134,7 @@ main (int argc, char **argv) #else rv = connect (ctrl->fd, (struct sockaddr *) &scm->server_addr, - sizeof (scm->server_addr)); + scm->server_addr_size); #endif if (rv < 0) { diff --git a/src/vcl/sock_test_server.c b/src/vcl/sock_test_server.c index 39ffb8e2f48..1280429f0f6 100644 --- a/src/vcl/sock_test_server.c +++ b/src/vcl/sock_test_server.c @@ -58,11 +58,19 @@ typedef struct #endif } sock_server_conn_t; +typedef struct +{ + uint32_t port; + uint32_t address_ip6; + uint32_t transport_udp; +} sock_server_cfg_t; + #define SOCK_SERVER_MAX_TEST_CONN 10 #define SOCK_SERVER_MAX_EPOLL_EVENTS 10 typedef struct { int listen_fd; + sock_server_cfg_t cfg; #if SOCK_SERVER_USE_EPOLL int epfd; struct epoll_event listen_ev; @@ -433,6 +441,18 @@ new_client (void) #endif } +void +print_usage_and_exit (void) +{ + fprintf (stderr, + "sock_test_server [OPTIONS] \n" + " OPTIONS\n" + " -h Print this message and exit.\n" + " -6 Use IPv6\n" + " -u Use UDP transport layer\n"); + exit (1); +} + int main (int argc, char **argv) { @@ -443,9 +463,9 @@ main (int argc, char **argv) sock_test_cfg_t *rx_cfg; uint32_t xtra = 0; uint64_t xtra_bytes = 0; - struct sockaddr_in servaddr; + struct sockaddr_storage servaddr; int errno_val; - int v, i; + int c, v, i; uint16_t port = SOCK_TEST_SERVER_PORT; #if ! SOCK_SERVER_USE_EPOLL fd_set _rfdset, *rfdset = &_rfdset; @@ -453,13 +473,54 @@ main (int argc, char **argv) #ifdef VCL_TEST vppcom_endpt_t endpt; #else + uint32_t servaddr_size; #if ! SOCK_SERVER_USE_EPOLL fd_set _wfdset, *wfdset = &_wfdset; #endif #endif - if ((argc == 2) && (sscanf (argv[1], "%d", &v) == 1)) + opterr = 0; + while ((c = getopt (argc, argv, "6D")) != -1) + switch (c) + { + case '6': + ssm->cfg.address_ip6 = 1; + break; + + case 'D': + ssm->cfg.transport_udp = 1; + break; + + case '?': + switch (optopt) + { + default: + if (isprint (optopt)) + fprintf (stderr, "SERVER: ERROR: Unknown " + "option `-%c'.\n", optopt); + else + fprintf (stderr, "SERVER: ERROR: Unknown " + "option character `\\x%x'.\n", optopt); + } + /* fall thru */ + case 'h': + default: + print_usage_and_exit (); + } + + if (argc < (optind + 1)) + { + fprintf (stderr, "SERVER: ERROR: Insufficient number of arguments!\n"); + print_usage_and_exit (); + } + + if (sscanf (argv[optind], "%d", &v) == 1) port = (uint16_t) v; + else + { + fprintf (stderr, "SERVER: ERROR: Invalid port (%s)!\n", argv[optind]); + print_usage_and_exit (); + } conn_pool_expand (SOCK_SERVER_MAX_TEST_CONN + 1); @@ -472,11 +533,15 @@ main (int argc, char **argv) } else { - ssm->listen_fd = - vppcom_session_create (VPPCOM_PROTO_TCP, 0 /* is_nonblocking */ ); + ssm->listen_fd = vppcom_session_create (ssm->cfg.transport_udp ? + VPPCOM_PROTO_UDP : + VPPCOM_PROTO_TCP, + 0 /* is_nonblocking */ ); } #else - ssm->listen_fd = socket (AF_INET, SOCK_STREAM, 0); + ssm->listen_fd = socket (ssm->cfg.address_ip6 ? AF_INET6 : AF_INET, + ssm->cfg.transport_udp ? SOCK_DGRAM : SOCK_STREAM, + 0); #if SOCK_SERVER_USE_EPOLL && !defined (VCL_TEST) unlink ((const char *) SOCK_TEST_AF_UNIX_FILENAME); ssm->af_unix_listen_fd = socket (AF_UNIX, SOCK_STREAM, 0); @@ -533,14 +598,42 @@ main (int argc, char **argv) memset (&servaddr, 0, sizeof (servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl (INADDR_ANY); - servaddr.sin_port = htons (port); + if (ssm->cfg.address_ip6) + { + struct sockaddr_in6 *server_addr = (struct sockaddr_in6 *) &servaddr; +#ifndef VCL_TEST + servaddr_size = sizeof (*server_addr); +#endif + server_addr->sin6_family = AF_INET6; + server_addr->sin6_addr = in6addr_any; + server_addr->sin6_port = htons (port); + } + else + { + struct sockaddr_in *server_addr = (struct sockaddr_in *) &servaddr; +#ifndef VCL_TEST + servaddr_size = sizeof (*server_addr); +#endif + server_addr->sin_family = AF_INET; + server_addr->sin_addr.s_addr = htonl (INADDR_ANY); + server_addr->sin_port = htons (port); + } #ifdef VCL_TEST - endpt.is_ip4 = (servaddr.sin_family == AF_INET); - endpt.ip = (uint8_t *) & servaddr.sin_addr; - endpt.port = (uint16_t) servaddr.sin_port; + if (ssm->cfg.address_ip6) + { + struct sockaddr_in6 *server_addr = (struct sockaddr_in6 *) &servaddr; + endpt.is_ip4 = 0; + endpt.ip = (uint8_t *) & server_addr->sin6_addr; + endpt.port = (uint16_t) server_addr->sin6_port; + } + else + { + struct sockaddr_in *server_addr = (struct sockaddr_in *) &servaddr; + endpt.is_ip4 = 1; + endpt.ip = (uint8_t *) & server_addr->sin_addr; + endpt.port = (uint16_t) server_addr->sin_port; + } rv = vppcom_session_bind (ssm->listen_fd, &endpt); if (rv) @@ -549,8 +642,7 @@ main (int argc, char **argv) rv = -1; } #else - rv = - bind (ssm->listen_fd, (struct sockaddr *) &servaddr, sizeof (servaddr)); + rv = bind (ssm->listen_fd, (struct sockaddr *) &servaddr, servaddr_size); #endif if (rv < 0) { diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index e8366d70566..cab2f6039e9 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -1207,8 +1207,7 @@ done: session->vpp_handle = mp->handle; session->lcl_addr.is_ip4 = mp->lcl_is_ip4; - clib_memcpy (&session->lcl_addr.ip46, mp->lcl_ip, - sizeof (session->peer_addr.ip46)); + session->lcl_addr.ip46 = to_ip46 (!mp->lcl_is_ip4, mp->lcl_ip); session->lcl_port = mp->lcl_port; vppcom_session_table_add_listener (mp->handle, session_index); session->state = STATE_LISTEN; @@ -1377,8 +1376,7 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) session->state = STATE_ACCEPT; session->peer_port = mp->port; session->peer_addr.is_ip4 = mp->is_ip4; - clib_memcpy (&session->peer_addr.ip46, mp->ip, - sizeof (session->peer_addr.ip46)); + session->peer_addr.ip46 = to_ip46 (!mp->is_ip4, mp->ip); /* Add it to lookup table */ hash_set (vcm->session_index_by_vpp_handles, mp->handle, session_index); @@ -1409,7 +1407,8 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) clib_warning ("VCL<%d>: vpp handle 0x%llx, sid %u: client accept " "request from %s address %U port %d queue %p!", getpid (), mp->handle, session_index, mp->is_ip4 ? "IPv4" : "IPv6", - format_ip46_address, &mp->ip, mp->is_ip4, + format_ip46_address, &mp->ip, + mp->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (mp->port), session->vpp_event_queue); if (VPPCOM_DEBUG > 0) @@ -2347,6 +2346,7 @@ void vppcom_app_destroy (void) { int rv; + f64 orig_app_timeout; if (vcm->my_client_index == ~0) return; @@ -2374,7 +2374,10 @@ vppcom_app_destroy (void) } vppcom_app_detach (); + orig_app_timeout = vcm->cfg.app_timeout; + vcm->cfg.app_timeout = 2.0; rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED); + vcm->cfg.app_timeout = orig_app_timeout; if (PREDICT_FALSE (rv)) { if (VPPCOM_DEBUG > 0) @@ -2627,7 +2630,7 @@ vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep) "port %u, proto %s", getpid (), session_index, session->lcl_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &session->lcl_addr.ip46, - session->lcl_addr.is_ip4, + session->lcl_addr.is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (session->lcl_port), session->proto ? "UDP" : "TCP"); @@ -2920,7 +2923,8 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep, client_session_index, client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &client_session->lcl_addr.ip46, - client_session->lcl_addr.is_ip4, + client_session->lcl_addr.is_ip4 ? + IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (client_session->lcl_port)); if (VPPCOM_DEBUG > 0) @@ -3014,7 +3018,8 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) getpid (), session->vpp_handle, session_index, session->peer_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, - &session->peer_addr.ip46, session->peer_addr.is_ip4, + &session->peer_addr.ip46, session->peer_addr.is_ip4 ? + IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (session->peer_port), session->proto ? "UDP" : "TCP", session->state, vppcom_session_state_str (session->state)); @@ -3033,7 +3038,8 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) getpid (), session->vpp_handle, session_index, session->peer_addr.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, - &session->peer_addr.ip46, session->peer_addr.is_ip4, + &session->peer_addr.ip46, session->peer_addr.is_ip4 ? + IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (session->peer_port), session->proto ? "UDP" : "TCP"); @@ -4459,7 +4465,8 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_PEER_ADDR: sid %u, " "is_ip4 = %u, addr = %U, port %u", getpid (), session_index, ep->is_ip4, format_ip46_address, - &session->peer_addr.ip46, ep->is_ip4, + &session->peer_addr.ip46, + ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (ep->port)); if (VPPCOM_DEBUG > 0) { @@ -4525,7 +4532,8 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, clib_warning ("VCL<%d>: VPPCOM_ATTR_GET_LCL_ADDR: sid %u, " "is_ip4 = %u, addr = %U port %d", getpid (), session_index, ep->is_ip4, format_ip46_address, - &session->lcl_addr.ip46, ep->is_ip4, + &session->lcl_addr.ip46, + ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6, clib_net_to_host_u16 (ep->port)); if (VPPCOM_DEBUG > 0) { diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c index 65eb50e9c4a..accb2d6d70c 100644 --- a/src/vnet/ip/ip.c +++ b/src/vnet/ip/ip.c @@ -31,7 +31,8 @@ ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4) if (is_ip4) return (ip46_address->ip4.as_u8[0] == 127); else - return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 1); + return (ip46_address->as_u64[0] == 0 && + clib_net_to_host_u64 (ip46_address->as_u64[1]) == 1); } u8 @@ -43,7 +44,8 @@ ip4_is_local_host (ip4_address_t * ip4_address) u8 ip6_is_local_host (ip6_address_t * ip6_address) { - return (ip6_address->as_u64[0] == 0 && ip6_address->as_u64[1] == 1); + return (ip6_address->as_u64[0] == 0 && + clib_net_to_host_u64 (ip6_address->as_u64[1]) == 1); } /** -- cgit 1.2.3-korg