[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