]>
Commit | Line | Data |
---|---|---|
3b7cb7e1 | 1 | /* |
b3bd2c33 | 2 | * Copyright (c) 2015, 2016, 2017 Nicira, Inc. |
3b7cb7e1 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 OVN_ACTIONS_H | |
18 | #define OVN_ACTIONS_H 1 | |
19 | ||
f1c16a85 | 20 | #include <stdbool.h> |
3b7cb7e1 BP |
21 | #include <stdint.h> |
22 | #include "compiler.h" | |
d5a76da4 | 23 | #include "expr.h" |
467085fd | 24 | #include "openvswitch/dynamic-string.h" |
d5a76da4 | 25 | #include "openvswitch/hmap.h" |
fa44a4a3 | 26 | #include "openvswitch/uuid.h" |
6335d074 | 27 | #include "util.h" |
3b7cb7e1 | 28 | |
a6095f81 | 29 | struct expr; |
3b7cb7e1 BP |
30 | struct lexer; |
31 | struct ofpbuf; | |
32 | struct shash; | |
33 | struct simap; | |
ad35c0c5 | 34 | struct ovn_extend_table; |
3b7cb7e1 | 35 | |
d5a76da4 BP |
36 | /* List of OVN logical actions. |
37 | * | |
38 | * This macro is used directly only internally by this header and its | |
39 | * corresponding .c file, but the list is still of interest to developers. | |
40 | * | |
41 | * Each OVNACT invocation has the following parameters: | |
42 | * | |
43 | * 1. <ENUM>, used below in the enum definition of OVNACT_<ENUM>, and | |
44 | * elsewhere. | |
45 | * | |
46 | * 2. <STRUCT> corresponding to a structure "struct <STRUCT>", that must be a | |
47 | * defined below. This structure must be an abstract definition of the | |
48 | * action. Its first member must have type "struct ovnact" and name | |
49 | * "ovnact". The structure must have a fixed length, that is, it may not | |
50 | * end with a flexible array member. | |
51 | */ | |
d383eed5 JP |
52 | #define OVNACTS \ |
53 | OVNACT(OUTPUT, ovnact_null) \ | |
54 | OVNACT(NEXT, ovnact_next) \ | |
55 | OVNACT(LOAD, ovnact_load) \ | |
56 | OVNACT(MOVE, ovnact_move) \ | |
57 | OVNACT(EXCHANGE, ovnact_move) \ | |
58 | OVNACT(DEC_TTL, ovnact_null) \ | |
59 | OVNACT(CT_NEXT, ovnact_ct_next) \ | |
60 | OVNACT(CT_COMMIT, ovnact_ct_commit) \ | |
61 | OVNACT(CT_DNAT, ovnact_ct_nat) \ | |
62 | OVNACT(CT_SNAT, ovnact_ct_nat) \ | |
63 | OVNACT(CT_LB, ovnact_ct_lb) \ | |
64 | OVNACT(CT_CLEAR, ovnact_null) \ | |
65 | OVNACT(CLONE, ovnact_nest) \ | |
66 | OVNACT(ARP, ovnact_nest) \ | |
bc3d6a63 | 67 | OVNACT(ICMP4, ovnact_nest) \ |
3e7fa1e3 | 68 | OVNACT(ICMP6, ovnact_nest) \ |
22b65e4d | 69 | OVNACT(TCP_RESET, ovnact_nest) \ |
d383eed5 JP |
70 | OVNACT(ND_NA, ovnact_nest) \ |
71 | OVNACT(GET_ARP, ovnact_get_mac_bind) \ | |
72 | OVNACT(PUT_ARP, ovnact_put_mac_bind) \ | |
73 | OVNACT(GET_ND, ovnact_get_mac_bind) \ | |
74 | OVNACT(PUT_ND, ovnact_put_mac_bind) \ | |
16936e4d NS |
75 | OVNACT(PUT_DHCPV4_OPTS, ovnact_put_opts) \ |
76 | OVNACT(PUT_DHCPV6_OPTS, ovnact_put_opts) \ | |
d383eed5 JP |
77 | OVNACT(SET_QUEUE, ovnact_set_queue) \ |
78 | OVNACT(DNS_LOOKUP, ovnact_dns_lookup) \ | |
52ed5fcc | 79 | OVNACT(LOG, ovnact_log) \ |
b1a3a6a4 | 80 | OVNACT(PUT_ND_RA_OPTS, ovnact_put_opts) \ |
66d89287 GL |
81 | OVNACT(ND_NS, ovnact_nest) \ |
82 | OVNACT(SET_METER, ovnact_set_meter) | |
d5a76da4 BP |
83 | |
84 | /* enum ovnact_type, with a member OVNACT_<ENUM> for each action. */ | |
85 | enum OVS_PACKED_ENUM ovnact_type { | |
86 | #define OVNACT(ENUM, STRUCT) OVNACT_##ENUM, | |
87 | OVNACTS | |
88 | #undef OVNACT | |
89 | }; | |
90 | ||
91 | /* Define N_OVNACTS to the number of types of ovnacts. */ | |
92 | enum { | |
93 | #define OVNACT(ENUM, STRUCT) + 1 | |
94 | N_OVNACTS = OVNACTS | |
95 | #undef OVNACT | |
96 | }; | |
97 | ||
98 | /* Header for an action. | |
99 | * | |
100 | * Each action is a structure "struct ovnact_*" that begins with "struct | |
101 | * ovnact", usually followed by other data that describes the action. Actions | |
102 | * are padded out to a multiple of OVNACT_ALIGNTO bytes in length. | |
103 | */ | |
104 | struct ovnact { | |
105 | /* We want the space advantage of an 8-bit type here on every | |
106 | * implementation, without giving up the advantage of having a useful type | |
107 | * on implementations that support packed enums. */ | |
108 | #ifdef HAVE_PACKED_ENUM | |
109 | enum ovnact_type type; /* OVNACT_*. */ | |
110 | #else | |
111 | uint8_t type; /* OVNACT_* */ | |
112 | #endif | |
113 | uint8_t pad; /* Pad to multiple of 16 bits. */ | |
114 | ||
115 | uint16_t len; /* Length of the action, in bytes, including | |
116 | * struct ovnact, excluding padding. */ | |
117 | }; | |
118 | BUILD_ASSERT_DECL(sizeof(struct ovnact) == 4); | |
119 | ||
120 | /* Alignment. */ | |
121 | #define OVNACT_ALIGNTO 8 | |
122 | #define OVNACT_ALIGN(SIZE) ROUND_UP(SIZE, OVNACT_ALIGNTO) | |
123 | ||
124 | /* Returns the ovnact following 'ovnact'. */ | |
125 | static inline struct ovnact * | |
126 | ovnact_next(const struct ovnact *ovnact) | |
127 | { | |
128 | return (void *) ((uint8_t *) ovnact + OVNACT_ALIGN(ovnact->len)); | |
129 | } | |
130 | ||
131 | struct ovnact *ovnact_next_flattened(const struct ovnact *); | |
132 | ||
133 | static inline struct ovnact * | |
134 | ovnact_end(const struct ovnact *ovnacts, size_t ovnacts_len) | |
135 | { | |
136 | return (void *) ((uint8_t *) ovnacts + ovnacts_len); | |
137 | } | |
138 | ||
139 | /* Assigns POS to each ovnact, in turn, in the OVNACTS_LEN bytes of ovnacts | |
140 | * starting at OVNACTS. */ | |
141 | #define OVNACT_FOR_EACH(POS, OVNACTS, OVNACTS_LEN) \ | |
142 | for ((POS) = (OVNACTS); (POS) < ovnact_end(OVNACTS, OVNACTS_LEN); \ | |
143 | (POS) = ovnact_next(POS)) | |
144 | \f | |
145 | /* Action structure for each OVNACT_*. */ | |
146 | ||
147 | /* Action structure for actions that do not have any extra data beyond the | |
148 | * action type. */ | |
149 | struct ovnact_null { | |
150 | struct ovnact ovnact; | |
151 | }; | |
152 | ||
c571f48c BP |
153 | /* Logical pipeline in which a set of actions is executed. */ |
154 | enum ovnact_pipeline { | |
155 | OVNACT_P_INGRESS, | |
156 | OVNACT_P_EGRESS, | |
157 | }; | |
158 | ||
ebb467ff | 159 | /* OVNACT_NEXT. */ |
d5a76da4 BP |
160 | struct ovnact_next { |
161 | struct ovnact ovnact; | |
8f5de083 BP |
162 | |
163 | /* Arguments. */ | |
4c99cb18 BP |
164 | uint8_t ltable; /* Logical table ID of next table. */ |
165 | enum ovnact_pipeline pipeline; /* Pipeline of next table. */ | |
8f5de083 BP |
166 | |
167 | /* Information about the flow that the action is in. This does not affect | |
168 | * behavior, since the implementation of "next" doesn't depend on the | |
169 | * source table or pipeline. It does affect how ovnacts_format() prints | |
170 | * the action. */ | |
4c99cb18 BP |
171 | uint8_t src_ltable; /* Logical table ID of source table. */ |
172 | enum ovnact_pipeline src_pipeline; /* Pipeline of source table. */ | |
d5a76da4 BP |
173 | }; |
174 | ||
175 | /* OVNACT_LOAD. */ | |
176 | struct ovnact_load { | |
177 | struct ovnact ovnact; | |
178 | struct expr_field dst; | |
179 | union expr_constant imm; | |
180 | }; | |
181 | ||
182 | /* OVNACT_MOVE, OVNACT_EXCHANGE. */ | |
183 | struct ovnact_move { | |
184 | struct ovnact ovnact; | |
185 | struct expr_field lhs; | |
186 | struct expr_field rhs; | |
187 | }; | |
188 | ||
ebb467ff BP |
189 | /* OVNACT_CT_NEXT. */ |
190 | struct ovnact_ct_next { | |
191 | struct ovnact ovnact; | |
192 | uint8_t ltable; /* Logical table ID of next table. */ | |
193 | }; | |
194 | ||
d5a76da4 BP |
195 | /* OVNACT_CT_COMMIT. */ |
196 | struct ovnact_ct_commit { | |
197 | struct ovnact ovnact; | |
198 | uint32_t ct_mark, ct_mark_mask; | |
199 | ovs_be128 ct_label, ct_label_mask; | |
200 | }; | |
201 | ||
202 | /* OVNACT_CT_DNAT, OVNACT_CT_SNAT. */ | |
203 | struct ovnact_ct_nat { | |
204 | struct ovnact ovnact; | |
205 | ovs_be32 ip; | |
206 | uint8_t ltable; /* Logical table ID of next table. */ | |
207 | }; | |
208 | ||
209 | struct ovnact_ct_lb_dst { | |
9d236afa MM |
210 | int family; |
211 | union { | |
212 | struct in6_addr ipv6; | |
213 | ovs_be32 ipv4; | |
214 | }; | |
d5a76da4 BP |
215 | uint16_t port; |
216 | }; | |
217 | ||
218 | /* OVNACT_CT_LB. */ | |
219 | struct ovnact_ct_lb { | |
220 | struct ovnact ovnact; | |
221 | struct ovnact_ct_lb_dst *dsts; | |
222 | size_t n_dsts; | |
223 | uint8_t ltable; /* Logical table ID of next table. */ | |
224 | }; | |
225 | ||
b3bd2c33 | 226 | /* OVNACT_ARP, OVNACT_ND_NA, OVNACT_CLONE. */ |
d5a76da4 BP |
227 | struct ovnact_nest { |
228 | struct ovnact ovnact; | |
229 | struct ovnact *nested; | |
230 | size_t nested_len; | |
231 | }; | |
232 | ||
233 | /* OVNACT_GET_ARP, OVNACT_GET_ND. */ | |
234 | struct ovnact_get_mac_bind { | |
235 | struct ovnact ovnact; | |
236 | struct expr_field port; /* Logical port name. */ | |
237 | struct expr_field ip; /* 32-bit or 128-bit IP address. */ | |
238 | }; | |
239 | ||
240 | /* OVNACT_PUT_ARP, ONVACT_PUT_ND. */ | |
241 | struct ovnact_put_mac_bind { | |
242 | struct ovnact ovnact; | |
243 | struct expr_field port; /* Logical port name. */ | |
244 | struct expr_field ip; /* 32-bit or 128-bit IP address. */ | |
245 | struct expr_field mac; /* 48-bit Ethernet address. */ | |
246 | }; | |
247 | ||
16936e4d NS |
248 | struct ovnact_gen_option { |
249 | const struct gen_opts_map *option; | |
d5a76da4 BP |
250 | struct expr_constant_set value; |
251 | }; | |
252 | ||
253 | /* OVNACT_PUT_DHCPV4_OPTS, OVNACT_PUT_DHCPV6_OPTS. */ | |
16936e4d | 254 | struct ovnact_put_opts { |
d5a76da4 BP |
255 | struct ovnact ovnact; |
256 | struct expr_field dst; /* 1-bit destination field. */ | |
16936e4d | 257 | struct ovnact_gen_option *options; |
d5a76da4 BP |
258 | size_t n_options; |
259 | }; | |
260 | ||
a6095f81 BS |
261 | /* Valid arguments to SET_QUEUE action. |
262 | * | |
263 | * QDISC_MIN_QUEUE_ID is the default queue, so user-defined queues should | |
264 | * start at QDISC_MIN_QUEUE_ID+1. */ | |
265 | #define QDISC_MIN_QUEUE_ID 0 | |
266 | #define QDISC_MAX_QUEUE_ID 0xf000 | |
267 | ||
268 | /* OVNACT_SET_QUEUE. */ | |
269 | struct ovnact_set_queue { | |
270 | struct ovnact ovnact; | |
271 | uint16_t queue_id; | |
272 | }; | |
273 | ||
ea991ad2 NS |
274 | /* OVNACT_DNS_LOOKUP. */ |
275 | struct ovnact_dns_lookup { | |
276 | struct ovnact ovnact; | |
277 | struct expr_field dst; /* 1-bit destination field. */ | |
278 | }; | |
279 | ||
d383eed5 JP |
280 | /* OVNACT_LOG. */ |
281 | struct ovnact_log { | |
282 | struct ovnact ovnact; | |
283 | uint8_t verdict; /* One of LOG_VERDICT_*. */ | |
284 | uint8_t severity; /* One of LOG_SEVERITY_*. */ | |
285 | char *name; | |
286 | }; | |
287 | ||
66d89287 GL |
288 | /* OVNACT_SET_METER. */ |
289 | struct ovnact_set_meter { | |
290 | struct ovnact ovnact; | |
291 | uint64_t rate; /* rate field, in kbps. */ | |
292 | uint64_t burst; /* burst rate field, in kbps. */ | |
293 | }; | |
294 | ||
d5a76da4 BP |
295 | /* Internal use by the helpers below. */ |
296 | void ovnact_init(struct ovnact *, enum ovnact_type, size_t len); | |
297 | void *ovnact_put(struct ofpbuf *, enum ovnact_type, size_t len); | |
298 | ||
299 | /* For each OVNACT_<ENUM> with a corresponding struct <STRUCT>, this defines | |
300 | * the following commonly useful functions: | |
301 | * | |
302 | * struct <STRUCT> *ovnact_put_<ENUM>(struct ofpbuf *ovnacts); | |
303 | * | |
304 | * Appends a new 'ovnact', of length OVNACT_<ENUM>_SIZE, to 'ovnacts', | |
305 | * initializes it with ovnact_init_<ENUM>(), and returns it. Also sets | |
306 | * 'ovnacts->header' to the returned action. | |
307 | * | |
308 | * struct <STRUCT> *ovnact_get_<ENUM>(const struct ovnact *ovnact); | |
309 | * | |
310 | * Returns 'ovnact' cast to "struct <STRUCT> *". 'ovnact->type' must be | |
311 | * OVNACT_<ENUM>. | |
312 | * | |
313 | * as well as the following more rarely useful definitions: | |
314 | * | |
315 | * void ovnact_init_<ENUM>(struct <STRUCT> *ovnact); | |
316 | * | |
317 | * Initializes the parts of 'ovnact' that identify it as having type | |
318 | * OVNACT_<ENUM> and length OVNACT_<ENUM>_SIZE and zeros the rest. | |
319 | * | |
320 | * <ENUM>_SIZE | |
321 | * | |
322 | * The size of the action structure, that is, sizeof(struct <STRUCT>) | |
323 | * rounded up to a multiple of OVNACT_ALIGNTO. | |
324 | */ | |
325 | #define OVNACT(ENUM, STRUCT) \ | |
326 | BUILD_ASSERT_DECL(offsetof(struct STRUCT, ovnact) == 0); \ | |
327 | \ | |
328 | enum { OVNACT_##ENUM##_SIZE = OVNACT_ALIGN(sizeof(struct STRUCT)) }; \ | |
329 | \ | |
330 | static inline struct STRUCT * \ | |
331 | ovnact_get_##ENUM(const struct ovnact *ovnact) \ | |
332 | { \ | |
333 | ovs_assert(ovnact->type == OVNACT_##ENUM); \ | |
334 | return ALIGNED_CAST(struct STRUCT *, ovnact); \ | |
335 | } \ | |
336 | \ | |
337 | static inline struct STRUCT * \ | |
338 | ovnact_put_##ENUM(struct ofpbuf *ovnacts) \ | |
339 | { \ | |
340 | return ovnact_put(ovnacts, OVNACT_##ENUM, \ | |
341 | OVNACT_##ENUM##_SIZE); \ | |
342 | } \ | |
343 | \ | |
344 | static inline void \ | |
345 | ovnact_init_##ENUM(struct STRUCT *ovnact) \ | |
346 | { \ | |
347 | ovnact_init(&ovnact->ovnact, OVNACT_##ENUM, \ | |
348 | OVNACT_##ENUM##_SIZE); \ | |
349 | } | |
350 | OVNACTS | |
351 | #undef OVNACT | |
352 | ||
6335d074 BP |
353 | enum action_opcode { |
354 | /* "arp { ...actions... }". | |
355 | * | |
356 | * The actions, in OpenFlow 1.3 format, follow the action_header. | |
357 | */ | |
358 | ACTION_OPCODE_ARP, | |
0bac7164 BP |
359 | |
360 | /* "put_arp(port, ip, mac)" | |
361 | * | |
362 | * Arguments are passed through the packet metadata and data, as follows: | |
363 | * | |
364 | * MFF_REG0 = ip | |
365 | * MFF_LOG_INPORT = port | |
366 | * MFF_ETH_SRC = mac | |
367 | */ | |
368 | ACTION_OPCODE_PUT_ARP, | |
42814145 NS |
369 | |
370 | /* "result = put_dhcp_opts(offer_ip, option, ...)". | |
371 | * | |
372 | * Arguments follow the action_header, in this format: | |
373 | * - A 32-bit or 64-bit OXM header designating the result field. | |
374 | * - A 32-bit integer specifying a bit offset within the result field. | |
375 | * - The 32-bit DHCP offer IP. | |
376 | * - Any number of DHCP options. | |
377 | */ | |
378 | ACTION_OPCODE_PUT_DHCP_OPTS, | |
e75451fe | 379 | |
f8a8db39 | 380 | /* "nd_na { ...actions... }". |
e75451fe ZKL |
381 | * |
382 | * The actions, in OpenFlow 1.3 format, follow the action_header. | |
383 | */ | |
f8a8db39 | 384 | ACTION_OPCODE_ND_NA, |
c34a87b6 JP |
385 | |
386 | /* "put_nd(port, ip6, mac)" | |
387 | * | |
388 | * Arguments are passed through the packet metadata and data, as follows: | |
389 | * | |
390 | * MFF_XXREG0 = ip6 | |
391 | * MFF_LOG_INPORT = port | |
392 | * MFF_ETH_SRC = mac | |
393 | */ | |
394 | ACTION_OPCODE_PUT_ND, | |
01cfdb2f NS |
395 | |
396 | /* "result = put_dhcpv6_opts(option, ...)". | |
397 | * | |
398 | * Arguments follow the action_header, in this format: | |
399 | * - A 32-bit or 64-bit OXM header designating the result field. | |
400 | * - A 32-bit integer specifying a bit offset within the result field. | |
401 | * - Any number of DHCPv6 options. | |
402 | */ | |
403 | ACTION_OPCODE_PUT_DHCPV6_OPTS, | |
ea991ad2 NS |
404 | |
405 | /* "result = dns_lookup()". | |
406 | * Arguments follow the action_header, in this format: | |
407 | * - A 32-bit or 64-bit OXM header designating the result field. | |
408 | * - A 32-bit integer specifying a bit offset within the result field. | |
409 | * | |
410 | */ | |
411 | ACTION_OPCODE_DNS_LOOKUP, | |
d383eed5 JP |
412 | |
413 | /* "log(arguments)". | |
414 | * | |
415 | * Arguments are as follows: | |
416 | * - An 8-bit verdict. | |
417 | * - An 8-bit severity. | |
418 | * - A variable length string containing the name. | |
419 | */ | |
420 | ACTION_OPCODE_LOG, | |
52ed5fcc NS |
421 | |
422 | /* "result = put_nd_ra_opts(option, ...)". | |
423 | * Arguments follow the action_header, in this format: | |
424 | * - A 32-bit or 64-bit OXM header designating the result field. | |
425 | * - A 32-bit integer specifying a bit offset within the result field. | |
426 | * - Any number of ICMPv6 options. | |
427 | */ | |
428 | ACTION_OPCODE_PUT_ND_RA_OPTS, | |
b1a3a6a4 NS |
429 | |
430 | /* "nd_ns { ...actions... }". | |
431 | * | |
432 | * The actions, in OpenFlow 1.3 format, follow the action_header. | |
433 | */ | |
434 | ACTION_OPCODE_ND_NS, | |
bc3d6a63 | 435 | |
3e7fa1e3 | 436 | /* "icmp4 { ...actions... } and icmp6 { ...actions... }". |
bc3d6a63 LB |
437 | * |
438 | * The actions, in OpenFlow 1.3 format, follow the action_header. | |
439 | */ | |
3e7fa1e3 | 440 | ACTION_OPCODE_ICMP, |
22b65e4d LB |
441 | |
442 | /* "tcp_reset { ...actions... }". | |
443 | * | |
444 | * The actions, in OpenFlow 1.3 format, follow the action_header. | |
445 | */ | |
446 | ACTION_OPCODE_TCP_RESET, | |
6335d074 BP |
447 | }; |
448 | ||
449 | /* Header. */ | |
450 | struct action_header { | |
451 | ovs_be32 opcode; /* One of ACTION_OPCODE_* */ | |
452 | uint8_t pad[4]; | |
453 | }; | |
454 | BUILD_ASSERT_DECL(sizeof(struct action_header) == 8); | |
455 | ||
d5a76da4 | 456 | struct ovnact_parse_params { |
1d7b2ece BP |
457 | /* A table of "struct expr_symbol"s to support (as one would provide to |
458 | * expr_parse()). */ | |
459 | const struct shash *symtab; | |
460 | ||
16936e4d | 461 | /* hmap of 'struct gen_opts_map' to support 'put_dhcp_opts' action */ |
42814145 NS |
462 | const struct hmap *dhcp_opts; |
463 | ||
16936e4d | 464 | /* hmap of 'struct gen_opts_map' to support 'put_dhcpv6_opts' action */ |
01cfdb2f NS |
465 | const struct hmap *dhcpv6_opts; |
466 | ||
52ed5fcc NS |
467 | /* hmap of 'struct gen_opts_map' to support 'put_nd_ra_opts' action */ |
468 | const struct hmap *nd_ra_opts; | |
469 | ||
4c99cb18 BP |
470 | /* Each OVN flow exists in a logical table within a logical pipeline. |
471 | * These parameters express this context for a set of OVN actions being | |
472 | * parsed: | |
d5a76da4 | 473 | * |
4c99cb18 BP |
474 | * - 'n_tables' is the number of tables in the logical ingress and |
475 | * egress pipelines, that is, "next" may specify a table less than | |
476 | * or equal to 'n_tables'. If 'n_tables' is 0 then "next" is | |
477 | * disallowed entirely. | |
d5a76da4 | 478 | * |
4c99cb18 BP |
479 | * - 'cur_ltable' is the logical table of the current flow, within |
480 | * 'pipeline'. If cur_ltable + 1 < n_tables, then this defines the | |
481 | * default table that "next" will jump to. | |
482 | * | |
483 | * - 'pipeline' is the logical pipeline. It is the default pipeline to | |
484 | * which 'next' will jump. If 'pipeline' is OVNACT_P_EGRESS, then | |
485 | * 'next' will also be able to jump into the ingress pipeline, but | |
486 | * the reverse is not true. */ | |
487 | enum ovnact_pipeline pipeline; /* Logical pipeline. */ | |
488 | uint8_t n_tables; /* Number of logical flow tables. */ | |
489 | uint8_t cur_ltable; /* 0 <= cur_ltable < n_tables. */ | |
d5a76da4 BP |
490 | }; |
491 | ||
9aef3c1b BP |
492 | bool ovnacts_parse(struct lexer *, const struct ovnact_parse_params *, |
493 | struct ofpbuf *ovnacts, struct expr **prereqsp); | |
d5a76da4 BP |
494 | char *ovnacts_parse_string(const char *s, const struct ovnact_parse_params *, |
495 | struct ofpbuf *ovnacts, struct expr **prereqsp) | |
496 | OVS_WARN_UNUSED_RESULT; | |
497 | ||
498 | void ovnacts_format(const struct ovnact[], size_t ovnacts_len, struct ds *); | |
499 | ||
500 | struct ovnact_encode_params { | |
f1c16a85 BP |
501 | /* Looks up logical port 'port_name'. If found, stores its port number in |
502 | * '*portp' and returns true; otherwise, returns false. */ | |
503 | bool (*lookup_port)(const void *aux, const char *port_name, | |
504 | unsigned int *portp); | |
505 | const void *aux; | |
1d7b2ece | 506 | |
c2e954a1 GS |
507 | /* 'true' if the flow is for a switch. */ |
508 | bool is_switch; | |
509 | ||
1b441300 MS |
510 | /* 'true' if the flow is for a gateway router. */ |
511 | bool is_gateway_router; | |
512 | ||
467085fd | 513 | /* A struct to figure out the group_id for group actions. */ |
ad35c0c5 | 514 | struct ovn_extend_table *group_table; |
467085fd | 515 | |
66d89287 GL |
516 | /* A struct to figure out the meter_id for meter actions. */ |
517 | struct ovn_extend_table *meter_table; | |
518 | ||
1d7b2ece BP |
519 | /* OVN maps each logical flow table (ltable), one-to-one, onto a physical |
520 | * OpenFlow flow table (ptable). A number of parameters describe this | |
521 | * mapping and data related to flow tables: | |
522 | * | |
4c99cb18 BP |
523 | * - 'pipeline' is the logical pipeline in which the actions are |
524 | * executing. | |
1d7b2ece | 525 | * |
4c99cb18 BP |
526 | * - 'ingress_ptable' is the OpenFlow table that corresponds to OVN |
527 | * ingress table 0. | |
528 | * | |
529 | * - 'egress_ptable' is the OpenFlow table that corresponds to OVN | |
530 | * egress table 0. | |
1d7b2ece BP |
531 | * |
532 | * - 'output_ptable' should be the OpenFlow table to which the logical | |
4c99cb18 BP |
533 | * "output" action will resubmit. |
534 | * | |
535 | * - 'mac_bind_ptable' should be the OpenFlow table used to track MAC | |
536 | * bindings. */ | |
537 | enum ovnact_pipeline pipeline; /* Logical pipeline. */ | |
538 | uint8_t ingress_ptable; /* First OpenFlow ingress table. */ | |
539 | uint8_t egress_ptable; /* First OpenFlow egress table. */ | |
1d7b2ece | 540 | uint8_t output_ptable; /* OpenFlow table for 'output' to resubmit. */ |
c34a87b6 JP |
541 | uint8_t mac_bind_ptable; /* OpenFlow table for 'get_arp'/'get_nd' to |
542 | resubmit. */ | |
1d7b2ece BP |
543 | }; |
544 | ||
d5a76da4 BP |
545 | void ovnacts_encode(const struct ovnact[], size_t ovnacts_len, |
546 | const struct ovnact_encode_params *, | |
547 | struct ofpbuf *ofpacts); | |
548 | ||
549 | void ovnacts_free(struct ovnact[], size_t ovnacts_len); | |
3b7cb7e1 BP |
550 | |
551 | #endif /* ovn/actions.h */ |