Coverage Report

Created: 2026-02-26 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openvswitch/lib/dpif-offload.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2025 Red Hat, Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at:
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#ifndef DPIF_OFFLOAD_H
18
#define DPIF_OFFLOAD_H
19
20
#include "dpif.h"
21
22
/* Forward declarations of private structures. */
23
struct dpif_offload_class;
24
struct dpif_offload;
25
26
/* Definition of the DPIF offload implementation type.
27
 *
28
 * The 'DPIF_OFFLOAD_IMPL_FLOWS_DPIF_SYNCED' implementation has a single view,
29
 * the offload provider is responsible for synchronizing flows and statistics
30
 * through the dpif flow operations.  An example of this is DPDK's rte_flow.
31
 *
32
 * The 'DPIF_OFFLOAD_IMPL_FLOWS_PROVIDER_ONLY' implementation tries to install
33
 * the offloaded flow first.  If successful, no dpif-layer software flow will
34
 * be installed.  Offload-specific callbacks are then used to manage the flow
35
 * and query statistics.  An example of this is kernel TC.
36
 */
37
enum dpif_offload_impl_type {
38
    DPIF_OFFLOAD_IMPL_NONE,
39
    DPIF_OFFLOAD_IMPL_FLOWS_DPIF_SYNCED,
40
    DPIF_OFFLOAD_IMPL_FLOWS_PROVIDER_ONLY,
41
};
42
43

44
/* Global functions. */
45
void dpif_offload_set_global_cfg(const struct ovsrec_open_vswitch *);
46
bool dpif_offload_enabled(void);
47
bool dpif_offload_rebalance_policy_enabled(void);
48
49

50
/* Per dpif specific functions. */
51
void dpif_offload_init(struct dpif_offload *,
52
                       const struct dpif_offload_class *, struct dpif *);
53
void dpif_offload_destroy(struct dpif_offload *);
54
int dpif_attach_offload_providers(struct dpif *);
55
void dpif_detach_offload_providers(struct dpif *);
56
const char *dpif_offload_name(const struct dpif_offload *);
57
const char *dpif_offload_type(const struct dpif_offload *);
58
bool dpif_offload_get_debug(const struct dpif_offload *, struct ds *,
59
                            struct json *);
60
void dpif_offload_flow_flush(struct dpif *);
61
void dpif_offload_dump_start(const struct dpif *, void **statep);
62
bool dpif_offload_dump_next(void *state, struct dpif_offload **);
63
int dpif_offload_dump_done(void *state);
64
uint64_t dpif_offload_flow_count(const struct dpif *);
65
uint64_t dpif_offload_flow_count_by_impl(const struct dpif *,
66
                                         enum dpif_offload_impl_type);
67
void dpif_offload_meter_set(const struct dpif *dpif, ofproto_meter_id meter_id,
68
                            struct ofputil_meter_config *);
69
void dpif_offload_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id,
70
                            struct ofputil_meter_stats *);
71
void dpif_offload_meter_del(const struct dpif *dpif, ofproto_meter_id meter_id,
72
                            struct ofputil_meter_stats *);
73
struct netdev *dpif_offload_get_netdev_by_port_id(struct dpif *,
74
                                                  struct dpif_offload **,
75
                                                  odp_port_t);
76
struct dpif_offload *dpif_offload_port_offloaded_by(const struct dpif *,
77
                                                    odp_port_t);
78
bool dpif_offload_netdevs_out_of_resources(struct dpif *);
79
enum dpif_offload_impl_type dpif_offload_get_impl_type(
80
    const struct dpif_offload *);
81
enum dpif_offload_impl_type dpif_offload_get_impl_type_by_class(
82
    const char *type);
83
84
/* Iterates through each DPIF_OFFLOAD in DPIF, using DUMP as state.
85
 *
86
 * Arguments all have pointer type.
87
 *
88
 * If you break out of the loop, then you need to free the dump structure by
89
 * hand using dpif_offload_dump_done(). */
90
#define DPIF_OFFLOAD_FOR_EACH(DPIF_OFFLOAD, DUMP_STATE, DPIF)  \
91
    for (dpif_offload_dump_start(DPIF, &DUMP_STATE);           \
92
         (dpif_offload_dump_next(DUMP_STATE, &DPIF_OFFLOAD)    \
93
          ? true                                               \
94
          : (dpif_offload_dump_done(DUMP_STATE), false));      \
95
        )
96
97
/* Queries the datapath for hardware offload stats.
98
 *
99
 * On success, '*stats' will point to a heap-allocated array of
100
 * 'netdev_custom_stats' structures, and '*n_stats' will be set to the
101
 * number of statistics returned.
102
 *
103
 * The caller is responsible for freeing the memory using
104
 * 'netdev_free_custom_stats_counters()' on each 'stats' object, and
105
 * call free() on 'stats'. */
106
int dpif_offload_stats_get(struct dpif *, struct netdev_custom_stats **stats,
107
                           size_t *n_stats);
108
109

110
/* Netdev specific function, which can be used in the fast path. */
111
bool dpif_offload_netdev_same_offload(const struct netdev *,
112
                                      const struct netdev *);
113
int dpif_offload_netdev_hw_post_process(struct netdev *, unsigned pmd_id,
114
                                        struct dp_packet *,
115
                                        void **flow_reference);
116
117

118
/* Callback invoked when a hardware flow offload operation (put/del) completes.
119
 * This callback is used for asynchronous flow offload operations.  When the
120
 * offload provider cannot complete an operation synchronously (returns
121
 * EINPROGRESS), it will invoke this callback later to notify the caller of
122
 * completion. */
123
typedef void dpif_offload_flow_op_cb(void *aux, struct dpif_flow_stats *stats,
124
                                     unsigned pmd_id, void *flow_reference,
125
                                     void *old_flow_reference,
126
                                     int error);
127
128
/* Callback invoked when the offload provider releases a flow reference.
129
 * When a flow is offloaded to hardware, the offload provider holds a reference
130
 * to the datapath flow (e.g., dp_netdev_flow).  This callback notifies the
131
 * datapath when that reference is no longer held, allowing proper cleanup and
132
 * reference count management. */
133
typedef void dpif_offload_flow_unreference_cb(unsigned pmd_id,
134
                                              void *flow_reference);
135
136
/* Supporting structures for flow modification functions. */
137
struct dpif_offload_flow_cb_data {
138
    dpif_offload_flow_op_cb *callback;
139
    void *callback_aux;
140
};
141
142
struct dpif_offload_flow_put {
143
    odp_port_t in_port;
144
    odp_port_t orig_in_port;  /* Originating in_port for tunneled packets. */
145
    unsigned pmd_id;
146
    const ovs_u128 *ufid;
147
    void *flow_reference;
148
    struct match *match;
149
    const struct nlattr *actions;
150
    size_t actions_len;
151
    struct dpif_flow_stats *stats;
152
    struct dpif_offload_flow_cb_data cb_data;
153
};
154
155
struct dpif_offload_flow_del {
156
    odp_port_t in_port;
157
    unsigned pmd_id;
158
    const ovs_u128 *ufid;
159
    void *flow_reference;
160
    struct dpif_flow_stats *stats;
161
    struct dpif_offload_flow_cb_data cb_data;
162
};
163
164
/* Flow modification functions, which can be used in the fast path. */
165
int dpif_offload_datapath_flow_put(const char *dpif_name,
166
                                   struct dpif_offload_flow_put *,
167
                                   void **previous_flow_reference);
168
int dpif_offload_datapath_flow_del(const char *dpif_name,
169
                                   struct dpif_offload_flow_del *);
170
bool dpif_offload_datapath_flow_stats(const char *dpif_name,
171
                                      odp_port_t in_port, const ovs_u128 *ufid,
172
                                      struct dpif_flow_stats *,
173
                                      struct dpif_flow_attrs *);
174
void dpif_offload_datapath_register_flow_unreference_cb(
175
    struct dpif *, dpif_offload_flow_unreference_cb *);
176
177
static inline void
178
dpif_offload_datapath_flow_op_continue(struct dpif_offload_flow_cb_data *cb,
179
                                       struct dpif_flow_stats *stats,
180
                                       unsigned pmd_id, void *flow_reference,
181
                                       void *old_flow_reference, int error)
182
0
{
183
0
    if (cb && cb->callback) {
184
0
        cb->callback(cb->callback_aux, stats, pmd_id, flow_reference,
185
0
                     old_flow_reference, error);
186
0
    }
187
0
}
Unexecuted instantiation: netdev-linux.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif-offload.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif-offload-dummy.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif-netlink.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif-offload-tc.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif-offload-tc-netdev.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpctl.c:dpif_offload_datapath_flow_op_continue
Unexecuted instantiation: dpif-netdev.c:dpif_offload_datapath_flow_op_continue
188
189
#endif /* DPIF_OFFLOAD_H */