/src/openvswitch/lib/odp-util.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, 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 ODP_UTIL_H |
18 | | #define ODP_UTIL_H 1 |
19 | | |
20 | | #include <stdbool.h> |
21 | | #include <stddef.h> |
22 | | #include <stdint.h> |
23 | | #include <string.h> |
24 | | #include "flow.h" |
25 | | #include "hash.h" |
26 | | #include "openvswitch/hmap.h" |
27 | | #include "openvswitch/ofp-actions.h" |
28 | | #include "openvswitch/uuid.h" |
29 | | #include "odp-netlink.h" |
30 | | #include "openflow/openflow.h" |
31 | | #include "util.h" |
32 | | |
33 | | struct ds; |
34 | | struct nlattr; |
35 | | struct ofpbuf; |
36 | | struct simap; |
37 | | struct pkt_metadata; |
38 | | |
39 | | #define SLOW_PATH_REASONS \ |
40 | | SPR(SLOW_CFM, "cfm", "Consists of CFM packets") \ |
41 | | SPR(SLOW_BFD, "bfd", "Consists of BFD packets") \ |
42 | | SPR(SLOW_LACP, "lacp", "Consists of LACP packets") \ |
43 | | SPR(SLOW_STP, "stp", "Consists of STP packets") \ |
44 | | SPR(SLOW_LLDP, "lldp", "Consists of LLDP packets") \ |
45 | | SPR(SLOW_ACTION, "action", \ |
46 | | "Uses action(s) not supported by datapath") \ |
47 | | SPR(SLOW_MATCH, "match", \ |
48 | | "Datapath can't match specifically enough") |
49 | | |
50 | | /* Indexes for slow-path reasons. Client code uses "enum slow_path_reason" |
51 | | * values instead of these, these are just a way to construct those. */ |
52 | | enum { |
53 | | #define SPR(ENUM, STRING, EXPLANATION) ENUM##_INDEX, |
54 | | SLOW_PATH_REASONS |
55 | | #undef SPR |
56 | | }; |
57 | | |
58 | | /* Reasons why a flow might not be fast-pathable. |
59 | | * |
60 | | * Each reason is a separate bit to allow reasons to be combined. */ |
61 | | enum slow_path_reason { |
62 | | #define SPR(ENUM, STRING, EXPLANATION) ENUM = 1 << ENUM##_INDEX, |
63 | | SLOW_PATH_REASONS |
64 | | #undef SPR |
65 | | }; |
66 | | |
67 | | /* Mask of all slow_path_reasons. */ |
68 | | enum { |
69 | | SLOW_PATH_REASON_MASK = 0 |
70 | | #define SPR(ENUM, STRING, EXPLANATION) | 1 << ENUM##_INDEX |
71 | | SLOW_PATH_REASONS |
72 | | #undef SPR |
73 | | }; |
74 | | |
75 | | const char *slow_path_reason_to_explanation(enum slow_path_reason); |
76 | | |
77 | | #define ODPP_LOCAL ODP_PORT_C(OVSP_LOCAL) |
78 | | #define ODPP_NONE ODP_PORT_C(UINT32_MAX) |
79 | | |
80 | | void format_odp_actions(struct ds *, const struct nlattr *odp_actions, |
81 | | size_t actions_len, const struct hmap *portno_names); |
82 | | int odp_actions_from_string(const char *, const struct simap *port_names, |
83 | | struct ofpbuf *odp_actions); |
84 | | |
85 | | /* A map from odp port number to its name. */ |
86 | | struct odp_portno_names { |
87 | | struct hmap_node hmap_node; /* A node in a port number to name hmap. */ |
88 | | odp_port_t port_no; /* Port number in the datapath. */ |
89 | | char *name; /* Name associated with the above 'port_no'. */ |
90 | | }; |
91 | | |
92 | | void odp_portno_names_set(struct hmap *portno_names, odp_port_t port_no, |
93 | | char *port_name); |
94 | | void odp_portno_names_destroy(struct hmap *portno_names); |
95 | | void odp_portno_name_format(const struct hmap *portno_names, |
96 | | odp_port_t, struct ds *); |
97 | | |
98 | | /* The maximum number of bytes that odp_flow_key_from_flow() appends to a |
99 | | * buffer. This is the upper bound on the length of a nlattr-formatted flow |
100 | | * key that ovs-vswitchd fully understands. |
101 | | * |
102 | | * OVS doesn't insist that ovs-vswitchd and the datapath have exactly the same |
103 | | * idea of a flow, so therefore this value isn't necessarily an upper bound on |
104 | | * the length of a flow key that the datapath can pass to ovs-vswitchd. |
105 | | * |
106 | | * The longest nlattr-formatted flow key appended by odp_flow_key_from_flow() |
107 | | * would be: |
108 | | * |
109 | | * struct pad nl hdr total |
110 | | * ------ --- ------ ----- |
111 | | * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 |
112 | | * OVS_KEY_ATTR_TUNNEL 0 -- 4 4 |
113 | | * - OVS_TUNNEL_KEY_ATTR_ID 8 -- 4 12 |
114 | | * - OVS_TUNNEL_KEY_ATTR_IPV4_SRC 4 -- 4 8 |
115 | | * - OVS_TUNNEL_KEY_ATTR_IPV4_DST 4 -- 4 8 |
116 | | * - OVS_TUNNEL_KEY_ATTR_IPV6_SRC 16 -- 4 20 |
117 | | * - OVS_TUNNEL_KEY_ATTR_IPV6_DST 16 -- 4 20 |
118 | | * - OVS_TUNNEL_KEY_ATTR_TOS 1 3 4 8 |
119 | | * - OVS_TUNNEL_KEY_ATTR_TTL 1 3 4 8 |
120 | | * - OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT 0 -- 4 4 |
121 | | * - OVS_TUNNEL_KEY_ATTR_CSUM 0 -- 4 4 |
122 | | * - OVS_TUNNEL_KEY_ATTR_OAM 0 -- 4 4 |
123 | | * - OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS 256 -- 4 260 |
124 | | * - OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS - -- - - (shared with _GENEVE_OPTS) |
125 | | * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 |
126 | | * OVS_KEY_ATTR_SKB_MARK 4 -- 4 8 |
127 | | * OVS_KEY_ATTR_DP_HASH 4 -- 4 8 |
128 | | * OVS_KEY_ATTR_RECIRC_ID 4 -- 4 8 |
129 | | * OVS_KEY_ATTR_CT_STATE 4 -- 4 8 |
130 | | * OVS_KEY_ATTR_CT_ZONE 2 2 4 8 |
131 | | * OVS_KEY_ATTR_CT_MARK 4 -- 4 8 |
132 | | * OVS_KEY_ATTR_CT_LABEL 16 -- 4 20 |
133 | | * OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 40 -- 4 44 |
134 | | * OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4 - -- - - (exclusive of_CT_ORIG_TUPLE_IPV6) |
135 | | * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 |
136 | | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) |
137 | | * OVS_KEY_ATTR_VLAN 2 2 4 8 |
138 | | * OVS_KEY_ATTR_ENCAP 0 -- 4 4 (VLAN encapsulation) |
139 | | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (inner VLAN ethertype) |
140 | | * OVS_KEY_ATTR_IPV6 40 -- 4 44 |
141 | | * OVS_KEY_ATTR_ICMPV6 2 2 4 8 |
142 | | * OVS_KEY_ATTR_ND 28 -- 4 32 |
143 | | * ---------------------------------------------------------- |
144 | | * total 616 |
145 | | * |
146 | | * We include some slack space in case the calculation isn't quite right or we |
147 | | * add another field and forget to adjust this value. |
148 | | */ |
149 | | #define ODPUTIL_FLOW_KEY_BYTES 640 |
150 | | BUILD_ASSERT_DECL(FLOW_WC_SEQ == 42); |
151 | | |
152 | | /* A buffer with sufficient size and alignment to hold an nlattr-formatted flow |
153 | | * key. An array of "struct nlattr" might not, in theory, be sufficiently |
154 | | * aligned because it only contains 16-bit types. */ |
155 | | struct odputil_keybuf { |
156 | | uint32_t keybuf[DIV_ROUND_UP(ODPUTIL_FLOW_KEY_BYTES, 4)]; |
157 | | }; |
158 | | |
159 | | enum odp_key_fitness odp_tun_key_from_attr(const struct nlattr *, |
160 | | struct flow_tnl *, char **errorp); |
161 | | enum odp_key_fitness odp_nsh_key_from_attr(const struct nlattr *, |
162 | | struct ovs_key_nsh *, |
163 | | struct ovs_key_nsh *, |
164 | | char **errorp); |
165 | | enum odp_key_fitness odp_nsh_hdr_from_attr(const struct nlattr *, |
166 | | struct nsh_hdr *, size_t); |
167 | | |
168 | | int odp_ufid_from_string(const char *s_, ovs_u128 *ufid); |
169 | | void odp_format_ufid(const ovs_u128 *ufid, struct ds *); |
170 | | |
171 | | void odp_flow_format(const struct nlattr *key, size_t key_len, |
172 | | const struct nlattr *mask, size_t mask_len, |
173 | | const struct hmap *portno_names, struct ds *, |
174 | | bool verbose, bool skip_no_mask); |
175 | | void odp_flow_key_format(const struct nlattr *, size_t, struct ds *); |
176 | | int odp_flow_from_string(const char *s, const struct simap *port_names, |
177 | | struct ofpbuf *, struct ofpbuf *, char **errorp); |
178 | | |
179 | | /* ODP_SUPPORT_FIELD(TYPE, FIELD_NAME, FIELD_DESCRIPTION) |
180 | | * |
181 | | * Each 'ODP_SUPPORT_FIELD' defines a member in 'struct odp_support', |
182 | | * and represents support for related OVS_KEY_ATTR_* fields. |
183 | | * They are defined as macros to keep 'dpif_show_support()' in sync |
184 | | * as new fields are added. */ |
185 | | #define ODP_SUPPORT_FIELDS \ |
186 | | /* Maximum number of 802.1q VLAN headers to serialize in a mask. */ \ |
187 | | ODP_SUPPORT_FIELD(size_t, max_vlan_headers, "Max VLAN headers") \ |
188 | | /* Maximum number of MPLS label stack entries to serialise in a mask. */ \ |
189 | | ODP_SUPPORT_FIELD(size_t, max_mpls_depth, "Max MPLS depth") \ |
190 | | /* If this is true, then recirculation fields will always be \ |
191 | | * serialised. */ \ |
192 | | ODP_SUPPORT_FIELD(bool, recirc, "Recirc") \ |
193 | | /* If true, serialise the corresponding OVS_KEY_ATTR_CONN_* field. */ \ |
194 | | ODP_SUPPORT_FIELD(bool, ct_state, "CT state") \ |
195 | | ODP_SUPPORT_FIELD(bool, ct_zone, "CT zone") \ |
196 | | ODP_SUPPORT_FIELD(bool, ct_mark, "CT mark") \ |
197 | | ODP_SUPPORT_FIELD(bool, ct_label, "CT label") \ |
198 | | \ |
199 | | /* If true, it means that the datapath supports the NAT bits in \ |
200 | | * 'ct_state'. The above 'ct_state' member must be true for this \ |
201 | | * to make sense */ \ |
202 | | ODP_SUPPORT_FIELD(bool, ct_state_nat, "CT state NAT") \ |
203 | | \ |
204 | | /* Conntrack original direction tuple matching * supported. */ \ |
205 | | ODP_SUPPORT_FIELD(bool, ct_orig_tuple, "CT orig tuple") \ |
206 | | ODP_SUPPORT_FIELD(bool, ct_orig_tuple6, "CT orig tuple for IPv6") \ |
207 | | \ |
208 | | /* If true, it means that the datapath supports the IPv6 Neigh \ |
209 | | * Discovery Extension bits. */ \ |
210 | | ODP_SUPPORT_FIELD(bool, nd_ext, "IPv6 ND Extension") |
211 | | |
212 | | /* Indicates support for various fields. This defines how flows will be |
213 | | * serialised. */ |
214 | | struct odp_support { |
215 | | #define ODP_SUPPORT_FIELD(TYPE, NAME, TITLE) TYPE NAME; |
216 | | ODP_SUPPORT_FIELDS |
217 | | #undef ODP_SUPPORT_FIELD |
218 | | }; |
219 | | |
220 | | struct odp_flow_key_parms { |
221 | | /* The flow and mask to be serialized. In the case of masks, 'flow' |
222 | | * is used as a template to determine how to interpret 'mask'. For |
223 | | * example, the 'dl_type' of 'mask' describes the mask, but it doesn't |
224 | | * indicate whether the other fields should be interpreted as ARP, IPv4, |
225 | | * IPv6, etc. */ |
226 | | const struct flow *flow; |
227 | | const struct flow *mask; |
228 | | |
229 | | /* Indicates support for various fields. If the datapath supports a field, |
230 | | * then it will always be serialised. */ |
231 | | struct odp_support support; |
232 | | |
233 | | /* Indicates if we are probing datapath capability. If true, ignore the |
234 | | * configured flow limits. */ |
235 | | bool probe; |
236 | | |
237 | | /* The netlink formatted version of the flow. It is used in cases where |
238 | | * the mask cannot be constructed from the OVS internal representation |
239 | | * and needs to see the original form. */ |
240 | | const struct ofpbuf *key_buf; |
241 | | }; |
242 | | |
243 | | void odp_flow_key_from_flow(const struct odp_flow_key_parms *, struct ofpbuf *); |
244 | | void odp_flow_key_from_mask(const struct odp_flow_key_parms *, struct ofpbuf *); |
245 | | |
246 | | void odp_flow_key_hash(const void *key, size_t key_len, ovs_u128 *hash); |
247 | | |
248 | | /* Estimated space needed for metadata. */ |
249 | | enum { ODP_KEY_METADATA_SIZE = 9 * 8 }; |
250 | | void odp_key_from_dp_packet(struct ofpbuf *, const struct dp_packet *); |
251 | | void odp_key_to_dp_packet(const struct nlattr *key, size_t key_len, |
252 | | struct dp_packet *md); |
253 | | |
254 | | /* How well a kernel-provided flow key (a sequence of OVS_KEY_ATTR_* |
255 | | * attributes) matches OVS userspace expectations. |
256 | | * |
257 | | * These values are arranged so that greater values are "more important" than |
258 | | * lesser ones. In particular, a single flow key can fit the descriptions for |
259 | | * both ODP_FIT_TOO_LITTLE and ODP_FIT_TOO_MUCH. Such a key is treated as |
260 | | * ODP_FIT_TOO_LITTLE. */ |
261 | | enum odp_key_fitness { |
262 | | ODP_FIT_PERFECT, /* The key had exactly the fields we expect. */ |
263 | | ODP_FIT_TOO_MUCH, /* The key had fields we don't understand. */ |
264 | | ODP_FIT_TOO_LITTLE, /* The key lacked fields we expected to see. */ |
265 | | ODP_FIT_ERROR, /* The key was invalid. */ |
266 | | }; |
267 | | enum odp_key_fitness odp_flow_key_to_flow(const struct nlattr *, size_t, |
268 | | struct flow *, char **errorp); |
269 | | enum odp_key_fitness odp_flow_key_to_mask(const struct nlattr *mask_key, |
270 | | size_t mask_key_len, |
271 | | struct flow_wildcards *mask, |
272 | | const struct flow *flow, |
273 | | char **errorp); |
274 | | int parse_key_and_mask_to_match(const struct nlattr *key, size_t key_len, |
275 | | const struct nlattr *mask, size_t mask_len, |
276 | | struct match *match); |
277 | | |
278 | | const char *odp_key_fitness_to_string(enum odp_key_fitness); |
279 | | |
280 | | void commit_odp_tunnel_action(const struct flow *, struct flow *base, |
281 | | struct ofpbuf *odp_actions, |
282 | | const char *tnl_type); |
283 | | void commit_masked_set_action(struct ofpbuf *odp_actions, |
284 | | enum ovs_key_attr key_type, const void *key, |
285 | | const void *mask, size_t key_size); |
286 | | enum slow_path_reason commit_odp_actions(const struct flow *, |
287 | | struct flow *base, |
288 | | struct ofpbuf *odp_actions, |
289 | | struct flow_wildcards *wc, |
290 | | bool use_masked, |
291 | | bool pending_encap, |
292 | | bool pending_decap, |
293 | | struct ofpbuf *encap_data); |
294 | | |
295 | | int odp_vxlan_tun_opts_from_attr(const struct nlattr *tun_attr, ovs_be16 *id, |
296 | | uint8_t *flags, bool *id_present); |
297 | | |
298 | | /* ofproto-dpif interface. |
299 | | * |
300 | | * The following types and functions are logically part of ofproto-dpif. |
301 | | * ofproto-dpif puts values of these types into the flows that it installs in |
302 | | * the kernel datapath, though, so ovs-dpctl needs to interpret them so that |
303 | | * it can print flows in a more human-readable manner. */ |
304 | | |
305 | | enum user_action_cookie_type { |
306 | | USER_ACTION_COOKIE_UNSPEC, |
307 | | USER_ACTION_COOKIE_SFLOW, /* Packet for per-bridge sFlow sampling. */ |
308 | | USER_ACTION_COOKIE_SLOW_PATH, /* Userspace must process this flow. */ |
309 | | USER_ACTION_COOKIE_FLOW_SAMPLE, /* Packet for per-flow sampling. */ |
310 | | USER_ACTION_COOKIE_IPFIX, /* Packet for per-bridge IPFIX sampling. */ |
311 | | USER_ACTION_COOKIE_CONTROLLER, /* Forward packet to controller. */ |
312 | | }; |
313 | | |
314 | | /* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. */ |
315 | | struct user_action_cookie { |
316 | | uint16_t type; /* enum user_action_cookie_type. */ |
317 | | ofp_port_t ofp_in_port; /* OpenFlow in port, or OFPP_NONE. */ |
318 | | struct uuid ofproto_uuid; /* UUID of ofproto-dpif. */ |
319 | | |
320 | | union { |
321 | | struct { |
322 | | /* USER_ACTION_COOKIE_SFLOW. */ |
323 | | ovs_be16 vlan_tci; /* Destination VLAN TCI. */ |
324 | | uint32_t output; /* SFL_FLOW_SAMPLE_TYPE 'output' value. */ |
325 | | } sflow; |
326 | | |
327 | | struct { |
328 | | /* USER_ACTION_COOKIE_SLOW_PATH. */ |
329 | | uint16_t unused; |
330 | | uint32_t reason; /* enum slow_path_reason. */ |
331 | | } slow_path; |
332 | | |
333 | | struct { |
334 | | /* USER_ACTION_COOKIE_FLOW_SAMPLE. */ |
335 | | uint16_t probability; /* Sampling probability. */ |
336 | | uint32_t collector_set_id; /* ID of IPFIX collector set. */ |
337 | | uint32_t obs_domain_id; /* Observation Domain ID. */ |
338 | | uint32_t obs_point_id; /* Observation Point ID. */ |
339 | | odp_port_t output_odp_port; /* The output odp port. */ |
340 | | enum nx_action_sample_direction direction; |
341 | | } flow_sample; |
342 | | |
343 | | struct { |
344 | | /* USER_ACTION_COOKIE_IPFIX. */ |
345 | | odp_port_t output_odp_port; /* The output odp port. */ |
346 | | } ipfix; |
347 | | |
348 | | struct { |
349 | | /* USER_ACTION_COOKIE_CONTROLLER. */ |
350 | | uint8_t dont_send; /* Don't send the packet to controller. */ |
351 | | uint8_t continuation; /* Send packet-in as a continuation. */ |
352 | | uint16_t reason; |
353 | | uint32_t recirc_id; |
354 | | ovs_32aligned_be64 rule_cookie; |
355 | | uint16_t controller_id; |
356 | | uint16_t max_len; |
357 | | } controller; |
358 | | }; |
359 | | }; |
360 | | BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 48); |
361 | | |
362 | | int odp_put_userspace_action(uint32_t pid, |
363 | | const void *userdata, size_t userdata_size, |
364 | | odp_port_t tunnel_out_port, |
365 | | bool include_actions, |
366 | | struct ofpbuf *odp_actions, |
367 | | size_t *odp_actions_ofs); |
368 | | void odp_put_tunnel_action(const struct flow_tnl *tunnel, |
369 | | struct ofpbuf *odp_actions, |
370 | | const char *tnl_type); |
371 | | |
372 | | void odp_put_tnl_push_action(struct ofpbuf *odp_actions, |
373 | | struct ovs_action_push_tnl *data); |
374 | | |
375 | | void odp_put_pop_eth_action(struct ofpbuf *odp_actions); |
376 | | void odp_put_push_eth_action(struct ofpbuf *odp_actions, |
377 | | const struct eth_addr *eth_src, |
378 | | const struct eth_addr *eth_dst); |
379 | | void odp_put_psample_action(struct ofpbuf *odp_actions, |
380 | | uint32_t group_id, uint8_t *cookie, |
381 | | size_t cookie_len); |
382 | | |
383 | | static inline void odp_decode_gbp_raw(uint32_t gbp_raw, |
384 | | ovs_be16 *id, |
385 | | uint8_t *flags) |
386 | 0 | { |
387 | 0 | *id = htons(gbp_raw & 0xFFFF); |
388 | 0 | *flags = (gbp_raw >> 16) & 0xFF; |
389 | 0 | } |
390 | | |
391 | | static inline uint32_t odp_encode_gbp_raw(uint8_t flags, ovs_be16 id) |
392 | 0 | { |
393 | 0 | return (flags << 16) | ntohs(id); |
394 | 0 | } |
395 | | |
396 | | struct attr_len_tbl { |
397 | | int len; |
398 | | const struct attr_len_tbl *next; |
399 | | int next_max; |
400 | | }; |
401 | | |
402 | | #define ATTR_LEN_INVALID -1 |
403 | | #define ATTR_LEN_VARIABLE -2 |
404 | | #define ATTR_LEN_NESTED -3 |
405 | | |
406 | | extern const struct attr_len_tbl ovs_flow_key_attr_lens[OVS_KEY_ATTR_MAX + 1]; |
407 | | #endif /* odp-util.h */ |