Message ID | 1478012010-32494-4-git-send-email-paulb@mellanox.com |
---|---|
State | Changes Requested |
Headers | show |
On 1 November 2016 at 07:53, Paul Blakey <paulb@mellanox.com> wrote: > A flow in ovs can be identified by its ufid, and in tc by its > flow handle + priority. > We use the flow protocol number as the priority when offloading to tc. > So we save a map that maps from ovs ufid <-> tc flow handle + protocol. > Also added a map to map ovs in_port to/from netdevice to be used > when offloading/dumping a flow. > > Signed-off-by: Paul Blakey <paulb@mellanox.com> > Signed-off-by: Shahar Klein <shahark@mellanox.com> Is it a stateless mapping between UFID and tc flow handle/priority? In that case do you need to store it? > --- > lib/dpif-hw-acc.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/dpif-hw-acc.h | 21 ++++ > 2 files changed, 313 insertions(+) > > diff --git a/lib/dpif-hw-acc.c b/lib/dpif-hw-acc.c > index 252a90f..5f65904 100644 > --- a/lib/dpif-hw-acc.c > +++ b/lib/dpif-hw-acc.c > @@ -40,10 +40,290 @@ > #include "unaligned.h" > #include "util.h" > #include "openvswitch/vlog.h" > +#include "netdev-provider.h" > #include "dpif-hw-acc.h" > > VLOG_DEFINE_THIS_MODULE(dpif_hw_acc); > > +static char * > +printufid(const ovs_u128 * ovs_ufid) > +{ > + static char ufid[64]; > + > + if (ovs_ufid) > + sprintf(ufid, "%x%x%x%x", ovs_ufid->u32[0], ovs_ufid->u32[1], > + ovs_ufid->u32[2], ovs_ufid->u32[3]); > + else > + sprintf(ufid, "(missing_ufid)"); > + return ufid; > +} OVS provides plenty of libraries using dynamic-string.h and odp-util.h to print a variety of things like this, not to mention that they are printed using the VLOG module to ensure logs are consistently outputted (in a thread-safe way!) to the appropriate locations. Please reuse them (or extend them if they don't quite do what you need). > +static inline size_t > +hash_ufid(const ovs_u128 * ovs_ufid) > +{ > + return hash_words64((const uint64_t *) ovs_ufid, > + sizeof *ovs_ufid / sizeof (uint64_t), 0); > +} > + > +static inline size_t > +hash_port(odp_port_t port) > +{ > + return hash_int((int) port, 0); > +} flow.h provides this function. Please use it. > +static inline size_t > +hash_handle_prio_port(int handle, uint16_t prio, odp_port_t port) > +{ > + /* TODO: fix utint cast */ > + return hash_int((uint32_t) prio, hash_int(handle, hash_port(port))); > +} Maybe you want hash_3words()? > + > +static struct netdev * > +port_find(struct dpif_hw_acc *dpif, odp_port_t port) > +{ > + struct port_netdev_hash_data *data; > + size_t hash = hash_port(port); > + struct netdev *res = 0; > + > + ovs_mutex_lock(&dpif->hash_mutex); > + HMAP_FOR_EACH_WITH_HASH(data, node, hash, &dpif->port_to_netdev) { > + if (data->port == port) > + break; > + } > + if (data) { > + res = data->netdev; > + VLOG_DBG > + ("found port mapping: port number %d -> port name %s (pointer: %p)\n", > + port, res->name, res); > + } > + ovs_mutex_unlock(&dpif->hash_mutex); > + > + return res; > +} > + > +static int > +port_del_name(struct dpif_hw_acc *dpif, char *name) > +{ > + struct port_netdev_hash_data *data; > + > + ovs_mutex_lock(&dpif->hash_mutex); > + HMAP_FOR_EACH(data, node, &dpif->port_to_netdev) { > + if (!strcmp(data->netdev->name, name)) > + break; > + } > + if (data) > + hmap_remove(&dpif->port_to_netdev, &data->node); > + ovs_mutex_unlock(&dpif->hash_mutex); > + > + free(data); > + return data ? 1 : 0; > +} > + > +static int > +port_del(struct dpif_hw_acc *dpif, odp_port_t port) > +{ > + struct port_netdev_hash_data *data; > + size_t hash = hash_port(port); > + > + ovs_mutex_lock(&dpif->hash_mutex); > + HMAP_FOR_EACH_WITH_HASH(data, node, hash, &dpif->port_to_netdev) { > + if (data->port == port) > + break; > + } > + if (data) > + hmap_remove(&dpif->port_to_netdev, &data->node); > + ovs_mutex_unlock(&dpif->hash_mutex); > + > + free(data); > + return data ? 1 : 0; > +} > + > +static int > +port_add(struct dpif_hw_acc *dpif, odp_port_t port, struct netdev *netdev) > +{ > + struct port_netdev_hash_data *data; > + size_t hash = hash_port(port); > + int ret = 0; > + > + if (!netdev || !netdev->name || !port) > + return -1; > + > + if (netdev->netdev_class == &netdev_internal_class) { > + if (!strcmp(netdev->name, "skip_hw")) { > + tc_set_skip_hw(true); > + } > + return -1; > + } > + if (port_del(dpif, port) || port_del_name(dpif, netdev->name)) { > + VLOG_DBG > + ("%s %d %s (%p) port number %d name: %s, deleted to be replaced\n", > + __FILE__, __LINE__, __func__, dpif, port, netdev->name); > + ret = 1; > + } > + > + data = malloc(sizeof (struct port_netdev_hash_data)); > + data->netdev = netdev; > + data->port = port; > + > + VLOG_DBG > + ("%s %d %s (%p): adding new port mapping: %d -> netdev %p name: %s, type: %s, ifindex: %d, hash: %lu\n", > + __FILE__, __LINE__, __func__, dpif, port, netdev, netdev->name, > + netdev->netdev_class->type, netdev_get_ifindex(netdev), hash); > + ovs_mutex_lock(&dpif->hash_mutex); > + hmap_insert(&dpif->port_to_netdev, &data->node, hash); > + ovs_mutex_unlock(&dpif->hash_mutex); > + return ret; > +} > + > +static int > +delhandle(struct dpif_hw_acc *dpif, const ovs_u128 * ovs_ufid) > +{ > + struct ufid_handle_hash_data *data; > + size_t hash; > + > + if (!ovs_ufid) { > + VLOG_ERR("%s %d %s (%p) can't delete missing ufid\n", __FILE__, > + __LINE__, __func__, dpif); > + return 0; > + } > + hash = hash_ufid(ovs_ufid); > + > + VLOG_DBG("%s %d %s (%p): removing %s\n", __FILE__, __LINE__, __func__, > + dpif, printufid(ovs_ufid)); > + > + ovs_mutex_lock(&dpif->hash_mutex); > + HMAP_FOR_EACH_WITH_HASH(data, node_ufid, hash, &dpif->ufid_to_handle) { > + if (!memcmp(&data->ovs_ufid, ovs_ufid, sizeof (*ovs_ufid))) > + break; > + } > + if (data) { > + VLOG_DBG("%s %d %s (%p) ufid %s found! handle: %d, removing it\n", > + __FILE__, __LINE__, __func__, dpif, printufid(ovs_ufid), > + data->handle); > + hmap_remove(&dpif->ufid_to_handle, &data->node_ufid); > + hmap_remove(&dpif->handle_to_ufid, &data->node_handle); > + free(data); > + } > + ovs_mutex_unlock(&dpif->hash_mutex); > + return data ? 1 : 0; > +} > + > +static int > +puthandle(struct dpif_hw_acc *dpif, const ovs_u128 * ovs_ufid, > + struct netdev *in, odp_port_t port, int handle, uint16_t prio) > +{ > + int ret = 0; > + size_t hash_to_ufid = hash_handle_prio_port(handle, prio, port); > + > + if (!ovs_ufid) { > + VLOG_ERR("%s %d %s (%p) missing UFID!\n", __FILE__, __LINE__, __func__, > + dpif); > + return 0; > + } > + > + if (delhandle(dpif, ovs_ufid)) > + ret = 1; > + > + struct ufid_handle_hash_data *data = > + malloc(sizeof (struct ufid_handle_hash_data)); > + data->ovs_ufid = *ovs_ufid; > + data->handle = handle; > + data->netdev = in; > + data->port = port; > + data->prio = prio; > + > + ovs_mutex_lock(&dpif->hash_mutex); > + hmap_insert(&dpif->ufid_to_handle, &data->node_ufid, hash_ufid(ovs_ufid)); > + hmap_insert(&dpif->handle_to_ufid, &data->node_handle, hash_to_ufid); > + VLOG_DBG > + ("%s %d %s (%p) added mapping %s <-> (handle: %d, prio: %d, port: %d, indev: %p)\n", > + __FILE__, __LINE__, __func__, dpif, printufid(ovs_ufid), handle, > + prio, port, in); > + ovs_mutex_unlock(&dpif->hash_mutex); > + return ret; > +} > + > +static ovs_u128 * > +findufid(struct dpif_hw_acc *dpif, odp_port_t port, int handle, > + uint16_t prio) > +{ > + struct ufid_handle_hash_data *data; > + size_t hash = hash_handle_prio_port(handle, prio, port); > + > + VLOG_DBG > + ("%s %d %s (%p) finding ufid of (handle: %d, prio: %d, port: %d), hash: %lu\n", > + __FILE__, __LINE__, __func__, dpif, handle, prio, port, hash); > + > + ovs_mutex_lock(&dpif->hash_mutex); > + HMAP_FOR_EACH_WITH_HASH(data, node_handle, hash, &dpif->handle_to_ufid) { > + if (data->handle == handle && data->port == port > + && data->prio == prio) > + break; > + } > + ovs_mutex_unlock(&dpif->hash_mutex); > + > + return data ? &data->ovs_ufid : 0; > +} > + > +static int > +gethandle(struct dpif_hw_acc *dpif, const ovs_u128 * ovs_ufid, > + struct netdev **in, uint16_t *prio, const char *func, int print) > +{ > + struct ufid_handle_hash_data *data; > + int handle = 0; > + size_t hash = 0; > + > + if (in) > + *in = 0; > + > + if (!ovs_ufid) { > + VLOG_DBG("%s %d %s (%p) called by %s without a ufid.\n", __FILE__, > + __LINE__, __func__, dpif, func); > + return 0; > + } else > + hash = hash_ufid(ovs_ufid); > + > + if (print) > + VLOG_DBG("%s %d %s (%p) called by %s to find ufid %s\n", __FILE__, > + __LINE__, __func__, dpif, func, printufid(ovs_ufid)); > + > + ovs_mutex_lock(&dpif->hash_mutex); > + HMAP_FOR_EACH_WITH_HASH(data, node_ufid, hash, &dpif->ufid_to_handle) { > + if (!memcmp(&data->ovs_ufid, ovs_ufid, sizeof (*ovs_ufid))) > + break; > + } > + ovs_mutex_unlock(&dpif->hash_mutex); > + > + if (data && (!data->handle || !data->netdev || !data->prio)) { > + VLOG_ERR > + ("mising handle/dev/prio for ufid: %s, handle: %d, netdev: %p, prio: %d\n", > + printufid(ovs_ufid), data->handle, data->netdev, data->prio); > + return 0; > + } > + handle = data ? data->handle : 0; > + if (in) > + *in = data ? data->netdev : 0; > + if (prio) > + *prio = data ? data->prio : 0; > + if (print && handle) > + VLOG_DBG("found ufid: %s, handle: %d, prio: %d, netdev: %p\n", > + printufid(ovs_ufid), handle, data->prio, data->netdev); > + return handle; > +} > + > +static int > +get_ovs_port(struct dpif_hw_acc *dpif, int ifindex) OVS ports aren't ints. Please use the appropriate types. (Presumably odp_port_t). I think that compiling with GCC + sparse should pick up on things like this. > +{ > + struct port_netdev_hash_data *data; > + > + HMAP_FOR_EACH(data, node, &dpif->port_to_netdev) { > + if (netdev_get_ifindex(data->netdev) == ifindex) { > + return data->port; > + } > + } > + return -1; > +} > + > static struct dpif_hw_acc * > dpif_hw_acc_cast(const struct dpif *dpif) > { > @@ -52,6 +332,16 @@ dpif_hw_acc_cast(const struct dpif *dpif) > } > > static int > +initmaps(struct dpif_hw_acc *dpif) > +{ > + hmap_init(&dpif->port_to_netdev); > + hmap_init(&dpif->ufid_to_handle); > + hmap_init(&dpif->handle_to_ufid); > + ovs_mutex_init(&dpif->hash_mutex); > + return 0; > +} > + > +static int > dpif_hw_acc_open(const struct dpif_class *class OVS_UNUSED, > const char *name, bool create, struct dpif **dpifp) > { > @@ -75,6 +365,8 @@ dpif_hw_acc_open(const struct dpif_class *class OVS_UNUSED, > } > dpif = xzalloc(sizeof *dpif); > > + initmaps(dpif); > + > *CONST_CAST(const char **, &dpif->name) = xstrdup(name); > uint16_t netflow_id = hash_string(dpif->name, 0); > > diff --git a/lib/dpif-hw-acc.h b/lib/dpif-hw-acc.h > index 5559b41..10467e3 100644 > --- a/lib/dpif-hw-acc.h > +++ b/lib/dpif-hw-acc.h > @@ -2,6 +2,7 @@ > #define DPIF_HW_NETLINK_H 1 > > #include "ovs-thread.h" > +#include "hmap.h" > #include "dpif-provider.h" > > /* Datapath interface for the openvswitch Linux kernel module. */ > @@ -9,6 +10,26 @@ struct dpif_hw_acc { > struct dpif dpif; > struct dpif *lp_dpif_netlink; > const char *const name; > + struct ovs_mutex hash_mutex; > + struct hmap port_to_netdev; > + struct hmap ufid_to_handle; > + struct hmap handle_to_ufid; > +}; > + > +struct port_netdev_hash_data { > + struct hmap_node node; > + struct netdev *netdev; > + odp_port_t port; > +}; > + > +struct ufid_handle_hash_data { > + struct hmap_node node_ufid; > + struct hmap_node node_handle; > + ovs_u128 ovs_ufid; > + int handle; > + int prio; > + struct netdev *netdev; > + odp_port_t port; > }; > > #endif > -- > 1.8.3.1 >
diff --git a/lib/dpif-hw-acc.c b/lib/dpif-hw-acc.c index 252a90f..5f65904 100644 --- a/lib/dpif-hw-acc.c +++ b/lib/dpif-hw-acc.c @@ -40,10 +40,290 @@ #include "unaligned.h" #include "util.h" #include "openvswitch/vlog.h" +#include "netdev-provider.h" #include "dpif-hw-acc.h" VLOG_DEFINE_THIS_MODULE(dpif_hw_acc); +static char * +printufid(const ovs_u128 * ovs_ufid) +{ + static char ufid[64]; + + if (ovs_ufid) + sprintf(ufid, "%x%x%x%x", ovs_ufid->u32[0], ovs_ufid->u32[1], + ovs_ufid->u32[2], ovs_ufid->u32[3]); + else + sprintf(ufid, "(missing_ufid)"); + return ufid; +} + +static inline size_t +hash_ufid(const ovs_u128 * ovs_ufid) +{ + return hash_words64((const uint64_t *) ovs_ufid, + sizeof *ovs_ufid / sizeof (uint64_t), 0); +} + +static inline size_t +hash_port(odp_port_t port) +{ + return hash_int((int) port, 0); +} + +static inline size_t +hash_handle_prio_port(int handle, uint16_t prio, odp_port_t port) +{ + /* TODO: fix utint cast */ + return hash_int((uint32_t) prio, hash_int(handle, hash_port(port))); +} + +static struct netdev * +port_find(struct dpif_hw_acc *dpif, odp_port_t port) +{ + struct port_netdev_hash_data *data; + size_t hash = hash_port(port); + struct netdev *res = 0; + + ovs_mutex_lock(&dpif->hash_mutex); + HMAP_FOR_EACH_WITH_HASH(data, node, hash, &dpif->port_to_netdev) { + if (data->port == port) + break; + } + if (data) { + res = data->netdev; + VLOG_DBG + ("found port mapping: port number %d -> port name %s (pointer: %p)\n", + port, res->name, res); + } + ovs_mutex_unlock(&dpif->hash_mutex); + + return res; +} + +static int +port_del_name(struct dpif_hw_acc *dpif, char *name) +{ + struct port_netdev_hash_data *data; + + ovs_mutex_lock(&dpif->hash_mutex); + HMAP_FOR_EACH(data, node, &dpif->port_to_netdev) { + if (!strcmp(data->netdev->name, name)) + break; + } + if (data) + hmap_remove(&dpif->port_to_netdev, &data->node); + ovs_mutex_unlock(&dpif->hash_mutex); + + free(data); + return data ? 1 : 0; +} + +static int +port_del(struct dpif_hw_acc *dpif, odp_port_t port) +{ + struct port_netdev_hash_data *data; + size_t hash = hash_port(port); + + ovs_mutex_lock(&dpif->hash_mutex); + HMAP_FOR_EACH_WITH_HASH(data, node, hash, &dpif->port_to_netdev) { + if (data->port == port) + break; + } + if (data) + hmap_remove(&dpif->port_to_netdev, &data->node); + ovs_mutex_unlock(&dpif->hash_mutex); + + free(data); + return data ? 1 : 0; +} + +static int +port_add(struct dpif_hw_acc *dpif, odp_port_t port, struct netdev *netdev) +{ + struct port_netdev_hash_data *data; + size_t hash = hash_port(port); + int ret = 0; + + if (!netdev || !netdev->name || !port) + return -1; + + if (netdev->netdev_class == &netdev_internal_class) { + if (!strcmp(netdev->name, "skip_hw")) { + tc_set_skip_hw(true); + } + return -1; + } + if (port_del(dpif, port) || port_del_name(dpif, netdev->name)) { + VLOG_DBG + ("%s %d %s (%p) port number %d name: %s, deleted to be replaced\n", + __FILE__, __LINE__, __func__, dpif, port, netdev->name); + ret = 1; + } + + data = malloc(sizeof (struct port_netdev_hash_data)); + data->netdev = netdev; + data->port = port; + + VLOG_DBG + ("%s %d %s (%p): adding new port mapping: %d -> netdev %p name: %s, type: %s, ifindex: %d, hash: %lu\n", + __FILE__, __LINE__, __func__, dpif, port, netdev, netdev->name, + netdev->netdev_class->type, netdev_get_ifindex(netdev), hash); + ovs_mutex_lock(&dpif->hash_mutex); + hmap_insert(&dpif->port_to_netdev, &data->node, hash); + ovs_mutex_unlock(&dpif->hash_mutex); + return ret; +} + +static int +delhandle(struct dpif_hw_acc *dpif, const ovs_u128 * ovs_ufid) +{ + struct ufid_handle_hash_data *data; + size_t hash; + + if (!ovs_ufid) { + VLOG_ERR("%s %d %s (%p) can't delete missing ufid\n", __FILE__, + __LINE__, __func__, dpif); + return 0; + } + hash = hash_ufid(ovs_ufid); + + VLOG_DBG("%s %d %s (%p): removing %s\n", __FILE__, __LINE__, __func__, + dpif, printufid(ovs_ufid)); + + ovs_mutex_lock(&dpif->hash_mutex); + HMAP_FOR_EACH_WITH_HASH(data, node_ufid, hash, &dpif->ufid_to_handle) { + if (!memcmp(&data->ovs_ufid, ovs_ufid, sizeof (*ovs_ufid))) + break; + } + if (data) { + VLOG_DBG("%s %d %s (%p) ufid %s found! handle: %d, removing it\n", + __FILE__, __LINE__, __func__, dpif, printufid(ovs_ufid), + data->handle); + hmap_remove(&dpif->ufid_to_handle, &data->node_ufid); + hmap_remove(&dpif->handle_to_ufid, &data->node_handle); + free(data); + } + ovs_mutex_unlock(&dpif->hash_mutex); + return data ? 1 : 0; +} + +static int +puthandle(struct dpif_hw_acc *dpif, const ovs_u128 * ovs_ufid, + struct netdev *in, odp_port_t port, int handle, uint16_t prio) +{ + int ret = 0; + size_t hash_to_ufid = hash_handle_prio_port(handle, prio, port); + + if (!ovs_ufid) { + VLOG_ERR("%s %d %s (%p) missing UFID!\n", __FILE__, __LINE__, __func__, + dpif); + return 0; + } + + if (delhandle(dpif, ovs_ufid)) + ret = 1; + + struct ufid_handle_hash_data *data = + malloc(sizeof (struct ufid_handle_hash_data)); + data->ovs_ufid = *ovs_ufid; + data->handle = handle; + data->netdev = in; + data->port = port; + data->prio = prio; + + ovs_mutex_lock(&dpif->hash_mutex); + hmap_insert(&dpif->ufid_to_handle, &data->node_ufid, hash_ufid(ovs_ufid)); + hmap_insert(&dpif->handle_to_ufid, &data->node_handle, hash_to_ufid); + VLOG_DBG + ("%s %d %s (%p) added mapping %s <-> (handle: %d, prio: %d, port: %d, indev: %p)\n", + __FILE__, __LINE__, __func__, dpif, printufid(ovs_ufid), handle, + prio, port, in); + ovs_mutex_unlock(&dpif->hash_mutex); + return ret; +} + +static ovs_u128 * +findufid(struct dpif_hw_acc *dpif, odp_port_t port, int handle, + uint16_t prio) +{ + struct ufid_handle_hash_data *data; + size_t hash = hash_handle_prio_port(handle, prio, port); + + VLOG_DBG + ("%s %d %s (%p) finding ufid of (handle: %d, prio: %d, port: %d), hash: %lu\n", + __FILE__, __LINE__, __func__, dpif, handle, prio, port, hash); + + ovs_mutex_lock(&dpif->hash_mutex); + HMAP_FOR_EACH_WITH_HASH(data, node_handle, hash, &dpif->handle_to_ufid) { + if (data->handle == handle && data->port == port + && data->prio == prio) + break; + } + ovs_mutex_unlock(&dpif->hash_mutex); + + return data ? &data->ovs_ufid : 0; +} + +static int +gethandle(struct dpif_hw_acc *dpif, const ovs_u128 * ovs_ufid, + struct netdev **in, uint16_t *prio, const char *func, int print) +{ + struct ufid_handle_hash_data *data; + int handle = 0; + size_t hash = 0; + + if (in) + *in = 0; + + if (!ovs_ufid) { + VLOG_DBG("%s %d %s (%p) called by %s without a ufid.\n", __FILE__, + __LINE__, __func__, dpif, func); + return 0; + } else + hash = hash_ufid(ovs_ufid); + + if (print) + VLOG_DBG("%s %d %s (%p) called by %s to find ufid %s\n", __FILE__, + __LINE__, __func__, dpif, func, printufid(ovs_ufid)); + + ovs_mutex_lock(&dpif->hash_mutex); + HMAP_FOR_EACH_WITH_HASH(data, node_ufid, hash, &dpif->ufid_to_handle) { + if (!memcmp(&data->ovs_ufid, ovs_ufid, sizeof (*ovs_ufid))) + break; + } + ovs_mutex_unlock(&dpif->hash_mutex); + + if (data && (!data->handle || !data->netdev || !data->prio)) { + VLOG_ERR + ("mising handle/dev/prio for ufid: %s, handle: %d, netdev: %p, prio: %d\n", + printufid(ovs_ufid), data->handle, data->netdev, data->prio); + return 0; + } + handle = data ? data->handle : 0; + if (in) + *in = data ? data->netdev : 0; + if (prio) + *prio = data ? data->prio : 0; + if (print && handle) + VLOG_DBG("found ufid: %s, handle: %d, prio: %d, netdev: %p\n", + printufid(ovs_ufid), handle, data->prio, data->netdev); + return handle; +} + +static int +get_ovs_port(struct dpif_hw_acc *dpif, int ifindex) +{ + struct port_netdev_hash_data *data; + + HMAP_FOR_EACH(data, node, &dpif->port_to_netdev) { + if (netdev_get_ifindex(data->netdev) == ifindex) { + return data->port; + } + } + return -1; +} + static struct dpif_hw_acc * dpif_hw_acc_cast(const struct dpif *dpif) { @@ -52,6 +332,16 @@ dpif_hw_acc_cast(const struct dpif *dpif) } static int +initmaps(struct dpif_hw_acc *dpif) +{ + hmap_init(&dpif->port_to_netdev); + hmap_init(&dpif->ufid_to_handle); + hmap_init(&dpif->handle_to_ufid); + ovs_mutex_init(&dpif->hash_mutex); + return 0; +} + +static int dpif_hw_acc_open(const struct dpif_class *class OVS_UNUSED, const char *name, bool create, struct dpif **dpifp) { @@ -75,6 +365,8 @@ dpif_hw_acc_open(const struct dpif_class *class OVS_UNUSED, } dpif = xzalloc(sizeof *dpif); + initmaps(dpif); + *CONST_CAST(const char **, &dpif->name) = xstrdup(name); uint16_t netflow_id = hash_string(dpif->name, 0); diff --git a/lib/dpif-hw-acc.h b/lib/dpif-hw-acc.h index 5559b41..10467e3 100644 --- a/lib/dpif-hw-acc.h +++ b/lib/dpif-hw-acc.h @@ -2,6 +2,7 @@ #define DPIF_HW_NETLINK_H 1 #include "ovs-thread.h" +#include "hmap.h" #include "dpif-provider.h" /* Datapath interface for the openvswitch Linux kernel module. */ @@ -9,6 +10,26 @@ struct dpif_hw_acc { struct dpif dpif; struct dpif *lp_dpif_netlink; const char *const name; + struct ovs_mutex hash_mutex; + struct hmap port_to_netdev; + struct hmap ufid_to_handle; + struct hmap handle_to_ufid; +}; + +struct port_netdev_hash_data { + struct hmap_node node; + struct netdev *netdev; + odp_port_t port; +}; + +struct ufid_handle_hash_data { + struct hmap_node node_ufid; + struct hmap_node node_handle; + ovs_u128 ovs_ufid; + int handle; + int prio; + struct netdev *netdev; + odp_port_t port; }; #endif