From: Ophir Munk <ophirmu@mellanox.com>
To: dev@dpdk.org, Pascal Mazon <pascal.mazon@6wind.com>
Cc: Thomas Monjalon <thomas@monjalon.net>,
Olga Shern <olgas@mellanox.com>,
Ophir Munk <ophirmu@mellanox.com>
Subject: [dpdk-dev] [PATCH v5 1/6] net/tap: support actions for different classifiers
Date: Thu, 18 Jan 2018 13:38:06 +0000 [thread overview]
Message-ID: <1516282691-29698-2-git-send-email-ophirmu@mellanox.com> (raw)
In-Reply-To: <1516282691-29698-1-git-send-email-ophirmu@mellanox.com>
Add a generic TC actions handling for TC actions: "mirred",
"gact", "skbedit". This will be useful when introducing
BPF actions, as it uses TCA_BPF_ACT instead of TCA_FLOWER_ACT
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/tap/Makefile | 8 ++
drivers/net/tap/rte_eth_tap.h | 4 +-
drivers/net/tap/tap_flow.c | 224 +++++++++++++++++++++++++-----------------
3 files changed, 145 insertions(+), 91 deletions(-)
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index fd4195f..fbf84e1 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -12,6 +12,12 @@ EXPORT_MAP := rte_pmd_tap_version.map
LIBABIVER := 1
+#
+# TAP_MAX_QUEUES must be a power of 2
+#
+ifeq ($(TAP_MAX_QUEUES),)
+ TAP_MAX_QUEUES = 16
+endif
CFLAGS += -O3
CFLAGS += -I$(SRCDIR)
CFLAGS += -I.
@@ -20,6 +26,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
LDLIBS += -lrte_bus_vdev
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
#
# all source are stored in SRCS-y
#
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..202b3cd 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
#include <rte_ether.h>
#ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES 16
+#define RTE_PMD_TAP_MAX_QUEUES TAP_MAX_QUEUES
#else
#define RTE_PMD_TAP_MAX_QUEUES 1
#endif
@@ -90,6 +90,8 @@ struct pmd_internals {
int ioctl_sock; /* socket for ioctl calls */
int nlsk_fd; /* Netlink socket fd */
int flow_isolate; /* 1 if flow isolation is enabled */
+ int flower_support; /* 1 if kernel supports, else 0 */
+ int flower_vlan_support; /* 1 if kernel supports, else 0 */
LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */
/* implicit rte_flow rules set when a remote device is active */
LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 90b2654..d2a69a7 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -33,6 +33,7 @@
#include <errno.h>
#include <string.h>
+#include <unistd.h>
#include <sys/queue.h>
#include <rte_byteorder.h>
@@ -104,6 +105,19 @@ struct remote_rule {
int mirred;
};
+struct action_data {
+ char id[16];
+
+ union {
+ struct tc_gact gact;
+ struct tc_mirred mirred;
+ struct skbedit {
+ struct tc_skbedit skbedit;
+ uint16_t queue;
+ } skbedit;
+ };
+};
+
static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -819,111 +833,89 @@ tap_flow_item_validate(const struct rte_flow_item *item,
}
/**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
+ * Configure the kernel with a TC action and its configured parameters
+ * Handled actions: "gact", "mirred", "skbedit", "bpf"
*
- * @param[in, out] flow
- * Flow to be filled.
- * @param[in] action
- * Appropriate action to be set in the TCA_GACT_PARMS structure.
+ * @param[in] flow
+ * Pointer to rte flow containing the netlink message
*
- * @return
- * 0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_gact(struct rte_flow *flow, int action)
-{
- struct nlmsg *msg = &flow->msg;
- size_t act_index = 1;
- struct tc_gact p = {
- .action = action
- };
-
- if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
- return -1;
- if (tap_nlattr_nested_start(msg, act_index++) < 0)
- return -1;
- tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
- if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
- return -1;
- tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
- tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
- tap_nlattr_nested_finish(msg); /* nested act_index */
- tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
- return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
+ * @param[in, out] act_index
+ * Pointer to action sequence number in the TC command
*
- * @param[in, out] flow
- * Flow to be filled.
- * @param[in] ifindex
- * Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- * Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
+ * @param[in] adata
+ * Pointer to struct holding the action parameters
*
* @return
- * 0 if checks are alright, -1 otherwise.
+ * -1 on failure, 0 on success
*/
static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
{
struct nlmsg *msg = &flow->msg;
- size_t act_index = 1;
- struct tc_mirred p = {
- .eaction = action_type,
- .ifindex = ifindex,
- };
- if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
- return -1;
- if (tap_nlattr_nested_start(msg, act_index++) < 0)
+ if (tap_nlattr_nested_start(msg, (*act_index)++) < 0)
return -1;
- tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+
+ tap_nlattr_add(&msg->nh, TCA_ACT_KIND,
+ strlen(adata->id) + 1, adata->id);
if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
return -1;
- if (action_type == TCA_EGRESS_MIRROR)
- p.action = TC_ACT_PIPE;
- else /* REDIRECT */
- p.action = TC_ACT_STOLEN;
- tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+ if (strcmp("gact", adata->id) == 0) {
+ tap_nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+ &adata->gact);
+ } else if (strcmp("mirred", adata->id) == 0) {
+ if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+ adata->mirred.action = TC_ACT_PIPE;
+ else /* REDIRECT */
+ adata->mirred.action = TC_ACT_STOLEN;
+ tap_nlattr_add(&msg->nh, TCA_MIRRED_PARMS,
+ sizeof(adata->mirred),
+ &adata->mirred);
+ } else if (strcmp("skbedit", adata->id) == 0) {
+ tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+ sizeof(adata->skbedit.skbedit),
+ &adata->skbedit.skbedit);
+ tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+ adata->skbedit.queue);
+ } else {
+ return -1;
+ }
tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
tap_nlattr_nested_finish(msg); /* nested act_index */
- tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
return 0;
}
/**
- * Transform a QUEUE action item in the provided flow for TC.
+ * Helper function to send a serie of TC actions to the kernel
*
- * @param[in, out] flow
- * Flow to be filled.
- * @param[in] queue
- * Queue id to use.
+ * @param[in] flow
+ * Pointer to rte flow containing the netlink message
+ *
+ * @param[in] nb_actions
+ * Number of actions in an array of action structs
+ *
+ * @param[in] data
+ * Pointer to an array of action structs
+ *
+ * @param[in] classifier_actions
+ * The classifier on behave of which the actions are configured
*
* @return
- * 0 if checks are alright, -1 otherwise.
+ * -1 on failure, 0 on success
*/
static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+ int classifier_action)
{
struct nlmsg *msg = &flow->msg;
size_t act_index = 1;
- struct tc_skbedit p = {
- .action = TC_ACT_PIPE
- };
+ int i;
- if (tap_nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
- return -1;
- if (tap_nlattr_nested_start(msg, act_index++) < 0)
+ if (tap_nlattr_nested_start(msg, classifier_action) < 0)
return -1;
- tap_nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
- if (tap_nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
- return -1;
- tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
- tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
- tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
- tap_nlattr_nested_finish(msg); /* nested act_index */
+ for (i = 0; i < nb_actions; i++)
+ if (add_action(flow, &act_index, data + i) < 0)
+ return -1;
tap_nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
return 0;
}
@@ -1056,7 +1048,12 @@ priv_flow_process(struct pmd_internals *pmd,
}
}
if (mirred && flow) {
- uint16_t if_index = pmd->if_index;
+ struct action_data adata = {
+ .id = "mirred",
+ .mirred = {
+ .eaction = mirred,
+ },
+ };
/*
* If attr->egress && mirred, then this is a special
@@ -1064,9 +1061,13 @@ priv_flow_process(struct pmd_internals *pmd,
* redirect packets coming from the DPDK App, out
* through the remote netdevice.
*/
- if (attr->egress)
- if_index = pmd->remote_if_index;
- if (add_action_mirred(flow, if_index, mirred) < 0)
+ adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+ pmd->remote_if_index;
+ if (mirred == TCA_EGRESS_MIRROR)
+ adata.mirred.action = TC_ACT_PIPE;
+ else
+ adata.mirred.action = TC_ACT_STOLEN;
+ if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
goto exit_action_not_supported;
else
goto end;
@@ -1080,14 +1081,33 @@ priv_flow_process(struct pmd_internals *pmd,
if (action)
goto exit_action_not_supported;
action = 1;
- if (flow)
- err = add_action_gact(flow, TC_ACT_SHOT);
+ if (flow) {
+ struct action_data adata = {
+ .id = "gact",
+ .gact = {
+ .action = TC_ACT_SHOT,
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
if (action)
goto exit_action_not_supported;
action = 1;
- if (flow)
- err = add_action_gact(flow, TC_ACT_UNSPEC);
+ if (flow) {
+ struct action_data adata = {
+ .id = "gact",
+ .gact = {
+ /* continue */
+ .action = TC_ACT_UNSPEC,
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
const struct rte_flow_action_queue *queue =
(const struct rte_flow_action_queue *)
@@ -1099,22 +1119,46 @@ priv_flow_process(struct pmd_internals *pmd,
if (!queue ||
(queue->index > pmd->dev->data->nb_rx_queues - 1))
goto exit_action_not_supported;
- if (flow)
- err = add_action_skbedit(flow, queue->index);
+ if (flow) {
+ struct action_data adata = {
+ .id = "skbedit",
+ .skbedit = {
+ .skbedit = {
+ .action = TC_ACT_PIPE,
+ },
+ .queue = queue->index,
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
/* Fake RSS support. */
const struct rte_flow_action_rss *rss =
(const struct rte_flow_action_rss *)
actions->conf;
- if (action)
+ if (action++)
goto exit_action_not_supported;
- action = 1;
+
if (!rss || rss->num < 1 ||
(rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
goto exit_action_not_supported;
- if (flow)
- err = add_action_skbedit(flow, rss->queue[0]);
+ if (flow) {
+ struct action_data adata = {
+ .id = "skbedit",
+ .skbedit = {
+ .skbedit = {
+ .action = TC_ACT_PIPE,
+ },
+ .queue = rss->queue[0],
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else {
goto exit_action_not_supported;
}
--
2.7.4
next prev parent reply other threads:[~2018-01-18 13:38 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-17 12:21 [dpdk-dev] [PATCH v1 0/3] TAP RSS eBPF cover letter Ophir Munk
2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 1/3] net/tap: add BPF sections for TAP device Ophir Munk
2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 2/3] net/tap: add eBPF instructions Ophir Munk
2017-12-17 12:21 ` [dpdk-dev] [PATCH v1 3/3] net/tap: add eBPF classifiers map and actions Ophir Munk
2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 0/2] TAP RSS eBPF cover letter Ophir Munk
2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
2017-12-28 10:09 ` [dpdk-dev] [PATCH v2 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
2018-01-10 7:06 ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Ophir Munk
2018-01-10 7:06 ` [dpdk-dev] [PATCH v3 1/2] net/tap: add eBPF instructions to TAP device Ophir Munk
2018-01-10 9:34 ` Pascal Mazon
2018-01-10 10:12 ` Ophir Munk
2018-01-10 7:06 ` [dpdk-dev] [PATCH v3 2/2] net/tap: implement RSS with eBPF classifier and action Ophir Munk
2018-01-10 10:19 ` Pascal Mazon
2018-01-11 17:20 ` Ophir Munk
2018-01-10 10:10 ` [dpdk-dev] [PATCH v3 0/2] TAP RSS eBPF cover letter Jason Wang
2018-01-10 15:34 ` Ophir Munk
2018-01-11 2:45 ` Jason Wang
2018-01-11 17:45 ` [dpdk-dev] [PATCH v4 0/5] " Ophir Munk
2018-01-11 17:45 ` [dpdk-dev] [PATCH v4 1/5] net/tap: support actions for different classifiers Ophir Munk
2018-01-11 17:45 ` [dpdk-dev] [PATCH v4 2/5] net/tap: add eBPF bytes code Ophir Munk
2018-01-11 17:45 ` [dpdk-dev] [PATCH v4 3/5] net/tap: add eBPF program file Ophir Munk
2018-01-11 17:45 ` [dpdk-dev] [PATCH v4 4/5] net/tap: add eBPF API Ophir Munk
2018-01-11 17:45 ` [dpdk-dev] [PATCH v4 5/5] net/tap: implement TAP RSS using eBPF Ophir Munk
2018-01-18 13:38 ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Ophir Munk
2018-01-18 13:38 ` Ophir Munk [this message]
2018-01-18 13:38 ` [dpdk-dev] [PATCH v5 2/6] net/tap: add eBPF bytes code Ophir Munk
2018-01-18 13:38 ` [dpdk-dev] [PATCH v5 3/6] net/tap: add eBPF program file Ophir Munk
2018-01-18 13:38 ` [dpdk-dev] [PATCH v5 4/6] net/tap: add eBPF API Ophir Munk
2018-01-18 13:38 ` [dpdk-dev] [PATCH v5 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
2018-01-18 13:38 ` [dpdk-dev] [PATCH v5 6/6] doc: detail new tap RSS feature in guides Ophir Munk
2018-01-19 6:48 ` [dpdk-dev] [PATCH v5 0/6] TAP RSS eBPF cover letter Pascal Mazon
2018-01-20 16:15 ` Ferruh Yigit
2018-01-20 21:25 ` Ophir Munk
2018-01-21 14:20 ` Ferruh Yigit
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 " Ophir Munk
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 1/6] net/tap: support actions for different classifiers Ophir Munk
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 2/6] net/tap: add eBPF program file Ophir Munk
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 3/6] net/tap: add eBPF bytes code Ophir Munk
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 4/6] net/tap: add eBPF API Ophir Munk
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 5/6] net/tap: implement TAP RSS using eBPF Ophir Munk
2018-01-20 21:11 ` [dpdk-dev] [PATCH v6 6/6] doc: detail new tap RSS feature in guides Ophir Munk
2018-01-21 14:50 ` [dpdk-dev] [PATCH v6 0/6] TAP RSS eBPF cover letter Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1516282691-29698-2-git-send-email-ophirmu@mellanox.com \
--to=ophirmu@mellanox.com \
--cc=dev@dpdk.org \
--cc=olgas@mellanox.com \
--cc=pascal.mazon@6wind.com \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).