On 10 Dec 2025, at 18:00, Eli Britstein wrote:

>> -----Original Message-----
>> From: dev <[email protected]> On Behalf Of Eelco Chaudron
>> Sent: Tuesday, 2 December 2025 16:05
>> To: [email protected]
>> Subject: [ovs-dev] [PATCH v2 13/41] dpif-offload: Call flow-flush netdev-
>> offload APIs via dpif-offload.
>>
>> Start using the new dpif-offload API by avoiding direct calls to 
>> netdev-offload.
>> This is the first step towards removing netdev-offload as an API layer.
>>
>> Signed-off-by: Eelco Chaudron <[email protected]>
>> ---
>>
>> v2 changes:
>>  - Added missing newline at end of netdev-offload-tc.h.
>>  - Fixed some indentation issues.
>> ---
>> lib/automake.mk               |  4 +++-
>> lib/dpif-netdev.c             |  2 +-
>> lib/dpif-netlink.c            |  5 ----
>> lib/dpif-offload-dpdk.c       |  9 ++++++++
>> lib/dpif-offload-provider.h   | 13 +++++++++++
>> lib/dpif-offload-tc.c         | 43 +++++++++++++++++++++++++++++++++++
>> lib/dpif-offload.c            | 36 +++++++++++++++++++++++++++++
>> lib/dpif-offload.h            |  5 ++++
>> lib/dpif.c                    |  1 +
>> lib/netdev-offload-dpdk.c     |  4 ++--
>> lib/netdev-offload-dpdk.h     | 27 ++++++++++++++++++++++
>> lib/netdev-offload-provider.h |  3 ---
>> lib/netdev-offload-tc.c       |  6 ++---
>> lib/netdev-offload-tc.h       | 27 ++++++++++++++++++++++
>> lib/netdev-offload.c          | 25 --------------------
>> lib/netdev-offload.h          |  2 --
>> 16 files changed, 170 insertions(+), 42 deletions(-)  create mode 100644
>> lib/netdev-offload-dpdk.h  create mode 100644 lib/netdev-offload-tc.h
>>
>> diff --git a/lib/automake.mk b/lib/automake.mk index 6db7daa9f..229064716
>> 100644
>> --- a/lib/automake.mk
>> +++ b/lib/automake.mk
>> @@ -481,6 +481,7 @@ lib_libopenvswitch_la_SOURCES += \
>>      lib/netdev-linux.h \
>>      lib/netdev-linux-private.h \
>>      lib/netdev-offload-tc.c \
>> +    lib/netdev-offload-tc.h \
>>      lib/netlink-conntrack.c \
>>      lib/netlink-conntrack.h \
>>      lib/netlink-notifier.c \
>> @@ -509,7 +510,8 @@ lib_libopenvswitch_la_SOURCES += \
>>      lib/dpdk.c \
>>      lib/dpif-offload-dpdk.c \
>>      lib/netdev-dpdk.c \
>> -    lib/netdev-offload-dpdk.c
>> +    lib/netdev-offload-dpdk.c \
>> +    lib/netdev-offload-dpdk.h
>> else
>> lib_libopenvswitch_la_SOURCES += \
>>      lib/dpdk-stub.c
>> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2e31041ef..79b05bc0d
>> 100644
>> --- a/lib/dpif-netdev.c
>> +++ b/lib/dpif-netdev.c
>> @@ -2911,7 +2911,7 @@ dp_offload_flush(struct dp_offload_thread_item
>> *item)
>>     struct dp_offload_flush_item *flush = &item->data->flush;
>>
>>     ovs_rwlock_rdlock(&item->dp->port_rwlock);
>> -    netdev_flow_flush(flush->netdev);
>> +    dpif_offload_netdev_flush_flows(flush->netdev);
>>     ovs_rwlock_unlock(&item->dp->port_rwlock);
>>
>>     ovs_barrier_block(flush->barrier);
>> diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 
>> e7e55bc05..6241ba8f7
>> 100644
>> --- a/lib/dpif-netlink.c
>> +++ b/lib/dpif-netlink.c
>> @@ -1309,7 +1309,6 @@ dpif_netlink_port_get_pid(const struct dpif *dpif_,
>> odp_port_t port_no)  static int  dpif_netlink_flow_flush(struct dpif *dpif_) 
>>  {
>> -    const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif_));
>>     const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
>>     struct dpif_netlink_flow flow;
>>
>> @@ -1317,10 +1316,6 @@ dpif_netlink_flow_flush(struct dpif *dpif_)
>>     flow.cmd = OVS_FLOW_CMD_DEL;
>>     flow.dp_ifindex = dpif->dp_ifindex;
>>
>> -    if (dpif_offload_is_offload_enabled()) {
>> -        netdev_ports_flow_flush(dpif_type_str);
>> -    }
>> -
>>     return dpif_netlink_flow_transact(&flow, NULL, NULL);  }
>>
>> diff --git a/lib/dpif-offload-dpdk.c b/lib/dpif-offload-dpdk.c index
>> 1f097bfc9..f231a1c68 100644
>> --- a/lib/dpif-offload-dpdk.c
>> +++ b/lib/dpif-offload-dpdk.c
>> @@ -19,6 +19,7 @@
>>
>> #include "dpif-offload.h"
>> #include "dpif-offload-provider.h"
>> +#include "netdev-offload-dpdk.h"
>> #include "netdev-provider.h"
>> #include "netdev-vport.h"
>> #include "util.h"
>> @@ -252,6 +253,13 @@ dpif_offload_dpdk_can_offload(struct dpif_offload
>> *offload OVS_UNUSED,
>>     return netdev_dpdk_flow_api_supported(netdev, true);  }
>>
>> +static int
>> +dpif_offload_dpdk_netdev_flow_flush(const struct dpif_offload *offload
>> +                                    OVS_UNUSED, struct netdev *netdev)
>> +{
>> +    return netdev_offload_dpdk_flow_flush(netdev);
>> +}
>> +
>> struct dpif_offload_class dpif_offload_dpdk_class = {
>>     .type = "dpdk",
>>     .supported_dpif_types = (const char *const[]) { @@ -264,6 +272,7 @@
>> struct dpif_offload_class dpif_offload_dpdk_class = {
>>     .can_offload = dpif_offload_dpdk_can_offload,
>>     .port_add = dpif_offload_dpdk_port_add,
>>     .port_del = dpif_offload_dpdk_port_del,
>> +    .netdev_flow_flush = dpif_offload_dpdk_netdev_flow_flush,
>> };
>>
>> /* XXX: Temporary functions below, which will be removed once fully diff 
>> --git
>> a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h index
>> 50f9a53c2..4439e9f71 100644
>> --- a/lib/dpif-offload-provider.h
>> +++ b/lib/dpif-offload-provider.h
>> @@ -126,6 +126,19 @@ struct dpif_offload_class {
>>      * as above in 'port_deleted' applies here.*/
>>     void (*port_set_config)(struct dpif_offload *, odp_port_t port_no,
>>                             const struct smap *cfg);
>> +
>> +    /* Deletes all offloaded flows for this offload_provider.  Return 0 if
>> +     * successful, otherwise returns a positive errno value. */
>> +    int (*flow_flush)(const struct dpif_offload *);
>> +
>> +
>> +    /* These APIs operate directly on the provided netdev for performance
>> +     * reasons.  They are intended for use in fast path processing and 
>> should
>> +     * be designed with speed and efficiency in mind. */
>> +
>> +    /* Deletes all offloaded flows on this netdev.  Return 0 if successful,
>> +     * otherwise returns a positive errno value. */
>> +    int (*netdev_flow_flush)(const struct dpif_offload *, struct netdev
>> + *);
>> };
>>
>>
>> diff --git a/lib/dpif-offload-tc.c b/lib/dpif-offload-tc.c index
>> 66d52851a..63ce789c6 100644
>> --- a/lib/dpif-offload-tc.c
>> +++ b/lib/dpif-offload-tc.c
>> @@ -19,6 +19,7 @@
>>
>> #include "dpif-offload.h"
>> #include "dpif-offload-provider.h"
>> +#include "netdev-offload-tc.h"
>> #include "netdev-provider.h"
>> #include "netdev-vport.h"
>> #include "util.h"
>> @@ -236,6 +237,46 @@ dpif_offload_tc_can_offload(struct dpif_offload
>> *dpif_offload OVS_UNUSED,
>>     return true;
>> }
>>
>> +static int
>> +dpif_offload_tc_netdev_flow_flush_(struct netdev *netdev) {
>> +    return netdev_offload_tc_flow_flush(netdev);
>> +}
>> +
>> +static int
>> +dpif_offload_tc_netdev_flow_flush(const struct dpif_offload *offload
>> +                                  OVS_UNUSED, struct netdev *netdev) {
>> +    return dpif_offload_tc_netdev_flow_flush_(netdev);
>> +}
>> +
>> +static bool
>> +dpif_offload_tc_flow_flush_cb(struct dpif_offload_port_mgr_port *port,
>> +                              void *aux) {
>> +    int *err_ptr = aux;
>> +    int err;
>> +
>> +    err = dpif_offload_tc_netdev_flow_flush_(port->netdev);
>> +    if (err && *err_ptr == 0) {
>> +        *err_ptr = err;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +static int
>> +dpif_offload_tc_flow_flush(const struct dpif_offload *offload) {
>> +    struct dpif_offload_tc *offload_tc = dpif_offload_tc_cast(offload);
>> +    int err = 0;
>> +
>> +    dpif_offload_port_mgr_traverse_ports(
>> +        offload_tc->port_mgr, dpif_offload_tc_flow_flush_cb, &err);
>> +
>> +    return err;
>> +}
>> +
>> struct dpif_offload_class dpif_offload_tc_class = {
>>     .type = "tc",
>>     .supported_dpif_types = (const char *const[]) { @@ -248,4 +289,6 @@
>> struct dpif_offload_class dpif_offload_tc_class = {
>>     .can_offload = dpif_offload_tc_can_offload,
>>     .port_add = dpif_offload_tc_port_add,
>>     .port_del = dpif_offload_tc_port_del,
>> +    .flow_flush = dpif_offload_tc_flow_flush,
>> +    .netdev_flow_flush = dpif_offload_tc_netdev_flow_flush,
>> };
>> diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c index 
>> bfaa953b5..5f2be95ee
>> 100644
>> --- a/lib/dpif-offload.c
>> +++ b/lib/dpif-offload.c
>> @@ -713,6 +713,42 @@ dpif_offload_set_global_cfg(const struct
>> ovsrec_open_vswitch *cfg)
>>     }
>> }
>>
>> +void
>> +dpif_offload_flow_flush(struct dpif *dpif) {
>> +    struct dp_offload *dp_offload = dpif_offload_get_dp_offload(dpif);
>> +    const struct dpif_offload *offload;
>> +
>> +    if (!dp_offload) {
>> +        return;
>> +    }
>> +
>> +    LIST_FOR_EACH (offload, dpif_list_node, &dp_offload->offload_providers) 
>> {
>> +        if (offload->class->flow_flush) {
>> +            int err = offload->class->flow_flush(offload);
> Blank line
>> +            if (err) {
>> +                VLOG_ERR("Failed flow flush on dpif-offload provider "
>> +                    "%s, error %s", dpif_offload_name(offload),
>> +                    ovs_strerror(err));
> indentation

ACK on both.

>> +            }
>> +        }
>> +    }
>> +}
>> +
>> +
>>
>>
>> +int
>> +dpif_offload_netdev_flush_flows(struct netdev *netdev) {
>> +    const struct dpif_offload *offload;
>> +
>> +    offload = ovsrcu_get(const struct dpif_offload *,
>> + &netdev->dpif_offload);
>> +
>> +    if (offload && offload->class->netdev_flow_flush) {
>> +        return offload->class->netdev_flow_flush(offload, netdev);
>> +    }
>> +    return EOPNOTSUPP;
>> +}
>> +
>>
>>
>>
>> struct dpif_offload_port_mgr *
>> dpif_offload_port_mgr_init(void)
>> diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h index 
>> 5b6c3038e..2d8778f7b
>> 100644
>> --- a/lib/dpif-offload.h
>> +++ b/lib/dpif-offload.h
>> @@ -46,6 +46,7 @@ const char *dpif_offload_name(const struct dpif_offload
>> *);  const char *dpif_offload_class_type(const struct dpif_offload *);  bool
>> dpif_offload_get_debug(const struct dpif_offload *, struct ds *,
>>                             struct json *);
>> +void dpif_offload_flow_flush(struct dpif *);
>> void dpif_offload_dump_start(struct dpif_offload_dump *, const struct dpif 
>> *);
>> bool dpif_offload_dump_next(struct dpif_offload_dump *,
>>                             struct dpif_offload **); @@ -64,4 +65,8 @@ int
>> dpif_offload_dump_done(struct dpif_offload_dump *);
>>           : (dpif_offload_dump_done(DUMP), false));      \
>>         )
>>
>> +
>>
>>
>> +/* Netdev specific function, which can be used in the fast path. */ int
>> +dpif_offload_netdev_flush_flows(struct netdev *);
>> +
>> #endif /* DPIF_OFFLOAD_H */
>> diff --git a/lib/dpif.c b/lib/dpif.c
>> index fb889322a..4e6f13255 100644
>> --- a/lib/dpif.c
>> +++ b/lib/dpif.c
>> @@ -958,6 +958,7 @@ dpif_flow_flush(struct dpif *dpif)
>>
>>     error = dpif->dpif_class->flow_flush(dpif);
>>     log_operation(dpif, "flow_flush", error);
>> +    dpif_offload_flow_flush(dpif);
>>     return error;
>> }
>>
>> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index
>> c4f97be70..072103596 100644
>> --- a/lib/netdev-offload-dpdk.c
>> +++ b/lib/netdev-offload-dpdk.c
>> @@ -25,6 +25,7 @@
>>
>> #include "cmap.h"
>> #include "dpif-netdev.h"
>> +#include "netdev-offload-dpdk.h"
>> #include "netdev-offload-provider.h"
>> #include "netdev-provider.h"
>> #include "netdev-vport.h"
>> @@ -2609,7 +2610,7 @@ flush_in_vport_cb(struct netdev *vport,
>>     return false;
>> }
>>
>> -static int
>> +int
>> netdev_offload_dpdk_flow_flush(struct netdev *netdev)  {
>>     flush_netdev_flows_in_related(netdev, netdev); @@ -2802,7 +2803,6 @@
>> const struct netdev_flow_api netdev_offload_dpdk = {
>>     .init_flow_api = netdev_offload_dpdk_init_flow_api,
>>     .uninit_flow_api = netdev_offload_dpdk_uninit_flow_api,
>>     .flow_get = netdev_offload_dpdk_flow_get,
>> -    .flow_flush = netdev_offload_dpdk_flow_flush,
>>     .hw_miss_packet_recover =
>> netdev_offload_dpdk_hw_miss_packet_recover,
>>     .flow_get_n_flows = netdev_offload_dpdk_get_n_flows,  }; diff --git
>> a/lib/netdev-offload-dpdk.h b/lib/netdev-offload-dpdk.h new file mode
>> 100644 index 000000000..feded432f
>> --- /dev/null
>> +++ b/lib/netdev-offload-dpdk.h
>> @@ -0,0 +1,27 @@
>> +/*
>> + * Copyright (c) 2025 Red Hat, Inc.
>> + *
>> + * 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_OFFLOAD_DPDK_H
>> + #define NETDEV_OFFLOAD_DPDK_H
>> +
>> +/* Forward declarations of private structures. */ struct netdev;
>> +
>> +/* Netdev-specific offload functions.  These should only be used by the
>> + * associated dpif offload provider. */ int
>> +netdev_offload_dpdk_flow_flush(struct netdev *);
>> +
>> +#endif /* NETDEV_OFFLOAD_DPDK_H */
>> diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h 
>> index
>> 9108856d1..6e36ed4c8 100644
>> --- a/lib/netdev-offload-provider.h
>> +++ b/lib/netdev-offload-provider.h
>> @@ -30,9 +30,6 @@ extern "C" {
>>
>> struct netdev_flow_api {
>>     char *type;
>> -    /* Flush all offloaded flows from a netdev.
>> -     * Return 0 if successful, otherwise returns a positive errno value. */
>> -    int (*flow_flush)(struct netdev *);
>>
>>     /* Flow dumping interface.
>>      *
>> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index
>> 9491dc90e..1c554416c 100644
>> --- a/lib/netdev-offload-tc.c
>> +++ b/lib/netdev-offload-tc.c
>> @@ -32,6 +32,7 @@
>> #include "openvswitch/vlog.h"
>> #include "netdev-linux.h"
>> #include "netdev-offload-provider.h"
>> +#include "netdev-offload-tc.h"
>> #include "netdev-provider.h"
>> #include "netdev-vport.h"
>> #include "netlink.h"
>> @@ -562,8 +563,8 @@ delete_chains_from_netdev(struct netdev *netdev,
>> struct tcf_id *id)
>>     return error;
>> }
>>
>> -static int
>> -netdev_tc_flow_flush(struct netdev *netdev)
>> +int
>> +netdev_offload_tc_flow_flush(struct netdev *netdev)
>> {
>>     struct ufid_tc_data *data;
>>     int err;
>> @@ -3426,7 +3427,6 @@ meter_tc_del_policer(ofproto_meter_id meter_id,
>>
>> const struct netdev_flow_api netdev_offload_tc = {
>>    .type = "linux_tc",
>> -   .flow_flush = netdev_tc_flow_flush,
>>    .flow_dump_create = netdev_tc_flow_dump_create,
>>    .flow_dump_destroy = netdev_tc_flow_dump_destroy,
>>    .flow_dump_next = netdev_tc_flow_dump_next, diff --git a/lib/netdev-
>> offload-tc.h b/lib/netdev-offload-tc.h new file mode 100644 index
>> 000000000..964559728
>> --- /dev/null
>> +++ b/lib/netdev-offload-tc.h
>> @@ -0,0 +1,27 @@
>> +/*
>> + * Copyright (c) 2025 Red Hat, Inc.
>> + *
>> + * 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_OFFLOAD_TC_H
>> +#define NETDEV_OFFLOAD_TC_H
>> +
>> +/* Forward declarations of private structures. */ struct netdev;
>> +
>> +/* Netdev-specific offload functions.  These should only be used by the
>> + * associated dpif offload provider. */ int
>> +netdev_offload_tc_flow_flush(struct netdev *);
>> +
>> +#endif /* NETDEV_OFFLOAD_TC_H */
>> diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index
>> 0fad1b983..2b1c99fb6 100644
>> --- a/lib/netdev-offload.c
>> +++ b/lib/netdev-offload.c
>> @@ -262,17 +262,6 @@ meter_offload_del(ofproto_meter_id meter_id,
>> struct ofputil_meter_stats *stats)
>>     return 0;
>> }
>>
>> -int
>> -netdev_flow_flush(struct netdev *netdev) -{
>> -    const struct netdev_flow_api *flow_api =
>> -        ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api);
>> -
>> -    return (flow_api && flow_api->flow_flush)
>> -           ? flow_api->flow_flush(netdev)
>> -           : EOPNOTSUPP;
>> -}
>> -
>> int
>> netdev_flow_dump_create(struct netdev *netdev, struct netdev_flow_dump
>> **dump,
>>                         bool terse)
>> @@ -591,20 +580,6 @@ netdev_offload_thread_init(void)
>>     }
>> }
>>
>> -void
>> -netdev_ports_flow_flush(const char *dpif_type) -{
>> -    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_flush(data->netdev);
>> -        }
>> -    }
>> -    ovs_rwlock_unlock(&port_to_netdev_rwlock);
>> -}
>> -
>> void
>> netdev_ports_traverse(const char *dpif_type,
>>                       bool (*cb)(struct netdev *, odp_port_t, void *), diff 
>> --git
>> a/lib/netdev-offload.h b/lib/netdev-offload.h index 5a18727eb..0bee005fd
>> 100644
>> --- a/lib/netdev-offload.h
>> +++ b/lib/netdev-offload.h
>> @@ -100,7 +100,6 @@ netdev_offload_thread_id(void)
>>     return id;
>> }
>>
>> -int netdev_flow_flush(struct netdev *);  int netdev_flow_dump_create(struct
>> netdev *, struct netdev_flow_dump **dump,
>>                             bool terse);  int netdev_flow_dump_destroy(struct
>> netdev_flow_dump *); @@ -144,7 +143,6 @@ struct netdev_flow_dump
>> **netdev_ports_flow_dump_create(
>>                                         const char *dpif_type,
>>                                         int *ports,
>>                                         bool terse); -void 
>> netdev_ports_flow_flush(const char
>> *dpif_type);  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,

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

Reply via email to