Invoke scapy to generate packet templates for each queue of specific port, command format: scapy <port> <pattern> Example: scapy 0 Ether()/IP()/GRE()/IP()/UDP(dport=(2,5))/"cool"
Signed-off-by: Xueming Li <xuemi...@mellanox.com> --- app/test-pmd/Makefile | 5 +++ app/test-pmd/cmdline.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++- config/common_base | 2 + 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile index 2c50f68a9..220be17f2 100644 --- a/app/test-pmd/Makefile +++ b/app/test-pmd/Makefile @@ -91,6 +91,11 @@ endif endif +ifeq ($(CONFIG_RTE_TEST_PMD_SCAPY),y) +LDLIBS += -l$(CONFIG_RTE_PYTHON) +CFLAGS += -I/usr/include/$(CONFIG_RTE_PYTHON) +endif + CFLAGS_cmdline.o := -D_GNU_SOURCE include $(RTE_SDK)/mk/rte.app.mk diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index bb01e989a..b6df7ea75 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -33,6 +33,9 @@ */ #include <stdarg.h> +#ifdef RTE_TEST_PMD_SCAPY +#include <Python.h> +#endif #include <errno.h> #include <stdio.h> #include <stdint.h> @@ -48,7 +51,6 @@ #endif #endif #include <netinet/in.h> - #include <sys/queue.h> #include <rte_common.h> @@ -15391,6 +15393,98 @@ cmdline_parse_inst_t cmd_load_from_file = { }, }; +#ifdef RTE_TEST_PMD_SCAPY +/* Common result structure for file commands */ +struct cmd_scapy_result { + cmdline_fixed_string_t scapy; + portid_t port; + cmdline_fixed_string_t pattern; +}; + +/* Common CLI fields for file commands */ +cmdline_parse_token_string_t cmd_scapy_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_scapy_result, scapy, "scapy"); +cmdline_parse_token_num_t cmd_scapy_port = + TOKEN_NUM_INITIALIZER(struct cmd_scapy_result, port, UINT16); +cmdline_parse_token_string_t cmd_scapy_pattern = + TOKEN_STRING_INITIALIZER(struct cmd_scapy_result, pattern, NULL); + +static void +cmd_scapy_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_scapy_result *res = parsed_result; + PyObject *mod, *gdict, *ldict, *list, *item; + int i, socket; + int len = 0; + struct rte_mbuf *mbuf; + char str[sizeof(res->pattern) + 128]; + + socket = rte_eth_dev_socket_id(res->port); + /* Clean port templates */ + for (i = 0; i < RTE_MAX_QUEUES_PER_PORT; i++) + if (pkt_templ[res->port][i]) + rte_mbuf_raw_free(pkt_templ[res->port][i]); + /* Invoke scapy */ + Py_Initialize(); + if (!Py_IsInitialized()) + goto err; + if (PyRun_SimpleString("import sys;from scapy.all import *")) + goto err; + mod = PyImport_AddModule("__main__"); + if (!mod) + goto err; + gdict = PyModule_GetDict(mod); + ldict = PyDict_New(); + if (!gdict || !ldict) + goto err; + snprintf(str, sizeof(str), "p = %s;r = [str(x) for x in p];\n", + res->pattern); + PyRun_String(str, Py_file_input, gdict, ldict); + list = PyDict_GetItem(ldict, PyString_FromString("r")); + if (!list) + goto err; + for (i = 0; i < PyList_Size(list) && i < RTE_MAX_QUEUES_PER_PORT; i++) { + item = PyList_GET_ITEM(list, i); + /* allocate mbuf & copy raw pkt */ + mbuf = rte_mbuf_raw_alloc(mbuf_pool_find(socket)); + if (!mbuf) + goto end; + rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, 0), + PyString_AsString(item), + PyString_Size(item)); + len = PyString_Size(item); + mbuf->data_len = len > TXONLY_DEF_PACKET_LEN ? + len : TXONLY_DEF_PACKET_LEN; + pkt_templ[res->port][i] = mbuf; + } + if (len > TXONLY_DEF_PACKET_LEN) + printf("%d templates saved, size: %d\n", i, len); + else + printf("%d templates saved, size: %d -> %d\n", i, len, + TXONLY_DEF_PACKET_LEN); + goto end; +err: + printf("Error!\n"); +end: + Py_Finalize(); +} + +cmdline_parse_inst_t cmd_scapy = { + .f = cmd_scapy_parsed, + .data = NULL, + .help_str = "scapy <port> Ether()/IP()/GRE()/IP()/UDP(dport=(2,5))/\"cool\"", + .tokens = { + (void *)&cmd_scapy_cmd, + (void *)&cmd_scapy_port, + (void *)&cmd_scapy_pattern, + NULL, + }, +}; +#endif + /* ******************************************************************************** */ /* list of instructions */ @@ -15399,6 +15493,9 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_help_long, (cmdline_parse_inst_t *)&cmd_quit, (cmdline_parse_inst_t *)&cmd_load_from_file, +#ifdef RTE_TEST_PMD_SCAPY + (cmdline_parse_inst_t *)&cmd_scapy, +#endif (cmdline_parse_inst_t *)&cmd_showport, (cmdline_parse_inst_t *)&cmd_showqueue, (cmdline_parse_inst_t *)&cmd_showportall, diff --git a/config/common_base b/config/common_base index d9471e806..4abb6f2e1 100644 --- a/config/common_base +++ b/config/common_base @@ -785,6 +785,8 @@ CONFIG_RTE_APP_TEST_RESOURCE_TAR=n CONFIG_RTE_TEST_PMD=y CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n +CONFIG_RTE_TEST_PMD_SCAPY=y +CONFIG_RTE_PYTHON=python2.7 # # Compile the crypto performance application -- 2.13.3