From 55151ab9d2c7432d7d63dba8a3c0d1fe56408f1b Mon Sep 17 00:00:00 2001 From: Hawker Date: Wed, 25 Nov 2020 11:31:04 +0800 Subject: [PATCH] Bugfix: support rte_flow_isolate for multi lcore (#562) * Bugfix: support rte_flow_isolate init flow isolate mode only run once --- lib/Makefile | 5 ++++ lib/ff_dpdk_if.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index da61edaca..a44f41727 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,6 +26,7 @@ HOST_OS:=$(shell uname -s) #DEBUG=-O0 -gdwarf-2 -g3 -Wno-format-truncation FF_KNI=1 +#FF_FLOW_ISOLATE=1 #FF_NETGRAPH=1 #FF_IPFW=1 #FF_USE_PAGE_ARRAY=1 @@ -76,6 +77,10 @@ endif HOST_CFLAGS+= ${DPDK_CFLAGS} HOST_CFLAGS+= ${CONF_CFLAGS} +ifdef FF_FLOW_ISOLATE +HOST_CFLAGS+= -DFF_FLOW_ISOLATE +endif + ifdef FF_NETGRAPH HOST_CFLAGS+= -DFF_NETGRAPH endif diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 17fd45504..8dbc33b6d 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -533,6 +533,8 @@ init_kni(void) } #endif +//RSS reta update will failed when enable flow isolate +#ifndef FF_FLOW_ISOLATE static void set_rss_table(uint16_t port_id, uint16_t reta_size, uint16_t nb_queues) { @@ -557,6 +559,7 @@ set_rss_table(uint16_t port_id, uint16_t reta_size, uint16_t nb_queues) port_id); } } +#endif static int init_port_start(void) @@ -783,7 +786,8 @@ init_port_start(void) if (ret < 0) { return ret; } - + //RSS reta update will failed when enable flow isolate + #ifndef FF_FLOW_ISOLATE if (nb_queues > 1) { /* set HW rss hash function to Toeplitz. */ if (!rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_HASH)) { @@ -800,6 +804,7 @@ init_port_start(void) set_rss_table(port_id, dev_info.reta_size, nb_queues); } + #endif /* Enable RX in promiscuous mode for the Ethernet device. */ if (ff_global_cfg.dpdk.promiscuous) { @@ -837,6 +842,64 @@ init_clock(void) return 0; } +#ifdef FF_FLOW_ISOLATE +/** Print a message out of a flow error. */ +static int +port_flow_complain(struct rte_flow_error *error) +{ + static const char *const errstrlist[] = { + [RTE_FLOW_ERROR_TYPE_NONE] = "no error", + [RTE_FLOW_ERROR_TYPE_UNSPECIFIED] = "cause unspecified", + [RTE_FLOW_ERROR_TYPE_HANDLE] = "flow rule (handle)", + [RTE_FLOW_ERROR_TYPE_ATTR_GROUP] = "group field", + [RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field", + [RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field", + [RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field", + [RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER] = "transfer field", + [RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure", + [RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length", + [RTE_FLOW_ERROR_TYPE_ITEM_SPEC] = "item specification", + [RTE_FLOW_ERROR_TYPE_ITEM_LAST] = "item specification range", + [RTE_FLOW_ERROR_TYPE_ITEM_MASK] = "item specification mask", + [RTE_FLOW_ERROR_TYPE_ITEM] = "specific pattern item", + [RTE_FLOW_ERROR_TYPE_ACTION_NUM] = "number of actions", + [RTE_FLOW_ERROR_TYPE_ACTION_CONF] = "action configuration", + [RTE_FLOW_ERROR_TYPE_ACTION] = "specific action", + }; + const char *errstr; + char buf[32]; + int err = rte_errno; + + if ((unsigned int)error->type >= RTE_DIM(errstrlist) || + !errstrlist[error->type]) + errstr = "unknown type"; + else + errstr = errstrlist[error->type]; + printf("Caught error type %d (%s): %s%s: %s\n", + error->type, errstr, + error->cause ? (snprintf(buf, sizeof(buf), "cause: %p, ", + error->cause), buf) : "", + error->message ? error->message : "(no stated reason)", + rte_strerror(err)); + return -err; +} + +static int +port_flow_isolate(uint16_t port_id, int set) +{ + struct rte_flow_error error; + + /* Poisoning to make sure PMDs update it in case of error. */ + memset(&error, 0x66, sizeof(error)); + if (rte_flow_isolate(port_id, set, &error)) + return port_flow_complain(&error); + printf("Ingress traffic on port %u is %s to the defined flow rules\n", + port_id, + set ? "now restricted" : "not restricted anymore"); + return 0; +} +#endif + int ff_dpdk_init(int argc, char **argv) { @@ -879,7 +942,16 @@ ff_dpdk_init(int argc, char **argv) #ifdef FF_USE_PAGE_ARRAY ff_mmap_init(); #endif - + +#ifdef FF_FLOW_ISOLATE + // run once in primary process + if (0 == lcore_conf.tx_queue_id[0]){ + ret = port_flow_isolate(0, 1); + if (ret < 0) + rte_exit(EXIT_FAILURE, "init_port_isolate failed\n"); + } +#endif + ret = init_port_start(); if (ret < 0) { rte_exit(EXIT_FAILURE, "init_port_start failed\n");