]> git.proxmox.com Git - mirror_ovs.git/blob - include/ovn/actions.h
OVN: add icmp6{} action support
[mirror_ovs.git] / include / ovn / actions.h
1 /*
2 * Copyright (c) 2015, 2016, 2017 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 OVN_ACTIONS_H
18 #define OVN_ACTIONS_H 1
19
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include "compiler.h"
23 #include "expr.h"
24 #include "openvswitch/dynamic-string.h"
25 #include "openvswitch/hmap.h"
26 #include "openvswitch/uuid.h"
27 #include "util.h"
28
29 struct expr;
30 struct lexer;
31 struct ofpbuf;
32 struct shash;
33 struct simap;
34 struct ovn_extend_table;
35
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 */
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) \
67 OVNACT(ICMP4, ovnact_nest) \
68 OVNACT(ICMP6, ovnact_nest) \
69 OVNACT(TCP_RESET, ovnact_nest) \
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) \
75 OVNACT(PUT_DHCPV4_OPTS, ovnact_put_opts) \
76 OVNACT(PUT_DHCPV6_OPTS, ovnact_put_opts) \
77 OVNACT(SET_QUEUE, ovnact_set_queue) \
78 OVNACT(DNS_LOOKUP, ovnact_dns_lookup) \
79 OVNACT(LOG, ovnact_log) \
80 OVNACT(PUT_ND_RA_OPTS, ovnact_put_opts) \
81 OVNACT(ND_NS, ovnact_nest) \
82 OVNACT(SET_METER, ovnact_set_meter)
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
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
159 /* OVNACT_NEXT. */
160 struct ovnact_next {
161 struct ovnact ovnact;
162
163 /* Arguments. */
164 uint8_t ltable; /* Logical table ID of next table. */
165 enum ovnact_pipeline pipeline; /* Pipeline of next table. */
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. */
171 uint8_t src_ltable; /* Logical table ID of source table. */
172 enum ovnact_pipeline src_pipeline; /* Pipeline of source table. */
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
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
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 {
210 int family;
211 union {
212 struct in6_addr ipv6;
213 ovs_be32 ipv4;
214 };
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
226 /* OVNACT_ARP, OVNACT_ND_NA, OVNACT_CLONE. */
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
248 struct ovnact_gen_option {
249 const struct gen_opts_map *option;
250 struct expr_constant_set value;
251 };
252
253 /* OVNACT_PUT_DHCPV4_OPTS, OVNACT_PUT_DHCPV6_OPTS. */
254 struct ovnact_put_opts {
255 struct ovnact ovnact;
256 struct expr_field dst; /* 1-bit destination field. */
257 struct ovnact_gen_option *options;
258 size_t n_options;
259 };
260
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
274 /* OVNACT_DNS_LOOKUP. */
275 struct ovnact_dns_lookup {
276 struct ovnact ovnact;
277 struct expr_field dst; /* 1-bit destination field. */
278 };
279
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
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
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
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,
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,
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,
379
380 /* "nd_na { ...actions... }".
381 *
382 * The actions, in OpenFlow 1.3 format, follow the action_header.
383 */
384 ACTION_OPCODE_ND_NA,
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,
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,
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,
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,
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,
429
430 /* "nd_ns { ...actions... }".
431 *
432 * The actions, in OpenFlow 1.3 format, follow the action_header.
433 */
434 ACTION_OPCODE_ND_NS,
435
436 /* "icmp4 { ...actions... } and icmp6 { ...actions... }".
437 *
438 * The actions, in OpenFlow 1.3 format, follow the action_header.
439 */
440 ACTION_OPCODE_ICMP,
441
442 /* "tcp_reset { ...actions... }".
443 *
444 * The actions, in OpenFlow 1.3 format, follow the action_header.
445 */
446 ACTION_OPCODE_TCP_RESET,
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
456 struct ovnact_parse_params {
457 /* A table of "struct expr_symbol"s to support (as one would provide to
458 * expr_parse()). */
459 const struct shash *symtab;
460
461 /* hmap of 'struct gen_opts_map' to support 'put_dhcp_opts' action */
462 const struct hmap *dhcp_opts;
463
464 /* hmap of 'struct gen_opts_map' to support 'put_dhcpv6_opts' action */
465 const struct hmap *dhcpv6_opts;
466
467 /* hmap of 'struct gen_opts_map' to support 'put_nd_ra_opts' action */
468 const struct hmap *nd_ra_opts;
469
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:
473 *
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.
478 *
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. */
490 };
491
492 bool ovnacts_parse(struct lexer *, const struct ovnact_parse_params *,
493 struct ofpbuf *ovnacts, struct expr **prereqsp);
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 {
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;
506
507 /* 'true' if the flow is for a switch. */
508 bool is_switch;
509
510 /* 'true' if the flow is for a gateway router. */
511 bool is_gateway_router;
512
513 /* A struct to figure out the group_id for group actions. */
514 struct ovn_extend_table *group_table;
515
516 /* A struct to figure out the meter_id for meter actions. */
517 struct ovn_extend_table *meter_table;
518
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 *
523 * - 'pipeline' is the logical pipeline in which the actions are
524 * executing.
525 *
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.
531 *
532 * - 'output_ptable' should be the OpenFlow table to which the logical
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. */
540 uint8_t output_ptable; /* OpenFlow table for 'output' to resubmit. */
541 uint8_t mac_bind_ptable; /* OpenFlow table for 'get_arp'/'get_nd' to
542 resubmit. */
543 };
544
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);
550
551 #endif /* ovn/actions.h */