Coverage Report

Created: 2026-02-09 06:06

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
int dpif_attach_offload_providers(struct dpif *);
54
void dpif_detach_offload_providers(struct dpif *);
55
const char *dpif_offload_name(const struct dpif_offload *);
56
const char *dpif_offload_type(const struct dpif_offload *);
57
bool dpif_offload_get_debug(const struct dpif_offload *, struct ds *,
58
                            struct json *);
59
void dpif_offload_flow_flush(struct dpif *);
60
void dpif_offload_dump_start(const struct dpif *, void **statep);
61
bool dpif_offload_dump_next(void *state, struct dpif_offload **);
62
int dpif_offload_dump_done(void *state);
63
uint64_t dpif_offload_flow_count(const struct dpif *);
64
uint64_t dpif_offload_flow_count_by_impl(const struct dpif *,
65
                                         enum dpif_offload_impl_type);
66
void dpif_offload_meter_set(const struct dpif *dpif, ofproto_meter_id meter_id,
67
                            struct ofputil_meter_config *);
68
void dpif_offload_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id,
69
                            struct ofputil_meter_stats *);
70
void dpif_offload_meter_del(const struct dpif *dpif, ofproto_meter_id meter_id,
71
                            struct ofputil_meter_stats *);
72
struct netdev *dpif_offload_get_netdev_by_port_id(struct dpif *,
73
                                                  struct dpif_offload **,
74
                                                  odp_port_t);
75
struct dpif_offload *dpif_offload_port_offloaded_by(const struct dpif *,
76
                                                    odp_port_t);
77
bool dpif_offload_netdevs_out_of_resources(struct dpif *);
78
enum dpif_offload_impl_type dpif_offload_get_impl_type(
79
    const struct dpif_offload *);
80
enum dpif_offload_impl_type dpif_offload_get_impl_type_by_class(
81
    const char *type);
82
83
/* Iterates through each DPIF_OFFLOAD in DPIF, using DUMP as state.
84
 *
85
 * Arguments all have pointer type.
86
 *
87
 * If you break out of the loop, then you need to free the dump structure by
88
 * hand using dpif_offload_dump_done(). */
89
#define DPIF_OFFLOAD_FOR_EACH(DPIF_OFFLOAD, DUMP_STATE, DPIF)  \
90
    for (dpif_offload_dump_start(DPIF, &DUMP_STATE);           \
91
         (dpif_offload_dump_next(DUMP_STATE, &DPIF_OFFLOAD)    \
92
          ? true                                               \
93
          : (dpif_offload_dump_done(DUMP_STATE), false));      \
94
        )
95
96
struct dpif_offload_port {
97
    struct netdev *netdev;
98
    odp_port_t port_no;
99
};
100
101
struct dpif_offload_port_dump {
102
    const struct dpif *dpif;
103
    const struct dpif_offload *offload;
104
    int error;
105
    void *state;
106
};
107
108
void dpif_offload_port_dump_start(struct dpif_offload_port_dump *,
109
                                  const struct dpif *);
110
bool dpif_offload_port_dump_next(struct dpif_offload_port_dump *,
111
                                 struct dpif_offload_port *);
112
int dpif_offload_port_dump_done(struct dpif_offload_port_dump *);
113
114
/* Iterates through each DPIF_OFFLOAD_PORT in DPIF, using DUMP as state.
115
 *
116
 * Arguments all have pointer type.
117
 *
118
 * If you break out of the loop, then you need to free the dump structure by
119
 * hand using dpif_offload_port_dump_done(). */
120
#define DPIF_OFFLOAD_PORT_FOR_EACH(DPIF_OFFLOAD_PORT, DUMP, DPIF)  \
121
0
    for (dpif_offload_port_dump_start(DUMP, DPIF);                 \
122
0
         (dpif_offload_port_dump_next(DUMP, DPIF_OFFLOAD_PORT)     \
123
0
          ? true                                                   \
124
0
          : (dpif_offload_port_dump_done(DUMP), false));           \
125
0
        )
126
127
/* Queries the datapath for hardware offload stats.
128
 *
129
 * On success, '*stats' will point to a heap-allocated array of
130
 * 'netdev_custom_stats' structures, and '*n_stats' will be set to the
131
 * number of statistics returned.
132
 *
133
 * The caller is responsible for freeing the memory using
134
 * 'netdev_free_custom_stats_counters()' on each 'stats' object, and
135
 * call free() on 'stats'. */
136
int dpif_offload_stats_get(struct dpif *, struct netdev_custom_stats **stats,
137
                           size_t *n_stats);
138
139

140
/* Netdev specific function, which can be used in the fast path. */
141
bool dpif_offload_netdev_same_offload(const struct netdev *,
142
                                      const struct netdev *);
143
int dpif_offload_netdev_hw_post_process(struct netdev *, unsigned pmd_id,
144
                                        struct dp_packet *,
145
                                        void **flow_reference);
146
147

148
/* Callback invoked when a hardware flow offload operation (put/del) completes.
149
 * This callback is used for asynchronous flow offload operations.  When the
150
 * offload provider cannot complete an operation synchronously (returns
151
 * EINPROGRESS), it will invoke this callback later to notify the caller of
152
 * completion. */
153
typedef void dpif_offload_flow_op_cb(void *aux, struct dpif_flow_stats *stats,
154
                                     unsigned pmd_id, void *flow_reference,
155
                                     void *old_flow_reference,
156
                                     int error);
157
158
/* Callback invoked when the offload provider releases a flow reference.
159
 * When a flow is offloaded to hardware, the offload provider holds a reference
160
 * to the datapath flow (e.g., dp_netdev_flow).  This callback notifies the
161
 * datapath when that reference is no longer held, allowing proper cleanup and
162
 * reference count management. */
163
typedef void dpif_offload_flow_unreference_cb(unsigned pmd_id,
164
                                              void *flow_reference);
165
166
/* Supporting structures for flow modification functions. */
167
struct dpif_offload_flow_cb_data {
168
    dpif_offload_flow_op_cb *callback;
169
    void *callback_aux;
170
};
171
172
struct dpif_offload_flow_put {
173
    odp_port_t in_port;
174
    odp_port_t orig_in_port;  /* Originating in_port for tunneled packets. */
175
    unsigned pmd_id;
176
    const ovs_u128 *ufid;
177
    void *flow_reference;
178
    struct match *match;
179
    const struct nlattr *actions;
180
    size_t actions_len;
181
    struct dpif_flow_stats *stats;
182
    struct dpif_offload_flow_cb_data cb_data;
183
};
184
185
struct dpif_offload_flow_del {
186
    odp_port_t in_port;
187
    unsigned pmd_id;
188
    const ovs_u128 *ufid;
189
    void *flow_reference;
190
    struct dpif_flow_stats *stats;
191
    struct dpif_offload_flow_cb_data cb_data;
192
};
193
194
/* Flow modification functions, which can be used in the fast path. */
195
int dpif_offload_datapath_flow_put(const char *dpif_name,
196
                                   struct dpif_offload_flow_put *,
197
                                   void **previous_flow_reference);
198
int dpif_offload_datapath_flow_del(const char *dpif_name,
199
                                   struct dpif_offload_flow_del *);
200
bool dpif_offload_datapath_flow_stats(const char *dpif_name,
201
                                      odp_port_t in_port, const ovs_u128 *ufid,
202
                                      struct dpif_flow_stats *,
203
                                      struct dpif_flow_attrs *);
204
void dpif_offload_datapath_register_flow_unreference_cb(
205
    struct dpif *, dpif_offload_flow_unreference_cb *);
206
207
static inline void
208
dpif_offload_datapath_flow_op_continue(struct dpif_offload_flow_cb_data *cb,
209
                                       struct dpif_flow_stats *stats,
210
                                       unsigned pmd_id, void *flow_reference,
211
                                       void *old_flow_reference, int error)
212
0
{
213
0
    if (cb && cb->callback) {
214
0
        cb->callback(cb->callback_aux, stats, pmd_id, flow_reference,
215
0
                     old_flow_reference, error);
216
0
    }
217
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
218
219
#endif /* DPIF_OFFLOAD_H */