[ovs-dev] [PATCH 3/7] netdev-dpdk: convert ufid to dpdk flow

Yuanhan Liu yliu at fridaylinux.org
Wed Aug 23 06:24:18 UTC 2017


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.

Signed-off-by: Yuanhan Liu <yliu at fridaylinux.org>
Signed-off-by: Finn Christensen <fc at napatech.com>
---
 lib/netdev-dpdk.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 1aaf6f7..15fef1e 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"
@@ -3310,6 +3311,93 @@ 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);
+    }
+}
+
+/* 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,             \
-- 
2.7.4



More information about the dev mailing list