VCL: add IPv6 to socket_test.sh and make test 39/11239/10
authorDave Wallace <dwallacelf@gmail.com>
Tue, 20 Mar 2018 13:22:13 +0000 (09:22 -0400)
committerFlorin Coras <florin.coras@gmail.com>
Mon, 26 Mar 2018 21:56:16 +0000 (21:56 +0000)
Change-Id: If3827828062a46f1cce43642535333f677f06e62
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
src/vcl/sock_test.h
src/vcl/sock_test_client.c
src/vcl/sock_test_server.c
src/vcl/vppcom.c
src/vnet/ip/ip.c
test/scripts/socket_test.sh
test/test_vcl.py

index 0729c31..f9f5c70 100644 (file)
@@ -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;
index 7a735f5..3559c68 100644 (file)
@@ -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] <ipaddr> <port>\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 <dir>         Write test results to <dir>.\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)
        {
index 39ffb8e..1280429 100644 (file)
@@ -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] <port>\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)
     {
index e8366d7..cab2f60 100644 (file)
@@ -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)
            {
index 65eb50e..accb2d6 100644 (file)
@@ -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);
 }
 
 /**
index ca33eee..0200f29 100755 (executable)
@@ -69,7 +69,6 @@ OPTIONS:
   -c                  Set VCL_CONFIG to use the vcl_test.conf file.
   -i                  Run iperf3 for client/server app in native tests.
   -n                  Name of ethernet for VPP to use in multi-host cfg.
-  -6                  Use ipv6 addressing.
   -f                  Full thru host stack vpp configuration. 
   -m c[lient]         Run client in multi-host cfg (server on remote host)
      s[erver]         Run server in multi-host cfg (client on remote host)
@@ -84,6 +83,8 @@ OPTIONS:
   -t                  Use tabs in one xterm if available (e.g. xfce4-terminal).
 
 OPTIONS passed to client/server:
+  -6                  Use IPv6.
+  -D                  Use UDP as the transport.
   -S <ip address>     Server IP address.
   -P <server port>    Server Port number.
   -E <data>           Run Echo test.
@@ -118,8 +119,9 @@ declare -i leave_tmp_files=0
 declare -i bash_after_exit=0
 declare -i iperf3=0
 declare -i use_ipv6=0
+declare -i transport_udp=0
 
-while getopts ":hitlbcd6fn:m:e:g:p:E:I:N:P:R:S:T:UBVX" opt; do
+while getopts ":hitlbcd6fn:m:e:g:p:E:I:N:P:R:S:T:UBVXD" opt; do
     case $opt in
         h) usage ;;
         l) leave_tmp_files=1
@@ -129,6 +131,9 @@ while getopts ":hitlbcd6fn:m:e:g:p:E:I:N:P:R:S:T:UBVX" opt; do
         i) iperf3=1
            ;;
         6) use_ipv6=1
+           sock_srvr_addr="::1"
+           sock_clnt_options="$sock_clnt_options -$opt"
+           sock_srvr_options="$sock_srvr_options -$opt"
            ;;
         f) full_thru_host_stack_vpp_cfg=1
            ;;
@@ -205,6 +210,9 @@ while getopts ":hitlbcd6fn:m:e:g:p:E:I:N:P:R:S:T:UBVX" opt; do
            ;;
         P) sock_srvr_port="$OPTARG"
            ;;
+        D) sock_clnt_options="$sock_clnt_options -$opt"
+           sock_srvr_options="$sock_srvr_options -$opt"
+           ;;
 E|I|N|R|T) sock_clnt_options="$sock_clnt_options -$opt \"$OPTARG\""
            ;;
   U|B|V|X) sock_clnt_options="$sock_clnt_options -$opt"
@@ -371,7 +379,7 @@ if [ $iperf3 -eq 1 ] ; then
     fi
 else
     app_dir="$vpp_dir"
-    srvr_app="$sock_srvr_app $sock_srvr_port"
+    srvr_app="$sock_srvr_app${sock_srvr_options} $sock_srvr_port"
     clnt_app="$sock_clnt_app${sock_clnt_options} \$srvr_addr $sock_srvr_port"
 fi
 
@@ -404,8 +412,11 @@ verify_no_vpp() {
         sudo mkdir $vpp_run_dir
         sudo chown root:$USER $vpp_run_dir
     fi
-    if [ -n "$full_thru_host_stack_vpp_cfg" ] ; then
+    if [ $use_ipv6 -eq 0 ] && [ -n "$full_thru_host_stack_vpp_cfg" ] ; then
+        sock_srvr_table=0
         sock_srvr_addr=172.16.1.1
+        sock_client_table=1
+        sock_client_addr=172.16.2.1
         client_namespace_id="1"
         client_namespace_secret="5678"
         server_namespace_id="0"
@@ -415,17 +426,40 @@ session enable
 create loop inter
 create loop inter
 set inter state loop0 up 
-set inter ip table loop0 0
-set inter ip address loop0 172.16.1.1/24
+set inter ip table loop0 $sock_srvr_table
+set inter ip address loop0 $sock_srvr_addr/24
 set inter state loop1 up
-set inter ip table loop1 1
-set inter ip address loop1 172.16.2.1/24
+set inter ip table loop1 $sock_client_table
+set inter ip address loop1 $sock_client_addr/24
 app ns add id 0 secret 1234 sw_if_index 1
 app ns add id 1 secret 5678 sw_if_index 2
-ip route add 172.16.1.1/32 table 1 via lookup in table 0
-ip route add 172.16.2.1/32 table 0 via lookup in table 1
+ip route add $sock_srvr_addr/32 table $sock_client_table via lookup in table $sock_srvr_table
+ip route add $sock_client_addr/32 table $sock_srvr_table via lookup in table $sock_client_table
+EOF
+    elif [ $use_ipv6 -eq 1 ] && [ -n "$full_thru_host_stack_vpp_cfg" ] ; then
+        sock_srvr_table=1
+        sock_srvr_addr=fd01:1::1
+        sock_client_table=2
+        sock_client_addr=fd01:2::1
+        client_namespace_id="1"
+        client_namespace_secret="5678"
+        server_namespace_id="0"
+        server_namespace_secret="1234"
+        cat <<EOF >> $tmp_vpp_exec_file
+session enable
+create loop inter
+create loop inter
+set inter state loop0 up 
+set inter ip6 table loop0 $sock_srvr_table
+set inter ip address loop0 $sock_srvr_addr/64
+set inter state loop1 up
+set inter ip6 table loop1 $sock_client_table
+set inter ip address loop1 $sock_client_addr/64
+app ns add id 0 secret 1234 sw_if_index 1
+app ns add id 1 secret 5678 sw_if_index 2
+ip route add $sock_srvr_addr/128 table $sock_client_table via lookup in table $sock_srvr_table
+ip route add $sock_client_addr/128 table $sock_srvr_table via lookup in table $sock_client_table
 EOF
-
     elif [ -n "$multi_host" ] ; then
         vpp_eth_pci_id="$(ls -ld /sys/class/net/$vpp_eth_name/device | awk '{print $11}' | cut -d/ -f4)"
         if [ -z "$vpp_eth_pci_id" ] ; then
@@ -689,7 +723,7 @@ native_preload() {
             namespace_id="$server_namespace_id"
             namespace_secret="$server_namespace_secret"
         fi
-        write_script_header $cmd2_file $tmp_gdb_cmdfile "$title2" "sleep 2"
+        write_script_header $cmd2_file $tmp_gdb_cmdfile "$title2" "sleep 3"
         echo "export LD_LIBRARY_PATH=\"$lib64_dir:$VCL_LDPRELOAD_LIB_DIR:$LD_LIBRARY_PATH\"" >> $cmd2_file
         echo "${pre_cmd}${app_dir}${srvr_app}" >> $cmd2_file
         write_script_footer $cmd2_file $perf_server
index 73537f6..b427c94 100644 (file)
@@ -41,6 +41,8 @@ class VCLTestCase(VppTestCase):
         self.server_addr = "127.0.0.1"
         self.server_port = "22000"
         self.server_args = [self.server_port]
+        self.server_ipv6_addr = "::1"
+        self.server_ipv6_args = ["-6", self.server_port]
         self.timeout = 3
         self.echo_phrase = "Hello, world! Jenny is a friend of mine."
 
@@ -112,6 +114,50 @@ class VCLTestCase(VppTestCase):
 
         self.vapi.session_enable_disable(is_enabled=0)
 
+    def thru_host_stack_ipv6_setup(self):
+        self.vapi.session_enable_disable(is_enabled=1)
+        self.create_loopback_interfaces(range(2))
+
+        table_id = 1
+
+        for i in self.lo_interfaces:
+            i.admin_up()
+
+            tbl = VppIpTable(self, table_id, is_ip6=1)
+            tbl.add_vpp_config()
+
+            i.set_table_ip6(table_id)
+            i.config_ip6()
+            table_id += 1
+
+        # Configure namespaces
+        self.vapi.app_namespace_add(namespace_id="0", secret=1234,
+                                    sw_if_index=self.loop0.sw_if_index)
+        self.vapi.app_namespace_add(namespace_id="1", secret=5678,
+                                    sw_if_index=self.loop1.sw_if_index)
+
+        # Add inter-table routes
+        ip_t01 = VppIpRoute(self, self.loop1.local_ip6, 128,
+                            [VppRoutePath("0.0.0.0", 0xffffffff,
+                                          nh_table_id=2)],
+                            table_id=1, is_ip6=1)
+        ip_t10 = VppIpRoute(self, self.loop0.local_ip6, 128,
+                            [VppRoutePath("0.0.0.0", 0xffffffff,
+                                          nh_table_id=1)],
+                            table_id=2, is_ip6=1)
+        ip_t01.add_vpp_config()
+        ip_t10.add_vpp_config()
+        self.logger.debug(self.vapi.cli("show interface addr"))
+        self.logger.debug(self.vapi.cli("show ip6 fib"))
+
+    def thru_host_stack_ipv6_tear_down(self):
+        for i in self.lo_interfaces:
+            i.unconfig_ip6()
+            i.set_table_ip6(0)
+            i.admin_down()
+
+        self.vapi.session_enable_disable(is_enabled=0)
+
     def thru_host_stack_test(self, server_app, server_args,
                              client_app, client_args):
         self.env = {'VCL_API_PREFIX': self.shm_prefix,
@@ -170,19 +216,19 @@ class VCLCutThruTestCase(VCLTestCase):
         super(VCLCutThruTestCase, self).setUp()
 
         self.cut_thru_setup()
-        self.client_echo_test_args = [self.server_addr, self.server_port,
-                                      "-E", self.echo_phrase, "-X"]
+        self.client_echo_test_args = ["-E", self.echo_phrase, "-X",
+                                      self.server_addr, self.server_port]
         self.client_iperf3_timeout = 20
         self.client_iperf3_args = ["-V4d", "-c", self.server_addr]
         self.server_iperf3_args = ["-V4d", "-s"]
         self.client_uni_dir_nsock_timeout = 60
-        self.client_uni_dir_nsock_test_args = [self.server_addr,
-                                               self.server_port,
-                                               "-I", "5", "-U", "-X"]
+        self.client_uni_dir_nsock_test_args = ["-I", "5", "-U", "-X",
+                                               self.server_addr,
+                                               self.server_port]
         self.client_bi_dir_nsock_timeout = 120
-        self.client_bi_dir_nsock_test_args = [self.server_addr,
-                                              self.server_port,
-                                              "-I", "2", "-B", "-X"]
+        self.client_bi_dir_nsock_test_args = ["-I", "2", "-B", "-X",
+                                              self.server_addr,
+                                              self.server_port]
 
     def tearDown(self):
         self.cut_thru_tear_down()
@@ -259,9 +305,9 @@ class VCLThruHostStackTestCase(VCLTestCase):
         super(VCLThruHostStackTestCase, self).setUp()
 
         self.thru_host_stack_setup()
-        self.client_echo_test_args = [self.loop0.local_ip4,
-                                      self.server_port,
-                                      "-E", self.echo_phrase, "-X"]
+        self.client_echo_test_args = ["-E", self.echo_phrase, "-X",
+                                      self.loop0.local_ip4,
+                                      self.server_port]
 
     def tearDown(self):
         self.thru_host_stack_tear_down()
@@ -301,11 +347,14 @@ class VCLThruHostStackExtendedATestCase(VCLTestCase):
         self.thru_host_stack_setup()
         if self.vppDebug:
             self.client_bi_dir_nsock_timeout = 120
+            self.client_bi_dir_nsock_test_args = ["-B", "-X",
+                                                  self.loop0.local_ip4,
+                                                  self.server_port]
         else:
-            self.client_bi_dir_nsock_timeout = 60
-        self.client_bi_dir_nsock_test_args = [self.loop0.local_ip4,
-                                              self.server_port,
-                                              "-I", "2", "-B", "-X"]
+            self.client_bi_dir_nsock_timeout = 90
+            self.client_bi_dir_nsock_test_args = ["-I", "2", "-B", "-X",
+                                                  self.loop0.local_ip4,
+                                                  self.server_port]
 
     def tearDown(self):
         self.thru_host_stack_tear_down()
@@ -331,11 +380,14 @@ class VCLThruHostStackExtendedBTestCase(VCLTestCase):
         self.thru_host_stack_setup()
         if self.vppDebug:
             self.client_bi_dir_nsock_timeout = 120
+            self.client_bi_dir_nsock_test_args = ["-B", "-X",
+                                                  self.loop0.local_ip4,
+                                                  self.server_port]
         else:
             self.client_bi_dir_nsock_timeout = 60
-        self.client_bi_dir_nsock_test_args = [self.loop0.local_ip4,
-                                              self.server_port,
-                                              "-I", "2", "-B", "-X"]
+            self.client_bi_dir_nsock_test_args = ["-I", "2", "-B", "-X",
+                                                  self.loop0.local_ip4,
+                                                  self.server_port]
 
     def tearDown(self):
         self.thru_host_stack_tear_down()
@@ -366,10 +418,10 @@ class VCLThruHostStackExtendedCTestCase(VCLTestCase):
             self.client_uni_dir_nsock_timeout = 120
             self.numSockets = "5"
 
-        self.client_uni_dir_nsock_test_args = [self.loop0.local_ip4,
-                                               self.server_port,
-                                               "-I", self.numSockets,
-                                               "-U", "-X"]
+        self.client_uni_dir_nsock_test_args = ["-I", self.numSockets,
+                                               "-U", "-X",
+                                               self.loop0.local_ip4,
+                                               self.server_port]
 
     def tearDown(self):
         self.thru_host_stack_tear_down()
@@ -400,10 +452,10 @@ class VCLThruHostStackExtendedDTestCase(VCLTestCase):
             self.client_uni_dir_nsock_timeout = 120
             self.numSockets = "5"
 
-        self.client_uni_dir_nsock_test_args = [self.loop0.local_ip4,
-                                               self.server_port,
-                                               "-I", self.numSockets,
-                                               "-U", "-X"]
+        self.client_uni_dir_nsock_test_args = ["-I", self.numSockets,
+                                               "-U", "-X",
+                                               self.loop0.local_ip4,
+                                               self.server_port]
 
     def tearDown(self):
         self.thru_host_stack_tear_down()
@@ -452,5 +504,313 @@ class VCLThruHostStackIperfTestCase(VCLTestCase):
                                   "iperf3", self.client_iperf3_args)
 
 
+class VCLIpv6CutThruTestCase(VCLTestCase):
+    """ VCL IPv6 Cut Thru Tests """
+
+    def setUp(self):
+        super(VCLIpv6CutThruTestCase, self).setUp()
+
+        self.cut_thru_setup()
+        self.client_iperf3_timeout = 20
+        self.client_uni_dir_nsock_timeout = 60
+        self.client_bi_dir_nsock_timeout = 120
+        self.client_ipv6_echo_test_args = ["-6", "-E", self.echo_phrase, "-X",
+                                           self.server_ipv6_addr,
+                                           self.server_port]
+        self.client_ipv6_iperf3_args = ["-V6d", "-c", self.server_ipv6_addr]
+        self.server_ipv6_iperf3_args = ["-V6d", "-s"]
+        self.client_ipv6_uni_dir_nsock_test_args = ["-6", "-I", "5",
+                                                    "-U", "-X",
+                                                    self.server_ipv6_addr,
+                                                    self.server_port]
+        self.client_ipv6_bi_dir_nsock_test_args = ["-6", "-I", "2",
+                                                   "-B", "-X",
+                                                   self.server_ipv6_addr,
+                                                   self.server_port]
+
+    def tearDown(self):
+        self.cut_thru_tear_down()
+
+        super(VCLIpv6CutThruTestCase, self).tearDown()
+
+    def test_ldp_ipv6_cut_thru_echo(self):
+        """ run LDP IPv6 cut thru echo test """
+
+        self.cut_thru_test("sock_test_server",
+                           self.server_ipv6_args,
+                           "sock_test_client",
+                           self.client_ipv6_echo_test_args)
+
+    def test_ldp_ipv6_cut_thru_iperf3(self):
+        """ run LDP IPv6 cut thru iperf3 test """
+
+        try:
+            subprocess.check_output(['iperf3', '-v'])
+        except:
+            self.logger.error("WARNING: 'iperf3' is not installed,")
+            self.logger.error(
+                "         'test_ldp_ipv6_cut_thru_iperf3' not run!")
+            return
+
+        self.timeout = self.client_iperf3_timeout
+        self.cut_thru_test("iperf3", self.server_ipv6_iperf3_args,
+                           "iperf3", self.client_ipv6_iperf3_args)
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_ldp_ipv6_cut_thru_uni_dir_nsock(self):
+        """ run LDP IPv6 cut thru uni-directional (multiple sockets) test """
+
+        self.timeout = self.client_uni_dir_nsock_timeout
+        self.cut_thru_test("sock_test_server", self.server_ipv6_args,
+                           "sock_test_client",
+                           self.client_ipv6_uni_dir_nsock_test_args)
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_ldp_ipv6_cut_thru_bi_dir_nsock(self):
+        """ run LDP IPv6 cut thru bi-directional (multiple sockets) test """
+
+        self.timeout = self.client_bi_dir_nsock_timeout
+        self.cut_thru_test("sock_test_server", self.server_ipv6_args,
+                           "sock_test_client",
+                           self.client_ipv6_bi_dir_nsock_test_args)
+
+    def test_vcl_ipv6_cut_thru_echo(self):
+        """ run VCL IPv6 cut thru echo test """
+
+        self.cut_thru_test("vcl_test_server",
+                           self.server_ipv6_args,
+                           "vcl_test_client",
+                           self.client_ipv6_echo_test_args)
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_vcl_ipv6_cut_thru_uni_dir_nsock(self):
+        """ run VCL IPv6 cut thru uni-directional (multiple sockets) test """
+
+        self.timeout = self.client_uni_dir_nsock_timeout
+        self.cut_thru_test("vcl_test_server", self.server_ipv6_args,
+                           "vcl_test_client",
+                           self.client_ipv6_uni_dir_nsock_test_args)
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_vcl_ipv6_cut_thru_bi_dir_nsock(self):
+        """ run VCL IPv6 cut thru bi-directional (multiple sockets) test """
+
+        self.timeout = self.client_bi_dir_nsock_timeout
+        self.cut_thru_test("vcl_test_server", self.server_ipv6_args,
+                           "vcl_test_client",
+                           self.client_ipv6_bi_dir_nsock_test_args)
+
+
+class VCLIpv6ThruHostStackTestCase(VCLTestCase):
+    """ VCL IPv6 Thru Host Stack Tests """
+
+    def setUp(self):
+        super(VCLIpv6ThruHostStackTestCase, self).setUp()
+
+        self.thru_host_stack_ipv6_setup()
+        self.client_ipv6_echo_test_args = ["-6", "-E", self.echo_phrase, "-X",
+                                           self.loop0.local_ip6,
+                                           self.server_port]
+
+    def tearDown(self):
+        self.thru_host_stack_ipv6_tear_down()
+
+        super(VCLIpv6ThruHostStackTestCase, self).tearDown()
+
+    def test_ldp_ipv6_thru_host_stack_echo(self):
+        """ run LDP IPv6 thru host stack echo test """
+
+        self.thru_host_stack_test("sock_test_server", self.server_ipv6_args,
+                                  "sock_test_client",
+                                  self.client_ipv6_echo_test_args)
+        # TBD: Remove these when VPP thru host teardown config bug is fixed.
+        self.thru_host_stack_test("vcl_test_server", self.server_ipv6_args,
+                                  "vcl_test_client",
+                                  self.client_ipv6_echo_test_args)
+
+    def test_vcl_ipv6_thru_host_stack_echo(self):
+        """ run VCL IPv6 thru host stack echo test """
+
+        # TBD: Enable this when VPP IPv6 thru host teardown
+        # config bug is fixed.
+        # self.thru_host_stack_test("vcl_test_server", self.server_ipv6_args,
+        #                           "vcl_test_client",
+        #                           self.client_ipv6_echo_test_args)
+
+    # TBD: Remove VCLIpv6ThruHostStackExtended*TestCase classes and move
+    #      tests here when VPP  thru host teardown/setup config bug
+    #      is fixed.
+
+
+class VCLIpv6ThruHostStackExtendedATestCase(VCLTestCase):
+    """ VCL IPv6 Thru Host Stack Extended Tests """
+
+    def setUp(self):
+        super(VCLIpv6ThruHostStackExtendedATestCase, self).setUp()
+
+        self.thru_host_stack_ipv6_setup()
+        if self.vppDebug:
+            self.client_bi_dir_nsock_timeout = 120
+            self.client_ipv6_bi_dir_nsock_test_args = ["-6", "-B", "-X",
+                                                       self.loop0.local_ip6,
+                                                       self.server_port]
+        else:
+            self.client_bi_dir_nsock_timeout = 90
+            self.client_ipv6_bi_dir_nsock_test_args = ["-6", "-I",
+                                                       "2", "-B", "-X",
+                                                       self.loop0.local_ip6,
+                                                       self.server_port]
+
+    def tearDown(self):
+        self.thru_host_stack_ipv6_tear_down()
+
+        super(VCLIpv6ThruHostStackExtendedATestCase, self).tearDown()
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_vcl_thru_host_stack_bi_dir_nsock(self):
+        """ run VCL thru host stack bi-directional (multiple sockets) test """
+
+        self.timeout = self.client_bi_dir_nsock_timeout
+        self.thru_host_stack_test("vcl_test_server", self.server_ipv6_args,
+                                  "vcl_test_client",
+                                  self.client_ipv6_bi_dir_nsock_test_args)
+
+
+class VCLIpv6ThruHostStackExtendedBTestCase(VCLTestCase):
+    """ VCL IPv6 Thru Host Stack Extended Tests """
+
+    def setUp(self):
+        super(VCLIpv6ThruHostStackExtendedBTestCase, self).setUp()
+
+        self.thru_host_stack_ipv6_setup()
+        if self.vppDebug:
+            self.client_bi_dir_nsock_timeout = 120
+            self.client_ipv6_bi_dir_nsock_test_args = ["-6", "-B", "-X",
+                                                       self.loop0.local_ip6,
+                                                       self.server_port]
+        else:
+            self.client_bi_dir_nsock_timeout = 60
+            self.client_ipv6_bi_dir_nsock_test_args = ["-6", "-I", "2",
+                                                       "-B", "-X",
+                                                       self.loop0.local_ip6,
+                                                       self.server_port]
+
+    def tearDown(self):
+        self.thru_host_stack_ipv6_tear_down()
+
+        super(VCLIpv6ThruHostStackExtendedBTestCase, self).tearDown()
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_ldp_thru_host_stack_bi_dir_nsock(self):
+        """ run LDP thru host stack bi-directional (multiple sockets) test """
+
+        self.timeout = self.client_bi_dir_nsock_timeout
+        self.thru_host_stack_test("sock_test_server", self.server_ipv6_args,
+                                  "sock_test_client",
+                                  self.client_ipv6_bi_dir_nsock_test_args)
+
+
+class VCLIpv6ThruHostStackExtendedCTestCase(VCLTestCase):
+    """ VCL IPv6 Thru Host Stack Extended Tests """
+
+    def setUp(self):
+        super(VCLIpv6ThruHostStackExtendedCTestCase, self).setUp()
+
+        self.thru_host_stack_ipv6_setup()
+        if self.vppDebug:
+            self.client_uni_dir_nsock_timeout = 120
+            self.numSockets = "2"
+        else:
+            self.client_uni_dir_nsock_timeout = 120
+            self.numSockets = "5"
+
+        self.client_ipv6_uni_dir_nsock_test_args = ["-6",
+                                                    "-I", self.numSockets,
+                                                    "-U", "-X",
+                                                    self.loop0.local_ip6,
+                                                    self.server_port]
+
+    def tearDown(self):
+        self.thru_host_stack_ipv6_tear_down()
+
+        super(VCLIpv6ThruHostStackExtendedCTestCase, self).tearDown()
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_ldp_thru_host_stack_uni_dir_nsock(self):
+        """ run LDP thru host stack uni-directional (multiple sockets) test """
+
+        self.timeout = self.client_uni_dir_nsock_timeout
+        self.thru_host_stack_test("sock_test_server", self.server_ipv6_args,
+                                  "sock_test_client",
+                                  self.client_ipv6_uni_dir_nsock_test_args)
+
+
+class VCLIpv6ThruHostStackExtendedDTestCase(VCLTestCase):
+    """ VCL IPv6 Thru Host Stack Extended Tests """
+
+    def setUp(self):
+        super(VCLIpv6ThruHostStackExtendedDTestCase, self).setUp()
+
+        self.thru_host_stack_ipv6_setup()
+        if self.vppDebug:
+            self.client_uni_dir_nsock_timeout = 120
+            self.numSockets = "2"
+        else:
+            self.client_uni_dir_nsock_timeout = 120
+            self.numSockets = "5"
+
+        self.client_ipv6_uni_dir_nsock_test_args = ["-6",
+                                                    "-I", self.numSockets,
+                                                    "-U", "-X",
+                                                    self.loop0.local_ip6,
+                                                    self.server_port]
+
+    def tearDown(self):
+        self.thru_host_stack_ipv6_tear_down()
+
+        super(VCLIpv6ThruHostStackExtendedDTestCase, self).tearDown()
+
+    @unittest.skipUnless(running_extended_tests(), "part of extended tests")
+    def test_vcl_thru_host_stack_uni_dir_nsock(self):
+        """ run VCL thru host stack uni-directional (multiple sockets) test """
+
+        self.timeout = self.client_uni_dir_nsock_timeout
+        self.thru_host_stack_test("vcl_test_server", self.server_ipv6_args,
+                                  "vcl_test_client",
+                                  self.client_ipv6_uni_dir_nsock_test_args)
+
+
+class VCLIpv6ThruHostStackIperfTestCase(VCLTestCase):
+    """ VCL IPv6 Thru Host Stack Iperf Tests """
+
+    def setUp(self):
+        super(VCLIpv6ThruHostStackIperfTestCase, self).setUp()
+
+        self.thru_host_stack_ipv6_setup()
+        self.client_iperf3_timeout = 20
+        self.client_ipv6_iperf3_args = ["-V6d", "-c", self.loop0.local_ip6]
+        self.server_ipv6_iperf3_args = ["-V6d", "-s"]
+
+    def tearDown(self):
+        self.thru_host_stack_ipv6_tear_down()
+
+        super(VCLIpv6ThruHostStackIperfTestCase, self).tearDown()
+
+    def test_ldp_thru_host_stack_iperf3(self):
+        """ run LDP thru host stack iperf3 test """
+
+        try:
+            subprocess.check_output(['iperf3', '-v'])
+        except:
+            self.logger.error("WARNING: 'iperf3' is not installed,")
+            self.logger.error(
+                "         'test_ldp_thru_host_stack_iperf3' not run!")
+            return
+
+        self.timeout = self.client_iperf3_timeout
+        self.thru_host_stack_test("iperf3", self.server_ipv6_iperf3_args,
+                                  "iperf3", self.client_ipv6_iperf3_args)
+
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)