This patch adds an API to retrieve the netdev by port_id from either the dpif or a specific offload provider.
Signed-off-by: Eelco Chaudron <echau...@redhat.com> --- lib/dpif-offload-dummy.c | 19 ++++++++++++++++ lib/dpif-offload-provider.h | 4 ++++ lib/dpif-offload-rte_flow.c | 17 +++++++++++++++ lib/dpif-offload-tc.c | 17 +++++++++++++++ lib/dpif-offload.c | 41 ++++++++++++++++++++++++++++++++++- lib/dpif-offload.h | 5 +++++ ofproto/ofproto-dpif-upcall.c | 5 ++--- 7 files changed, 104 insertions(+), 4 deletions(-) diff --git a/lib/dpif-offload-dummy.c b/lib/dpif-offload-dummy.c index 1bdb9d043..b15d2192d 100644 --- a/lib/dpif-offload-dummy.c +++ b/lib/dpif-offload-dummy.c @@ -98,6 +98,24 @@ dpif_offload_dummy_port_del(struct dpif_offload *dpif_offload, return 0; } +static struct netdev * +dpif_offload_dummy_get_netdev(struct dpif_offload *dpif_offload, + odp_port_t port_no) +{ + struct dpif_offload_dummy *offload_dummy; + struct dpif_offload_port_mgr_port *port; + + offload_dummy = dpif_offload_dummy_cast(dpif_offload); + + port = dpif_offload_port_mgr_find_by_odp_port(offload_dummy->port_mgr, + port_no); + if (!port) { + return NULL; + } + + return port->netdev; +} + static int dpif_offload_dummy_open(const struct dpif_offload_class *offload_class, struct dpif *dpif, struct dpif_offload **dpif_offload) @@ -246,6 +264,7 @@ dpif_offload_dummy_can_offload(struct dpif_offload *dpif_offload OVS_UNUSED, .can_offload = dpif_offload_dummy_can_offload, \ .port_add = dpif_offload_dummy_port_add, \ .port_del = dpif_offload_dummy_port_del, \ + .get_netdev = dpif_offload_dummy_get_netdev, \ } DEFINE_DPIF_DUMMY_CLASS(dpif_offload_dummy_class, "dummy"); diff --git a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h index cce815ae2..68e13843c 100644 --- a/lib/dpif-offload-provider.h +++ b/lib/dpif-offload-provider.h @@ -224,6 +224,10 @@ struct dpif_offload_class { int (*meter_del)(const struct dpif_offload *, ofproto_meter_id meter_id, struct ofputil_meter_stats *); + /* Return the 'netdev' associated with the port_no if this offload + * provider is handling offload for this port/netdev. */ + struct netdev *(*get_netdev)(struct dpif_offload *, odp_port_t port_no); + /* These APIs operate directly on the provided netdev for performance * reasons. They are intended for use in fast path processing and should diff --git a/lib/dpif-offload-rte_flow.c b/lib/dpif-offload-rte_flow.c index 9e2fff78b..e5c40fb12 100644 --- a/lib/dpif-offload-rte_flow.c +++ b/lib/dpif-offload-rte_flow.c @@ -103,6 +103,22 @@ dpif_offload_rte_port_del(struct dpif_offload *offload, odp_port_t port_no) return ret; } +static struct netdev * +dpif_offload_rte_flow_get_netdev(struct dpif_offload *offload, + odp_port_t port_no) +{ + struct dpif_offload_rte_flow *offload_rte = dpif_offload_rte_cast(offload); + struct dpif_offload_port_mgr_port *port; + + port = dpif_offload_port_mgr_find_by_odp_port(offload_rte->port_mgr, + port_no); + if (!port) { + return NULL; + } + + return port->netdev; +} + static int dpif_offload_rte_open(const struct dpif_offload_class *offload_class, struct dpif *dpif, struct dpif_offload **dpif_offload) @@ -309,6 +325,7 @@ struct dpif_offload_class dpif_offload_rte_flow_class = { .port_add = dpif_offload_rte_port_add, .port_del = dpif_offload_rte_port_del, .flow_get_n_offloaded = dpif_offload_rte_flow_get_n_offloaded, + .get_netdev = dpif_offload_rte_flow_get_netdev, .netdev_flow_flush = dpif_offload_rte_netdev_flow_flush, .netdev_hw_miss_packet_recover = \ dpif_offload_rte_netdev_hw_miss_packet_recover, diff --git a/lib/dpif-offload-tc.c b/lib/dpif-offload-tc.c index e2e18b5b1..961953961 100644 --- a/lib/dpif-offload-tc.c +++ b/lib/dpif-offload-tc.c @@ -127,6 +127,22 @@ dpif_offload_tc_port_del(struct dpif_offload *dpif_offload, return ret; } +static struct netdev * +dpif_offload_tc_get_netdev(struct dpif_offload *dpif_offload, + odp_port_t port_no) +{ + struct dpif_offload_tc *offload_tc = dpif_offload_tc_cast(dpif_offload); + struct dpif_offload_port_mgr_port *port; + + port = dpif_offload_port_mgr_find_by_odp_port(offload_tc->port_mgr, + port_no); + if (!port) { + return NULL; + } + + return port->netdev; +} + static int dpif_offload_tc_open(const struct dpif_offload_class *offload_class, struct dpif *dpif, struct dpif_offload **dpif_offload) @@ -564,5 +580,6 @@ struct dpif_offload_class dpif_offload_tc_class = { .meter_set = dpif_offload_tc_meter_set, .meter_get = dpif_offload_tc_meter_get, .meter_del = dpif_offload_tc_meter_del, + .get_netdev = dpif_offload_tc_get_netdev, .netdev_flow_flush = dpif_offload_tc_netdev_flow_flush, }; diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c index 7e58dbd98..eb5eda834 100644 --- a/lib/dpif-offload.c +++ b/lib/dpif-offload.c @@ -151,7 +151,8 @@ dp_offload_initialize(void) && base_dpif_offload_classes[i]->close && base_dpif_offload_classes[i]->can_offload && base_dpif_offload_classes[i]->port_add - && base_dpif_offload_classes[i]->port_del); + && base_dpif_offload_classes[i]->port_del + && base_dpif_offload_classes[i]->get_netdev); ovs_assert((base_dpif_offload_classes[i]->flow_dump_create && base_dpif_offload_classes[i]->flow_dump_next && @@ -1008,6 +1009,44 @@ dpif_offload_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread) free(thread->offload_threads); } +struct netdev * +dpif_offload_offload_get_netdev_by_port_id(struct dpif_offload *offload, + odp_port_t port_no) +{ + if (!dpif_offload_is_offload_enabled() || !offload) { + return NULL; + } + + return offload->class->get_netdev(offload, port_no); +} + +struct netdev * +dpif_offload_get_netdev_by_port_id(struct dpif *dpif, + struct dpif_offload **offload, + odp_port_t port_no) +{ + struct dp_offload *dp_offload = dpif_offload_get_dp_offload(dpif); + struct dpif_offload *tmp_offload; + struct netdev *netdev = NULL; + + if (!dp_offload || !dpif_offload_is_offload_enabled()) { + return NULL; + } + + LIST_FOR_EACH (tmp_offload, dpif_list_node, + &dp_offload->offload_providers) { + netdev = tmp_offload->class->get_netdev(tmp_offload, port_no); + if (netdev) { + if (offload) { + *offload = tmp_offload; + } + break; + } + } + + return netdev; +} + int dpif_offload_netdev_flush_flows(struct netdev *netdev) diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h index f8b22e4ab..265585c49 100644 --- a/lib/dpif-offload.h +++ b/lib/dpif-offload.h @@ -58,6 +58,11 @@ void dpif_offload_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id, struct ofputil_meter_stats *); void dpif_offload_meter_del(const struct dpif *dpif, ofproto_meter_id meter_id, struct ofputil_meter_stats *); +struct netdev *dpif_offload_get_netdev_by_port_id(struct dpif *, + struct dpif_offload **, + odp_port_t); +struct netdev *dpif_offload_offload_get_netdev_by_port_id( + struct dpif_offload *, odp_port_t); /* Iterates through each DPIF_OFFLOAD in DPIF, using DUMP as state. * diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 3fa96b673..d0c537bc9 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2710,7 +2710,6 @@ ukey_netdev_unref(struct udpif_key *ukey) static void ukey_to_flow_netdev(struct udpif *udpif, struct udpif_key *ukey) { - const char *dpif_type_str = dpif_normalize_type(dpif_type(udpif->dpif)); const struct nlattr *k; unsigned int left; @@ -2722,8 +2721,8 @@ ukey_to_flow_netdev(struct udpif *udpif, struct udpif_key *ukey) enum ovs_key_attr type = nl_attr_type(k); if (type == OVS_KEY_ATTR_IN_PORT) { - ukey->in_netdev = netdev_ports_get(nl_attr_get_odp_port(k), - dpif_type_str); + ukey->in_netdev = dpif_offload_get_netdev_by_port_id( + udpif->dpif, NULL, nl_attr_get_odp_port(k)); } else if (type == OVS_KEY_ATTR_TUNNEL) { struct flow_tnl tnl; enum odp_key_fitness res; -- 2.50.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev