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 <[email protected]> Signed-off-by: Yuanhan Liu <[email protected]> Signed-off-by: Finn Christensen <[email protected]> --- v3: warn on failed to find ufi_data_flow_data now assocociated with ufid --- lib/netdev-dpdk.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) 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, \ -- 2.7.4 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
