]>
Commit | Line | Data |
---|---|---|
f25d0cf3 | 1 | /* |
269dc90a | 2 | * Copyright (c) 2012, 2013, 2014 Nicira, Inc. |
f25d0cf3 BP |
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 OFP_ACTIONS_H | |
18 | #define OFP_ACTIONS_H 1 | |
19 | ||
7fdb60a7 | 20 | #include <stddef.h> |
f25d0cf3 BP |
21 | #include <stdint.h> |
22 | #include "meta-flow.h" | |
23 | #include "ofp-errors.h" | |
24 | #include "ofp-util.h" | |
25 | #include "openflow/openflow.h" | |
26 | #include "openflow/nicira-ext.h" | |
27 | #include "openvswitch/types.h" | |
28 | ||
29 | /* List of OVS abstracted actions. | |
30 | * | |
31 | * This macro is used directly only internally by this header, but the list is | |
32 | * still of interest to developers. | |
33 | * | |
34 | * Each DEFINE_OFPACT invocation has the following parameters: | |
35 | * | |
36 | * 1. <ENUM>, used below in the enum definition of OFPACT_<ENUM>, and | |
37 | * elsewhere. | |
38 | * | |
39 | * 2. <STRUCT> corresponding to a structure "struct <STRUCT>", that must be | |
40 | * defined below. This structure must be an abstract definition of the | |
41 | * action. Its first member must have type "struct ofpact" and name | |
42 | * "ofpact". It may be fixed length or end with a flexible array member | |
43 | * (e.g. "int member[];"). | |
44 | * | |
45 | * 3. <MEMBER>, which has one of two possible values: | |
46 | * | |
47 | * - If "struct <STRUCT>" is fixed-length, it must be "ofpact". | |
48 | * | |
49 | * - If "struct <STRUCT>" is variable-length, it must be the name of the | |
50 | * flexible array member. | |
51 | */ | |
52 | #define OFPACTS \ | |
53 | /* Output. */ \ | |
54 | DEFINE_OFPACT(OUTPUT, ofpact_output, ofpact) \ | |
7395c052 | 55 | DEFINE_OFPACT(GROUP, ofpact_group, ofpact) \ |
f25d0cf3 BP |
56 | DEFINE_OFPACT(CONTROLLER, ofpact_controller, ofpact) \ |
57 | DEFINE_OFPACT(ENQUEUE, ofpact_enqueue, ofpact) \ | |
58 | DEFINE_OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact) \ | |
59 | DEFINE_OFPACT(BUNDLE, ofpact_bundle, slaves) \ | |
60 | \ | |
61 | /* Header changes. */ \ | |
b2dd70be | 62 | DEFINE_OFPACT(SET_FIELD, ofpact_set_field, ofpact) \ |
f25d0cf3 BP |
63 | DEFINE_OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact) \ |
64 | DEFINE_OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact) \ | |
65 | DEFINE_OFPACT(STRIP_VLAN, ofpact_null, ofpact) \ | |
3e34fbdd | 66 | DEFINE_OFPACT(PUSH_VLAN, ofpact_null, ofpact) \ |
f25d0cf3 BP |
67 | DEFINE_OFPACT(SET_ETH_SRC, ofpact_mac, ofpact) \ |
68 | DEFINE_OFPACT(SET_ETH_DST, ofpact_mac, ofpact) \ | |
69 | DEFINE_OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact) \ | |
70 | DEFINE_OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact) \ | |
04f01c24 | 71 | DEFINE_OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact) \ |
ff14eb7a | 72 | DEFINE_OFPACT(SET_IP_ECN, ofpact_ecn, ofpact) \ |
0c20dbe4 | 73 | DEFINE_OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact) \ |
f25d0cf3 BP |
74 | DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact) \ |
75 | DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact) \ | |
76 | DEFINE_OFPACT(REG_MOVE, ofpact_reg_move, ofpact) \ | |
77 | DEFINE_OFPACT(REG_LOAD, ofpact_reg_load, ofpact) \ | |
bd85dac1 AZ |
78 | DEFINE_OFPACT(STACK_PUSH, ofpact_stack, ofpact) \ |
79 | DEFINE_OFPACT(STACK_POP, ofpact_stack, ofpact) \ | |
c2d967a5 | 80 | DEFINE_OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids) \ |
097d4939 JR |
81 | DEFINE_OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact) \ |
82 | DEFINE_OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact) \ | |
0f3f3c3d | 83 | DEFINE_OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact) \ |
b676167a | 84 | DEFINE_OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact) \ |
b02475c5 SH |
85 | DEFINE_OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact) \ |
86 | DEFINE_OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact) \ | |
f25d0cf3 BP |
87 | \ |
88 | /* Metadata. */ \ | |
89 | DEFINE_OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact) \ | |
90 | DEFINE_OFPACT(SET_QUEUE, ofpact_queue, ofpact) \ | |
91 | DEFINE_OFPACT(POP_QUEUE, ofpact_null, ofpact) \ | |
92 | DEFINE_OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact) \ | |
93 | \ | |
94 | /* Flow table interaction. */ \ | |
95 | DEFINE_OFPACT(RESUBMIT, ofpact_resubmit, ofpact) \ | |
96 | DEFINE_OFPACT(LEARN, ofpact_learn, specs) \ | |
97 | \ | |
98 | /* Arithmetic. */ \ | |
99 | DEFINE_OFPACT(MULTIPATH, ofpact_multipath, ofpact) \ | |
f25d0cf3 BP |
100 | \ |
101 | /* Other. */ \ | |
102 | DEFINE_OFPACT(NOTE, ofpact_note, data) \ | |
8dd54666 | 103 | DEFINE_OFPACT(EXIT, ofpact_null, ofpact) \ |
29089a54 | 104 | DEFINE_OFPACT(SAMPLE, ofpact_sample, ofpact) \ |
8dd54666 IY |
105 | \ |
106 | /* Instructions */ \ | |
638a19b0 | 107 | DEFINE_OFPACT(METER, ofpact_meter, ofpact) \ |
b19e8793 | 108 | DEFINE_OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact) \ |
7fdb60a7 | 109 | DEFINE_OFPACT(WRITE_ACTIONS, ofpact_nest, ofpact) \ |
638a19b0 | 110 | DEFINE_OFPACT(WRITE_METADATA, ofpact_metadata, ofpact) \ |
8dd54666 | 111 | DEFINE_OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact) |
f25d0cf3 BP |
112 | |
113 | /* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */ | |
114 | enum OVS_PACKED_ENUM ofpact_type { | |
115 | #define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) OFPACT_##ENUM, | |
116 | OFPACTS | |
117 | #undef DEFINE_OFPACT | |
118 | }; | |
119 | ||
120 | /* N_OFPACTS, the number of values of "enum ofpact_type". */ | |
121 | enum { | |
122 | N_OFPACTS = | |
123 | #define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) + 1 | |
124 | OFPACTS | |
125 | #undef DEFINE_OFPACT | |
126 | }; | |
127 | ||
128 | /* Header for an action. | |
129 | * | |
130 | * Each action is a structure "struct ofpact_*" that begins with "struct | |
131 | * ofpact", usually followed by other data that describes the action. Actions | |
2ac3c572 BP |
132 | * are padded out to a multiple of OFPACT_ALIGNTO bytes in length. |
133 | * | |
134 | * The 'compat' member is special: | |
135 | * | |
136 | * - Most "struct ofpact"s correspond to one particular kind of OpenFlow | |
137 | * action, at least in a given OpenFlow version. For example, | |
138 | * OFPACT_SET_VLAN_VID corresponds to OFPAT10_SET_VLAN_VID in OpenFlow | |
139 | * 1.0. | |
140 | * | |
141 | * For such actions, the 'compat' member is not meaningful and generally | |
142 | * should be zero. | |
143 | * | |
144 | * - A few "struct ofpact"s correspond to multiple OpenFlow actions. For | |
145 | * example, OFPACT_SET_TUNNEL can be NXAST_SET_TUNNEL or | |
146 | * NXAST_SET_TUNNEL64. In these cases, if the "struct ofpact" originated | |
147 | * from OpenFlow, then we want to make sure that, if it gets translated | |
148 | * back to OpenFlow later, it is translated back to the same action type. | |
149 | * (Otherwise, we'd violate the promise made in DESIGN, in the "Action | |
150 | * Reproduction" section.) | |
151 | * | |
152 | * For such actions, the 'compat' member should be the original action | |
153 | * type. (If the action didn't originate from OpenFlow, then setting | |
154 | * 'compat' to zero should be fine: code to translate the ofpact to | |
155 | * OpenFlow must tolerate this case.) | |
156 | */ | |
f25d0cf3 BP |
157 | struct ofpact { |
158 | enum ofpact_type type; /* OFPACT_*. */ | |
159 | enum ofputil_action_code compat; /* Original type when added, if any. */ | |
160 | uint16_t len; /* Length of the action, in bytes, including | |
161 | * struct ofpact, excluding padding. */ | |
162 | }; | |
163 | ||
164 | #ifdef __GNUC__ | |
165 | /* Make sure that OVS_PACKED_ENUM really worked. */ | |
166 | BUILD_ASSERT_DECL(sizeof(struct ofpact) == 4); | |
167 | #endif | |
168 | ||
169 | /* Alignment. */ | |
170 | #define OFPACT_ALIGNTO 8 | |
171 | #define OFPACT_ALIGN(SIZE) ROUND_UP(SIZE, OFPACT_ALIGNTO) | |
172 | ||
173 | static inline struct ofpact * | |
174 | ofpact_next(const struct ofpact *ofpact) | |
175 | { | |
176 | return (void *) ((uint8_t *) ofpact + OFPACT_ALIGN(ofpact->len)); | |
177 | } | |
178 | ||
179 | static inline struct ofpact * | |
180 | ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len) | |
181 | { | |
182 | return (void *) ((uint8_t *) ofpacts + ofpacts_len); | |
183 | } | |
184 | ||
185 | /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts | |
186 | * starting at OFPACTS. */ | |
187 | #define OFPACT_FOR_EACH(POS, OFPACTS, OFPACTS_LEN) \ | |
188 | for ((POS) = (OFPACTS); (POS) < ofpact_end(OFPACTS, OFPACTS_LEN); \ | |
189 | (POS) = ofpact_next(POS)) | |
190 | \f | |
191 | /* Action structure for each OFPACT_*. */ | |
192 | ||
b19e8793 | 193 | /* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS. |
f25d0cf3 | 194 | * |
7bcb1506 | 195 | * Used for OFPAT10_STRIP_VLAN, NXAST_POP_QUEUE, NXAST_EXIT, |
8e61c110 | 196 | * OFPAT11_POP_VLAN, OFPIT11_CLEAR_ACTIONS. |
f25d0cf3 BP |
197 | * |
198 | * Action structure for actions that do not have any extra data beyond the | |
199 | * action type. */ | |
200 | struct ofpact_null { | |
201 | struct ofpact ofpact; | |
202 | }; | |
203 | ||
204 | /* OFPACT_OUTPUT. | |
205 | * | |
206 | * Used for OFPAT10_OUTPUT. */ | |
207 | struct ofpact_output { | |
208 | struct ofpact ofpact; | |
4e022ec0 | 209 | ofp_port_t port; /* Output port. */ |
f25d0cf3 BP |
210 | uint16_t max_len; /* Max send len, for port OFPP_CONTROLLER. */ |
211 | }; | |
212 | ||
213 | /* OFPACT_CONTROLLER. | |
214 | * | |
215 | * Used for NXAST_CONTROLLER. */ | |
216 | struct ofpact_controller { | |
217 | struct ofpact ofpact; | |
218 | uint16_t max_len; /* Maximum length to send to controller. */ | |
219 | uint16_t controller_id; /* Controller ID to send packet-in. */ | |
220 | enum ofp_packet_in_reason reason; /* Reason to put in packet-in. */ | |
221 | }; | |
222 | ||
223 | /* OFPACT_ENQUEUE. | |
224 | * | |
225 | * Used for OFPAT10_ENQUEUE. */ | |
226 | struct ofpact_enqueue { | |
227 | struct ofpact ofpact; | |
4e022ec0 | 228 | ofp_port_t port; |
f25d0cf3 BP |
229 | uint32_t queue; |
230 | }; | |
231 | ||
232 | /* OFPACT_OUTPUT_REG. | |
233 | * | |
234 | * Used for NXAST_OUTPUT_REG. */ | |
235 | struct ofpact_output_reg { | |
236 | struct ofpact ofpact; | |
f25d0cf3 | 237 | uint16_t max_len; |
dc723c44 | 238 | struct mf_subfield src; |
f25d0cf3 BP |
239 | }; |
240 | ||
241 | /* OFPACT_BUNDLE. | |
242 | * | |
243 | * Used for NXAST_BUNDLE. */ | |
244 | struct ofpact_bundle { | |
245 | struct ofpact ofpact; | |
246 | ||
247 | /* Slave choice algorithm to apply to hash value. */ | |
248 | enum nx_bd_algorithm algorithm; | |
249 | ||
250 | /* What fields to hash and how. */ | |
251 | enum nx_hash_fields fields; | |
252 | uint16_t basis; /* Universal hash parameter. */ | |
253 | ||
254 | struct mf_subfield dst; | |
255 | ||
256 | /* Slaves for output. */ | |
257 | unsigned int n_slaves; | |
4e022ec0 | 258 | ofp_port_t slaves[]; |
f25d0cf3 BP |
259 | }; |
260 | ||
261 | /* OFPACT_SET_VLAN_VID. | |
262 | * | |
ca287d20 JR |
263 | * We keep track if vlan was present at action validation time to avoid a |
264 | * PUSH_VLAN when translating to OpenFlow 1.1+. | |
265 | * | |
266 | * We also keep the originating OFPUTIL action code in ofpact.compat. | |
267 | * | |
268 | * Used for OFPAT10_SET_VLAN_VID and OFPAT11_SET_VLAN_VID. */ | |
f25d0cf3 BP |
269 | struct ofpact_vlan_vid { |
270 | struct ofpact ofpact; | |
271 | uint16_t vlan_vid; /* VLAN VID in low 12 bits, 0 in other bits. */ | |
ca287d20 JR |
272 | bool push_vlan_if_needed; /* OF 1.0 semantics if true. */ |
273 | bool flow_has_vlan; /* VLAN present at action validation time? */ | |
f25d0cf3 BP |
274 | }; |
275 | ||
276 | /* OFPACT_SET_VLAN_PCP. | |
277 | * | |
ca287d20 JR |
278 | * We keep track if vlan was present at action validation time to avoid a |
279 | * PUSH_VLAN when translating to OpenFlow 1.1+. | |
280 | * | |
281 | * We also keep the originating OFPUTIL action code in ofpact.compat. | |
282 | * | |
283 | * Used for OFPAT10_SET_VLAN_PCP and OFPAT11_SET_VLAN_PCP. */ | |
f25d0cf3 BP |
284 | struct ofpact_vlan_pcp { |
285 | struct ofpact ofpact; | |
286 | uint8_t vlan_pcp; /* VLAN PCP in low 3 bits, 0 in other bits. */ | |
ca287d20 JR |
287 | bool push_vlan_if_needed; /* OF 1.0 semantics if true. */ |
288 | bool flow_has_vlan; /* VLAN present at action validation time? */ | |
f25d0cf3 BP |
289 | }; |
290 | ||
291 | /* OFPACT_SET_ETH_SRC, OFPACT_SET_ETH_DST. | |
292 | * | |
293 | * Used for OFPAT10_SET_DL_SRC, OFPAT10_SET_DL_DST. */ | |
294 | struct ofpact_mac { | |
295 | struct ofpact ofpact; | |
296 | uint8_t mac[ETH_ADDR_LEN]; | |
297 | }; | |
298 | ||
299 | /* OFPACT_SET_IPV4_SRC, OFPACT_SET_IPV4_DST. | |
300 | * | |
301 | * Used for OFPAT10_SET_NW_SRC, OFPAT10_SET_NW_DST. */ | |
302 | struct ofpact_ipv4 { | |
303 | struct ofpact ofpact; | |
304 | ovs_be32 ipv4; | |
305 | }; | |
306 | ||
04f01c24 | 307 | /* OFPACT_SET_IP_DSCP. |
f25d0cf3 BP |
308 | * |
309 | * Used for OFPAT10_SET_NW_TOS. */ | |
310 | struct ofpact_dscp { | |
311 | struct ofpact ofpact; | |
312 | uint8_t dscp; /* DSCP in high 6 bits, rest ignored. */ | |
313 | }; | |
314 | ||
ff14eb7a JR |
315 | /* OFPACT_SET_IP_ECN. |
316 | * | |
317 | * Used for OFPAT11_SET_NW_ECN. */ | |
318 | struct ofpact_ecn { | |
319 | struct ofpact ofpact; | |
320 | uint8_t ecn; /* ECN in low 2 bits, rest ignored. */ | |
321 | }; | |
322 | ||
0c20dbe4 JR |
323 | /* OFPACT_SET_IP_TTL. |
324 | * | |
325 | * Used for OFPAT11_SET_NW_TTL. */ | |
326 | struct ofpact_ip_ttl { | |
327 | struct ofpact ofpact; | |
328 | uint8_t ttl; | |
329 | }; | |
330 | ||
f25d0cf3 BP |
331 | /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT. |
332 | * | |
333 | * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */ | |
334 | struct ofpact_l4_port { | |
335 | struct ofpact ofpact; | |
1e7db674 JR |
336 | uint16_t port; /* TCP, UDP or SCTP port number. */ |
337 | uint8_t flow_ip_proto; /* IP proto from corresponding match, or 0 */ | |
f25d0cf3 BP |
338 | }; |
339 | ||
340 | /* OFPACT_REG_MOVE. | |
341 | * | |
342 | * Used for NXAST_REG_MOVE. */ | |
343 | struct ofpact_reg_move { | |
344 | struct ofpact ofpact; | |
345 | struct mf_subfield src; | |
346 | struct mf_subfield dst; | |
347 | }; | |
348 | ||
bd85dac1 AZ |
349 | /* OFPACT_STACK_PUSH. |
350 | * | |
351 | * Used for NXAST_STACK_PUSH and NXAST_STACK_POP. */ | |
352 | struct ofpact_stack { | |
353 | struct ofpact ofpact; | |
354 | struct mf_subfield subfield; | |
355 | }; | |
356 | ||
f25d0cf3 BP |
357 | /* OFPACT_REG_LOAD. |
358 | * | |
b2dd70be | 359 | * Used for NXAST_REG_LOAD. */ |
f25d0cf3 BP |
360 | struct ofpact_reg_load { |
361 | struct ofpact ofpact; | |
362 | struct mf_subfield dst; | |
158edc8d | 363 | union mf_subvalue subvalue; /* Least-significant bits are used. */ |
f25d0cf3 BP |
364 | }; |
365 | ||
b2dd70be JR |
366 | /* OFPACT_SET_FIELD. |
367 | * | |
368 | * Used for OFPAT12_SET_FIELD. */ | |
369 | struct ofpact_set_field { | |
370 | struct ofpact ofpact; | |
371 | const struct mf_field *field; | |
a6fd70bb | 372 | bool flow_has_vlan; /* VLAN present at action validation time. */ |
b2dd70be JR |
373 | union mf_value value; |
374 | }; | |
375 | ||
b02475c5 SH |
376 | /* OFPACT_PUSH_VLAN/MPLS/PBB |
377 | * | |
378 | * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */ | |
379 | struct ofpact_push_mpls { | |
380 | struct ofpact ofpact; | |
381 | ovs_be16 ethertype; | |
382 | }; | |
383 | ||
384 | /* OFPACT_POP_MPLS | |
385 | * | |
386 | * Used for NXAST_POP_MPLS, OFPAT11_POP_MPLS.. */ | |
387 | struct ofpact_pop_mpls { | |
388 | struct ofpact ofpact; | |
389 | ovs_be16 ethertype; | |
390 | }; | |
391 | ||
f25d0cf3 BP |
392 | /* OFPACT_SET_TUNNEL. |
393 | * | |
394 | * Used for NXAST_SET_TUNNEL, NXAST_SET_TUNNEL64. */ | |
395 | struct ofpact_tunnel { | |
396 | struct ofpact ofpact; | |
397 | uint64_t tun_id; | |
398 | }; | |
399 | ||
400 | /* OFPACT_SET_QUEUE. | |
401 | * | |
402 | * Used for NXAST_SET_QUEUE. */ | |
403 | struct ofpact_queue { | |
404 | struct ofpact ofpact; | |
405 | uint32_t queue_id; | |
406 | }; | |
407 | ||
408 | /* OFPACT_FIN_TIMEOUT. | |
409 | * | |
410 | * Used for NXAST_FIN_TIMEOUT. */ | |
411 | struct ofpact_fin_timeout { | |
412 | struct ofpact ofpact; | |
413 | uint16_t fin_idle_timeout; | |
414 | uint16_t fin_hard_timeout; | |
415 | }; | |
416 | ||
4cceacb9 JS |
417 | /* OFPACT_WRITE_METADATA. |
418 | * | |
419 | * Used for NXAST_WRITE_METADATA. */ | |
420 | struct ofpact_metadata { | |
421 | struct ofpact ofpact; | |
422 | ovs_be64 metadata; | |
423 | ovs_be64 mask; | |
424 | }; | |
425 | ||
638a19b0 JR |
426 | /* OFPACT_METER. |
427 | * | |
428 | * Used for OFPIT13_METER. */ | |
429 | struct ofpact_meter { | |
430 | struct ofpact ofpact; | |
431 | uint32_t meter_id; | |
432 | }; | |
433 | ||
7fdb60a7 SH |
434 | /* OFPACT_WRITE_ACTIONS. |
435 | * | |
436 | * Used for OFPIT11_WRITE_ACTIONS. */ | |
437 | struct ofpact_nest { | |
438 | struct ofpact ofpact; | |
f6e984d7 | 439 | uint8_t pad[PAD_SIZE(sizeof(struct ofpact), OFPACT_ALIGNTO)]; |
7fdb60a7 SH |
440 | struct ofpact actions[]; |
441 | }; | |
93904c85 | 442 | BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) % OFPACT_ALIGNTO == 0); |
7fdb60a7 SH |
443 | |
444 | static inline size_t | |
445 | ofpact_nest_get_action_len(const struct ofpact_nest *on) | |
446 | { | |
447 | return on->ofpact.len - offsetof(struct ofpact_nest, actions); | |
448 | } | |
449 | ||
450 | void ofpacts_execute_action_set(struct ofpbuf *action_list, | |
451 | const struct ofpbuf *action_set); | |
452 | ||
f25d0cf3 BP |
453 | /* OFPACT_RESUBMIT. |
454 | * | |
455 | * Used for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE. */ | |
456 | struct ofpact_resubmit { | |
457 | struct ofpact ofpact; | |
4e022ec0 | 458 | ofp_port_t in_port; |
f25d0cf3 BP |
459 | uint8_t table_id; |
460 | }; | |
461 | ||
462 | /* Part of struct ofpact_learn, below. */ | |
463 | struct ofpact_learn_spec { | |
e956d63b | 464 | int n_bits; /* Number of bits in source and dest. */ |
f25d0cf3 | 465 | |
e956d63b BP |
466 | int src_type; /* One of NX_LEARN_SRC_*. */ |
467 | struct mf_subfield src; /* NX_LEARN_SRC_FIELD only. */ | |
468 | union mf_subvalue src_imm; /* NX_LEARN_SRC_IMMEDIATE only. */ | |
f25d0cf3 | 469 | |
e956d63b BP |
470 | int dst_type; /* One of NX_LEARN_DST_*. */ |
471 | struct mf_subfield dst; /* NX_LEARN_DST_MATCH, NX_LEARN_DST_LOAD only. */ | |
f25d0cf3 BP |
472 | }; |
473 | ||
474 | /* OFPACT_LEARN. | |
475 | * | |
476 | * Used for NXAST_LEARN. */ | |
477 | struct ofpact_learn { | |
478 | struct ofpact ofpact; | |
479 | ||
480 | uint16_t idle_timeout; /* Idle time before discarding (seconds). */ | |
481 | uint16_t hard_timeout; /* Max time before discarding (seconds). */ | |
482 | uint16_t priority; /* Priority level of flow entry. */ | |
e0822031 | 483 | uint8_t table_id; /* Table to insert flow entry. */ |
f25d0cf3 | 484 | uint64_t cookie; /* Cookie for new flow. */ |
0fb88c18 | 485 | enum ofputil_flow_mod_flags flags; |
f25d0cf3 BP |
486 | uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */ |
487 | uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */ | |
488 | ||
489 | unsigned int n_specs; | |
490 | struct ofpact_learn_spec specs[]; | |
491 | }; | |
492 | ||
493 | /* OFPACT_MULTIPATH. | |
494 | * | |
495 | * Used for NXAST_MULTIPATH. */ | |
496 | struct ofpact_multipath { | |
497 | struct ofpact ofpact; | |
498 | ||
499 | /* What fields to hash and how. */ | |
500 | enum nx_hash_fields fields; | |
501 | uint16_t basis; /* Universal hash parameter. */ | |
502 | ||
503 | /* Multipath link choice algorithm to apply to hash value. */ | |
504 | enum nx_mp_algorithm algorithm; | |
505 | uint16_t max_link; /* Number of output links, minus 1. */ | |
506 | uint32_t arg; /* Algorithm-specific argument. */ | |
507 | ||
508 | /* Where to store the result. */ | |
509 | struct mf_subfield dst; | |
510 | }; | |
511 | ||
f25d0cf3 BP |
512 | /* OFPACT_NOTE. |
513 | * | |
514 | * Used for NXAST_NOTE. */ | |
515 | struct ofpact_note { | |
516 | struct ofpact ofpact; | |
517 | size_t length; | |
518 | uint8_t data[]; | |
519 | }; | |
520 | ||
29089a54 RL |
521 | /* OFPACT_SAMPLE. |
522 | * | |
523 | * Used for NXAST_SAMPLE. */ | |
524 | struct ofpact_sample { | |
525 | struct ofpact ofpact; | |
526 | uint16_t probability; // Always >0. | |
527 | uint32_t collector_set_id; | |
528 | uint32_t obs_domain_id; | |
529 | uint32_t obs_point_id; | |
530 | }; | |
531 | ||
c2d967a5 MM |
532 | /* OFPACT_DEC_TTL. |
533 | * | |
7bcb1506 | 534 | * Used for OFPAT11_DEC_NW_TTL, NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */ |
c2d967a5 MM |
535 | struct ofpact_cnt_ids { |
536 | struct ofpact ofpact; | |
537 | ||
538 | /* Controller ids. */ | |
539 | unsigned int n_controllers; | |
540 | uint16_t cnt_ids[]; | |
8dd54666 | 541 | }; |
c2d967a5 | 542 | |
097d4939 JR |
543 | /* OFPACT_SET_MPLS_LABEL. |
544 | * | |
545 | * Used for OFPAT11_SET_MPLS_LABEL and NXAST_SET_MPLS_LABEL */ | |
546 | struct ofpact_mpls_label { | |
547 | struct ofpact ofpact; | |
548 | ||
549 | ovs_be32 label; | |
550 | }; | |
551 | ||
552 | /* OFPACT_SET_MPLS_TC. | |
553 | * | |
554 | * Used for OFPAT11_SET_MPLS_TC and NXAST_SET_MPLS_TC */ | |
555 | struct ofpact_mpls_tc { | |
556 | struct ofpact ofpact; | |
557 | ||
558 | uint8_t tc; | |
559 | }; | |
560 | ||
0f3f3c3d SH |
561 | /* OFPACT_SET_MPLS_TTL. |
562 | * | |
097d4939 | 563 | * Used for OFPAT11_SET_MPLS_TTL and NXAST_SET_MPLS_TTL */ |
0f3f3c3d SH |
564 | struct ofpact_mpls_ttl { |
565 | struct ofpact ofpact; | |
566 | ||
567 | uint8_t ttl; | |
568 | }; | |
569 | ||
8dd54666 IY |
570 | /* OFPACT_GOTO_TABLE |
571 | * | |
572 | * Used for OFPIT11_GOTO_TABLE */ | |
573 | struct ofpact_goto_table { | |
574 | struct ofpact ofpact; | |
575 | uint8_t table_id; | |
c2d967a5 MM |
576 | }; |
577 | ||
7395c052 NZ |
578 | /* OFPACT_GROUP. |
579 | * | |
580 | * Used for OFPAT11_GROUP. */ | |
581 | struct ofpact_group { | |
582 | struct ofpact ofpact; | |
583 | uint32_t group_id; | |
584 | }; | |
585 | ||
f25d0cf3 | 586 | /* Converting OpenFlow to ofpacts. */ |
e3f8f887 JR |
587 | enum ofperr ofpacts_pull_openflow_actions(struct ofpbuf *openflow, |
588 | unsigned int actions_len, | |
589 | enum ofp_version version, | |
590 | struct ofpbuf *ofpacts); | |
591 | enum ofperr ofpacts_pull_openflow_instructions(struct ofpbuf *openflow, | |
592 | unsigned int instructions_len, | |
593 | enum ofp_version version, | |
594 | struct ofpbuf *ofpacts); | |
ca287d20 | 595 | enum ofperr ofpacts_check(struct ofpact[], size_t ofpacts_len, |
ba2fe8e9 BP |
596 | struct flow *, ofp_port_t max_ports, |
597 | uint8_t table_id, uint8_t n_tables, | |
598 | enum ofputil_protocol *usable_protocols); | |
599 | enum ofperr ofpacts_check_consistency(struct ofpact[], size_t ofpacts_len, | |
600 | struct flow *, ofp_port_t max_ports, | |
601 | uint8_t table_id, uint8_t n_tables, | |
602 | enum ofputil_protocol usable_protocols); | |
4cceacb9 | 603 | enum ofperr ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len); |
57ad4e9e | 604 | enum ofperr ofpact_check_output_port(ofp_port_t port, ofp_port_t max_ports); |
f25d0cf3 BP |
605 | |
606 | /* Converting ofpacts to OpenFlow. */ | |
e3f8f887 JR |
607 | size_t ofpacts_put_openflow_actions(const struct ofpact[], size_t ofpacts_len, |
608 | struct ofpbuf *openflow, enum ofp_version); | |
609 | void ofpacts_put_openflow_instructions(const struct ofpact[], | |
610 | size_t ofpacts_len, | |
611 | struct ofpbuf *openflow, | |
612 | enum ofp_version ofp_version); | |
f25d0cf3 BP |
613 | |
614 | /* Working with ofpacts. */ | |
615 | bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len, | |
4e022ec0 | 616 | ofp_port_t port); |
7395c052 NZ |
617 | bool ofpacts_output_to_group(const struct ofpact[], size_t ofpacts_len, |
618 | uint32_t group_id); | |
f25d0cf3 BP |
619 | bool ofpacts_equal(const struct ofpact a[], size_t a_len, |
620 | const struct ofpact b[], size_t b_len); | |
d6fb622d | 621 | uint32_t ofpacts_get_meter(const struct ofpact[], size_t ofpacts_len); |
f25d0cf3 BP |
622 | |
623 | /* Formatting ofpacts. | |
624 | * | |
625 | * (For parsing ofpacts, see ofp-parse.h.) */ | |
626 | void ofpacts_format(const struct ofpact[], size_t ofpacts_len, struct ds *); | |
627 | ||
628 | /* Internal use by the helpers below. */ | |
629 | void ofpact_init(struct ofpact *, enum ofpact_type, size_t len); | |
630 | void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len); | |
631 | ||
632 | /* For each OFPACT_<ENUM> with a corresponding struct <STRUCT>, this defines | |
633 | * the following commonly useful functions: | |
634 | * | |
635 | * struct <STRUCT> *ofpact_put_<ENUM>(struct ofpbuf *ofpacts); | |
636 | * | |
637 | * Appends a new 'ofpact', of length OFPACT_<ENUM>_RAW_SIZE, to 'ofpacts', | |
638 | * initializes it with ofpact_init_<ENUM>(), and returns it. Also sets | |
639 | * 'ofpacts->l2' to the returned action. | |
640 | * | |
641 | * After using this function to add a variable-length action, add the | |
642 | * elements of the flexible array (e.g. with ofpbuf_put()), then use | |
643 | * ofpact_update_len() to update the length embedded into the action. | |
ea96b766 JR |
644 | * (Keep in mind the need to refresh the structure from 'ofpacts->frame' |
645 | * after adding data to 'ofpacts'.) | |
f25d0cf3 BP |
646 | * |
647 | * struct <STRUCT> *ofpact_get_<ENUM>(const struct ofpact *ofpact); | |
648 | * | |
649 | * Returns 'ofpact' cast to "struct <STRUCT> *". 'ofpact->type' must be | |
650 | * OFPACT_<ENUM>. | |
651 | * | |
652 | * as well as the following more rarely useful definitions: | |
653 | * | |
654 | * void ofpact_init_<ENUM>(struct <STRUCT> *ofpact); | |
655 | * | |
656 | * Initializes the parts of 'ofpact' that identify it as having type | |
657 | * OFPACT_<ENUM> and length OFPACT_<ENUM>_RAW_SIZE and zeros the rest. | |
658 | * | |
659 | * <ENUM>_RAW_SIZE | |
660 | * | |
661 | * The size of the action structure. For a fixed-length action, this is | |
662 | * sizeof(struct <STRUCT>). For a variable-length action, this is the | |
663 | * offset to the variable-length part. | |
664 | * | |
665 | * <ENUM>_SIZE | |
666 | * | |
667 | * An integer constant, the value of OFPACT_<ENUM>_RAW_SIZE rounded up to a | |
668 | * multiple of OFPACT_ALIGNTO. | |
669 | */ | |
670 | #define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) \ | |
671 | BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \ | |
672 | \ | |
673 | enum { OFPACT_##ENUM##_RAW_SIZE \ | |
674 | = (offsetof(struct STRUCT, MEMBER) \ | |
675 | ? offsetof(struct STRUCT, MEMBER) \ | |
676 | : sizeof(struct STRUCT)) }; \ | |
677 | \ | |
678 | enum { OFPACT_##ENUM##_SIZE \ | |
679 | = ROUND_UP(OFPACT_##ENUM##_RAW_SIZE, OFPACT_ALIGNTO) }; \ | |
680 | \ | |
681 | static inline struct STRUCT * \ | |
682 | ofpact_get_##ENUM(const struct ofpact *ofpact) \ | |
683 | { \ | |
cb22974d | 684 | ovs_assert(ofpact->type == OFPACT_##ENUM); \ |
db5a1019 | 685 | return ALIGNED_CAST(struct STRUCT *, ofpact); \ |
f25d0cf3 BP |
686 | } \ |
687 | \ | |
688 | static inline struct STRUCT * \ | |
689 | ofpact_put_##ENUM(struct ofpbuf *ofpacts) \ | |
690 | { \ | |
691 | return ofpact_put(ofpacts, OFPACT_##ENUM, \ | |
692 | OFPACT_##ENUM##_RAW_SIZE); \ | |
693 | } \ | |
694 | \ | |
695 | static inline void \ | |
696 | ofpact_init_##ENUM(struct STRUCT *ofpact) \ | |
697 | { \ | |
698 | ofpact_init(&ofpact->ofpact, OFPACT_##ENUM, \ | |
699 | OFPACT_##ENUM##_RAW_SIZE); \ | |
700 | } | |
701 | OFPACTS | |
702 | #undef DEFINE_OFPACT | |
703 | ||
704 | /* Functions to use after adding ofpacts to a buffer. */ | |
705 | void ofpact_update_len(struct ofpbuf *, struct ofpact *); | |
706 | void ofpact_pad(struct ofpbuf *); | |
707 | ||
99c476dc IY |
708 | /* OpenFlow 1.1 instructions. |
709 | * The order is sorted in execution order. Not in the value of OFPIT11_xxx. | |
710 | * It is enforced on parser from text string. | |
711 | */ | |
a64f0b0f | 712 | #define OVS_INSTRUCTIONS \ |
638a19b0 JR |
713 | DEFINE_INST(OFPIT13_METER, \ |
714 | ofp13_instruction_meter, false, \ | |
715 | "meter") \ | |
716 | \ | |
99c476dc IY |
717 | DEFINE_INST(OFPIT11_APPLY_ACTIONS, \ |
718 | ofp11_instruction_actions, true, \ | |
719 | "apply_actions") \ | |
a64f0b0f | 720 | \ |
99c476dc IY |
721 | DEFINE_INST(OFPIT11_CLEAR_ACTIONS, \ |
722 | ofp11_instruction, false, \ | |
723 | "clear_actions") \ | |
a64f0b0f IY |
724 | \ |
725 | DEFINE_INST(OFPIT11_WRITE_ACTIONS, \ | |
726 | ofp11_instruction_actions, true, \ | |
727 | "write_actions") \ | |
728 | \ | |
99c476dc IY |
729 | DEFINE_INST(OFPIT11_WRITE_METADATA, \ |
730 | ofp11_instruction_write_metadata, false, \ | |
731 | "write_metadata") \ | |
a64f0b0f | 732 | \ |
99c476dc IY |
733 | DEFINE_INST(OFPIT11_GOTO_TABLE, \ |
734 | ofp11_instruction_goto_table, false, \ | |
735 | "goto_table") | |
a64f0b0f IY |
736 | |
737 | enum ovs_instruction_type { | |
738 | #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) OVSINST_##ENUM, | |
739 | OVS_INSTRUCTIONS | |
740 | #undef DEFINE_INST | |
741 | }; | |
742 | ||
743 | enum { | |
744 | #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) + 1 | |
745 | N_OVS_INSTRUCTIONS = OVS_INSTRUCTIONS | |
746 | #undef DEFINE_INST | |
747 | }; | |
748 | ||
ba0bc9b0 BP |
749 | const char *ovs_instruction_name_from_type(enum ovs_instruction_type type); |
750 | int ovs_instruction_type_from_name(const char *name); | |
084c53de BP |
751 | enum ovs_instruction_type ovs_instruction_type_from_ofpact_type( |
752 | enum ofpact_type); | |
c0621c39 AW |
753 | enum ofperr ovs_instruction_type_from_inst_type( |
754 | enum ovs_instruction_type *instruction_type, const uint16_t inst_type); | |
755 | ||
f25d0cf3 | 756 | #endif /* ofp-actions.h */ |