Skip to content

Commit

Permalink
Bugfix: support rte_flow_isolate for multi lcore (F-Stack#562)
Browse files Browse the repository at this point in the history
* Bugfix: support rte_flow_isolate

init flow isolate mode only run once
  • Loading branch information
hawkxiang authored Nov 25, 2020
1 parent 32ff8fd commit 2474e16
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
5 changes: 5 additions & 0 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
76 changes: 74 additions & 2 deletions lib/ff_dpdk_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
Expand Down Expand Up @@ -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)) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 2474e16

Please sign in to comment.