/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 */ |