@@ -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, \