2 * Copyright (c) 2015, 2016, 2017 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #define OVN_ACTIONS_H 1
24 #include "openvswitch/dynamic-string.h"
25 #include "openvswitch/hmap.h"
26 #include "openvswitch/uuid.h"
34 struct ovn_extend_table
;
36 /* List of OVN logical actions.
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.
41 * Each OVNACT invocation has the following parameters:
43 * 1. <ENUM>, used below in the enum definition of OVNACT_<ENUM>, and
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.
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)
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,
91 /* Define N_OVNACTS to the number of types of ovnacts. */
93 #define OVNACT(ENUM, STRUCT) + 1
98 /* Header for an action.
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.
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_*. */
111 uint8_t type
; /* OVNACT_* */
113 uint8_t pad
; /* Pad to multiple of 16 bits. */
115 uint16_t len
; /* Length of the action, in bytes, including
116 * struct ovnact, excluding padding. */
118 BUILD_ASSERT_DECL(sizeof(struct ovnact
) == 4);
121 #define OVNACT_ALIGNTO 8
122 #define OVNACT_ALIGN(SIZE) ROUND_UP(SIZE, OVNACT_ALIGNTO)
124 /* Returns the ovnact following 'ovnact'. */
125 static inline struct ovnact
*
126 ovnact_next(const struct ovnact
*ovnact
)
128 return (void *) ((uint8_t *) ovnact
+ OVNACT_ALIGN(ovnact
->len
));
131 struct ovnact
*ovnact_next_flattened(const struct ovnact
*);
133 static inline struct ovnact
*
134 ovnact_end(const struct ovnact
*ovnacts
, size_t ovnacts_len
)
136 return (void *) ((uint8_t *) ovnacts
+ ovnacts_len
);
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))
145 /* Action structure for each OVNACT_*. */
147 /* Action structure for actions that do not have any extra data beyond the
150 struct ovnact ovnact
;
153 /* Logical pipeline in which a set of actions is executed. */
154 enum ovnact_pipeline
{
161 struct ovnact ovnact
;
164 uint8_t ltable
; /* Logical table ID of next table. */
165 enum ovnact_pipeline pipeline
; /* Pipeline of next table. */
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
171 uint8_t src_ltable
; /* Logical table ID of source table. */
172 enum ovnact_pipeline src_pipeline
; /* Pipeline of source table. */
177 struct ovnact ovnact
;
178 struct expr_field dst
;
179 union expr_constant imm
;
182 /* OVNACT_MOVE, OVNACT_EXCHANGE. */
184 struct ovnact ovnact
;
185 struct expr_field lhs
;
186 struct expr_field rhs
;
189 /* OVNACT_CT_NEXT. */
190 struct ovnact_ct_next
{
191 struct ovnact ovnact
;
192 uint8_t ltable
; /* Logical table ID of next table. */
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
;
202 /* OVNACT_CT_DNAT, OVNACT_CT_SNAT. */
203 struct ovnact_ct_nat
{
204 struct ovnact ovnact
;
206 uint8_t ltable
; /* Logical table ID of next table. */
209 struct ovnact_ct_lb_dst
{
212 struct in6_addr ipv6
;
219 struct ovnact_ct_lb
{
220 struct ovnact ovnact
;
221 struct ovnact_ct_lb_dst
*dsts
;
223 uint8_t ltable
; /* Logical table ID of next table. */
226 /* OVNACT_ARP, OVNACT_ND_NA, OVNACT_CLONE. */
228 struct ovnact ovnact
;
229 struct ovnact
*nested
;
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. */
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. */
248 struct ovnact_gen_option
{
249 const struct gen_opts_map
*option
;
250 struct expr_constant_set value
;
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
;
261 /* Valid arguments to SET_QUEUE action.
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
268 /* OVNACT_SET_QUEUE. */
269 struct ovnact_set_queue
{
270 struct ovnact ovnact
;
274 /* OVNACT_DNS_LOOKUP. */
275 struct ovnact_dns_lookup
{
276 struct ovnact ovnact
;
277 struct expr_field dst
; /* 1-bit destination field. */
282 struct ovnact ovnact
;
283 uint8_t verdict
; /* One of LOG_VERDICT_*. */
284 uint8_t severity
; /* One of LOG_SEVERITY_*. */
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. */
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
);
299 /* For each OVNACT_<ENUM> with a corresponding struct <STRUCT>, this defines
300 * the following commonly useful functions:
302 * struct <STRUCT> *ovnact_put_<ENUM>(struct ofpbuf *ovnacts);
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.
308 * struct <STRUCT> *ovnact_get_<ENUM>(const struct ovnact *ovnact);
310 * Returns 'ovnact' cast to "struct <STRUCT> *". 'ovnact->type' must be
313 * as well as the following more rarely useful definitions:
315 * void ovnact_init_<ENUM>(struct <STRUCT> *ovnact);
317 * Initializes the parts of 'ovnact' that identify it as having type
318 * OVNACT_<ENUM> and length OVNACT_<ENUM>_SIZE and zeros the rest.
322 * The size of the action structure, that is, sizeof(struct <STRUCT>)
323 * rounded up to a multiple of OVNACT_ALIGNTO.
325 #define OVNACT(ENUM, STRUCT) \
326 BUILD_ASSERT_DECL(offsetof(struct STRUCT, ovnact) == 0); \
328 enum { OVNACT_##ENUM##_SIZE = OVNACT_ALIGN(sizeof(struct STRUCT)) }; \
330 static inline struct STRUCT * \
331 ovnact_get_##ENUM(const struct ovnact *ovnact) \
333 ovs_assert(ovnact->type == OVNACT_##ENUM); \
334 return ALIGNED_CAST(struct STRUCT *, ovnact); \
337 static inline struct STRUCT * \
338 ovnact_put_##ENUM(struct ofpbuf *ovnacts) \
340 return ovnact_put(ovnacts, OVNACT_##ENUM, \
341 OVNACT_##ENUM##_SIZE); \
345 ovnact_init_##ENUM(struct STRUCT *ovnact) \
347 ovnact_init(&ovnact->ovnact, OVNACT_##ENUM, \
348 OVNACT_##ENUM##_SIZE); \
354 /* "arp { ...actions... }".
356 * The actions, in OpenFlow 1.3 format, follow the action_header.
360 /* "put_arp(port, ip, mac)"
362 * Arguments are passed through the packet metadata and data, as follows:
365 * MFF_LOG_INPORT = port
368 ACTION_OPCODE_PUT_ARP
,
370 /* "result = put_dhcp_opts(offer_ip, option, ...)".
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.
378 ACTION_OPCODE_PUT_DHCP_OPTS
,
380 /* "nd_na { ...actions... }".
382 * The actions, in OpenFlow 1.3 format, follow the action_header.
386 /* "put_nd(port, ip6, mac)"
388 * Arguments are passed through the packet metadata and data, as follows:
391 * MFF_LOG_INPORT = port
394 ACTION_OPCODE_PUT_ND
,
396 /* "result = put_dhcpv6_opts(option, ...)".
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.
403 ACTION_OPCODE_PUT_DHCPV6_OPTS
,
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.
411 ACTION_OPCODE_DNS_LOOKUP
,
415 * Arguments are as follows:
416 * - An 8-bit verdict.
417 * - An 8-bit severity.
418 * - A variable length string containing the name.
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.
428 ACTION_OPCODE_PUT_ND_RA_OPTS
,
430 /* "nd_ns { ...actions... }".
432 * The actions, in OpenFlow 1.3 format, follow the action_header.
436 /* "icmp4 { ...actions... } and icmp6 { ...actions... }".
438 * The actions, in OpenFlow 1.3 format, follow the action_header.
442 /* "tcp_reset { ...actions... }".
444 * The actions, in OpenFlow 1.3 format, follow the action_header.
446 ACTION_OPCODE_TCP_RESET
,
450 struct action_header
{
451 ovs_be32 opcode
; /* One of ACTION_OPCODE_* */
454 BUILD_ASSERT_DECL(sizeof(struct action_header
) == 8);
456 struct ovnact_parse_params
{
457 /* A table of "struct expr_symbol"s to support (as one would provide to
459 const struct shash
*symtab
;
461 /* hmap of 'struct gen_opts_map' to support 'put_dhcp_opts' action */
462 const struct hmap
*dhcp_opts
;
464 /* hmap of 'struct gen_opts_map' to support 'put_dhcpv6_opts' action */
465 const struct hmap
*dhcpv6_opts
;
467 /* hmap of 'struct gen_opts_map' to support 'put_nd_ra_opts' action */
468 const struct hmap
*nd_ra_opts
;
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
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.
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.
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. */
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
;
498 void ovnacts_format(const struct ovnact
[], size_t ovnacts_len
, struct ds
*);
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
);
507 /* 'true' if the flow is for a switch. */
510 /* 'true' if the flow is for a gateway router. */
511 bool is_gateway_router
;
513 /* A struct to figure out the group_id for group actions. */
514 struct ovn_extend_table
*group_table
;
516 /* A struct to figure out the meter_id for meter actions. */
517 struct ovn_extend_table
*meter_table
;
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:
523 * - 'pipeline' is the logical pipeline in which the actions are
526 * - 'ingress_ptable' is the OpenFlow table that corresponds to OVN
529 * - 'egress_ptable' is the OpenFlow table that corresponds to OVN
532 * - 'output_ptable' should be the OpenFlow table to which the logical
533 * "output" action will resubmit.
535 * - 'mac_bind_ptable' should be the OpenFlow table used to track MAC
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
545 void ovnacts_encode(const struct ovnact
[], size_t ovnacts_len
,
546 const struct ovnact_encode_params
*,
547 struct ofpbuf
*ofpacts
);
549 void ovnacts_free(struct ovnact
[], size_t ovnacts_len
);
551 #endif /* ovn/actions.h */