aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--build/external/deb/debian/control2
-rw-r--r--build/optional/deb/debian/control2
-rw-r--r--extras/hs-test/echo_test.go2
-rw-r--r--extras/hs-test/http_test.go9
-rw-r--r--extras/hs-test/infra/container.go5
-rw-r--r--extras/hs-test/infra/vppinstance.go6
-rw-r--r--extras/hs-test/raw_session_test.go3
-rw-r--r--extras/hs-test/vcl_test.go14
-rw-r--r--extras/scripts/host-stack/http-speed-test/speed_test_startup_conf31
-rw-r--r--extras/scripts/host-stack/http-speed-test/speedtest.cli5
-rw-r--r--src/plugins/dev_octeon/crypto.c12
-rw-r--r--src/plugins/dev_octeon/crypto.h7
-rw-r--r--src/plugins/dev_octeon/init.c43
-rw-r--r--src/plugins/dev_octeon/octeon.h6
-rw-r--r--src/plugins/dma_intel/dsa.c2
-rw-r--r--src/plugins/hs_apps/echo_client.c8
-rw-r--r--src/plugins/http/http.c7
-rw-r--r--src/plugins/http/http1.c11
-rw-r--r--src/plugins/http/http_private.h2
-rw-r--r--src/plugins/http_static/http_static.h8
-rw-r--r--src/plugins/http_static/static_server.c147
-rw-r--r--src/vcl/vcl_private.c6
-rw-r--r--test/Makefile1
-rw-r--r--test/asf/asfframework.py2
-rw-r--r--test/asf/test_quic.py14
-rw-r--r--test/asf/test_session_sdl.py5
-rw-r--r--test/asf/test_tcp.py2
-rw-r--r--test/asf/test_tls.py2
-rw-r--r--test/test_pg_stream.py13
-rw-r--r--test/test_udp.py2
31 files changed, 279 insertions, 101 deletions
diff --git a/Makefile b/Makefile
index 6e8f9bb6304..15fdc836470 100644
--- a/Makefile
+++ b/Makefile
@@ -106,6 +106,7 @@ DEB_DEPENDS += iperf ethtool # for 'make test TEST=vm_vpp_interfaces'
DEB_DEPENDS += libpcap-dev
DEB_DEPENDS += tshark
DEB_DEPENDS += jq # for extracting test summary from .json report (hs-test)
+DEB_DEPENDS += nasm libnuma-dev # for make-ext-deps
LIBFFI=libffi6 # works on all but 20.04 and debian-testing
ifeq ($(OS_VERSION_ID),24.04)
diff --git a/build/external/deb/debian/control b/build/external/deb/debian/control
index a4e59f4c577..701d7bf0961 100644
--- a/build/external/deb/debian/control
+++ b/build/external/deb/debian/control
@@ -2,7 +2,7 @@ Source: vpp-ext-deps
Section: net
Priority: extra
Maintainer: vpp-dev@lists.fd.io
-Build-Depends: debhelper (>= 9), dkms
+Build-Depends: debhelper (>= 9)
Standards-Version: 3.9.4
Package: vpp-ext-deps
diff --git a/build/optional/deb/debian/control b/build/optional/deb/debian/control
index d892395ddab..c18809f7f5e 100644
--- a/build/optional/deb/debian/control
+++ b/build/optional/deb/debian/control
@@ -2,7 +2,7 @@ Source: vpp-opt-deps
Section: net
Priority: extra
Maintainer: vpp-dev@lists.fd.io
-Build-Depends: debhelper (>= 9), dkms
+Build-Depends: debhelper (>= 9)
Standards-Version: 3.9.4
Package: vpp-opt-deps
diff --git a/extras/hs-test/echo_test.go b/extras/hs-test/echo_test.go
index b21c69a1e99..8d69c007113 100644
--- a/extras/hs-test/echo_test.go
+++ b/extras/hs-test/echo_test.go
@@ -39,7 +39,7 @@ func TcpWithLossTest(s *VethsSuite) {
clientVpp.Vppctl("nsim output-feature enable-disable host-" + s.Interfaces.Server.Name())
// Do echo test from client-vpp container
- output := clientVpp.Vppctl("test echo client uri tcp://%s/20022 verbose echo-bytes mbytes 50",
+ output := clientVpp.Vppctl("test echo client uri tcp://%s/20022 verbose echo-bytes bytes 50m",
s.Interfaces.Server.Ip4AddressString())
s.Log(output)
s.AssertNotEqual(len(output), 0)
diff --git a/extras/hs-test/http_test.go b/extras/hs-test/http_test.go
index 760ca3ca936..93317bbf8d8 100644
--- a/extras/hs-test/http_test.go
+++ b/extras/hs-test/http_test.go
@@ -412,7 +412,8 @@ func httpClientGet(s *NoTopoSuite, response string, size int) {
s.AssertContains(o, response)
s.AssertContains(o, "Content-Length: "+strconv.Itoa(size))
- file_contents := vpp.Container.Exec(false, "cat /tmp/response.txt")
+ file_contents, err := vpp.Container.Exec(false, "cat /tmp/response.txt")
+ s.AssertNil(err)
s.AssertContains(file_contents, response)
}
@@ -463,7 +464,8 @@ func httpClientRepeat(s *NoTopoSuite, requestMethod string, clientArgs string) {
o := vpp.Vppctl(cmd)
s.Log(o)
- replyCount := s.Containers.NginxServer.Exec(false, "awk 'END { print NR }' "+logPath)
+ replyCount, err := s.Containers.NginxServer.Exec(false, "awk 'END { print NR }' "+logPath)
+ s.AssertNil(err)
if replyCount != "" {
replyCountInt, err = strconv.Atoi(replyCount[:len(replyCount)-1])
s.AssertNil(err)
@@ -485,7 +487,8 @@ func httpClientRepeat(s *NoTopoSuite, requestMethod string, clientArgs string) {
o = vpp.Vppctl(cmd)
s.Log(o)
- replyCount = s.Containers.NginxServer.Exec(false, "awk 'END { print NR }' "+logPath)
+ replyCount, err = s.Containers.NginxServer.Exec(false, "awk 'END { print NR }' "+logPath)
+ s.AssertNil(err)
if replyCount != "" {
replyCountInt, err = strconv.Atoi(replyCount[:len(replyCount)-1])
s.AssertNil(err)
diff --git a/extras/hs-test/infra/container.go b/extras/hs-test/infra/container.go
index 918c19e669e..efc317fa96d 100644
--- a/extras/hs-test/infra/container.go
+++ b/extras/hs-test/infra/container.go
@@ -460,7 +460,7 @@ func (c *Container) ExecServer(useEnvVars bool, command string, arguments ...any
c.Suite.AssertNil(exechelper.Run(containerExecCommand))
}
-func (c *Container) Exec(useEnvVars bool, command string, arguments ...any) string {
+func (c *Container) Exec(useEnvVars bool, command string, arguments ...any) (string, error) {
var envVars string
serverCommand := fmt.Sprintf(command, arguments...)
if useEnvVars {
@@ -472,8 +472,7 @@ func (c *Container) Exec(useEnvVars bool, command string, arguments ...any) stri
GinkgoHelper()
c.Suite.Log(containerExecCommand)
byteOutput, err := exechelper.CombinedOutput(containerExecCommand)
- c.Suite.AssertNil(err, fmt.Sprint(err))
- return string(byteOutput)
+ return string(byteOutput), err
}
func (c *Container) saveLogs() {
diff --git a/extras/hs-test/infra/vppinstance.go b/extras/hs-test/infra/vppinstance.go
index 370d2be38d1..59d17de4d20 100644
--- a/extras/hs-test/infra/vppinstance.go
+++ b/extras/hs-test/infra/vppinstance.go
@@ -243,9 +243,11 @@ func (vpp *VppInstance) Start() error {
}
func (vpp *VppInstance) Stop() {
- pid := strings.TrimSpace(vpp.Container.Exec(false, "pidof vpp"))
+ pid, err := vpp.Container.Exec(false, "pidof vpp")
+ pid = strings.TrimSpace(pid)
// Stop VPP only if it's still running
- if len(pid) > 0 {
+ if err == nil {
+ vpp.getSuite().Log("Stopping VPP")
vpp.Container.Exec(false, "bash -c \"kill -15 "+pid+"\"")
}
}
diff --git a/extras/hs-test/raw_session_test.go b/extras/hs-test/raw_session_test.go
index c104031f78f..b93b27ab56b 100644
--- a/extras/hs-test/raw_session_test.go
+++ b/extras/hs-test/raw_session_test.go
@@ -35,6 +35,7 @@ func testVppEcho(s *VethsSuite, proto string) {
" socket-name " + s.Containers.ClientApp.GetContainerWorkDir() + "/var/run/app_ns_sockets/default" +
" use-app-socket-api uri " + uri
s.Log(clientCommand)
- o := s.Containers.ClientApp.Exec(true, clientCommand)
+ o, err := s.Containers.ClientApp.Exec(true, clientCommand)
+ s.AssertNil(err)
s.Log(o)
}
diff --git a/extras/hs-test/vcl_test.go b/extras/hs-test/vcl_test.go
index 11e2be1258e..bc557a90508 100644
--- a/extras/hs-test/vcl_test.go
+++ b/extras/hs-test/vcl_test.go
@@ -50,7 +50,8 @@ func testXEchoVclClient(s *VethsSuite, proto string) {
testClientCommand := "vcl_test_client -N 100 -p " + proto + " " + s.Interfaces.Server.Ip4AddressString() + " " + port
s.Log(testClientCommand)
echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- o := echoClnContainer.Exec(true, testClientCommand)
+ o, err := echoClnContainer.Exec(true, testClientCommand)
+ s.AssertNil(err)
s.Log(o)
s.AssertContains(o, "CLIENT RESULTS")
}
@@ -76,7 +77,7 @@ func testXEchoVclServer(s *VethsSuite, proto string) {
serverVethAddress := s.Interfaces.Server.Ip4AddressString()
clientVpp := s.Containers.ClientVpp.VppInstance
- o := clientVpp.Vppctl("test echo client uri %s://%s/%s fifo-size 64k verbose mbytes 2", proto, serverVethAddress, port)
+ o := clientVpp.Vppctl("test echo client uri %s://%s/%s fifo-size 64k verbose bytes 2m", proto, serverVethAddress, port)
s.Log(o)
s.AssertContains(o, "Test finished at")
}
@@ -97,7 +98,8 @@ func testVclEcho(s *VethsSuite, proto string) {
testClientCommand := "vcl_test_client -p " + proto + " " + serverVethAddress + " " + port
echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- o := echoClnContainer.Exec(true, testClientCommand)
+ o, err := echoClnContainer.Exec(true, testClientCommand)
+ s.AssertNil(err)
s.Log(o)
}
@@ -137,7 +139,8 @@ func testRetryAttach(s *VethsSuite, proto string) {
testClientCommand := "vcl_test_client -U -p " + proto + " " + serverVethAddress + " 12346"
echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf")
- o := echoClnContainer.Exec(true, testClientCommand)
+ o, err := echoClnContainer.Exec(true, testClientCommand)
+ s.AssertNil(err)
s.Log(o)
s.Log("... First test ended. Stopping VPP server now.")
@@ -152,7 +155,8 @@ func testRetryAttach(s *VethsSuite, proto string) {
time.Sleep(30 * time.Second) // Wait a moment for the re-attachment to happen
s.Log("... Running second echo client test, after disconnect and re-attachment.")
- o = echoClnContainer.Exec(true, testClientCommand)
+ o, err = echoClnContainer.Exec(true, testClientCommand)
+ s.AssertNil(err)
s.Log(o)
s.Log("Done.")
}
diff --git a/extras/scripts/host-stack/http-speed-test/speed_test_startup_conf b/extras/scripts/host-stack/http-speed-test/speed_test_startup_conf
new file mode 100644
index 00000000000..ec9230148e5
--- /dev/null
+++ b/extras/scripts/host-stack/http-speed-test/speed_test_startup_conf
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright (c) 2025 Cisco Systems, Inc.
+unix {
+ interactive log /tmp/vpp.log
+ full-coredump
+ exec /scratch/matfabia/vpp/extras/scripts/host-stack/http-speed-test/speedtest.cli
+ cli-listen /run/vpp/cli.sock
+ poll-sleep-usec 0
+}
+heapsize 4g
+api-trace { on }
+api-segment { global-size 2000M api-size 1G gid vpp }
+dpdk {
+ dev 0000:17:00.0 {
+ num-tx-desc 256
+ num-rx-desc 512
+ num-rx-queues 1
+ tso on
+ }
+ enable-tcp-udp-checksum
+}
+cpu {
+ skip-cores 0
+ main-core 1
+ corelist-workers 2-10
+}
+buffers { buffers-per-numa 16536 }
+session { event-queue-length 100000 use-app-socket-api }
+tcp { max-rx-fifo 128m tso }
+socksvr { socket-name /run/vpp-api.sock }
+
diff --git a/extras/scripts/host-stack/http-speed-test/speedtest.cli b/extras/scripts/host-stack/http-speed-test/speedtest.cli
new file mode 100644
index 00000000000..555aa173d6b
--- /dev/null
+++ b/extras/scripts/host-stack/http-speed-test/speedtest.cli
@@ -0,0 +1,5 @@
+comment {SPDX-License-Identifier: Apache-2.0}
+comment {Copyright (c) 2025 Cisco Systems, Inc.}
+set int ip address HundredGigabitEthernet17/0/0 6.0.1.1/24
+set int state HundredGigabitEthernet17/0/0 up
+http static server www-root /scratch/matfabia/Speed-Test max-body-size 40m max-age 0 keepalive-timeout 120 cache-size 100m fifo-size 512k
diff --git a/src/plugins/dev_octeon/crypto.c b/src/plugins/dev_octeon/crypto.c
index 800f24a008a..52c796089d5 100644
--- a/src/plugins/dev_octeon/crypto.c
+++ b/src/plugins/dev_octeon/crypto.c
@@ -1354,7 +1354,7 @@ oct_crypto_aead_session_update (vlib_main_t *vm, oct_crypto_sess_t *sess,
vnet_crypto_key_t *key = vnet_crypto_get_key (key_index);
roc_se_cipher_type enc_type = 0;
roc_se_auth_type auth_type = 0;
- u32 digest_len = ~0;
+ u32 digest_len = 16;
i32 rv = 0;
switch (key->alg)
@@ -1366,9 +1366,6 @@ oct_crypto_aead_session_update (vlib_main_t *vm, oct_crypto_sess_t *sess,
sess->aes_gcm = 1;
sess->iv_offset = 0;
sess->iv_length = 16;
- sess->cpt_ctx.mac_len = 16;
- sess->cpt_op = type;
- digest_len = 16;
break;
case VNET_CRYPTO_ALG_CHACHA20_POLY1305:
enc_type = ROC_SE_CHACHA20;
@@ -1381,6 +1378,9 @@ oct_crypto_aead_session_update (vlib_main_t *vm, oct_crypto_sess_t *sess,
return -1;
}
+ sess->cpt_ctx.mac_len = digest_len;
+ sess->cpt_op = type;
+
rv = roc_se_ciph_key_set (&sess->cpt_ctx, enc_type, key->data, key->length);
if (rv)
{
@@ -1940,7 +1940,7 @@ oct_init_crypto_engine_handlers (vlib_main_t *vm, vnet_dev_t *dev)
}
int
-oct_conf_sw_queue (vlib_main_t *vm, vnet_dev_t *dev)
+oct_conf_sw_queue (vlib_main_t *vm, vnet_dev_t *dev, oct_crypto_dev_t *ocd)
{
oct_crypto_main_t *ocm = &oct_crypto_main;
vlib_thread_main_t *tm = vlib_get_thread_main ();
@@ -1961,7 +1961,7 @@ oct_conf_sw_queue (vlib_main_t *vm, vnet_dev_t *dev)
* Each pending queue will get number of cpt desc / number of cores.
* And that desc count is shared across inflight entries.
*/
- n_inflight_req = (OCT_CPT_LF_MAX_NB_DESC / tm->n_vlib_mains);
+ n_inflight_req = (ocd->n_desc / tm->n_vlib_mains);
for (i = 0; i < tm->n_vlib_mains; ++i)
{
diff --git a/src/plugins/dev_octeon/crypto.h b/src/plugins/dev_octeon/crypto.h
index 5bd26f6b9be..4d8c56a314c 100644
--- a/src/plugins/dev_octeon/crypto.h
+++ b/src/plugins/dev_octeon/crypto.h
@@ -11,6 +11,9 @@
#define OCT_MAX_N_CPT_DEV 2
+#define OCT_CPT_LF_DEF_NB_DESC 16384
+
+#define OCT_CPT_LF_MIN_NB_DESC 1024
#define OCT_CPT_LF_MAX_NB_DESC 128000
/* CRYPTO_ID, KEY_LENGTH_IN_BYTES, TAG_LEN, AAD_LEN */
@@ -81,6 +84,7 @@ typedef struct
struct roc_cpt_lmtline lmtline;
struct roc_cpt_lf lf;
vnet_dev_t *dev;
+ u32 n_desc;
} oct_crypto_dev_t;
typedef struct
@@ -211,5 +215,6 @@ vnet_crypto_async_frame_t *oct_crypto_frame_dequeue (vlib_main_t *vm,
u32 *nb_elts_processed,
u32 *enqueue_thread_idx);
int oct_init_crypto_engine_handlers (vlib_main_t *vm, vnet_dev_t *dev);
-int oct_conf_sw_queue (vlib_main_t *vm, vnet_dev_t *dev);
+int oct_conf_sw_queue (vlib_main_t *vm, vnet_dev_t *dev,
+ oct_crypto_dev_t *ocd);
#endif /* _CRYPTO_H_ */
diff --git a/src/plugins/dev_octeon/init.c b/src/plugins/dev_octeon/init.c
index 561cbe94fed..69fb097e91f 100644
--- a/src/plugins/dev_octeon/init.c
+++ b/src/plugins/dev_octeon/init.c
@@ -61,6 +61,22 @@ static struct
#undef _
};
+static vnet_dev_arg_t oct_dev_args[] = {
+ {
+ .id = OCT_DEV_ARG_CRYPTO_N_DESC,
+ .name = "n_desc",
+ .desc = "number of cpt descriptors, applicable to cpt devices only",
+ .type = VNET_DEV_ARG_TYPE_UINT32,
+ .default_val.uint32 = OCT_CPT_LF_DEF_NB_DESC,
+ },
+ {
+ .id = OCT_DEV_ARG_END,
+ .name = "end",
+ .desc = "Argument end",
+ .type = VNET_DEV_ARG_END,
+ },
+};
+
static u8 *
oct_probe (vlib_main_t *vm, vnet_dev_bus_index_t bus_index, void *dev_info)
{
@@ -241,7 +257,7 @@ oct_conf_cpt_queue (vlib_main_t *vm, vnet_dev_t *dev, oct_crypto_dev_t *ocd)
cpt_lf = &ocd->lf;
cpt_lmtline = &ocd->lmtline;
- cpt_lf->nb_desc = OCT_CPT_LF_MAX_NB_DESC;
+ cpt_lf->nb_desc = ocd->n_desc;
cpt_lf->lf_id = 0;
if ((rrv = roc_cpt_lf_init (roc_cpt, cpt_lf)) < 0)
return cnx_return_roc_err (dev, rrv, "roc_cpt_lf_init");
@@ -261,6 +277,7 @@ oct_init_cpt (vlib_main_t *vm, vnet_dev_t *dev)
extern oct_plt_init_param_t oct_plt_init_param;
oct_device_t *cd = vnet_dev_get_data (dev);
oct_crypto_dev_t *ocd = NULL;
+ u32 n_desc;
int rrv;
if (ocm->n_cpt == OCT_MAX_N_CPT_DEV || ocm->started)
@@ -274,6 +291,27 @@ oct_init_cpt (vlib_main_t *vm, vnet_dev_t *dev)
ocd->roc_cpt->pci_dev = &cd->plt_pci_dev;
ocd->dev = dev;
+ ocd->n_desc = OCT_CPT_LF_DEF_NB_DESC;
+
+ foreach_vnet_dev_args (arg, dev)
+ {
+ if (arg->id == OCT_DEV_ARG_CRYPTO_N_DESC &&
+ vnet_dev_arg_get_uint32 (arg))
+ {
+ n_desc = vnet_dev_arg_get_uint32 (arg);
+ if (n_desc < OCT_CPT_LF_MIN_NB_DESC ||
+ n_desc > OCT_CPT_LF_MAX_NB_DESC)
+ {
+ log_err (dev,
+ "number of cpt descriptors should be within range "
+ "of %u and %u",
+ OCT_CPT_LF_MIN_NB_DESC, OCT_CPT_LF_MAX_NB_DESC);
+ return VNET_DEV_ERR_NOT_SUPPORTED;
+ }
+
+ ocd->n_desc = vnet_dev_arg_get_uint32 (arg);
+ }
+ }
if ((rrv = roc_cpt_dev_init (ocd->roc_cpt)))
return cnx_return_roc_err (dev, rrv, "roc_cpt_dev_init");
@@ -290,7 +328,7 @@ oct_init_cpt (vlib_main_t *vm, vnet_dev_t *dev)
* Initialize s/w queues, which are common across multiple
* crypto devices
*/
- oct_conf_sw_queue (vm, dev);
+ oct_conf_sw_queue (vm, dev, ocd);
ocm->crypto_dev[0] = ocd;
}
@@ -396,6 +434,7 @@ VNET_DEV_REGISTER_DRIVER (octeon) = {
.free = oct_free,
.probe = oct_probe,
},
+ .args = oct_dev_args,
};
static clib_error_t *
diff --git a/src/plugins/dev_octeon/octeon.h b/src/plugins/dev_octeon/octeon.h
index ccf8f62880d..0cf937528f0 100644
--- a/src/plugins/dev_octeon/octeon.h
+++ b/src/plugins/dev_octeon/octeon.h
@@ -25,6 +25,12 @@
typedef enum
{
+ OCT_DEV_ARG_CRYPTO_N_DESC = 1,
+ OCT_DEV_ARG_END,
+} oct_dev_args_t;
+
+typedef enum
+{
OCT_DEVICE_TYPE_UNKNOWN = 0,
OCT_DEVICE_TYPE_RVU_PF,
OCT_DEVICE_TYPE_RVU_VF,
diff --git a/src/plugins/dma_intel/dsa.c b/src/plugins/dma_intel/dsa.c
index 473f2efa93e..20a90e34b0e 100644
--- a/src/plugins/dma_intel/dsa.c
+++ b/src/plugins/dma_intel/dsa.c
@@ -103,7 +103,6 @@ intel_dsa_batch_fallback (vlib_main_t *vm, intel_dsa_batch_t *b,
clib_memcpy_fast (desc->dst, desc->src, desc->size);
}
b->status = INTEL_DSA_STATUS_CPU_SUCCESS;
- ch->submitted++;
return;
}
@@ -407,6 +406,7 @@ intel_dsa_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
/* fallback to software if exception happened */
intel_dsa_batch_fallback (vm, b, ch);
glitch = 1 & b->barrier_before_last;
+ t->pending_batches[n++] = b;
}
else
{
diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c
index ff5a3bd6b3c..b08edaaa5f5 100644
--- a/src/plugins/hs_apps/echo_client.c
+++ b/src/plugins/hs_apps/echo_client.c
@@ -1073,7 +1073,7 @@ ec_command_fn (vlib_main_t *vm, unformat_input_t *input,
uword *event_data = 0, event_type;
clib_error_t *error = 0;
int rv, had_config = 1;
- u64 tmp, total_bytes;
+ u64 total_bytes;
f64 delta;
if (ecm->test_client_attached)
@@ -1099,10 +1099,6 @@ ec_command_fn (vlib_main_t *vm, unformat_input_t *input,
;
else if (unformat (line_input, "quic-streams %d", &ecm->quic_streams))
;
- else if (unformat (line_input, "mbytes %lld", &tmp))
- ecm->bytes_to_send = tmp << 20;
- else if (unformat (line_input, "gbytes %lld", &tmp))
- ecm->bytes_to_send = tmp << 30;
else if (unformat (line_input, "bytes %U", unformat_memory_size,
&ecm->bytes_to_send))
;
@@ -1336,7 +1332,7 @@ cleanup:
VLIB_CLI_COMMAND (ec_command, static) = {
.path = "test echo clients",
.short_help =
- "test echo clients [nclients %d][[m|g]bytes <bytes>]"
+ "test echo clients [nclients %d][bytes <bytes>[m|g]]"
"[test-timeout <time>][syn-timeout <time>][echo-bytes][fifo-size <size>]"
"[private-segment-count <count>][private-segment-size <bytes>[m|g]]"
"[preallocate-fifos][preallocate-sessions][client-batch <batch-size>]"
diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c
index 5998a9ebd18..43b0993e462 100644
--- a/src/plugins/http/http.c
+++ b/src/plugins/http/http.c
@@ -525,7 +525,7 @@ http_ts_disconnect_callback (session_t *ts)
hc_handle.as_u32 = ts->opaque;
- HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_index);
+ HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_handle.conn_index);
hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
@@ -543,7 +543,7 @@ http_ts_reset_callback (session_t *ts)
hc_handle.as_u32 = ts->opaque;
- HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_index);
+ HTTP_DBG (1, "hc [%u]%x", ts->thread_index, hc_handle.conn_index);
hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
@@ -607,7 +607,8 @@ http_ts_cleanup_callback (session_t *ts, session_cleanup_ntf_t ntf)
hc_handle.as_u32 = ts->opaque;
hc = http_conn_get_w_thread (hc_handle.conn_index, ts->thread_index);
- HTTP_DBG (1, "going to free hc [%u]%x", ts->thread_index, hc_index);
+ HTTP_DBG (1, "going to free hc [%u]%x", ts->thread_index,
+ hc_handle.conn_index);
if (!(hc->flags & HTTP_CONN_F_PENDING_TIMER))
http_conn_timer_stop (hc);
diff --git a/src/plugins/http/http1.c b/src/plugins/http/http1.c
index ec118aa4e52..265f6e7b24f 100644
--- a/src/plugins/http/http1.c
+++ b/src/plugins/http/http1.c
@@ -998,6 +998,7 @@ http1_req_state_wait_transport_method (http_conn_t *hc, http_req_t *req,
/* send at least "control data" which is necessary minimum,
* if there is some space send also portion of body */
max_enq = http_io_as_max_write (req);
+ max_enq -= sizeof (msg);
if (max_enq < req->control_data_len)
{
clib_warning ("not enough room for control data in app's rx fifo");
@@ -1859,10 +1860,12 @@ http1_transport_rx_callback (http_conn_t *hc)
if (!http1_req_state_is_rx_valid (req))
{
- clib_warning ("hc [%u]%x invalid rx state: http req state "
- "'%U', session state '%U'",
- hc->c_thread_index, hc->hc_hc_index, format_http_req_state,
- req->state, format_http_conn_state, hc);
+ if (http_io_ts_max_read (hc))
+ clib_warning ("hc [%u]%x invalid rx state: http req state "
+ "'%U', session state '%U'",
+ hc->c_thread_index, hc->hc_hc_index,
+ format_http_req_state, req->state,
+ format_http_conn_state, hc);
http_io_ts_drain_all (hc);
return;
}
diff --git a/src/plugins/http/http_private.h b/src/plugins/http/http_private.h
index ebec59aeaee..8354bf29289 100644
--- a/src/plugins/http/http_private.h
+++ b/src/plugins/http/http_private.h
@@ -691,7 +691,7 @@ http_conn_accept_request (http_conn_t *hc, http_req_t *req)
int rv;
HTTP_DBG (1, "hc [%u]%x req %x", hc->hc_hc_index, hc->c_thread_index,
- req->hr_req_index);
+ req->hr_req_handle);
/* allocate app session and initialize */
as = session_alloc (hc->c_thread_index);
diff --git a/src/plugins/http_static/http_static.h b/src/plugins/http_static/http_static.h
index e158a32dbc9..2b6de03c71a 100644
--- a/src/plugins/http_static/http_static.h
+++ b/src/plugins/http_static/http_static.h
@@ -33,7 +33,7 @@
/** \brief Application session
*/
-typedef struct
+typedef struct hss_session_
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
u32 session_index;
@@ -42,6 +42,9 @@ typedef struct
/** vpp session index, handle */
u32 vpp_session_index;
session_handle_t vpp_session_handle;
+ u8 *target_path;
+ u8 *target_query;
+ http_req_method_t rt;
/** Fully-resolved file path */
u8 *path;
/** Data to send */
@@ -58,6 +61,9 @@ typedef struct
http_headers_ctx_t resp_headers;
/** Response header buffer */
u8 *headers_buf;
+ /** POST body left to receive */
+ u64 left_recv;
+ int (*read_body_handler) (struct hss_session_ *hs, session_t *ts);
} hss_session_t;
typedef struct hss_session_handle_
diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c
index d7958fd3f1f..75481f840b2 100644
--- a/src/plugins/http_static/static_server.c
+++ b/src/plugins/http_static/static_server.c
@@ -30,6 +30,8 @@
#define HSS_HEADER_BUF_MAX_SIZE 16192
hss_main_t hss_main;
+static int file_handler_discard_body (hss_session_t *hs, session_t *ts);
+
static int
hss_add_header (hss_session_t *hs, http_header_name_t name, const char *value,
uword value_len)
@@ -280,14 +282,18 @@ content_type_from_request (u8 *request)
}
static int
-try_url_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
- u8 *target_path, u8 *target_query, u8 *data)
+try_url_handler (hss_session_t *hs)
{
+ hss_main_t *hsm = &hss_main;
http_status_code_t sc = HTTP_STATUS_OK;
hss_url_handler_args_t args = {};
uword *p, *url_table;
+ session_t *ts;
+ u8 *data = 0, *target_path;
int rv;
+ target_path = hs->target_path;
+
if (!hsm->enable_url_handlers || !target_path)
return -1;
@@ -299,28 +305,48 @@ try_url_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
/* Look for built-in GET / POST handlers */
url_table =
- (rt == HTTP_REQ_GET) ? hsm->get_url_handlers : hsm->post_url_handlers;
+ (hs->rt == HTTP_REQ_GET) ? hsm->get_url_handlers : hsm->post_url_handlers;
p = hash_get_mem (url_table, target_path);
if (!p)
return -1;
+ /* Read request body */
+ if (hs->left_recv)
+ {
+ ts = session_get (hs->vpp_session_index, hs->thread_index);
+ /* TODO: add support for large content (use hs->read_body_handler) */
+ if (svm_fifo_max_dequeue (ts->rx_fifo) < hs->left_recv)
+ {
+ hs->left_recv = 0;
+ start_send_data (hs, HTTP_STATUS_INTERNAL_ERROR);
+ hss_session_disconnect_transport (hs);
+ return 0;
+ }
+ vec_validate (data, hs->left_recv - 1);
+ rv = svm_fifo_dequeue (ts->rx_fifo, hs->left_recv, data);
+ ASSERT (rv == hs->left_recv);
+ hs->left_recv = 0;
+ }
+
hs->path = 0;
hs->data_offset = 0;
hs->cache_pool_index = ~0;
if (hsm->debug_level > 0)
- clib_warning ("%s '%s'", (rt == HTTP_REQ_GET) ? "GET" : "POST",
+ clib_warning ("%s '%s'", (hs->rt == HTTP_REQ_GET) ? "GET" : "POST",
target_path);
- args.req_type = rt;
- args.query = target_query;
+ args.req_type = hs->rt;
+ args.query = hs->target_query;
args.req_data = data;
args.sh.thread_index = hs->thread_index;
args.sh.session_index = hs->session_index;
rv = ((hss_url_handler_fn) p[0]) (&args);
+ vec_free (data);
+
/* Wait for data from handler */
if (rv == HSS_URL_HANDLER_ASYNC)
return 0;
@@ -328,7 +354,7 @@ try_url_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
if (rv == HSS_URL_HANDLER_ERROR)
{
clib_warning ("builtin handler %llx hit on %s '%s' but failed!", p[0],
- (rt == HTTP_REQ_GET) ? "GET" : "POST", target_path);
+ (hs->rt == HTTP_REQ_GET) ? "GET" : "POST", target_path);
sc = HTTP_STATUS_BAD_GATEWAY;
}
@@ -429,32 +455,49 @@ try_index_file (hss_main_t *hsm, hss_session_t *hs, u8 *path)
}
static int
-try_file_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
- u8 *target)
+try_file_handler (hss_session_t *hs)
{
+ hss_main_t *hsm = &hss_main;
http_status_code_t sc = HTTP_STATUS_OK;
u8 *path, *sanitized_path;
- u32 ce_index;
+ u32 ce_index, max_dequeue;
http_content_type_t type;
u8 *last_modified;
+ session_t *ts;
/* Feature not enabled */
if (!hsm->www_root)
return -1;
+ /* Discard request body */
+ if (hs->left_recv)
+ {
+ ts = session_get (hs->vpp_session_index, hs->thread_index);
+ max_dequeue = svm_fifo_max_dequeue (ts->rx_fifo);
+ if (max_dequeue < hs->left_recv)
+ {
+ svm_fifo_dequeue_drop (ts->rx_fifo, max_dequeue);
+ hs->left_recv -= max_dequeue;
+ hs->read_body_handler = file_handler_discard_body;
+ return 0;
+ }
+ svm_fifo_dequeue_drop (ts->rx_fifo, hs->left_recv);
+ hs->left_recv = 0;
+ }
+
/* Sanitize received path */
- sanitized_path = http_path_sanitize (target);
+ sanitized_path = http_path_sanitize (hs->target_path);
/*
* Construct the file to open
*/
- if (!target)
+ if (!sanitized_path)
path = format (0, "%s%c", hsm->www_root, 0);
else
path = format (0, "%s/%s%c", hsm->www_root, sanitized_path, 0);
if (hsm->debug_level > 0)
- clib_warning ("%s '%s'", (rt == HTTP_REQ_GET) ? "GET" : "POST", path);
+ clib_warning ("%s '%s'", (hs->rt == HTTP_REQ_GET) ? "GET" : "POST", path);
if (hs->data && hs->free_data)
vec_free (hs->data);
@@ -498,7 +541,7 @@ try_file_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
* Cache-Control max-age
* Last-Modified
*/
- type = content_type_from_request (target);
+ type = content_type_from_request (sanitized_path);
if (hss_add_header (hs, HTTP_HEADER_CONTENT_TYPE,
http_content_type_token (type)) ||
hss_add_header (hs, HTTP_HEADER_CACHE_CONTROL,
@@ -520,15 +563,12 @@ done:
}
static void
-handle_request (hss_session_t *hs, http_req_method_t rt, u8 *target_path,
- u8 *target_query, u8 *data)
+handle_request (hss_session_t *hs)
{
- hss_main_t *hsm = &hss_main;
-
- if (!try_url_handler (hsm, hs, rt, target_path, target_query, data))
+ if (!try_url_handler (hs))
return;
- if (!try_file_handler (hsm, hs, rt, target_path))
+ if (!try_file_handler (hs))
return;
/* Handler did not find anything return 404 */
@@ -537,19 +577,41 @@ handle_request (hss_session_t *hs, http_req_method_t rt, u8 *target_path,
}
static int
+file_handler_discard_body (hss_session_t *hs, session_t *ts)
+{
+ u32 max_dequeue, to_discard;
+
+ max_dequeue = svm_fifo_max_dequeue (ts->rx_fifo);
+ to_discard = clib_min (max_dequeue, hs->left_recv);
+ svm_fifo_dequeue_drop (ts->rx_fifo, to_discard);
+ hs->left_recv -= to_discard;
+ if (hs->left_recv == 0)
+ return try_file_handler (hs);
+ return 0;
+}
+
+static int
hss_ts_rx_callback (session_t *ts)
{
hss_main_t *hsm = &hss_main;
hss_session_t *hs;
- u8 *target_path = 0, *target_query = 0, *data = 0;
http_msg_t msg;
int rv;
hs = hss_session_get (ts->thread_index, ts->opaque);
+ if (hs->left_recv != 0)
+ {
+ ASSERT (hs->read_body_handler);
+ return hs->read_body_handler (hs, ts);
+ }
+
if (hs->free_data)
vec_free (hs->data);
+
hs->data = 0;
hs->data_len = 0;
+ vec_free (hs->target_path);
+ vec_free (hs->target_query);
http_init_headers_ctx (&hs->resp_headers, hs->headers_buf,
vec_len (hs->headers_buf));
@@ -567,37 +629,38 @@ hss_ts_rx_callback (session_t *ts)
goto err_done;
}
+ hs->rt = msg.method_type;
+
/* Read target path */
if (msg.data.target_path_len)
{
- vec_validate (target_path, msg.data.target_path_len - 1);
+ vec_validate (hs->target_path, msg.data.target_path_len - 1);
rv = svm_fifo_peek (ts->rx_fifo, msg.data.target_path_offset,
- msg.data.target_path_len, target_path);
+ msg.data.target_path_len, hs->target_path);
ASSERT (rv == msg.data.target_path_len);
- if (http_validate_abs_path_syntax (target_path, 0))
+ if (http_validate_abs_path_syntax (hs->target_path, 0))
{
start_send_data (hs, HTTP_STATUS_BAD_REQUEST);
goto err_done;
}
/* Target path must be a proper C-string in addition to a vector */
- vec_add1 (target_path, 0);
+ vec_add1 (hs->target_path, 0);
}
/* Read target query */
if (msg.data.target_query_len)
{
- vec_validate (target_query, msg.data.target_query_len - 1);
+ vec_validate (hs->target_query, msg.data.target_query_len - 1);
rv = svm_fifo_peek (ts->rx_fifo, msg.data.target_query_offset,
- msg.data.target_query_len, target_query);
+ msg.data.target_query_len, hs->target_query);
ASSERT (rv == msg.data.target_query_len);
- if (http_validate_query_syntax (target_query, 0))
+ if (http_validate_query_syntax (hs->target_query, 0))
{
start_send_data (hs, HTTP_STATUS_BAD_REQUEST);
goto err_done;
}
}
- /* Read request body for POST requests */
if (msg.data.body_len && msg.method_type == HTTP_REQ_POST)
{
if (msg.data.body_len > hsm->max_body_size)
@@ -605,28 +668,19 @@ hss_ts_rx_callback (session_t *ts)
start_send_data (hs, HTTP_STATUS_CONTENT_TOO_LARGE);
goto err_done;
}
- if (svm_fifo_max_dequeue (ts->rx_fifo) - msg.data.body_offset <
- msg.data.body_len)
- {
- start_send_data (hs, HTTP_STATUS_INTERNAL_ERROR);
- goto err_done;
- }
- vec_validate (data, msg.data.body_len - 1);
- rv = svm_fifo_peek (ts->rx_fifo, msg.data.body_offset, msg.data.body_len,
- data);
- ASSERT (rv == msg.data.body_len);
+
+ hs->left_recv = msg.data.body_len;
+ /* drop everything up to body */
+ svm_fifo_dequeue_drop (ts->rx_fifo, msg.data.body_offset);
}
/* Find and send data */
- handle_request (hs, msg.method_type, target_path, target_query, data);
+ handle_request (hs);
goto done;
err_done:
hss_session_disconnect_transport (hs);
done:
- vec_free (target_path);
- vec_free (target_query);
- vec_free (data);
svm_fifo_dequeue_drop (ts->rx_fifo, msg.data.len);
return 0;
}
@@ -757,6 +811,8 @@ hss_ts_cleanup (session_t *s, session_cleanup_ntf_t ntf)
hs->free_data = 0;
vec_free (hs->headers_buf);
vec_free (hs->path);
+ vec_free (hs->target_path);
+ vec_free (hs->target_query);
hss_session_free (hs);
}
@@ -952,8 +1008,9 @@ hss_create_command_fn (vlib_main_t *vm, unformat_input_t *input,
else if (unformat (line_input, "private-segment-size %U",
unformat_memory_size, &seg_size))
hsm->private_segment_size = seg_size;
- else if (unformat (line_input, "fifo-size %d", &hsm->fifo_size))
- hsm->fifo_size <<= 10;
+ else if (unformat (line_input, "fifo-size %U", unformat_memory_size,
+ &hsm->fifo_size))
+ ;
else if (unformat (line_input, "cache-size %U", unformat_memory_size,
&hsm->cache_size))
;
diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c
index 1adc8cb6666..7a9b60a1959 100644
--- a/src/vcl/vcl_private.c
+++ b/src/vcl/vcl_private.c
@@ -212,14 +212,16 @@ vcl_worker_detached_start_signal_mq (vcl_worker_t *wrk)
exit (1);
}
- int sig = 1, __clib_unused rv;
+ int __clib_unused rv;
+ u8 sig = 1;
rv = write (wrk->detached_pipefds[1], &sig, 1);
}
void
vcl_worker_detached_signal_mq (vcl_worker_t *wrk)
{
- int buf, __clib_unused rv;
+ int __clib_unused rv;
+ u8 buf;
rv = read (wrk->detached_pipefds[0], &buf, 1);
rv = write (wrk->detached_pipefds[1], &buf, 1);
}
diff --git a/test/Makefile b/test/Makefile
index de3a3ca2a52..37f8e2db18b 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -423,6 +423,7 @@ cov-post: wipe-cov $(BUILD_COV_DIR)
-o $(BUILD_COV_DIR)/coverage-filtered$(HS_TEST).info
@genhtml $(BUILD_COV_DIR)/coverage-filtered$(HS_TEST).info \
--output-directory $(BUILD_COV_DIR)/html
+ @rm -f $(BUILD_COV_DIR)/html/cmd_line
@test -z "$(EXTERN_COV_DIR)" || \
genhtml $(BUILD_COV_DIR)/extern-coverage$(HS_TEST).info \
--output-directory $(BUILD_COV_DIR)/extern-html
diff --git a/test/asf/asfframework.py b/test/asf/asfframework.py
index 8e565d26a52..7670a0753d1 100644
--- a/test/asf/asfframework.py
+++ b/test/asf/asfframework.py
@@ -652,8 +652,6 @@ class VppAsfTestCase(CPUInterface, unittest.TestCase):
cls.pump_thread.start()
if cls.debug_gdb or cls.debug_gdbserver or cls.debug_attach:
cls.vapi_response_timeout = 0
- elif config.gcov:
- cls.vapi_response_timeout = 20
cls.vapi = VppPapiProvider(cls.__name__, cls, cls.vapi_response_timeout)
if cls.step:
hook = hookmodule.StepHook(cls)
diff --git a/test/asf/test_quic.py b/test/asf/test_quic.py
index c4fa6912114..78ebe0f40a7 100644
--- a/test/asf/test_quic.py
+++ b/test/asf/test_quic.py
@@ -178,7 +178,7 @@ class QUICEchoIntTransferTestCase(QUICEchoIntTestCase):
def test_quic_int_transfer(self):
"""QUIC internal transfer"""
self.server()
- self.client("mbytes", "2")
+ self.client("bytes", "2m")
@tag_fixme_vpp_workers
@@ -188,11 +188,11 @@ class QUICEchoIntSerialTestCase(QUICEchoIntTestCase):
def test_quic_serial_int_transfer(self):
"""QUIC serial internal transfer"""
self.server()
- self.client("mbytes", "2")
- self.client("mbytes", "2")
- self.client("mbytes", "2")
- self.client("mbytes", "2")
- self.client("mbytes", "2")
+ self.client("bytes", "2m")
+ self.client("bytes", "2m")
+ self.client("bytes", "2m")
+ self.client("bytes", "2m")
+ self.client("bytes", "2m")
@tag_fixme_vpp_workers
@@ -202,7 +202,7 @@ class QUICEchoIntMStreamTestCase(QUICEchoIntTestCase):
def test_quic_int_multistream_transfer(self):
"""QUIC internal multi-stream transfer"""
self.server()
- self.client("nclients", "10", "mbytes", "1")
+ self.client("nclients", "10", "bytes", "1m")
class QUICEchoExtTestCase(QUICTestCase):
diff --git a/test/asf/test_session_sdl.py b/test/asf/test_session_sdl.py
index 53301f7bd6c..d2e30daa9f2 100644
--- a/test/asf/test_session_sdl.py
+++ b/test/asf/test_session_sdl.py
@@ -5,6 +5,7 @@ import unittest
from framework import VppTestCase
from asfframework import VppTestRunner, tag_fixme_vpp_workers
from ipaddress import IPv4Network, IPv6Network
+from config import config
from vpp_ip_route import (
VppIpRoute,
@@ -25,6 +26,10 @@ class TestSessionSDL(VppTestCase):
@classmethod
def setUpClass(cls):
+ # increase vapi timeout, to avoid
+ # failures reported on test-cov
+ if config.gcov:
+ cls.vapi_response_timeout = 20
super(TestSessionSDL, cls).setUpClass()
@classmethod
diff --git a/test/asf/test_tcp.py b/test/asf/test_tcp.py
index 23772d34c76..e9c9e1efb68 100644
--- a/test/asf/test_tcp.py
+++ b/test/asf/test_tcp.py
@@ -89,7 +89,7 @@ class TestTCP(VppAsfTestCase):
self.assertNotIn("failed", error)
error = self.vapi.cli(
- "test echo client mbytes 10 appns 1 "
+ "test echo client bytes 10m appns 1 "
+ "fifo-size 4k test-bytes "
+ "syn-timeout 2 uri "
+ uri
diff --git a/test/asf/test_tls.py b/test/asf/test_tls.py
index 2ce87143339..6676132417c 100644
--- a/test/asf/test_tls.py
+++ b/test/asf/test_tls.py
@@ -142,7 +142,7 @@ class TestTLS(VppAsfTestCase):
self.assertNotIn("failed", error)
error = self.vapi.cli(
- "test echo client mbytes 10 appns 1 "
+ "test echo client bytes 10m appns 1 "
"fifo-size 4k test-bytes "
"tls-engine 1 "
"syn-timeout 2 uri " + uri
diff --git a/test/test_pg_stream.py b/test/test_pg_stream.py
index 471c85c43f0..915a5aa73d9 100644
--- a/test/test_pg_stream.py
+++ b/test/test_pg_stream.py
@@ -11,6 +11,7 @@ from scapy.layers.inet6 import IPv6
from framework import VppTestCase
from asfframework import VppTestRunner
+from config import config
class TestPgStream(VppTestCase):
@@ -19,6 +20,18 @@ class TestPgStream(VppTestCase):
def __init__(self, *args):
VppTestCase.__init__(self, *args)
+ @classmethod
+ def setUpClass(cls):
+ # increase vapi timeout, to avoid
+ # failures reported on test-cov
+ if config.gcov:
+ cls.vapi_response_timeout = 20
+ super(TestPgStream, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestPgStream, cls).tearDownClass()
+
def setUp(self):
super(TestPgStream, self).setUp()
diff --git a/test/test_udp.py b/test/test_udp.py
index 6315f0efd5e..c7620fb7e9d 100644
--- a/test/test_udp.py
+++ b/test/test_udp.py
@@ -764,7 +764,7 @@ class TestUDP(VppTestCase):
self.assertNotIn("failed", error)
error = self.vapi.cli(
- "test echo client mbytes 10 appns 1 "
+ "test echo client bytes 10m appns 1 "
+ "fifo-size 4k "
+ "syn-timeout 2 uri "
+ uri