On 12 Nov 2025, at 16:35, Eelco Chaudron via dev wrote:

> This patch removes the global netdev_flow_api in favor of the new
> dpif-offload infrastructure. All offload-related handling is now
> performed via the dpif-offload layer, simplifying the code and
> removing redundant global interfaces from netdev-offload.
>
> Signed-off-by: Eelco Chaudron <[email protected]>

Oops, I forgot to include a patch modification before sending it out :(

I added the diff inline below, and will incorporate it in a v3 once more people 
have reviewed the series.

//Eelco
> ---
>  lib/automake.mk               |   1 -
>  lib/dpif-netdev.c             |   3 +-
>  lib/dpif-netdev.h             |  12 +
>  lib/dpif.c                    |  27 --
>  lib/netdev-dummy.c            |   1 -
>  lib/netdev-offload-dpdk.c     |   5 +-
>  lib/netdev-offload-dpdk.h     |   7 +-
>  lib/netdev-offload-provider.h |  79 ------
>  lib/netdev-offload.c          | 457 +---------------------------------
>  lib/netdev-offload.h          |  63 -----
>  lib/netdev-provider.h         |   8 +-
>  lib/netdev.c                  |   4 -
>  ofproto/ofproto-dpif.c        |   2 +-
>  vswitchd/bridge.c             |   1 -
>  14 files changed, 27 insertions(+), 643 deletions(-)
>  delete mode 100644 lib/netdev-offload-provider.h
>
> diff --git a/lib/automake.mk b/lib/automake.mk
> index 229064716..f7586bb0a 100644
> --- a/lib/automake.mk
> +++ b/lib/automake.mk
> @@ -212,7 +212,6 @@ lib_libopenvswitch_la_SOURCES = \
>       lib/netdev-dummy.c \
>       lib/netdev-offload.c \
>       lib/netdev-offload.h \
> -     lib/netdev-offload-provider.h \
>       lib/netdev-provider.h \
>       lib/netdev-vport.c \
>       lib/netdev-vport.h \
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index df6c94912..484eefccb 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -2404,7 +2404,6 @@ do_del_port(struct dp_netdev *dp, struct dp_netdev_port 
> *port)
>       * offload modification or deletion. Managing those stray requests
>       * is done in the offload threads. */
>      dp_netdev_offload_flush(dp, port);
> -    netdev_uninit_flow_api(port->netdev);
>
>      port_destroy(port);
>  }
> @@ -2813,7 +2812,7 @@ dp_netdev_flow_offload_put(struct 
> dp_offload_thread_item *item)
>      odp_port_t in_port = flow->flow.in_port.odp_port;
>      bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD
>                          && flow->mark != INVALID_FLOW_MARK;
> -    struct offload_info info;
> +    struct dpif_netdev_offload_info info;
>      struct netdev *port;
>      uint32_t mark;
>      int ret;
> diff --git a/lib/dpif-netdev.h b/lib/dpif-netdev.h
> index 6db6ed2e2..5df344367 100644
> --- a/lib/dpif-netdev.h
> +++ b/lib/dpif-netdev.h
> @@ -38,6 +38,18 @@ bool dpif_is_netdev(const struct dpif *);
>  #define NR_QUEUE   1
>  #define NR_PMD_THREADS 1
>
> +/* Flow offloading info structure. XXX: This needs to be moved once the
> + * implementation is migrated to dpif-offload-dpdk. */
> +struct dpif_netdev_offload_info {
> +    /*
> +     * The flow mark id assigned to the flow. If any pkts hit the flow,
> +     * it will be in the pkt meta data.
> +     */
> +    uint32_t flow_mark;
> +
> +    odp_port_t orig_in_port; /* Originating in_port for tnl flows. */
> +};
> +
>  #ifdef  __cplusplus
>  }
>  #endif
> diff --git a/lib/dpif.c b/lib/dpif.c
> index 323a2bf6c..006d9276e 100644
> --- a/lib/dpif.c
> +++ b/lib/dpif.c
> @@ -378,7 +378,6 @@ do_open(const char *name, const char *type, bool create, 
> struct dpif **dpifp)
>
>              if (!err) {
>                  netdev_set_dpif_type(netdev, dpif_type_str);
> -                netdev_ports_insert(netdev, &dpif_port);
>                  if (new_offload_provider) {
>                      dpif_offload_port_add(dpif, netdev, dpif_port.port_no);
>                  }
> @@ -443,19 +442,6 @@ dpif_create_and_open(const char *name, const char *type, 
> struct dpif **dpifp)
>      return error;
>  }

What was missing in this patch:

diff --git a/lib/dpif.c b/lib/dpif.c
index 089043ad4..817cb941a 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -359,32 +359,31 @@ do_open(const char *name, const char *type, bool create, 
struct dpif **dpifp)
         const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
         struct dpif_port_dump port_dump;
         struct dpif_port dpif_port;
-        bool new_offload_provider;

         ovs_assert(dpif->dpif_class == registered_class->dpif_class);

-        new_offload_provider = dpif_offload_attach_providers(dpif) == EEXIST
-                                   ? false : true;
+        /* Only if a new provider was attached should we try to add already
+         * existing ports. */
+        if (dpif_offload_attach_providers(dpif) == 0) {
+            DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
+                struct netdev *netdev;
+                int err;

-        DPIF_PORT_FOR_EACH(&dpif_port, &port_dump, dpif) {
-            struct netdev *netdev;
-            int err;
-
-            if (dpif_is_tap_port(dpif_port.type)) {
-                continue;
-            }
+                if (dpif_is_tap_port(dpif_port.type)) {
+                    continue;
+                }

-            err = netdev_open(dpif_port.name, dpif_port.type, &netdev);
+                err = netdev_open(dpif_port.name, dpif_port.type, &netdev);
+                if (err) {
+                    VLOG_WARN("could not open netdev %s type %s: %s",
+                              dpif_port.name, dpif_port.type,
+                              ovs_strerror(err));
+                    continue;
+                }

-            if (!err) {
                 netdev_set_dpif_type(netdev, dpif_type_str);
-                if (new_offload_provider) {
-                    dpif_offload_port_add(dpif, netdev, dpif_port.port_no);
-                }
+                dpif_offload_port_add(dpif, netdev, dpif_port.port_no);
                 netdev_close(netdev);
-            } else {
-                VLOG_WARN("could not open netdev %s type %s: %s",
-                          dpif_port.name, dpif_port.type, ovs_strerror(err));
             }
         }
     } else {


> -static void
> -dpif_remove_netdev_ports(struct dpif *dpif) {
> -    const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
> -    struct dpif_port_dump port_dump;
> -    struct dpif_port dpif_port;
> -
> -    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
> -        if (!dpif_is_tap_port(dpif_port.type)) {
> -            netdev_ports_remove(dpif_port.port_no, dpif_type_str);
> -        }
> -    }
> -}
> -
>  /* Closes and frees the connection to 'dpif'.  Does not destroy the datapath
>   * itself; call dpif_delete() first, instead, if that is desirable. */
>  void
> @@ -466,9 +452,6 @@ dpif_close(struct dpif *dpif)
>
>          rc = shash_find_data(&dpif_classes, dpif->dpif_class->type);
>
> -        if (rc->refcount == 1) {
> -            dpif_remove_netdev_ports(dpif);
> -        }
>          dpif_offload_detach_providers(dpif);
>          dpif_uninit(dpif, true);
>          dp_class_unref(rc);
> @@ -626,17 +609,9 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, 
> odp_port_t *port_nop)
>                      dpif_name(dpif), netdev_name, port_no);
>
>          if (!dpif_is_tap_port(netdev_get_type(netdev))) {
> -
>              const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
> -            struct dpif_port dpif_port;
>
>              netdev_set_dpif_type(netdev, dpif_type_str);
> -
> -            dpif_port.type = CONST_CAST(char *, netdev_get_type(netdev));
> -            dpif_port.name = CONST_CAST(char *, netdev_name);
> -            dpif_port.port_no = port_no;
> -            netdev_ports_insert(netdev, &dpif_port);
> -
>              dpif_offload_port_add(dpif, netdev, port_no);
>          }
>      } else {
> @@ -670,8 +645,6 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no, bool 
> local_delete)
>      }
>
>      dpif_offload_port_del(dpif, port_no);
> -
> -    netdev_ports_remove(port_no, dpif_normalize_type(dpif_type(dpif)));
>      return error;
>  }
>
> diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
> index 8ae1151ea..6a99f4ced 100644
> --- a/lib/netdev-dummy.c
> +++ b/lib/netdev-dummy.c
> @@ -24,7 +24,6 @@
>  #include "dp-packet.h"
>  #include "dpif-netdev.h"
>  #include "flow.h"
> -#include "netdev-offload-provider.h"
>  #include "netdev-provider.h"
>  #include "netdev-vport.h"
>  #include "odp-util.h"
> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
> index cda5f3dbb..de10a71c4 100644
> --- a/lib/netdev-offload-dpdk.c
> +++ b/lib/netdev-offload-dpdk.c
> @@ -2311,7 +2311,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev,
>                               struct nlattr *nl_actions,
>                               size_t actions_len,
>                               const ovs_u128 *ufid,
> -                             struct offload_info *info)
> +                             struct dpif_netdev_offload_info *info)
>  {
>      struct flow_patterns patterns = {
>          .items = NULL,
> @@ -2428,7 +2428,8 @@ get_netdev_odp_cb(struct netdev *netdev,
>  int
>  netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match,
>                               struct nlattr *actions, size_t actions_len,
> -                             const ovs_u128 *ufid, struct offload_info *info,
> +                             const ovs_u128 *ufid,
> +                             struct dpif_netdev_offload_info *info,
>                               struct dpif_flow_stats *stats)
>  {
>      struct ufid_to_rte_flow_data *rte_flow_data;
> diff --git a/lib/netdev-offload-dpdk.h b/lib/netdev-offload-dpdk.h
> index 835220974..3587a3a72 100644
> --- a/lib/netdev-offload-dpdk.h
> +++ b/lib/netdev-offload-dpdk.h
> @@ -19,7 +19,7 @@
>
>  /* Forward declarations of private structures. */
>  struct netdev;
> -struct offload_info;
> +struct dpif_netdev_offload_info;
>
>  /* Netdev-specific offload functions.  These should only be used by the
>   * associated dpif offload provider. */
> @@ -32,7 +32,8 @@ int netdev_offload_dpdk_hw_miss_packet_recover(struct 
> netdev *,
>  #ifdef DPDK_NETDEV
>  int netdev_offload_dpdk_flow_put(struct netdev *, struct match *,
>                                   struct nlattr *actions, size_t actions_len,
> -                                 const ovs_u128 *ufid, struct offload_info *,
> +                                 const ovs_u128 *ufid,
> +                                 struct dpif_netdev_offload_info *,
>                                   struct dpif_flow_stats *);
>  int netdev_offload_dpdk_flow_del(struct netdev *, const ovs_u128 *ufid,
>                                   struct dpif_flow_stats *);
> @@ -47,7 +48,7 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev 
> OVS_UNUSED,
>                                struct nlattr *actions OVS_UNUSED,
>                                size_t actions_len OVS_UNUSED,
>                                const ovs_u128 *ufid OVS_UNUSED,
> -                              struct offload_info *info OVS_UNUSED,
> +                              struct dpif_netdev_offload_info *info 
> OVS_UNUSED,
>                                struct dpif_flow_stats *stats OVS_UNUSED)
>  {
>      return EOPNOTSUPP;
> diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h
> deleted file mode 100644
> index 8087b84e3..000000000
> --- a/lib/netdev-offload-provider.h
> +++ /dev/null
> @@ -1,79 +0,0 @@
> -/*
> - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc.
> - * Copyright (c) 2019 Samsung Electronics Co.,Ltd.
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at:
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -
> -#ifndef NETDEV_FLOW_API_PROVIDER_H
> -#define NETDEV_FLOW_API_PROVIDER_H 1
> -
> -#include "flow.h"
> -#include "netdev-offload.h"
> -#include "openvswitch/netdev.h"
> -#include "openvswitch/types.h"
> -#include "packets.h"
> -
> -#ifdef  __cplusplus
> -extern "C" {
> -#endif
> -
> -struct netdev_flow_api {
> -    char *type;
> -
> -    /* Offload the given flow on netdev.
> -     * To modify a flow, use the same ufid.
> -     * 'actions' are in netlink format, as with struct dpif_flow_put.
> -     * 'info' is extra info needed to offload the flow.
> -     * 'stats' is populated according to the rules set out in the description
> -     * above 'struct dpif_flow_put'.
> -     * Return 0 if successful, otherwise returns a positive errno value. */
> -    int (*flow_put)(struct netdev *, struct match *, struct nlattr *actions,
> -                    size_t actions_len, const ovs_u128 *ufid,
> -                    struct offload_info *info, struct dpif_flow_stats *);
> -
> -    /* Queries a flow specified by ufid on netdev.
> -     * Fills output buffer as 'wbuffer' in flow_dump_next, which
> -     * needs to be be pre allocated.
> -     * Return 0 if successful, otherwise returns a positive errno value. */
> -    int (*flow_get)(struct netdev *, struct match *, struct nlattr **actions,
> -                    const ovs_u128 *ufid, struct dpif_flow_stats *,
> -                    struct dpif_flow_attrs *, struct ofpbuf *wbuffer);
> -
> -    /* Delete a flow specified by ufid from netdev.
> -     * 'stats' is populated according to the rules set out in the description
> -     * above 'struct dpif_flow_del'.
> -     * Return 0 if successful, otherwise returns a positive errno value. */
> -    int (*flow_del)(struct netdev *, const ovs_u128 *ufid,
> -                    struct dpif_flow_stats *);
> -
> -    /* Initializies the netdev flow api.
> -     * Return 0 if successful, otherwise returns a positive errno value. */
> -    int (*init_flow_api)(struct netdev *);
> -
> -    /* Uninitializes the netdev flow api. */
> -    void (*uninit_flow_api)(struct netdev *);
> -};
> -
> -int netdev_register_flow_api_provider(const struct netdev_flow_api *);
> -int netdev_unregister_flow_api_provider(const char *type);
> -
> -#ifdef __linux__
> -extern const struct netdev_flow_api netdev_offload_tc;
> -#endif
> -
> -#ifdef  __cplusplus
> -}
> -#endif
> -
> -#endif /* NETDEV_FLOW_API_PROVIDER_H */
> diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
> index fff49240d..f24c415a2 100644
> --- a/lib/netdev-offload.c
> +++ b/lib/netdev-offload.c
> @@ -16,248 +16,13 @@
>   */
>
>  #include <config.h>
> -#include "netdev-offload.h"
> -
> -#include <errno.h>
> -#include <inttypes.h>
> -#include <sys/types.h>
> -#include <netinet/in.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <unistd.h>
>
> -#include "cmap.h"
> -#include "coverage.h"
> -#include "dpif.h"
> -#include "dpif-offload.h"
> -#include "dp-packet.h"
> -#include "openvswitch/dynamic-string.h"
> -#include "fatal-signal.h"
> -#include "hash.h"
> -#include "openvswitch/list.h"
> -#include "netdev-offload-provider.h"
> +#include "netdev-offload.h"
>  #include "netdev-provider.h"
> -#include "netdev-vport.h"
> -#include "odp-netlink.h"
> -#include "openflow/openflow.h"
> -#include "packets.h"
> -#include "openvswitch/ofp-print.h"
> -#include "openvswitch/poll-loop.h"
> -#include "seq.h"
> -#include "openvswitch/shash.h"
> -#include "smap.h"
> -#include "socket-util.h"
> -#include "sset.h"
> -#include "svec.h"
>  #include "openvswitch/vlog.h"
> -#include "flow.h"
> -#include "util.h"
> -#ifdef __linux__
> -#include "tc.h"
> -#endif
>
>  VLOG_DEFINE_THIS_MODULE(netdev_offload);
>
> -/* Protects 'netdev_flow_apis'.  */
> -static struct ovs_mutex netdev_flow_api_provider_mutex = 
> OVS_MUTEX_INITIALIZER;
> -
> -/* Contains 'struct netdev_registered_flow_api's. */
> -static struct cmap netdev_flow_apis = CMAP_INITIALIZER;
> -
> -struct netdev_registered_flow_api {
> -    struct cmap_node cmap_node; /* In 'netdev_flow_apis', by flow_api->type. 
> */
> -    const struct netdev_flow_api *flow_api;
> -
> -    /* Number of references: one for the flow_api itself and one for every
> -     * instance of the netdev that uses it. */
> -    struct ovs_refcount refcnt;
> -};
> -
> -static struct netdev_registered_flow_api *
> -netdev_lookup_flow_api(const char *type)
> -{
> -    struct netdev_registered_flow_api *rfa;
> -    CMAP_FOR_EACH_WITH_HASH (rfa, cmap_node, hash_string(type, 0),
> -                             &netdev_flow_apis) {
> -        if (!strcmp(type, rfa->flow_api->type)) {
> -            return rfa;
> -        }
> -    }
> -    return NULL;
> -}
> -
> -/* Registers a new netdev flow api provider. */
> -int
> -netdev_register_flow_api_provider(const struct netdev_flow_api *new_flow_api)
> -    OVS_EXCLUDED(netdev_flow_api_provider_mutex)
> -{
> -    int error = 0;
> -
> -    if (!new_flow_api->init_flow_api) {
> -        VLOG_WARN("attempted to register invalid flow api provider: %s",
> -                   new_flow_api->type);
> -        error = EINVAL;
> -    }
> -
> -    ovs_mutex_lock(&netdev_flow_api_provider_mutex);
> -    if (netdev_lookup_flow_api(new_flow_api->type)) {
> -        VLOG_WARN("attempted to register duplicate flow api provider: %s",
> -                   new_flow_api->type);
> -        error = EEXIST;
> -    } else {
> -        struct netdev_registered_flow_api *rfa;
> -
> -        rfa = xmalloc(sizeof *rfa);
> -        cmap_insert(&netdev_flow_apis, &rfa->cmap_node,
> -                    hash_string(new_flow_api->type, 0));
> -        rfa->flow_api = new_flow_api;
> -        ovs_refcount_init(&rfa->refcnt);
> -        VLOG_DBG("netdev: flow API '%s' registered.", new_flow_api->type);
> -    }
> -    ovs_mutex_unlock(&netdev_flow_api_provider_mutex);
> -
> -    return error;
> -}
> -
> -/* Unregisters a netdev flow api provider.  'type' must have been previously
> - * registered and not currently be in use by any netdevs.  After 
> unregistration
> - * netdev flow api of that type cannot be used for netdevs.  (However, the
> - * provider may still be accessible from other threads until the next RCU 
> grace
> - * period, so the caller must not free or re-register the same 
> netdev_flow_api
> - * until that has passed.) */
> -int
> -netdev_unregister_flow_api_provider(const char *type)
> -    OVS_EXCLUDED(netdev_flow_api_provider_mutex)
> -{
> -    struct netdev_registered_flow_api *rfa;
> -    int error;
> -
> -    ovs_mutex_lock(&netdev_flow_api_provider_mutex);
> -    rfa = netdev_lookup_flow_api(type);
> -    if (!rfa) {
> -        VLOG_WARN("attempted to unregister a flow api provider that is not "
> -                  "registered: %s", type);
> -        error = EAFNOSUPPORT;
> -    } else if (ovs_refcount_unref(&rfa->refcnt) != 1) {
> -        ovs_refcount_ref(&rfa->refcnt);
> -        VLOG_WARN("attempted to unregister in use flow api provider: %s",
> -                  type);
> -        error = EBUSY;
> -    } else  {
> -        cmap_remove(&netdev_flow_apis, &rfa->cmap_node,
> -                    hash_string(rfa->flow_api->type, 0));
> -        ovsrcu_postpone(free, rfa);
> -        error = 0;
> -    }
> -    ovs_mutex_unlock(&netdev_flow_api_provider_mutex);
> -
> -    return error;
> -}
> -
> -static int
> -netdev_assign_flow_api(struct netdev *netdev)
> -{
> -    struct netdev_registered_flow_api *rfa;
> -
> -    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
> -        if (!rfa->flow_api->init_flow_api(netdev)) {
> -            ovs_refcount_ref(&rfa->refcnt);
> -            atomic_store_relaxed(&netdev->hw_info.postprocess_api_supported,
> -                                 true);
> -            ovsrcu_set(&netdev->flow_api, rfa->flow_api);
> -            VLOG_INFO("%s: Assigned flow API '%s'.",
> -                      netdev_get_name(netdev), rfa->flow_api->type);
> -            return 0;
> -        }
> -        VLOG_DBG("%s: flow API '%s' is not suitable.",
> -                 netdev_get_name(netdev), rfa->flow_api->type);
> -    }
> -    atomic_store_relaxed(&netdev->hw_info.postprocess_api_supported, false);
> -    VLOG_INFO("%s: No suitable flow API found.", netdev_get_name(netdev));
> -
> -    return -1;
> -}
> -
> -int
> -netdev_flow_put(struct netdev *netdev, struct match *match,
> -                struct nlattr *actions, size_t act_len,
> -                const ovs_u128 *ufid, struct offload_info *info,
> -                struct dpif_flow_stats *stats)
> -{
> -    const struct netdev_flow_api *flow_api =
> -        ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api);
> -
> -    return (flow_api && flow_api->flow_put)
> -           ? flow_api->flow_put(netdev, match, actions, act_len, ufid,
> -                                info, stats)
> -           : EOPNOTSUPP;
> -}
> -
> -int
> -netdev_flow_get(struct netdev *netdev, struct match *match,
> -                struct nlattr **actions, const ovs_u128 *ufid,
> -                struct dpif_flow_stats *stats,
> -                struct dpif_flow_attrs *attrs, struct ofpbuf *buf)
> -{
> -    const struct netdev_flow_api *flow_api =
> -        ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api);
> -
> -    return (flow_api && flow_api->flow_get)
> -           ? flow_api->flow_get(netdev, match, actions, ufid,
> -                                stats, attrs, buf)
> -           : EOPNOTSUPP;
> -}
> -
> -int
> -netdev_flow_del(struct netdev *netdev, const ovs_u128 *ufid,
> -                struct dpif_flow_stats *stats)
> -{
> -    const struct netdev_flow_api *flow_api =
> -        ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api);
> -
> -    return (flow_api && flow_api->flow_del)
> -           ? flow_api->flow_del(netdev, ufid, stats)
> -           : EOPNOTSUPP;
> -}
> -
> -int
> -netdev_init_flow_api(struct netdev *netdev)
> -{
> -    if (!dpif_offload_is_offload_enabled()) {
> -        return EOPNOTSUPP;
> -    }
> -
> -    if (ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api)) {
> -        return 0;
> -    }
> -
> -    if (netdev_assign_flow_api(netdev)) {
> -        return EOPNOTSUPP;
> -    }
> -
> -    return 0;
> -}
> -
> -void
> -netdev_uninit_flow_api(struct netdev *netdev)
> -{
> -    struct netdev_registered_flow_api *rfa;
> -    const struct netdev_flow_api *flow_api =
> -            ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api);
> -
> -    if (!flow_api) {
> -        return;
> -    }
> -
> -    if (flow_api->uninit_flow_api) {
> -        flow_api->uninit_flow_api(netdev);
> -    }
> -
> -    ovsrcu_set(&netdev->flow_api, NULL);
> -    rfa = netdev_lookup_flow_api(flow_api->type);
> -    ovs_refcount_unref(&rfa->refcnt);
> -}
> -
>  /*
>   * Get the value of the hw info parameter specified by type.
>   * Returns the value on success (>= 0). Returns -1 on failure.
> @@ -307,223 +72,3 @@ netdev_set_hw_info(struct netdev *netdev, int type, int 
> val)
>          break;
>      }
>  }
> -
> -/* Protects below port hashmaps. */
> -static struct ovs_rwlock ifindex_to_port_rwlock = OVS_RWLOCK_INITIALIZER;
> -static struct ovs_rwlock port_to_netdev_rwlock
> -    OVS_ACQ_BEFORE(ifindex_to_port_rwlock) = OVS_RWLOCK_INITIALIZER;
> -
> -static struct hmap port_to_netdev OVS_GUARDED_BY(port_to_netdev_rwlock)
> -    = HMAP_INITIALIZER(&port_to_netdev);
> -static struct hmap ifindex_to_port OVS_GUARDED_BY(ifindex_to_port_rwlock)
> -    = HMAP_INITIALIZER(&ifindex_to_port);
> -
> -struct port_to_netdev_data {
> -    struct hmap_node portno_node; /* By (dpif_type, dpif_port.port_no). */
> -    struct hmap_node ifindex_node; /* By (dpif_type, ifindex). */
> -    struct netdev *netdev;
> -    struct dpif_port dpif_port;
> -    int ifindex;
> -};
> -
> -void
> -netdev_ports_traverse(const char *dpif_type,
> -                      bool (*cb)(struct netdev *, odp_port_t, void *),
> -                      void *aux)
> -{
> -    struct port_to_netdev_data *data;
> -
> -    ovs_rwlock_rdlock(&port_to_netdev_rwlock);
> -    HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
> -        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
> -            if (cb(data->netdev, data->dpif_port.port_no, aux)) {
> -                break;
> -            }
> -        }
> -    }
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -}
> -
> -int
> -netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid,
> -                      struct dpif_flow_stats *stats)
> -{
> -    struct port_to_netdev_data *data;
> -
> -    ovs_rwlock_rdlock(&port_to_netdev_rwlock);
> -    HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
> -        if (netdev_get_dpif_type(data->netdev) == dpif_type
> -            && !netdev_flow_del(data->netdev, ufid, stats)) {
> -            ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -            return 0;
> -        }
> -    }
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -
> -    return ENOENT;
> -}
> -
> -int
> -netdev_ports_flow_get(const char *dpif_type, struct match *match,
> -                      struct nlattr **actions, const ovs_u128 *ufid,
> -                      struct dpif_flow_stats *stats,
> -                      struct dpif_flow_attrs *attrs, struct ofpbuf *buf)
> -{
> -    struct port_to_netdev_data *data;
> -
> -    ovs_rwlock_rdlock(&port_to_netdev_rwlock);
> -    HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
> -        if (netdev_get_dpif_type(data->netdev) == dpif_type
> -            && !netdev_flow_get(data->netdev, match, actions,
> -                                ufid, stats, attrs, buf)) {
> -            ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -            return 0;
> -        }
> -    }
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -    return ENOENT;
> -}
> -
> -static uint32_t
> -netdev_ports_hash(odp_port_t port, const char *dpif_type)
> -{
> -    return hash_int(odp_to_u32(port), hash_pointer(dpif_type, 0));
> -}
> -
> -static struct port_to_netdev_data *
> -netdev_ports_lookup(odp_port_t port_no, const char *dpif_type)
> -    OVS_REQ_RDLOCK(port_to_netdev_rwlock)
> -{
> -    struct port_to_netdev_data *data;
> -
> -    HMAP_FOR_EACH_WITH_HASH (data, portno_node,
> -                             netdev_ports_hash(port_no, dpif_type),
> -                             &port_to_netdev) {
> -        if (netdev_get_dpif_type(data->netdev) == dpif_type
> -            && data->dpif_port.port_no == port_no) {
> -            return data;
> -        }
> -    }
> -    return NULL;
> -}
> -
> -int
> -netdev_ports_insert(struct netdev *netdev, struct dpif_port *dpif_port)
> -{
> -    const char *dpif_type = netdev_get_dpif_type(netdev);
> -    struct port_to_netdev_data *data;
> -    int ifindex = netdev_get_ifindex(netdev);
> -
> -    ovs_assert(dpif_type);
> -
> -    ovs_rwlock_wrlock(&port_to_netdev_rwlock);
> -    if (netdev_ports_lookup(dpif_port->port_no, dpif_type)) {
> -        ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -        return EEXIST;
> -    }
> -
> -    data = xzalloc(sizeof *data);
> -    data->netdev = netdev_ref(netdev);
> -    dpif_port_clone(&data->dpif_port, dpif_port);
> -
> -    if (ifindex >= 0) {
> -        data->ifindex = ifindex;
> -        ovs_rwlock_wrlock(&ifindex_to_port_rwlock);
> -        hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex);
> -        ovs_rwlock_unlock(&ifindex_to_port_rwlock);
> -    } else {
> -        data->ifindex = -1;
> -    }
> -
> -    hmap_insert(&port_to_netdev, &data->portno_node,
> -                netdev_ports_hash(dpif_port->port_no, dpif_type));
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -
> -    netdev_init_flow_api(netdev);
> -
> -    return 0;
> -}
> -
> -struct netdev *
> -netdev_ports_get(odp_port_t port_no, const char *dpif_type)
> -{
> -    struct port_to_netdev_data *data;
> -    struct netdev *ret = NULL;
> -
> -    ovs_rwlock_rdlock(&port_to_netdev_rwlock);
> -    data = netdev_ports_lookup(port_no, dpif_type);
> -    if (data) {
> -        ret = netdev_ref(data->netdev);
> -    }
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -
> -    return ret;
> -}
> -
> -int
> -netdev_ports_remove(odp_port_t port_no, const char *dpif_type)
> -{
> -    struct port_to_netdev_data *data;
> -    int ret = ENOENT;
> -
> -    ovs_rwlock_wrlock(&port_to_netdev_rwlock);
> -    data = netdev_ports_lookup(port_no, dpif_type);
> -    if (data) {
> -        dpif_port_destroy(&data->dpif_port);
> -        netdev_close(data->netdev); /* unref and possibly close */
> -        hmap_remove(&port_to_netdev, &data->portno_node);
> -        if (data->ifindex >= 0) {
> -            ovs_rwlock_wrlock(&ifindex_to_port_rwlock);
> -            hmap_remove(&ifindex_to_port, &data->ifindex_node);
> -            ovs_rwlock_unlock(&ifindex_to_port_rwlock);
> -        }
> -        free(data);
> -        ret = 0;
> -    }
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -
> -    return ret;
> -}
> -
> -odp_port_t
> -netdev_ifindex_to_odp_port(int ifindex)
> -{
> -    struct port_to_netdev_data *data;
> -    odp_port_t ret = 0;
> -
> -    ovs_rwlock_rdlock(&ifindex_to_port_rwlock);
> -    HMAP_FOR_EACH_WITH_HASH (data, ifindex_node, ifindex, &ifindex_to_port) {
> -        if (data->ifindex == ifindex) {
> -            ret = data->dpif_port.port_no;
> -            break;
> -        }
> -    }
> -    ovs_rwlock_unlock(&ifindex_to_port_rwlock);
> -
> -    return ret;
> -}
> -
> -static void
> -netdev_ports_flow_init(void)
> -{
> -    struct port_to_netdev_data *data;
> -
> -    ovs_rwlock_rdlock(&port_to_netdev_rwlock);
> -    HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
> -       netdev_init_flow_api(data->netdev);
> -    }
> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
> -}
> -
> -void
> -netdev_set_flow_api_enabled(const struct smap *ovs_other_config OVS_UNUSED)
> -{
> -    if (dpif_offload_is_offload_enabled()) {
> -        static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
> -
> -        if (ovsthread_once_start(&once)) {
> -            netdev_ports_flow_init();
> -            ovsthread_once_done(&once);
> -        }
> -    }
> -}
> diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
> index b8701bad6..fe42c9b4d 100644
> --- a/lib/netdev-offload.h
> +++ b/lib/netdev-offload.h
> @@ -19,31 +19,13 @@
>  #define NETDEV_OFFLOAD_H 1
>
>  #include "openvswitch/netdev.h"
> -#include "openvswitch/types.h"
>  #include "ovs-atomic.h"
>  #include "ovs-rcu.h"
> -#include "ovs-thread.h"
> -#include "openvswitch/ofp-meter.h"
> -#include "packets.h"
> -#include "flow.h"
>
>  #ifdef  __cplusplus
>  extern "C" {
>  #endif
>
> -struct dp_packet_batch;
> -struct dp_packet;
> -struct netdev_class;
> -struct netdev_rxq;
> -struct netdev_saved_flags;
> -struct ofpbuf;
> -struct in_addr;
> -struct in6_addr;
> -struct smap;
> -struct sset;
> -struct ovs_action_push_tnl;
> -
> -
>  /* Offload-capable (HW) netdev information */
>  struct netdev_hw_info {
>      bool oor;                         /* Out of Offload Resources ? */
> @@ -60,53 +42,8 @@ enum hw_info_type {
>      HW_INFO_TYPE_OFFL_COUNT = 3              /* Offloaded flow count */
>  };
>
> -/* Flow offloading. */
> -struct offload_info {
> -    /*
> -     * The flow mark id assigned to the flow. If any pkts hit the flow,
> -     * it will be in the pkt meta data.
> -     */
> -    uint32_t flow_mark;
> -
> -    odp_port_t orig_in_port; /* Originating in_port for tnl flows. */
> -};
> -
> -int netdev_flow_put(struct netdev *, struct match *, struct nlattr *actions,
> -                    size_t actions_len, const ovs_u128 *,
> -                    struct offload_info *, struct dpif_flow_stats *);
> -int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions,
> -                    const ovs_u128 *, struct dpif_flow_stats *,
> -                    struct dpif_flow_attrs *, struct ofpbuf *wbuffer);
> -int netdev_flow_del(struct netdev *, const ovs_u128 *,
> -                    struct dpif_flow_stats *);
> -int netdev_init_flow_api(struct netdev *);
> -void netdev_uninit_flow_api(struct netdev *);
>  int netdev_get_hw_info(struct netdev *, int);
>  void netdev_set_hw_info(struct netdev *, int, int);
> -void netdev_set_flow_api_enabled(const struct smap *ovs_other_config);
> -
> -struct dpif_port;
> -int netdev_ports_insert(struct netdev *, struct dpif_port *);
> -struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type);
> -int netdev_ports_remove(odp_port_t port, const char *dpif_type);
> -odp_port_t netdev_ifindex_to_odp_port(int ifindex);
> -
> -/* For each of the ports with dpif_type, call cb with the netdev and port
> - * number of the port, and an opaque user argument.
> - * The returned value is used to continue traversing upon false or stop if
> - * true.
> - */
> -void netdev_ports_traverse(const char *dpif_type,
> -                           bool (*cb)(struct netdev *, odp_port_t, void *),
> -                           void *aux);
> -int netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid,
> -                          struct dpif_flow_stats *stats);
> -int netdev_ports_flow_get(const char *dpif_type, struct match *match,
> -                          struct nlattr **actions,
> -                          const ovs_u128 *ufid,
> -                          struct dpif_flow_stats *stats,
> -                          struct dpif_flow_attrs *attrs,
> -                          struct ofpbuf *buf);
>
>  #ifdef  __cplusplus
>  }
> diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
> index 87bc95180..753151330 100644
> --- a/lib/netdev-provider.h
> +++ b/lib/netdev-provider.h
> @@ -99,10 +99,12 @@ struct netdev {
>      struct shash_node *node;            /* Pointer to element in global map. 
> */
>      struct ovs_list saved_flags_list; /* Contains "struct 
> netdev_saved_flags". */
>
> -    /* Functions to control flow offloading. */
> +    /* The type of dpif this netdev is associated with.  This is set once
> +     * when the netdev is added to a specific dpif. */
> +    const char *dpif_type;
> +
> +    /* Data used for controlling flow offloading via dpif-offload. */
>      OVSRCU_TYPE(const struct dpif_offload *) dpif_offload;
> -    OVSRCU_TYPE(const struct netdev_flow_api *) flow_api;
> -    const char *dpif_type;          /* Type of dpif this netdev belongs to. 
> */
>      struct netdev_hw_info hw_info;  /* Offload-capable netdev info. */
>  };
>
> diff --git a/lib/netdev.c b/lib/netdev.c
> index 6a4218553..6b0ea8e11 100644
> --- a/lib/netdev.c
> +++ b/lib/netdev.c
> @@ -40,7 +40,6 @@
>  #include "fatal-signal.h"
>  #include "hash.h"
>  #include "openvswitch/list.h"
> -#include "netdev-offload-provider.h"
>  #include "netdev-provider.h"
>  #include "netdev-vport.h"
>  #include "odp-netlink.h"
> @@ -431,7 +430,6 @@ netdev_open(const char *name, const char *type, struct 
> netdev **netdevp)
>                  netdev->reconfigure_seq = seq_create();
>                  netdev->last_reconfigure_seq =
>                      seq_read(netdev->reconfigure_seq);
> -                ovsrcu_set(&netdev->flow_api, NULL);
>                  netdev->hw_info.oor = false;
>                  atomic_init(&netdev->hw_info.postprocess_api_supported, 
> false);
>                  netdev->node = shash_add(&netdev_shash, name, netdev);
> @@ -583,8 +581,6 @@ netdev_unref(struct netdev *dev)
>          const struct netdev_class *class = dev->netdev_class;
>          struct netdev_registered_class *rc;
>
> -        netdev_uninit_flow_api(dev);
> -
>          dev->netdev_class->destruct(dev);
>
>          if (dev->node) {
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index f751cdd4f..a7395ce09 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -1765,7 +1765,7 @@ check_support(struct dpif_backer *backer)
>  /* TC does not support offloading the explicit drop action. As such we need 
> to
>   * re-probe the datapath if hw-offload has been modified.
>   * Note: We don't support true --> false transition as that requires a 
> restart.
> - * See netdev_set_flow_api_enabled(). */
> + * See dpif_offload_set_global_cfg(). */
>  static bool
>  recheck_support_explicit_drop_action(struct dpif_backer *backer)
>  {
> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> index 20eec1e4d..b82338b2d 100644
> --- a/vswitchd/bridge.c
> +++ b/vswitchd/bridge.c
> @@ -3400,7 +3400,6 @@ bridge_run(void)
>       }
>
>      if (cfg) {
> -        netdev_set_flow_api_enabled(&cfg->other_config);
>          dpdk_init(&cfg->other_config);
>          userspace_tso_init(&cfg->other_config);
>      }
> -- 
> 2.50.1
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to