]>
Commit | Line | Data |
---|---|---|
f25d0cf3 | 1 | /* |
9ff262f4 | 2 | * Copyright (c) 2012 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 | ||
20 | #include <stdint.h> | |
21 | #include "meta-flow.h" | |
22 | #include "ofp-errors.h" | |
23 | #include "ofp-util.h" | |
24 | #include "openflow/openflow.h" | |
25 | #include "openflow/nicira-ext.h" | |
26 | #include "openvswitch/types.h" | |
27 | ||
28 | /* List of OVS abstracted actions. | |
29 | * | |
30 | * This macro is used directly only internally by this header, but the list is | |
31 | * still of interest to developers. | |
32 | * | |
33 | * Each DEFINE_OFPACT invocation has the following parameters: | |
34 | * | |
35 | * 1. <ENUM>, used below in the enum definition of OFPACT_<ENUM>, and | |
36 | * elsewhere. | |
37 | * | |
38 | * 2. <STRUCT> corresponding to a structure "struct <STRUCT>", that must be | |
39 | * defined below. This structure must be an abstract definition of the | |
40 | * action. Its first member must have type "struct ofpact" and name | |
41 | * "ofpact". It may be fixed length or end with a flexible array member | |
42 | * (e.g. "int member[];"). | |
43 | * | |
44 | * 3. <MEMBER>, which has one of two possible values: | |
45 | * | |
46 | * - If "struct <STRUCT>" is fixed-length, it must be "ofpact". | |
47 | * | |
48 | * - If "struct <STRUCT>" is variable-length, it must be the name of the | |
49 | * flexible array member. | |
50 | */ | |
51 | #define OFPACTS \ | |
52 | /* Output. */ \ | |
53 | DEFINE_OFPACT(OUTPUT, ofpact_output, ofpact) \ | |
54 | DEFINE_OFPACT(CONTROLLER, ofpact_controller, ofpact) \ | |
55 | DEFINE_OFPACT(ENQUEUE, ofpact_enqueue, ofpact) \ | |
56 | DEFINE_OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact) \ | |
57 | DEFINE_OFPACT(BUNDLE, ofpact_bundle, slaves) \ | |
58 | \ | |
59 | /* Header changes. */ \ | |
60 | DEFINE_OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact) \ | |
61 | DEFINE_OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact) \ | |
62 | DEFINE_OFPACT(STRIP_VLAN, ofpact_null, ofpact) \ | |
63 | DEFINE_OFPACT(SET_ETH_SRC, ofpact_mac, ofpact) \ | |
64 | DEFINE_OFPACT(SET_ETH_DST, ofpact_mac, ofpact) \ | |
65 | DEFINE_OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact) \ | |
66 | DEFINE_OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact) \ | |
67 | DEFINE_OFPACT(SET_IPV4_DSCP, ofpact_dscp, ofpact) \ | |
68 | DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact) \ | |
69 | DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact) \ | |
70 | DEFINE_OFPACT(REG_MOVE, ofpact_reg_move, ofpact) \ | |
71 | DEFINE_OFPACT(REG_LOAD, ofpact_reg_load, ofpact) \ | |
c2d967a5 | 72 | DEFINE_OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids) \ |
f25d0cf3 BP |
73 | \ |
74 | /* Metadata. */ \ | |
75 | DEFINE_OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact) \ | |
76 | DEFINE_OFPACT(SET_QUEUE, ofpact_queue, ofpact) \ | |
77 | DEFINE_OFPACT(POP_QUEUE, ofpact_null, ofpact) \ | |
78 | DEFINE_OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact) \ | |
79 | \ | |
80 | /* Flow table interaction. */ \ | |
81 | DEFINE_OFPACT(RESUBMIT, ofpact_resubmit, ofpact) \ | |
82 | DEFINE_OFPACT(LEARN, ofpact_learn, specs) \ | |
83 | \ | |
84 | /* Arithmetic. */ \ | |
85 | DEFINE_OFPACT(MULTIPATH, ofpact_multipath, ofpact) \ | |
86 | DEFINE_OFPACT(AUTOPATH, ofpact_autopath, ofpact) \ | |
87 | \ | |
88 | /* Other. */ \ | |
89 | DEFINE_OFPACT(NOTE, ofpact_note, data) \ | |
90 | DEFINE_OFPACT(EXIT, ofpact_null, ofpact) | |
91 | ||
92 | /* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */ | |
93 | enum OVS_PACKED_ENUM ofpact_type { | |
94 | #define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) OFPACT_##ENUM, | |
95 | OFPACTS | |
96 | #undef DEFINE_OFPACT | |
97 | }; | |
98 | ||
99 | /* N_OFPACTS, the number of values of "enum ofpact_type". */ | |
100 | enum { | |
101 | N_OFPACTS = | |
102 | #define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) + 1 | |
103 | OFPACTS | |
104 | #undef DEFINE_OFPACT | |
105 | }; | |
106 | ||
107 | /* Header for an action. | |
108 | * | |
109 | * Each action is a structure "struct ofpact_*" that begins with "struct | |
110 | * ofpact", usually followed by other data that describes the action. Actions | |
111 | * are padded out to a multiple of OFPACT_ALIGNTO bytes in length. */ | |
112 | struct ofpact { | |
113 | enum ofpact_type type; /* OFPACT_*. */ | |
114 | enum ofputil_action_code compat; /* Original type when added, if any. */ | |
115 | uint16_t len; /* Length of the action, in bytes, including | |
116 | * struct ofpact, excluding padding. */ | |
117 | }; | |
118 | ||
119 | #ifdef __GNUC__ | |
120 | /* Make sure that OVS_PACKED_ENUM really worked. */ | |
121 | BUILD_ASSERT_DECL(sizeof(struct ofpact) == 4); | |
122 | #endif | |
123 | ||
124 | /* Alignment. */ | |
125 | #define OFPACT_ALIGNTO 8 | |
126 | #define OFPACT_ALIGN(SIZE) ROUND_UP(SIZE, OFPACT_ALIGNTO) | |
127 | ||
128 | static inline struct ofpact * | |
129 | ofpact_next(const struct ofpact *ofpact) | |
130 | { | |
131 | return (void *) ((uint8_t *) ofpact + OFPACT_ALIGN(ofpact->len)); | |
132 | } | |
133 | ||
134 | static inline struct ofpact * | |
135 | ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len) | |
136 | { | |
137 | return (void *) ((uint8_t *) ofpacts + ofpacts_len); | |
138 | } | |
139 | ||
140 | /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts | |
141 | * starting at OFPACTS. */ | |
142 | #define OFPACT_FOR_EACH(POS, OFPACTS, OFPACTS_LEN) \ | |
143 | for ((POS) = (OFPACTS); (POS) < ofpact_end(OFPACTS, OFPACTS_LEN); \ | |
144 | (POS) = ofpact_next(POS)) | |
145 | \f | |
146 | /* Action structure for each OFPACT_*. */ | |
147 | ||
c2d967a5 | 148 | /* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT. |
f25d0cf3 BP |
149 | * |
150 | * Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT. | |
151 | * | |
152 | * Action structure for actions that do not have any extra data beyond the | |
153 | * action type. */ | |
154 | struct ofpact_null { | |
155 | struct ofpact ofpact; | |
156 | }; | |
157 | ||
158 | /* OFPACT_OUTPUT. | |
159 | * | |
160 | * Used for OFPAT10_OUTPUT. */ | |
161 | struct ofpact_output { | |
162 | struct ofpact ofpact; | |
163 | uint16_t port; /* Output port. */ | |
164 | uint16_t max_len; /* Max send len, for port OFPP_CONTROLLER. */ | |
165 | }; | |
166 | ||
167 | /* OFPACT_CONTROLLER. | |
168 | * | |
169 | * Used for NXAST_CONTROLLER. */ | |
170 | struct ofpact_controller { | |
171 | struct ofpact ofpact; | |
172 | uint16_t max_len; /* Maximum length to send to controller. */ | |
173 | uint16_t controller_id; /* Controller ID to send packet-in. */ | |
174 | enum ofp_packet_in_reason reason; /* Reason to put in packet-in. */ | |
175 | }; | |
176 | ||
177 | /* OFPACT_ENQUEUE. | |
178 | * | |
179 | * Used for OFPAT10_ENQUEUE. */ | |
180 | struct ofpact_enqueue { | |
181 | struct ofpact ofpact; | |
182 | uint16_t port; | |
183 | uint32_t queue; | |
184 | }; | |
185 | ||
186 | /* OFPACT_OUTPUT_REG. | |
187 | * | |
188 | * Used for NXAST_OUTPUT_REG. */ | |
189 | struct ofpact_output_reg { | |
190 | struct ofpact ofpact; | |
191 | struct mf_subfield src; | |
192 | uint16_t max_len; | |
193 | }; | |
194 | ||
195 | /* OFPACT_BUNDLE. | |
196 | * | |
197 | * Used for NXAST_BUNDLE. */ | |
198 | struct ofpact_bundle { | |
199 | struct ofpact ofpact; | |
200 | ||
201 | /* Slave choice algorithm to apply to hash value. */ | |
202 | enum nx_bd_algorithm algorithm; | |
203 | ||
204 | /* What fields to hash and how. */ | |
205 | enum nx_hash_fields fields; | |
206 | uint16_t basis; /* Universal hash parameter. */ | |
207 | ||
208 | struct mf_subfield dst; | |
209 | ||
210 | /* Slaves for output. */ | |
211 | unsigned int n_slaves; | |
212 | uint16_t slaves[]; | |
213 | }; | |
214 | ||
215 | /* OFPACT_SET_VLAN_VID. | |
216 | * | |
217 | * Used for OFPAT10_SET_VLAN_VID. */ | |
218 | struct ofpact_vlan_vid { | |
219 | struct ofpact ofpact; | |
220 | uint16_t vlan_vid; /* VLAN VID in low 12 bits, 0 in other bits. */ | |
221 | }; | |
222 | ||
223 | /* OFPACT_SET_VLAN_PCP. | |
224 | * | |
225 | * Used for OFPAT10_SET_VLAN_PCP. */ | |
226 | struct ofpact_vlan_pcp { | |
227 | struct ofpact ofpact; | |
228 | uint8_t vlan_pcp; /* VLAN PCP in low 3 bits, 0 in other bits. */ | |
229 | }; | |
230 | ||
231 | /* OFPACT_SET_ETH_SRC, OFPACT_SET_ETH_DST. | |
232 | * | |
233 | * Used for OFPAT10_SET_DL_SRC, OFPAT10_SET_DL_DST. */ | |
234 | struct ofpact_mac { | |
235 | struct ofpact ofpact; | |
236 | uint8_t mac[ETH_ADDR_LEN]; | |
237 | }; | |
238 | ||
239 | /* OFPACT_SET_IPV4_SRC, OFPACT_SET_IPV4_DST. | |
240 | * | |
241 | * Used for OFPAT10_SET_NW_SRC, OFPAT10_SET_NW_DST. */ | |
242 | struct ofpact_ipv4 { | |
243 | struct ofpact ofpact; | |
244 | ovs_be32 ipv4; | |
245 | }; | |
246 | ||
247 | /* OFPACT_SET_IPV4_DSCP. | |
248 | * | |
249 | * Used for OFPAT10_SET_NW_TOS. */ | |
250 | struct ofpact_dscp { | |
251 | struct ofpact ofpact; | |
252 | uint8_t dscp; /* DSCP in high 6 bits, rest ignored. */ | |
253 | }; | |
254 | ||
255 | /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT. | |
256 | * | |
257 | * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */ | |
258 | struct ofpact_l4_port { | |
259 | struct ofpact ofpact; | |
260 | uint16_t port; /* TCP or UDP port number. */ | |
261 | }; | |
262 | ||
263 | /* OFPACT_REG_MOVE. | |
264 | * | |
265 | * Used for NXAST_REG_MOVE. */ | |
266 | struct ofpact_reg_move { | |
267 | struct ofpact ofpact; | |
268 | struct mf_subfield src; | |
269 | struct mf_subfield dst; | |
270 | }; | |
271 | ||
272 | /* OFPACT_REG_LOAD. | |
273 | * | |
274 | * Used for NXAST_REG_LOAD. */ | |
275 | struct ofpact_reg_load { | |
276 | struct ofpact ofpact; | |
277 | struct mf_subfield dst; | |
278 | uint64_t value; | |
279 | }; | |
280 | ||
281 | /* OFPACT_SET_TUNNEL. | |
282 | * | |
283 | * Used for NXAST_SET_TUNNEL, NXAST_SET_TUNNEL64. */ | |
284 | struct ofpact_tunnel { | |
285 | struct ofpact ofpact; | |
286 | uint64_t tun_id; | |
287 | }; | |
288 | ||
289 | /* OFPACT_SET_QUEUE. | |
290 | * | |
291 | * Used for NXAST_SET_QUEUE. */ | |
292 | struct ofpact_queue { | |
293 | struct ofpact ofpact; | |
294 | uint32_t queue_id; | |
295 | }; | |
296 | ||
297 | /* OFPACT_FIN_TIMEOUT. | |
298 | * | |
299 | * Used for NXAST_FIN_TIMEOUT. */ | |
300 | struct ofpact_fin_timeout { | |
301 | struct ofpact ofpact; | |
302 | uint16_t fin_idle_timeout; | |
303 | uint16_t fin_hard_timeout; | |
304 | }; | |
305 | ||
306 | /* OFPACT_RESUBMIT. | |
307 | * | |
308 | * Used for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE. */ | |
309 | struct ofpact_resubmit { | |
310 | struct ofpact ofpact; | |
311 | uint16_t in_port; | |
312 | uint8_t table_id; | |
313 | }; | |
314 | ||
315 | /* Part of struct ofpact_learn, below. */ | |
316 | struct ofpact_learn_spec { | |
317 | int n_bits; | |
318 | ||
319 | int src_type; | |
320 | struct mf_subfield src; | |
321 | union mf_subvalue src_imm; | |
322 | ||
323 | int dst_type; | |
324 | struct mf_subfield dst; | |
325 | }; | |
326 | ||
327 | /* OFPACT_LEARN. | |
328 | * | |
329 | * Used for NXAST_LEARN. */ | |
330 | struct ofpact_learn { | |
331 | struct ofpact ofpact; | |
332 | ||
333 | uint16_t idle_timeout; /* Idle time before discarding (seconds). */ | |
334 | uint16_t hard_timeout; /* Max time before discarding (seconds). */ | |
335 | uint16_t priority; /* Priority level of flow entry. */ | |
336 | uint64_t cookie; /* Cookie for new flow. */ | |
337 | uint16_t flags; /* Either 0 or OFPFF_SEND_FLOW_REM. */ | |
338 | uint8_t table_id; /* Table to insert flow entry. */ | |
339 | uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */ | |
340 | uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */ | |
341 | ||
342 | unsigned int n_specs; | |
343 | struct ofpact_learn_spec specs[]; | |
344 | }; | |
345 | ||
346 | /* OFPACT_MULTIPATH. | |
347 | * | |
348 | * Used for NXAST_MULTIPATH. */ | |
349 | struct ofpact_multipath { | |
350 | struct ofpact ofpact; | |
351 | ||
352 | /* What fields to hash and how. */ | |
353 | enum nx_hash_fields fields; | |
354 | uint16_t basis; /* Universal hash parameter. */ | |
355 | ||
356 | /* Multipath link choice algorithm to apply to hash value. */ | |
357 | enum nx_mp_algorithm algorithm; | |
358 | uint16_t max_link; /* Number of output links, minus 1. */ | |
359 | uint32_t arg; /* Algorithm-specific argument. */ | |
360 | ||
361 | /* Where to store the result. */ | |
362 | struct mf_subfield dst; | |
363 | }; | |
364 | ||
365 | /* OFPACT_AUTOPATH. | |
366 | * | |
367 | * Used for NXAST_AUTOPATH. */ | |
368 | struct ofpact_autopath { | |
369 | struct ofpact ofpact; | |
370 | struct mf_subfield dst; | |
371 | uint32_t port; | |
372 | }; | |
373 | ||
374 | /* OFPACT_NOTE. | |
375 | * | |
376 | * Used for NXAST_NOTE. */ | |
377 | struct ofpact_note { | |
378 | struct ofpact ofpact; | |
379 | size_t length; | |
380 | uint8_t data[]; | |
381 | }; | |
382 | ||
c2d967a5 MM |
383 | /* OFPACT_DEC_TTL. |
384 | * | |
385 | * Used for NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */ | |
386 | struct ofpact_cnt_ids { | |
387 | struct ofpact ofpact; | |
388 | ||
389 | /* Controller ids. */ | |
390 | unsigned int n_controllers; | |
391 | uint16_t cnt_ids[]; | |
392 | ||
393 | }; | |
394 | ||
f25d0cf3 | 395 | /* Converting OpenFlow to ofpacts. */ |
d01c980f BP |
396 | enum ofperr ofpacts_pull_openflow10(struct ofpbuf *openflow, |
397 | unsigned int actions_len, | |
398 | struct ofpbuf *ofpacts); | |
399 | enum ofperr ofpacts_pull_openflow11_actions(struct ofpbuf *openflow, | |
400 | unsigned int actions_len, | |
401 | struct ofpbuf *ofpacts); | |
402 | enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, | |
403 | unsigned int instructions_len, | |
404 | struct ofpbuf *ofpacts); | |
f25d0cf3 BP |
405 | enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len, |
406 | const struct flow *, int max_ports); | |
407 | ||
408 | /* Converting ofpacts to OpenFlow. */ | |
d01c980f BP |
409 | void ofpacts_put_openflow10(const struct ofpact[], size_t ofpacts_len, |
410 | struct ofpbuf *openflow); | |
a07c15bc SH |
411 | size_t ofpacts_put_openflow11_actions(const struct ofpact[], size_t ofpacts_len, |
412 | struct ofpbuf *openflow); | |
d01c980f BP |
413 | void ofpacts_put_openflow11_instructions(const struct ofpact[], |
414 | size_t ofpacts_len, | |
415 | struct ofpbuf *openflow); | |
f25d0cf3 BP |
416 | |
417 | /* Working with ofpacts. */ | |
418 | bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len, | |
419 | uint16_t port); | |
420 | bool ofpacts_equal(const struct ofpact a[], size_t a_len, | |
421 | const struct ofpact b[], size_t b_len); | |
422 | ||
423 | /* Formatting ofpacts. | |
424 | * | |
425 | * (For parsing ofpacts, see ofp-parse.h.) */ | |
426 | void ofpacts_format(const struct ofpact[], size_t ofpacts_len, struct ds *); | |
427 | ||
428 | /* Internal use by the helpers below. */ | |
429 | void ofpact_init(struct ofpact *, enum ofpact_type, size_t len); | |
430 | void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len); | |
431 | ||
432 | /* For each OFPACT_<ENUM> with a corresponding struct <STRUCT>, this defines | |
433 | * the following commonly useful functions: | |
434 | * | |
435 | * struct <STRUCT> *ofpact_put_<ENUM>(struct ofpbuf *ofpacts); | |
436 | * | |
437 | * Appends a new 'ofpact', of length OFPACT_<ENUM>_RAW_SIZE, to 'ofpacts', | |
438 | * initializes it with ofpact_init_<ENUM>(), and returns it. Also sets | |
439 | * 'ofpacts->l2' to the returned action. | |
440 | * | |
441 | * After using this function to add a variable-length action, add the | |
442 | * elements of the flexible array (e.g. with ofpbuf_put()), then use | |
443 | * ofpact_update_len() to update the length embedded into the action. | |
444 | * (Keep in mind the need to refresh the structure from 'ofpacts->l2' after | |
445 | * adding data to 'ofpacts'.) | |
446 | * | |
447 | * struct <STRUCT> *ofpact_get_<ENUM>(const struct ofpact *ofpact); | |
448 | * | |
449 | * Returns 'ofpact' cast to "struct <STRUCT> *". 'ofpact->type' must be | |
450 | * OFPACT_<ENUM>. | |
451 | * | |
452 | * as well as the following more rarely useful definitions: | |
453 | * | |
454 | * void ofpact_init_<ENUM>(struct <STRUCT> *ofpact); | |
455 | * | |
456 | * Initializes the parts of 'ofpact' that identify it as having type | |
457 | * OFPACT_<ENUM> and length OFPACT_<ENUM>_RAW_SIZE and zeros the rest. | |
458 | * | |
459 | * <ENUM>_RAW_SIZE | |
460 | * | |
461 | * The size of the action structure. For a fixed-length action, this is | |
462 | * sizeof(struct <STRUCT>). For a variable-length action, this is the | |
463 | * offset to the variable-length part. | |
464 | * | |
465 | * <ENUM>_SIZE | |
466 | * | |
467 | * An integer constant, the value of OFPACT_<ENUM>_RAW_SIZE rounded up to a | |
468 | * multiple of OFPACT_ALIGNTO. | |
469 | */ | |
470 | #define DEFINE_OFPACT(ENUM, STRUCT, MEMBER) \ | |
471 | BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \ | |
472 | \ | |
473 | enum { OFPACT_##ENUM##_RAW_SIZE \ | |
474 | = (offsetof(struct STRUCT, MEMBER) \ | |
475 | ? offsetof(struct STRUCT, MEMBER) \ | |
476 | : sizeof(struct STRUCT)) }; \ | |
477 | \ | |
478 | enum { OFPACT_##ENUM##_SIZE \ | |
479 | = ROUND_UP(OFPACT_##ENUM##_RAW_SIZE, OFPACT_ALIGNTO) }; \ | |
480 | \ | |
481 | static inline struct STRUCT * \ | |
482 | ofpact_get_##ENUM(const struct ofpact *ofpact) \ | |
483 | { \ | |
484 | assert(ofpact->type == OFPACT_##ENUM); \ | |
485 | return (struct STRUCT *) ofpact; \ | |
486 | } \ | |
487 | \ | |
488 | static inline struct STRUCT * \ | |
489 | ofpact_put_##ENUM(struct ofpbuf *ofpacts) \ | |
490 | { \ | |
491 | return ofpact_put(ofpacts, OFPACT_##ENUM, \ | |
492 | OFPACT_##ENUM##_RAW_SIZE); \ | |
493 | } \ | |
494 | \ | |
495 | static inline void \ | |
496 | ofpact_init_##ENUM(struct STRUCT *ofpact) \ | |
497 | { \ | |
498 | ofpact_init(&ofpact->ofpact, OFPACT_##ENUM, \ | |
499 | OFPACT_##ENUM##_RAW_SIZE); \ | |
500 | } | |
501 | OFPACTS | |
502 | #undef DEFINE_OFPACT | |
503 | ||
504 | /* Functions to use after adding ofpacts to a buffer. */ | |
505 | void ofpact_update_len(struct ofpbuf *, struct ofpact *); | |
506 | void ofpact_pad(struct ofpbuf *); | |
507 | ||
99c476dc IY |
508 | /* OpenFlow 1.1 instructions. |
509 | * The order is sorted in execution order. Not in the value of OFPIT11_xxx. | |
510 | * It is enforced on parser from text string. | |
511 | */ | |
a64f0b0f | 512 | #define OVS_INSTRUCTIONS \ |
99c476dc IY |
513 | DEFINE_INST(OFPIT11_APPLY_ACTIONS, \ |
514 | ofp11_instruction_actions, true, \ | |
515 | "apply_actions") \ | |
a64f0b0f | 516 | \ |
99c476dc IY |
517 | DEFINE_INST(OFPIT11_CLEAR_ACTIONS, \ |
518 | ofp11_instruction, false, \ | |
519 | "clear_actions") \ | |
a64f0b0f IY |
520 | \ |
521 | DEFINE_INST(OFPIT11_WRITE_ACTIONS, \ | |
522 | ofp11_instruction_actions, true, \ | |
523 | "write_actions") \ | |
524 | \ | |
99c476dc IY |
525 | DEFINE_INST(OFPIT11_WRITE_METADATA, \ |
526 | ofp11_instruction_write_metadata, false, \ | |
527 | "write_metadata") \ | |
a64f0b0f | 528 | \ |
99c476dc IY |
529 | DEFINE_INST(OFPIT11_GOTO_TABLE, \ |
530 | ofp11_instruction_goto_table, false, \ | |
531 | "goto_table") | |
a64f0b0f IY |
532 | |
533 | enum ovs_instruction_type { | |
534 | #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) OVSINST_##ENUM, | |
535 | OVS_INSTRUCTIONS | |
536 | #undef DEFINE_INST | |
537 | }; | |
538 | ||
539 | enum { | |
540 | #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) + 1 | |
541 | N_OVS_INSTRUCTIONS = OVS_INSTRUCTIONS | |
542 | #undef DEFINE_INST | |
543 | }; | |
544 | ||
a359d5ad IY |
545 | const char *ofpact_instruction_name_from_type(enum ovs_instruction_type type); |
546 | int ofpact_instruction_type_from_name(const char *name); | |
547 | ||
f25d0cf3 | 548 | #endif /* ofp-actions.h */ |