[ovs-dev] [PATCH 5/5] netdev-offload-dpdk: Support multiple remote destinations
Salem Sol
salems at nvidia.com
Sun Aug 22 09:25:30 UTC 2021
From: Noa Levy <noae at nvidia.com>
Add support for offloading multiple remote destinations by parsing the
actions and adding remote destinations actions.
Update dump_flow_action in order to support tunnel actions.
Co-authored-by: Salem Sol <salems at nvidia.com>
Signed-off-by: Noa Levy <noae at nvidia.com>
Signed-off-by: Salem Sol <salems at nvidia.com>
---
NEWS | 3 +-
lib/netdev-offload-dpdk.c | 69 ++++++++++++++++++++++++++++++---------
2 files changed, 55 insertions(+), 17 deletions(-)
diff --git a/NEWS b/NEWS
index 793e1adc5..6c45f0f2b 100644
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,8 @@ Post-v2.16.0
by default. 'other_config:dpdk-socket-limit' can be set equal to
the 'other_config:dpdk-socket-mem' to preserve the legacy memory
limiting behavior.
- * Add support for offloading multiple local destinations actions.
+ * Add support for offloading multiple local and remote destinations
+ actions.
v2.16.0 - 16 Aug 2021
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 251515707..9bbf91bd7 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -640,6 +640,13 @@ dump_flow_action(struct ds *s, struct ds *s_extra,
rte_actions->type != RTE_FLOW_ACTION_TYPE_END) {
if (rte_actions->type == RTE_FLOW_ACTION_TYPE_PORT_ID) {
dump_port_id(s_extra, rte_actions->conf);
+ } else if (rte_actions->type ==
+ RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
+ const struct rte_flow_action_raw_encap *raw_encap =
+ rte_actions->conf;
+
+ dump_raw_encap(s, s_extra, raw_encap);
+ ds_put_format(s_extra, "raw_encap index 0 / ");
} else {
ds_put_format(s, "unknown rte flow action (%d)\n",
rte_actions->type);
@@ -1761,37 +1768,53 @@ parse_clone_actions(struct netdev *netdev,
}
/* Maximum number of actions in multiple local destinations.
- * PORT_ID / END
+ * RAW_ENCAP / PORT_ID / END
*/
-#define SAMPLE_EMBEDDED_ACTIONS_NUM 2
+#define SAMPLE_EMBEDDED_ACTIONS_NUM 3
static int
add_sample_embedded_output_action(struct netdev *netdev,
struct flow_actions *actions,
- const struct nlattr *nla)
+ const struct nlattr *nla,
+ const size_t clone_actions_len)
{
struct netdev *outdev;
struct sample_conf {
struct rte_flow_action_sample sample;
struct rte_flow_action_port_id port_id;
+ struct rte_flow_action_raw_encap raw_encap;
struct rte_flow_action sample_actions[SAMPLE_EMBEDDED_ACTIONS_NUM];
} *sample_conf;
BUILD_ASSERT_DECL(offsetof(struct sample_conf, sample) == 0);
struct rte_flow_action *sample_itr;
+ bool is_raw;
int port_id;
- if (get_netdev_by_port(netdev, nla, &port_id, &outdev)) {
- return -1;
- }
- netdev_close(outdev);
-
sample_conf = xzalloc(sizeof *sample_conf);
sample_itr = sample_conf->sample_actions;
+ is_raw = false;
+ if (!clone_actions_len) {
+ if (get_netdev_by_port(netdev, nla, &port_id, &outdev)) {
+ goto err;
+ }
+ netdev_close(outdev);
+ } else {
+ if (parse_clone_actions(netdev, NULL, nla,
+ clone_actions_len, &port_id,
+ &sample_conf->raw_encap)) {
+ goto err;
+ }
+ is_raw = sample_conf->raw_encap.size > 0;
+ }
/* Initialize sample struct */
sample_conf->sample.ratio = 1;
sample_conf->sample.actions = sample_conf->sample_actions;
sample_conf->port_id.id = port_id;
-
+ if (is_raw) {
+ sample_itr->conf = &sample_conf->raw_encap;
+ sample_itr->type = RTE_FLOW_ACTION_TYPE_RAW_ENCAP;
+ sample_itr++;
+ }
sample_itr->conf = &sample_conf->port_id;
sample_itr->type = RTE_FLOW_ACTION_TYPE_PORT_ID;
sample_itr++;
@@ -1799,6 +1822,9 @@ add_sample_embedded_output_action(struct netdev *netdev,
add_flow_action(actions, RTE_FLOW_ACTION_TYPE_SAMPLE, sample_conf);
return 0;
+err:
+ free(sample_conf);
+ return -1;
}
static void
@@ -1874,7 +1900,8 @@ parse_flow_actions(struct netdev *netdev,
return -1;
}
} else {
- if (add_sample_embedded_output_action(netdev, actions, nla)) {
+ if (add_sample_embedded_output_action(netdev, actions, nla,
+ 0)) {
return -1;
}
}
@@ -1898,14 +1925,24 @@ parse_flow_actions(struct netdev *netdev,
}
} else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) {
add_flow_action(actions, RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, NULL);
- } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CLONE &&
- left <= NLA_ALIGN(nla->nla_len)) {
+ } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_CLONE) {
const struct nlattr *clone_actions = nl_attr_get(nla);
size_t clone_actions_len = nl_attr_get_size(nla);
-
- if (parse_clone_actions(netdev, actions, clone_actions,
- clone_actions_len, NULL, NULL)) {
- return -1;
+ /* The last cloned action is parsed and actions are applied
+ * natively, while previous ones are parsed and the actions are
+ * applied embedded in a sample action.
+ */
+ if (left <= NLA_ALIGN(nla->nla_len)) {
+ if (parse_clone_actions(netdev, actions, clone_actions,
+ clone_actions_len, NULL, NULL)) {
+ return -1;
+ }
+ } else {
+ if (add_sample_embedded_output_action(netdev, actions,
+ clone_actions,
+ clone_actions_len)) {
+ return -1;
+ }
}
#ifdef ALLOW_EXPERIMENTAL_API /* Packet restoration API required. */
} else if (nl_attr_type(nla) == OVS_ACTION_ATTR_TUNNEL_POP) {
--
2.21.0
More information about the dev
mailing list