[ovs-dev,v3,3/9] netdev-dpdk: convert ufid to dpdk flow

Message ID 1506404199-23579-4-git-send-email-yliu@fridaylinux.org
State Changes Requested
Headers show
Series
  • OVS-DPDK flow offload with rte_flow
Related show

Commit Message

Yuanhan Liu Sept. 26, 2017, 5:36 a.m.
Flows offloaded to DPDK are identified by rte_flow pointer while OVS
flows are identified by ufid. This patches adds a hmap to convert ufid
to dpdk flow (rte_flow).

Most of the code are stolen from netdev-tc-offloads.c, with some
modificatons.

Some functions are marked as "inline", which is a trick to workaround
the temp "functiond defined but not used" warnings.

Co-authored-by: Finn Christensen <fc@napatech.com>
Signed-off-by: Yuanhan Liu <yliu@fridaylinux.org>
Signed-off-by: Finn Christensen <fc@napatech.com>
---

v3: warn on failed to find ufi_data_flow_data now assocociated with ufid
---
 lib/netdev-dpdk.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

Patch

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index f58e9be..1be9131 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -36,6 +36,7 @@ 
 #include <rte_meter.h>
 #include <rte_pci.h>
 #include <rte_vhost.h>
+#include <rte_flow.h>
 
 #include "dirs.h"
 #include "dp-packet.h"
@@ -58,6 +59,7 @@ 
 #include "sset.h"
 #include "unaligned.h"
 #include "timeval.h"
+#include "uuid.h"
 #include "unixctl.h"
 
 enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
@@ -3312,6 +3314,96 @@  unlock:
     return err;
 }
 
+/*
+ * A mapping from ufid to dpdk rte_flow pointer
+ */
+
+static struct hmap ufid_dpdk_flow = HMAP_INITIALIZER(&ufid_dpdk_flow);
+static struct ovs_mutex ufid_lock = OVS_MUTEX_INITIALIZER;
+
+struct ufid_dpdk_flow_data {
+    struct hmap_node node;
+    ovs_u128 ufid;
+    struct rte_flow *rte_flow;
+};
+
+/*
+ * Find ufid_dpdk_flow_data node associated with @ufid
+ */
+static struct ufid_dpdk_flow_data *
+find_ufid_dpdk_flow_mapping(const ovs_u128 *ufid)
+{
+    size_t hash = hash_bytes(ufid, sizeof(*ufid), 0);
+    struct ufid_dpdk_flow_data *data = NULL;
+
+    ovs_mutex_lock(&ufid_lock);
+    HMAP_FOR_EACH_WITH_HASH (data, node, hash, &ufid_dpdk_flow) {
+        if (ovs_u128_equals(*ufid, data->ufid)) {
+            break;
+        }
+    }
+    ovs_mutex_unlock(&ufid_lock);
+
+    return data;
+}
+
+/*
+ * Remove ufid_dpdk_flow_data node associated with @ufid
+ */
+static inline void
+del_ufid_dpdk_flow_mapping(const ovs_u128 *ufid)
+{
+    struct ufid_dpdk_flow_data *data;
+
+    data = find_ufid_dpdk_flow_mapping(ufid);
+    if (data) {
+        ovs_mutex_lock(&ufid_lock);
+        hmap_remove(&ufid_dpdk_flow, &data->node);
+        free(data);
+        ovs_mutex_unlock(&ufid_lock);
+    } else {
+        VLOG_WARN("ufid "UUID_FMT"is not installed in the dpdk flow mapping\n",
+                  UUID_ARGS((struct uuid *)ufid));
+    }
+}
+
+/* Add ufid to dpdk_flow mapping */
+static inline void
+add_ufid_dpdk_flow_mapping(const ovs_u128 *ufid, struct rte_flow *rte_flow)
+{
+    size_t hash = hash_bytes(ufid, sizeof(*ufid), 0);
+    struct ufid_dpdk_flow_data *data = xzalloc(sizeof(*data));
+
+    /*
+     * We should not simply overwrite an existing rte flow.
+     * We should have deleted it first before re-adding it.
+     * Thus, if following assert triggers, something is wrong:
+     * the rte_flow is not destroyed.
+     */
+    ovs_assert(find_ufid_dpdk_flow_mapping(ufid) == NULL);
+
+    data->ufid = *ufid;
+    data->rte_flow = rte_flow;
+
+    ovs_mutex_lock(&ufid_lock);
+    hmap_insert(&ufid_dpdk_flow, &data->node, hash);
+    ovs_mutex_unlock(&ufid_lock);
+}
+
+/* Get rte_flow by ufid.
+ *
+ * Returns rte rte_flow if successful. Otherwise returns 0.
+ */
+static inline struct rte_flow *
+get_rte_flow_by_ufid(const ovs_u128 *ufid)
+{
+    struct ufid_dpdk_flow_data *data;
+
+    data = find_ufid_dpdk_flow_mapping(ufid);
+    return data ? data->rte_flow : NULL;
+}
+
+
 #define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT,    \
                           SET_CONFIG, SET_TX_MULTIQ, SEND,    \
                           GET_CARRIER, GET_STATS,             \