]> git.proxmox.com Git - mirror_ovs.git/blame - include/ovn/actions.h
OVN: add icmp6{} action support
[mirror_ovs.git] / include / ovn / actions.h
CommitLineData
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 29struct expr;
3b7cb7e1
BP
30struct lexer;
31struct ofpbuf;
32struct shash;
33struct simap;
ad35c0c5 34struct 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. */
85enum 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. */
92enum {
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 */
104struct 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};
118BUILD_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'. */
125static inline struct ovnact *
126ovnact_next(const struct ovnact *ovnact)
127{
128 return (void *) ((uint8_t *) ovnact + OVNACT_ALIGN(ovnact->len));
129}
130
131struct ovnact *ovnact_next_flattened(const struct ovnact *);
132
133static inline struct ovnact *
134ovnact_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. */
149struct ovnact_null {
150 struct ovnact ovnact;
151};
152
c571f48c
BP
153/* Logical pipeline in which a set of actions is executed. */
154enum ovnact_pipeline {
155 OVNACT_P_INGRESS,
156 OVNACT_P_EGRESS,
157};
158
ebb467ff 159/* OVNACT_NEXT. */
d5a76da4
BP
160struct 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. */
176struct ovnact_load {
177 struct ovnact ovnact;
178 struct expr_field dst;
179 union expr_constant imm;
180};
181
182/* OVNACT_MOVE, OVNACT_EXCHANGE. */
183struct ovnact_move {
184 struct ovnact ovnact;
185 struct expr_field lhs;
186 struct expr_field rhs;
187};
188
ebb467ff
BP
189/* OVNACT_CT_NEXT. */
190struct 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. */
196struct 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. */
203struct ovnact_ct_nat {
204 struct ovnact ovnact;
205 ovs_be32 ip;
206 uint8_t ltable; /* Logical table ID of next table. */
207};
208
209struct 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. */
219struct 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
227struct ovnact_nest {
228 struct ovnact ovnact;
229 struct ovnact *nested;
230 size_t nested_len;
231};
232
233/* OVNACT_GET_ARP, OVNACT_GET_ND. */
234struct 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. */
241struct 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
248struct 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 254struct 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. */
269struct ovnact_set_queue {
270 struct ovnact ovnact;
271 uint16_t queue_id;
272};
273
ea991ad2
NS
274/* OVNACT_DNS_LOOKUP. */
275struct ovnact_dns_lookup {
276 struct ovnact ovnact;
277 struct expr_field dst; /* 1-bit destination field. */
278};
279
d383eed5
JP
280/* OVNACT_LOG. */
281struct 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. */
289struct 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. */
296void ovnact_init(struct ovnact *, enum ovnact_type, size_t len);
297void *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 }
350OVNACTS
351#undef OVNACT
352
6335d074
BP
353enum 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. */
450struct action_header {
451 ovs_be32 opcode; /* One of ACTION_OPCODE_* */
452 uint8_t pad[4];
453};
454BUILD_ASSERT_DECL(sizeof(struct action_header) == 8);
455
d5a76da4 456struct 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
492bool ovnacts_parse(struct lexer *, const struct ovnact_parse_params *,
493 struct ofpbuf *ovnacts, struct expr **prereqsp);
d5a76da4
BP
494char *ovnacts_parse_string(const char *s, const struct ovnact_parse_params *,
495 struct ofpbuf *ovnacts, struct expr **prereqsp)
496 OVS_WARN_UNUSED_RESULT;
497
498void ovnacts_format(const struct ovnact[], size_t ovnacts_len, struct ds *);
499
500struct 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
545void ovnacts_encode(const struct ovnact[], size_t ovnacts_len,
546 const struct ovnact_encode_params *,
547 struct ofpbuf *ofpacts);
548
549void ovnacts_free(struct ovnact[], size_t ovnacts_len);
3b7cb7e1
BP
550
551#endif /* ovn/actions.h */