2 * Copyright (c) 2008-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.
19 #include <sys/types.h>
20 #include <netinet/in.h>
23 #include "byte-order.h"
27 #include "openvswitch/hmap.h"
29 #include "multipath.h"
31 #include "odp-netlink.h"
32 #include "openvswitch/dynamic-string.h"
33 #include "openvswitch/meta-flow.h"
34 #include "openvswitch/ofp-actions.h"
35 #include "openvswitch/ofp-packet.h"
36 #include "openvswitch/ofp-parse.h"
37 #include "openvswitch/ofp-port.h"
38 #include "openvswitch/ofp-prop.h"
39 #include "openvswitch/ofp-table.h"
40 #include "openvswitch/ofpbuf.h"
41 #include "openvswitch/vlog.h"
42 #include "unaligned.h"
44 #include "vl-mff-map.h"
46 VLOG_DEFINE_THIS_MODULE(ofp_actions
);
48 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
50 struct ofp_action_header
;
52 /* Header for Open vSwitch and ONF vendor extension actions.
54 * This is the entire header for a few Open vSwitch vendor extension actions,
55 * the ones that either have no arguments or for which variable-length
56 * arguments follow the header.
58 * This cannot be used as an entirely generic vendor extension action header,
59 * because OpenFlow does not specify the location or size of the action
60 * subtype; it just happens that ONF extensions and Nicira extensions share
62 struct ext_action_header
{
63 ovs_be16 type
; /* OFPAT_VENDOR. */
64 ovs_be16 len
; /* At least 16. */
65 ovs_be32 vendor
; /* NX_VENDOR_ID or ONF_VENDOR_ID. */
66 ovs_be16 subtype
; /* See enum ofp_raw_action_type. */
69 OFP_ASSERT(sizeof(struct ext_action_header
) == 16);
71 /* Raw identifiers for OpenFlow actions.
73 * Decoding and encoding OpenFlow actions across multiple versions is difficult
74 * to do in a clean, consistent way. This enumeration lays out all of the
75 * forms of actions that Open vSwitch supports.
77 * The comments here must follow a stylized form because the
78 * "extract-ofp-actions" program parses them at build time to generate data
81 * - The first part of each comment specifies the vendor, OpenFlow versions,
82 * and type for each protocol that supports the action:
84 * # The vendor is OF for standard OpenFlow actions, NX for Nicira
85 * extension actions. (Support for other vendors can be added, but
86 * it can't be done just based on a vendor ID definition alone
87 * because OpenFlow doesn't define a standard way to specify a
88 * subtype for vendor actions, so other vendors might do it different
91 * # The version can specify a specific OpenFlow version, a version
92 * range delimited by "-", or an open-ended range with "+".
94 * # The type, in parentheses, is the action type number (for standard
95 * OpenFlow actions) or subtype (for vendor extension actions).
97 * # Optionally one may add "is deprecated" followed by a
98 * human-readable reason in parentheses (which will be used in log
99 * messages), if a particular action should no longer be used.
101 * Multiple such specifications may be separated by commas.
103 * - The second part describes the action's wire format. It may be:
105 * # "struct <name>": The struct fully specifies the wire format. The
106 * action is exactly the size of the struct. (Thus, the struct must
107 * be an exact multiple of 8 bytes in size.)
109 * # "struct <name>, ...": The struct specifies the beginning of the
110 * wire format. An instance of the action is either the struct's
111 * exact size, or a multiple of 8 bytes longer.
113 * # "uint<N>_t" or "ovs_be<N>": The action consists of a (standard or
114 * vendor extension) header, followed by 0 or more pad bytes to align
115 * to a multiple of <N> bits, followed by an argument of the given
116 * type, followed by 0 or more pad bytes to bring the total action up
117 * to a multiple of 8 bytes.
119 * # "void": The action is just a (standard or vendor extension)
122 * # Optionally, one may add "VLMFF" in the end of the second part if
123 * the Openflow action may use a variable length meta-flow field
124 * (i.e. tun_metadata). Adding "VLMFF" will pass the per-switch based
125 * variable length meta-flow field mapping map (struct vl_mff_map) to
126 * the corresponding action decoding function.
128 * - Optional additional text enclosed in square brackets is commentary for
131 enum ofp_raw_action_type
{
132 /* ## ----------------- ## */
133 /* ## Standard actions. ## */
134 /* ## ----------------- ## */
136 /* OF1.0(0): struct ofp10_action_output. */
138 /* OF1.1+(0): struct ofp11_action_output. */
141 /* OF1.0(1): uint16_t. */
142 OFPAT_RAW10_SET_VLAN_VID
,
143 /* OF1.0(2): uint8_t. */
144 OFPAT_RAW10_SET_VLAN_PCP
,
146 /* OF1.1(1), OF1.2+(1) is deprecated (use Set-Field): uint16_t.
148 * [Semantics differ slightly between the 1.0 and 1.1 versions of the VLAN
149 * modification actions: the 1.0 versions push a VLAN header if none is
150 * present, but the 1.1 versions do not. That is the only reason that we
151 * distinguish their raw action types.] */
152 OFPAT_RAW11_SET_VLAN_VID
,
153 /* OF1.1(2), OF1.2+(2) is deprecated (use Set-Field): uint8_t. */
154 OFPAT_RAW11_SET_VLAN_PCP
,
156 /* OF1.1+(17): ovs_be16.
158 * [The argument is the Ethertype, e.g. ETH_TYPE_VLAN_8021Q, not the VID or
160 OFPAT_RAW11_PUSH_VLAN
,
162 /* OF1.0(3): void. */
163 OFPAT_RAW10_STRIP_VLAN
,
164 /* OF1.1+(18): void. */
165 OFPAT_RAW11_POP_VLAN
,
167 /* OF1.0(4), OF1.1(3), OF1.2+(3) is deprecated (use Set-Field): struct
168 * ofp_action_dl_addr. */
169 OFPAT_RAW_SET_DL_SRC
,
171 /* OF1.0(5), OF1.1(4), OF1.2+(4) is deprecated (use Set-Field): struct
172 * ofp_action_dl_addr. */
173 OFPAT_RAW_SET_DL_DST
,
175 /* OF1.0(6), OF1.1(5), OF1.2+(5) is deprecated (use Set-Field):
177 OFPAT_RAW_SET_NW_SRC
,
179 /* OF1.0(7), OF1.1(6), OF1.2+(6) is deprecated (use Set-Field):
181 OFPAT_RAW_SET_NW_DST
,
183 /* OF1.0(8), OF1.1(7), OF1.2+(7) is deprecated (use Set-Field): uint8_t. */
184 OFPAT_RAW_SET_NW_TOS
,
186 /* OF1.1(8), OF1.2+(8) is deprecated (use Set-Field): uint8_t. */
187 OFPAT_RAW11_SET_NW_ECN
,
189 /* OF1.0(9), OF1.1(9), OF1.2+(9) is deprecated (use Set-Field):
191 OFPAT_RAW_SET_TP_SRC
,
193 /* OF1.0(10), OF1.1(10), OF1.2+(10) is deprecated (use Set-Field):
195 OFPAT_RAW_SET_TP_DST
,
197 /* OF1.0(11): struct ofp10_action_enqueue. */
200 /* NX1.0(30), OF1.1(13), OF1.2+(13) is deprecated (use Set-Field):
202 OFPAT_RAW_SET_MPLS_LABEL
,
204 /* NX1.0(31), OF1.1(14), OF1.2+(14) is deprecated (use Set-Field):
206 OFPAT_RAW_SET_MPLS_TC
,
208 /* NX1.0(25), OF1.1(15), OF1.2+(15) is deprecated (use Set-Field):
210 OFPAT_RAW_SET_MPLS_TTL
,
212 /* NX1.0(26), OF1.1+(16): void. */
213 OFPAT_RAW_DEC_MPLS_TTL
,
215 /* NX1.0(23), OF1.1+(19): ovs_be16.
217 * [The argument is the Ethertype, e.g. ETH_TYPE_MPLS, not the label.] */
220 /* NX1.0(24), OF1.1+(20): ovs_be16.
222 * [The argument is the Ethertype, e.g. ETH_TYPE_IPV4 if at BoS or
223 * ETH_TYPE_MPLS otherwise, not the label.] */
226 /* NX1.0(4), OF1.1+(21): uint32_t. */
229 /* NX1.0(40), OF1.1+(22): uint32_t. */
232 /* OF1.1+(23): uint8_t. */
233 OFPAT_RAW11_SET_NW_TTL
,
235 /* NX1.0(18), OF1.1+(24): void. */
236 OFPAT_RAW_DEC_NW_TTL
,
237 /* NX1.0+(21): struct nx_action_cnt_ids, ... */
238 NXAST_RAW_DEC_TTL_CNT_IDS
,
240 /* OF1.2-1.4(25): struct ofp12_action_set_field, ... VLMFF */
241 OFPAT_RAW12_SET_FIELD
,
242 /* OF1.5+(25): struct ofp12_action_set_field, ... VLMFF */
243 OFPAT_RAW15_SET_FIELD
,
244 /* NX1.0-1.4(7): struct nx_action_reg_load. VLMFF
246 * [In OpenFlow 1.5, set_field is a superset of reg_load functionality, so
247 * we drop reg_load.] */
249 /* NX1.0-1.4(33): struct ext_action_header, ... VLMFF
251 * [In OpenFlow 1.5, set_field is a superset of reg_load2 functionality, so
252 * we drop reg_load2.] */
255 /* OF1.5+(28): struct ofp15_action_copy_field, ... VLMFF */
256 OFPAT_RAW15_COPY_FIELD
,
257 /* ONF1.3-1.4(3200): struct onf_action_copy_field, ... VLMFF */
258 ONFACT_RAW13_COPY_FIELD
,
259 /* NX1.0-1.4(6): struct nx_action_reg_move, ... VLMFF */
262 /* ## ------------------------- ## */
263 /* ## Nicira extension actions. ## */
264 /* ## ------------------------- ## */
266 /* Actions similar to standard actions are listed with the standard actions. */
268 /* NX1.0+(1): uint16_t. */
270 /* NX1.0+(14): struct nx_action_resubmit. */
271 NXAST_RAW_RESUBMIT_TABLE
,
272 /* NX1.0+(44): struct nx_action_resubmit. */
273 NXAST_RAW_RESUBMIT_TABLE_CT
,
275 /* NX1.0+(2): uint32_t. */
276 NXAST_RAW_SET_TUNNEL
,
277 /* NX1.0+(9): uint64_t. */
278 NXAST_RAW_SET_TUNNEL64
,
280 /* NX1.0+(5): void. */
283 /* NX1.0+(8): struct nx_action_note, ... */
286 /* NX1.0+(10): struct nx_action_multipath. VLMFF */
289 /* NX1.0+(12): struct nx_action_bundle, ... */
291 /* NX1.0+(13): struct nx_action_bundle, ... VLMFF */
292 NXAST_RAW_BUNDLE_LOAD
,
294 /* NX1.0+(15): struct nx_action_output_reg. VLMFF */
295 NXAST_RAW_OUTPUT_REG
,
296 /* NX1.0+(32): struct nx_action_output_reg2. VLMFF */
297 NXAST_RAW_OUTPUT_REG2
,
299 /* NX1.0+(16): struct nx_action_learn, ... VLMFF */
301 /* NX1.0+(45): struct nx_action_learn2, ... VLMFF */
304 /* NX1.0+(17): void. */
307 /* NX1.0+(19): struct nx_action_fin_timeout. */
308 NXAST_RAW_FIN_TIMEOUT
,
310 /* NX1.0+(20): struct nx_action_controller. */
311 NXAST_RAW_CONTROLLER
,
312 /* NX1.0+(37): struct ext_action_header, ... */
313 NXAST_RAW_CONTROLLER2
,
315 /* NX1.0+(22): struct nx_action_write_metadata. */
316 NXAST_RAW_WRITE_METADATA
,
318 /* NX1.0+(27): struct nx_action_stack. VLMFF */
319 NXAST_RAW_STACK_PUSH
,
321 /* NX1.0+(28): struct nx_action_stack. VLMFF */
324 /* NX1.0+(29): struct nx_action_sample. */
326 /* NX1.0+(38): struct nx_action_sample2. */
328 /* NX1.0+(41): struct nx_action_sample2. */
331 /* NX1.0+(34): struct nx_action_conjunction. */
332 NXAST_RAW_CONJUNCTION
,
334 /* NX1.0+(35): struct nx_action_conntrack, ... VLMFF */
337 /* NX1.0+(36): struct nx_action_nat, ... */
340 /* NX1.0+(39): struct nx_action_output_trunc. */
341 NXAST_RAW_OUTPUT_TRUNC
,
343 /* NX1.0+(42): struct ext_action_header, ... VLMFF */
346 /* NX1.0+(43): void. */
349 /* NX1.3+(46): struct nx_action_encap, ... */
352 /* NX1.3+(47): struct nx_action_decap, ... */
355 /* NX1.3+(48): void. */
356 NXAST_RAW_DEC_NSH_TTL
,
358 /* ## ------------------ ## */
359 /* ## Debugging actions. ## */
360 /* ## ------------------ ## */
362 /* These are intentionally undocumented, subject to change, and ovs-vswitchd */
363 /* accepts them only if started with --enable-dummy. */
365 /* NX1.0+(254): void. */
366 NXAST_RAW_DEBUG_SLOW
,
368 /* NX1.0+(255): void. */
369 NXAST_RAW_DEBUG_RECIRC
,
372 /* OpenFlow actions are always a multiple of 8 bytes in length. */
373 #define OFP_ACTION_ALIGN 8
375 /* Define a few functions for working with instructions. */
376 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
377 static inline const struct STRUCT * OVS_UNUSED \
378 instruction_get_##ENUM(const struct ofp11_instruction *inst)\
380 ovs_assert(inst->type == htons(ENUM)); \
381 return ALIGNED_CAST(struct STRUCT *, inst); \
384 static inline void OVS_UNUSED \
385 instruction_init_##ENUM(struct STRUCT *s) \
387 memset(s, 0, sizeof *s); \
388 s->type = htons(ENUM); \
389 s->len = htons(sizeof *s); \
392 static inline struct STRUCT * OVS_UNUSED \
393 instruction_put_##ENUM(struct ofpbuf *buf) \
395 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
396 instruction_init_##ENUM(s); \
402 static void ofpacts_update_instruction_actions(struct ofpbuf
*openflow
,
404 static void pad_ofpat(struct ofpbuf
*openflow
, size_t start_ofs
);
406 static enum ofperr
ofpacts_verify(const struct ofpact
[], size_t ofpacts_len
,
407 uint32_t allowed_ovsinsts
,
408 enum ofpact_type outer_action
);
410 static void put_set_field(struct ofpbuf
*openflow
, enum ofp_version
,
411 enum mf_field_id
, uint64_t value
);
413 static void put_reg_load(struct ofpbuf
*openflow
,
414 const struct mf_subfield
*, uint64_t value
);
416 static enum ofperr
ofpact_pull_raw(struct ofpbuf
*, enum ofp_version
,
417 enum ofp_raw_action_type
*, uint64_t *arg
);
418 static void *ofpact_put_raw(struct ofpbuf
*, enum ofp_version
,
419 enum ofp_raw_action_type
, uint64_t arg
);
421 static char *OVS_WARN_UNUSED_RESULT
ofpacts_parse(
422 char *str
, const struct ofpact_parse_params
*pp
,
423 bool allow_instructions
, enum ofpact_type outer_action
);
424 static enum ofperr
ofpacts_pull_openflow_actions__(
425 struct ofpbuf
*openflow
, unsigned int actions_len
,
426 enum ofp_version version
, uint32_t allowed_ovsinsts
,
427 struct ofpbuf
*ofpacts
, enum ofpact_type outer_action
,
428 const struct vl_mff_map
*vl_mff_map
, uint64_t *ofpacts_tlv_bitmap
);
429 static char * OVS_WARN_UNUSED_RESULT
ofpacts_parse_copy(
430 const char *s_
, const struct ofpact_parse_params
*pp
,
431 bool allow_instructions
, enum ofpact_type outer_action
);
433 static void inconsistent_match(enum ofputil_protocol
*usable_protocols
);
435 /* Returns the ofpact following 'ofpact', except that if 'ofpact' contains
436 * nested ofpacts it returns the first one. */
438 ofpact_next_flattened(const struct ofpact
*ofpact
)
440 switch (ofpact
->type
) {
443 case OFPACT_CONTROLLER
:
445 case OFPACT_OUTPUT_REG
:
446 case OFPACT_OUTPUT_TRUNC
:
448 case OFPACT_SET_FIELD
:
449 case OFPACT_SET_VLAN_VID
:
450 case OFPACT_SET_VLAN_PCP
:
451 case OFPACT_STRIP_VLAN
:
452 case OFPACT_PUSH_VLAN
:
453 case OFPACT_SET_ETH_SRC
:
454 case OFPACT_SET_ETH_DST
:
455 case OFPACT_SET_IPV4_SRC
:
456 case OFPACT_SET_IPV4_DST
:
457 case OFPACT_SET_IP_DSCP
:
458 case OFPACT_SET_IP_ECN
:
459 case OFPACT_SET_IP_TTL
:
460 case OFPACT_SET_L4_SRC_PORT
:
461 case OFPACT_SET_L4_DST_PORT
:
462 case OFPACT_REG_MOVE
:
463 case OFPACT_STACK_PUSH
:
464 case OFPACT_STACK_POP
:
466 case OFPACT_SET_MPLS_LABEL
:
467 case OFPACT_SET_MPLS_TC
:
468 case OFPACT_SET_MPLS_TTL
:
469 case OFPACT_DEC_MPLS_TTL
:
470 case OFPACT_PUSH_MPLS
:
471 case OFPACT_POP_MPLS
:
472 case OFPACT_SET_TUNNEL
:
473 case OFPACT_SET_QUEUE
:
474 case OFPACT_POP_QUEUE
:
475 case OFPACT_FIN_TIMEOUT
:
476 case OFPACT_RESUBMIT
:
478 case OFPACT_CONJUNCTION
:
479 case OFPACT_MULTIPATH
:
483 case OFPACT_UNROLL_XLATE
:
484 case OFPACT_CT_CLEAR
:
485 case OFPACT_DEBUG_RECIRC
:
486 case OFPACT_DEBUG_SLOW
:
488 case OFPACT_CLEAR_ACTIONS
:
489 case OFPACT_WRITE_METADATA
:
490 case OFPACT_GOTO_TABLE
:
494 case OFPACT_DEC_NSH_TTL
:
495 return ofpact_next(ofpact
);
498 return ofpact_get_CLONE(ofpact
)->actions
;
501 return ofpact_get_CT(ofpact
)->actions
;
503 case OFPACT_WRITE_ACTIONS
:
504 return ofpact_get_WRITE_ACTIONS(ofpact
)->actions
;
510 /* Pull off existing actions or instructions. Used by nesting actions to keep
511 * ofpacts_parse() oblivious of actions nesting.
513 * Push the actions back on after nested parsing, e.g.:
515 * size_t ofs = ofpacts_pull(ofpacts);
516 * ...nested parsing...
517 * ofpbuf_push_uninit(ofpacts, ofs);
520 ofpacts_pull(struct ofpbuf
*ofpacts
)
525 ofpbuf_pull(ofpacts
, ofs
);
530 #include "ofp-actions.inc1"
532 /* Output actions. */
534 /* Action structure for OFPAT10_OUTPUT, which sends packets out 'port'.
535 * When the 'port' is the OFPP_CONTROLLER, 'max_len' indicates the max
536 * number of bytes to send. A 'max_len' of zero means no bytes of the
537 * packet should be sent. */
538 struct ofp10_action_output
{
539 ovs_be16 type
; /* OFPAT10_OUTPUT. */
540 ovs_be16 len
; /* Length is 8. */
541 ovs_be16 port
; /* Output port. */
542 ovs_be16 max_len
; /* Max length to send to controller. */
544 OFP_ASSERT(sizeof(struct ofp10_action_output
) == 8);
546 /* Action structure for OFPAT_OUTPUT, which sends packets out 'port'.
547 * When the 'port' is the OFPP_CONTROLLER, 'max_len' indicates the max
548 * number of bytes to send. A 'max_len' of zero means no bytes of the
549 * packet should be sent.*/
550 struct ofp11_action_output
{
551 ovs_be16 type
; /* OFPAT11_OUTPUT. */
552 ovs_be16 len
; /* Length is 16. */
553 ovs_be32 port
; /* Output port. */
554 ovs_be16 max_len
; /* Max length to send to controller. */
555 uint8_t pad
[6]; /* Pad to 64 bits. */
557 OFP_ASSERT(sizeof(struct ofp11_action_output
) == 16);
560 decode_OFPAT_RAW10_OUTPUT(const struct ofp10_action_output
*oao
,
561 enum ofp_version ofp_version OVS_UNUSED
,
564 struct ofpact_output
*output
;
566 output
= ofpact_put_OUTPUT(out
);
567 output
->port
= u16_to_ofp(ntohs(oao
->port
));
568 output
->max_len
= ntohs(oao
->max_len
);
570 return ofpact_check_output_port(output
->port
, OFPP_MAX
);
574 decode_OFPAT_RAW11_OUTPUT(const struct ofp11_action_output
*oao
,
575 enum ofp_version ofp_version OVS_UNUSED
,
578 struct ofpact_output
*output
;
581 output
= ofpact_put_OUTPUT(out
);
582 output
->max_len
= ntohs(oao
->max_len
);
584 error
= ofputil_port_from_ofp11(oao
->port
, &output
->port
);
589 return ofpact_check_output_port(output
->port
, OFPP_MAX
);
593 encode_OUTPUT(const struct ofpact_output
*output
,
594 enum ofp_version ofp_version
, struct ofpbuf
*out
)
596 if (ofp_version
== OFP10_VERSION
) {
597 struct ofp10_action_output
*oao
;
599 oao
= put_OFPAT10_OUTPUT(out
);
600 oao
->port
= htons(ofp_to_u16(output
->port
));
601 oao
->max_len
= htons(output
->max_len
);
603 struct ofp11_action_output
*oao
;
605 oao
= put_OFPAT11_OUTPUT(out
);
606 oao
->port
= ofputil_port_to_ofp11(output
->port
);
607 oao
->max_len
= htons(output
->max_len
);
611 static char * OVS_WARN_UNUSED_RESULT
612 parse_truncate_subfield(const char *arg_
,
613 const struct ofpact_parse_params
*pp
,
614 struct ofpact_output_trunc
*output_trunc
)
617 char *arg
= CONST_CAST(char *, arg_
);
619 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
620 if (!strcmp(key
, "port")) {
621 if (!ofputil_port_from_string(value
, pp
->port_map
,
622 &output_trunc
->port
)) {
623 return xasprintf("output to unknown truncate port: %s",
626 if (ofp_to_u16(output_trunc
->port
) > ofp_to_u16(OFPP_MAX
)) {
627 if (output_trunc
->port
!= OFPP_LOCAL
&&
628 output_trunc
->port
!= OFPP_IN_PORT
)
629 return xasprintf("output to unsupported truncate port: %s",
632 } else if (!strcmp(key
, "max_len")) {
635 err
= str_to_u32(value
, &output_trunc
->max_len
);
640 return xasprintf("invalid key '%s' in output_trunc argument",
647 static char * OVS_WARN_UNUSED_RESULT
648 parse_OUTPUT(const char *arg
, const struct ofpact_parse_params
*pp
)
650 if (strstr(arg
, "port") && strstr(arg
, "max_len")) {
651 struct ofpact_output_trunc
*output_trunc
;
653 output_trunc
= ofpact_put_OUTPUT_TRUNC(pp
->ofpacts
);
654 return parse_truncate_subfield(arg
, pp
, output_trunc
);
658 if (ofputil_port_from_string(arg
, pp
->port_map
, &port
)) {
659 struct ofpact_output
*output
= ofpact_put_OUTPUT(pp
->ofpacts
);
661 output
->max_len
= output
->port
== OFPP_CONTROLLER
? UINT16_MAX
: 0;
665 struct mf_subfield src
;
666 char *error
= mf_parse_subfield(&src
, arg
);
668 struct ofpact_output_reg
*output_reg
;
670 output_reg
= ofpact_put_OUTPUT_REG(pp
->ofpacts
);
671 output_reg
->max_len
= UINT16_MAX
;
672 output_reg
->src
= src
;
677 return xasprintf("%s: output to unknown port", arg
);
681 format_OUTPUT(const struct ofpact_output
*a
,
682 const struct ofpact_format_params
*fp
)
684 if (ofp_to_u16(a
->port
) < ofp_to_u16(OFPP_MAX
)) {
685 ds_put_format(fp
->s
, "%soutput:%s", colors
.special
, colors
.end
);
687 ofputil_format_port(a
->port
, fp
->port_map
, fp
->s
);
688 if (a
->port
== OFPP_CONTROLLER
) {
689 ds_put_format(fp
->s
, ":%"PRIu16
, a
->max_len
);
694 check_OUTPUT(const struct ofpact_output
*a
,
695 const struct ofpact_check_params
*cp
)
697 return ofpact_check_output_port(a
->port
, cp
->max_ports
);
703 decode_OFPAT_RAW_GROUP(uint32_t group_id
,
704 enum ofp_version ofp_version OVS_UNUSED
,
707 ofpact_put_GROUP(out
)->group_id
= group_id
;
712 encode_GROUP(const struct ofpact_group
*group
,
713 enum ofp_version ofp_version
, struct ofpbuf
*out
)
715 put_OFPAT_GROUP(out
, ofp_version
, group
->group_id
);
718 static char * OVS_WARN_UNUSED_RESULT
719 parse_GROUP(char *arg
, const struct ofpact_parse_params
*pp
)
721 return str_to_u32(arg
, &ofpact_put_GROUP(pp
->ofpacts
)->group_id
);
725 format_GROUP(const struct ofpact_group
*a
,
726 const struct ofpact_format_params
*fp
)
728 ds_put_format(fp
->s
, "%sgroup:%s%"PRIu32
,
729 colors
.special
, colors
.end
, a
->group_id
);
733 check_GROUP(const struct ofpact_group
*a OVS_UNUSED
,
734 const struct ofpact_check_params
*cp OVS_UNUSED
)
739 /* Action structure for NXAST_CONTROLLER.
741 * This generalizes using OFPAT_OUTPUT to send a packet to OFPP_CONTROLLER. In
742 * addition to the 'max_len' that OFPAT_OUTPUT supports, it also allows
745 * - 'reason': The reason code to use in the ofp_packet_in or nx_packet_in.
747 * - 'controller_id': The ID of the controller connection to which the
748 * ofp_packet_in should be sent. The ofp_packet_in or nx_packet_in is
749 * sent only to controllers that have the specified controller connection
750 * ID. See "struct nx_controller_id" for more information. */
751 struct nx_action_controller
{
752 ovs_be16 type
; /* OFPAT_VENDOR. */
753 ovs_be16 len
; /* Length is 16. */
754 ovs_be32 vendor
; /* NX_VENDOR_ID. */
755 ovs_be16 subtype
; /* NXAST_CONTROLLER. */
756 ovs_be16 max_len
; /* Maximum length to send to controller. */
757 ovs_be16 controller_id
; /* Controller ID to send packet-in. */
758 uint8_t reason
; /* enum ofp_packet_in_reason (OFPR_*). */
759 uint8_t zero
; /* Must be zero. */
761 OFP_ASSERT(sizeof(struct nx_action_controller
) == 16);
763 /* Properties for NXAST_CONTROLLER2.
765 * For more information on the effect of NXAC2PT_PAUSE, see the large comment
766 * on NXT_PACKET_IN2 in nicira-ext.h */
767 enum nx_action_controller2_prop_type
{
768 NXAC2PT_MAX_LEN
, /* ovs_be16 max bytes to send (default all). */
769 NXAC2PT_CONTROLLER_ID
, /* ovs_be16 dest controller ID (default 0). */
770 NXAC2PT_REASON
, /* uint8_t reason (OFPR_*), default 0. */
771 NXAC2PT_USERDATA
, /* Data to copy into NXPINT_USERDATA. */
772 NXAC2PT_PAUSE
, /* Flag to pause pipeline to resume later. */
773 NXAC2PT_METER_ID
, /* ovs_b32 meter (default NX_CTLR_NO_METER). */
776 /* The action structure for NXAST_CONTROLLER2 is "struct ext_action_header",
777 * followed by NXAC2PT_* properties. */
780 decode_NXAST_RAW_CONTROLLER(const struct nx_action_controller
*nac
,
781 enum ofp_version ofp_version OVS_UNUSED
,
784 struct ofpact_controller
*oc
;
786 oc
= ofpact_put_CONTROLLER(out
);
787 oc
->ofpact
.raw
= NXAST_RAW_CONTROLLER
;
788 oc
->max_len
= ntohs(nac
->max_len
);
789 oc
->controller_id
= ntohs(nac
->controller_id
);
790 oc
->reason
= nac
->reason
;
791 oc
->meter_id
= NX_CTLR_NO_METER
;
792 ofpact_finish_CONTROLLER(out
, &oc
);
798 decode_NXAST_RAW_CONTROLLER2(const struct ext_action_header
*eah
,
799 enum ofp_version ofp_version OVS_UNUSED
,
802 if (!is_all_zeros(eah
->pad
, sizeof eah
->pad
)) {
803 return OFPERR_NXBRC_MUST_BE_ZERO
;
806 size_t start_ofs
= out
->size
;
807 struct ofpact_controller
*oc
= ofpact_put_CONTROLLER(out
);
808 oc
->ofpact
.raw
= NXAST_RAW_CONTROLLER2
;
809 oc
->max_len
= UINT16_MAX
;
810 oc
->reason
= OFPR_ACTION
;
811 oc
->meter_id
= NX_CTLR_NO_METER
;
813 struct ofpbuf properties
;
814 ofpbuf_use_const(&properties
, eah
, ntohs(eah
->len
));
815 ofpbuf_pull(&properties
, sizeof *eah
);
817 while (properties
.size
> 0) {
818 struct ofpbuf payload
;
821 enum ofperr error
= ofpprop_pull(&properties
, &payload
, &type
);
827 case NXAC2PT_MAX_LEN
:
828 error
= ofpprop_parse_u16(&payload
, &oc
->max_len
);
831 case NXAC2PT_CONTROLLER_ID
:
832 error
= ofpprop_parse_u16(&payload
, &oc
->controller_id
);
835 case NXAC2PT_REASON
: {
837 error
= ofpprop_parse_u8(&payload
, &u8
);
842 case NXAC2PT_USERDATA
:
843 out
->size
= start_ofs
+ sizeof(struct ofpact_controller
);
844 ofpbuf_put(out
, payload
.msg
, ofpbuf_msgsize(&payload
));
845 oc
= ofpbuf_at_assert(out
, start_ofs
, sizeof *oc
);
846 oc
->userdata_len
= ofpbuf_msgsize(&payload
);
853 case NXAC2PT_METER_ID
:
854 error
= ofpprop_parse_u32(&payload
, &oc
->meter_id
);
858 error
= OFPPROP_UNKNOWN(false, "NXAST_RAW_CONTROLLER2", type
);
866 ofpact_finish_CONTROLLER(out
, &oc
);
872 encode_CONTROLLER(const struct ofpact_controller
*controller
,
873 enum ofp_version ofp_version OVS_UNUSED
,
876 if (controller
->userdata_len
878 || controller
->meter_id
!= NX_CTLR_NO_METER
879 || controller
->ofpact
.raw
== NXAST_RAW_CONTROLLER2
) {
880 size_t start_ofs
= out
->size
;
881 put_NXAST_CONTROLLER2(out
);
882 if (controller
->max_len
!= UINT16_MAX
) {
883 ofpprop_put_u16(out
, NXAC2PT_MAX_LEN
, controller
->max_len
);
885 if (controller
->controller_id
!= 0) {
886 ofpprop_put_u16(out
, NXAC2PT_CONTROLLER_ID
,
887 controller
->controller_id
);
889 if (controller
->reason
!= OFPR_ACTION
) {
890 ofpprop_put_u8(out
, NXAC2PT_REASON
, controller
->reason
);
892 if (controller
->userdata_len
!= 0) {
893 ofpprop_put(out
, NXAC2PT_USERDATA
, controller
->userdata
,
894 controller
->userdata_len
);
896 if (controller
->pause
) {
897 ofpprop_put_flag(out
, NXAC2PT_PAUSE
);
899 if (controller
->meter_id
!= NX_CTLR_NO_METER
) {
900 ofpprop_put_u32(out
, NXAC2PT_METER_ID
, controller
->meter_id
);
902 pad_ofpat(out
, start_ofs
);
904 struct nx_action_controller
*nac
;
906 nac
= put_NXAST_CONTROLLER(out
);
907 nac
->max_len
= htons(controller
->max_len
);
908 nac
->controller_id
= htons(controller
->controller_id
);
909 nac
->reason
= controller
->reason
;
913 static char * OVS_WARN_UNUSED_RESULT
914 parse_CONTROLLER(char *arg
, const struct ofpact_parse_params
*pp
)
916 enum ofp_packet_in_reason reason
= OFPR_ACTION
;
917 uint16_t controller_id
= 0;
918 uint16_t max_len
= UINT16_MAX
;
919 uint32_t meter_id
= NX_CTLR_NO_METER
;
920 const char *userdata
= NULL
;
925 } else if (strspn(arg
, "0123456789") == strlen(arg
)) {
926 char *error
= str_to_u16(arg
, "max_len", &max_len
);
933 while (ofputil_parse_key_value(&arg
, &name
, &value
)) {
934 if (!strcmp(name
, "reason")) {
935 if (!ofputil_packet_in_reason_from_string(value
, &reason
)) {
936 return xasprintf("unknown reason \"%s\"", value
);
938 } else if (!strcmp(name
, "max_len")) {
939 char *error
= str_to_u16(value
, "max_len", &max_len
);
943 } else if (!strcmp(name
, "id")) {
944 char *error
= str_to_u16(value
, "id", &controller_id
);
948 } else if (!strcmp(name
, "userdata")) {
950 } else if (!strcmp(name
, "pause")) {
952 } else if (!strcmp(name
, "meter_id")) {
953 char *error
= str_to_u32(value
, &meter_id
);
958 return xasprintf("unknown key \"%s\" parsing controller "
964 if (reason
== OFPR_ACTION
&& controller_id
== 0 && !userdata
&& !pause
965 && meter_id
== NX_CTLR_NO_METER
) {
966 struct ofpact_output
*output
;
968 output
= ofpact_put_OUTPUT(pp
->ofpacts
);
969 output
->port
= OFPP_CONTROLLER
;
970 output
->max_len
= max_len
;
972 struct ofpact_controller
*controller
;
974 controller
= ofpact_put_CONTROLLER(pp
->ofpacts
);
975 controller
->max_len
= max_len
;
976 controller
->reason
= reason
;
977 controller
->controller_id
= controller_id
;
978 controller
->pause
= pause
;
979 controller
->meter_id
= meter_id
;
982 size_t start_ofs
= pp
->ofpacts
->size
;
983 const char *end
= ofpbuf_put_hex(pp
->ofpacts
, userdata
, NULL
);
985 return xstrdup("bad hex digit in `controller' "
986 "action `userdata'");
988 size_t userdata_len
= pp
->ofpacts
->size
- start_ofs
;
989 controller
= pp
->ofpacts
->header
;
990 controller
->userdata_len
= userdata_len
;
992 ofpact_finish_CONTROLLER(pp
->ofpacts
, &controller
);
999 format_hex_arg(struct ds
*s
, const uint8_t *data
, size_t len
)
1001 for (size_t i
= 0; i
< len
; i
++) {
1003 ds_put_char(s
, '.');
1005 ds_put_format(s
, "%02"PRIx8
, data
[i
]);
1010 format_CONTROLLER(const struct ofpact_controller
*a
,
1011 const struct ofpact_format_params
*fp
)
1013 if (a
->reason
== OFPR_ACTION
&& !a
->controller_id
&& !a
->userdata_len
1014 && !a
->pause
&& a
->meter_id
== NX_CTLR_NO_METER
) {
1015 ds_put_format(fp
->s
, "%sCONTROLLER:%s%"PRIu16
,
1016 colors
.special
, colors
.end
, a
->max_len
);
1018 enum ofp_packet_in_reason reason
= a
->reason
;
1020 ds_put_format(fp
->s
, "%scontroller(%s", colors
.paren
, colors
.end
);
1021 if (reason
!= OFPR_ACTION
) {
1022 char reasonbuf
[OFPUTIL_PACKET_IN_REASON_BUFSIZE
];
1024 ds_put_format(fp
->s
, "%sreason=%s%s,", colors
.param
, colors
.end
,
1025 ofputil_packet_in_reason_to_string(
1026 reason
, reasonbuf
, sizeof reasonbuf
));
1028 if (a
->max_len
!= UINT16_MAX
) {
1029 ds_put_format(fp
->s
, "%smax_len=%s%"PRIu16
",",
1030 colors
.param
, colors
.end
, a
->max_len
);
1032 if (a
->controller_id
!= 0) {
1033 ds_put_format(fp
->s
, "%sid=%s%"PRIu16
",",
1034 colors
.param
, colors
.end
, a
->controller_id
);
1036 if (a
->userdata_len
) {
1037 ds_put_format(fp
->s
, "%suserdata=%s", colors
.param
, colors
.end
);
1038 format_hex_arg(fp
->s
, a
->userdata
, a
->userdata_len
);
1039 ds_put_char(fp
->s
, ',');
1042 ds_put_format(fp
->s
, "%spause%s,", colors
.value
, colors
.end
);
1044 if (a
->meter_id
!= NX_CTLR_NO_METER
) {
1045 ds_put_format(fp
->s
, "%smeter_id=%s%"PRIu32
",",
1046 colors
.param
, colors
.end
, a
->meter_id
);
1048 ds_chomp(fp
->s
, ',');
1049 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
1054 check_CONTROLLER(const struct ofpact_controller
*a OVS_UNUSED
,
1055 const struct ofpact_check_params
*cp OVS_UNUSED
)
1060 /* Enqueue action. */
1061 struct ofp10_action_enqueue
{
1062 ovs_be16 type
; /* OFPAT10_ENQUEUE. */
1063 ovs_be16 len
; /* Len is 16. */
1064 ovs_be16 port
; /* Port that queue belongs. Should
1065 refer to a valid physical port
1066 (i.e. < OFPP_MAX) or OFPP_IN_PORT. */
1067 uint8_t pad
[6]; /* Pad for 64-bit alignment. */
1068 ovs_be32 queue_id
; /* Where to enqueue the packets. */
1070 OFP_ASSERT(sizeof(struct ofp10_action_enqueue
) == 16);
1073 decode_OFPAT_RAW10_ENQUEUE(const struct ofp10_action_enqueue
*oae
,
1074 enum ofp_version ofp_version OVS_UNUSED
,
1077 struct ofpact_enqueue
*enqueue
;
1079 enqueue
= ofpact_put_ENQUEUE(out
);
1080 enqueue
->port
= u16_to_ofp(ntohs(oae
->port
));
1081 enqueue
->queue
= ntohl(oae
->queue_id
);
1082 if (ofp_to_u16(enqueue
->port
) >= ofp_to_u16(OFPP_MAX
)
1083 && enqueue
->port
!= OFPP_IN_PORT
1084 && enqueue
->port
!= OFPP_LOCAL
) {
1085 return OFPERR_OFPBAC_BAD_OUT_PORT
;
1091 encode_ENQUEUE(const struct ofpact_enqueue
*enqueue
,
1092 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1094 if (ofp_version
== OFP10_VERSION
) {
1095 struct ofp10_action_enqueue
*oae
;
1097 oae
= put_OFPAT10_ENQUEUE(out
);
1098 oae
->port
= htons(ofp_to_u16(enqueue
->port
));
1099 oae
->queue_id
= htonl(enqueue
->queue
);
1101 put_OFPAT_SET_QUEUE(out
, ofp_version
, enqueue
->queue
);
1103 struct ofp11_action_output
*oao
= put_OFPAT11_OUTPUT(out
);
1104 oao
->port
= ofputil_port_to_ofp11(enqueue
->port
);
1105 oao
->max_len
= OVS_BE16_MAX
;
1107 put_NXAST_POP_QUEUE(out
);
1111 static char * OVS_WARN_UNUSED_RESULT
1112 parse_ENQUEUE(char *arg
, const struct ofpact_parse_params
*pp
)
1115 char *port
= strtok_r(arg
, ":q,", &sp
);
1116 char *queue
= strtok_r(NULL
, "", &sp
);
1117 struct ofpact_enqueue
*enqueue
;
1119 if (port
== NULL
|| queue
== NULL
) {
1120 return xstrdup("\"enqueue\" syntax is \"enqueue:PORT:QUEUE\" or "
1121 "\"enqueue(PORT,QUEUE)\"");
1124 enqueue
= ofpact_put_ENQUEUE(pp
->ofpacts
);
1125 if (!ofputil_port_from_string(port
, pp
->port_map
, &enqueue
->port
)) {
1126 return xasprintf("%s: enqueue to unknown port", port
);
1128 return str_to_u32(queue
, &enqueue
->queue
);
1132 format_ENQUEUE(const struct ofpact_enqueue
*a
,
1133 const struct ofpact_format_params
*fp
)
1135 ds_put_format(fp
->s
, "%senqueue:%s", colors
.param
, colors
.end
);
1136 ofputil_format_port(a
->port
, fp
->port_map
, fp
->s
);
1137 ds_put_format(fp
->s
, ":%"PRIu32
, a
->queue
);
1141 check_ENQUEUE(const struct ofpact_enqueue
*a
,
1142 const struct ofpact_check_params
*cp
)
1144 if (ofp_to_u16(a
->port
) >= ofp_to_u16(cp
->max_ports
)
1145 && a
->port
!= OFPP_IN_PORT
1146 && a
->port
!= OFPP_LOCAL
) {
1147 return OFPERR_OFPBAC_BAD_OUT_PORT
;
1152 /* Action structure for NXAST_OUTPUT_REG.
1154 * Outputs to the OpenFlow port number written to src[ofs:ofs+nbits].
1156 * The format and semantics of 'src' and 'ofs_nbits' are similar to those for
1157 * the NXAST_REG_LOAD action.
1159 * The acceptable nxm_header values for 'src' are the same as the acceptable
1160 * nxm_header values for the 'src' field of NXAST_REG_MOVE.
1162 * The 'max_len' field indicates the number of bytes to send when the chosen
1163 * port is OFPP_CONTROLLER. Its semantics are equivalent to the 'max_len'
1164 * field of OFPAT_OUTPUT.
1166 * The 'zero' field is required to be zeroed for forward compatibility. */
1167 struct nx_action_output_reg
{
1168 ovs_be16 type
; /* OFPAT_VENDOR. */
1169 ovs_be16 len
; /* 24. */
1170 ovs_be32 vendor
; /* NX_VENDOR_ID. */
1171 ovs_be16 subtype
; /* NXAST_OUTPUT_REG. */
1173 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
1174 ovs_be32 src
; /* Source. */
1176 ovs_be16 max_len
; /* Max length to send to controller. */
1178 uint8_t zero
[6]; /* Reserved, must be zero. */
1180 OFP_ASSERT(sizeof(struct nx_action_output_reg
) == 24);
1182 /* Action structure for NXAST_OUTPUT_REG2.
1184 * Like the NXAST_OUTPUT_REG but organized so that there is room for a 64-bit
1185 * experimenter OXM as 'src'.
1187 struct nx_action_output_reg2
{
1188 ovs_be16 type
; /* OFPAT_VENDOR. */
1189 ovs_be16 len
; /* 24. */
1190 ovs_be32 vendor
; /* NX_VENDOR_ID. */
1191 ovs_be16 subtype
; /* NXAST_OUTPUT_REG2. */
1193 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
1194 ovs_be16 max_len
; /* Max length to send to controller. */
1197 * - 'src', as an OXM/NXM header (either 4 or 8 bytes).
1198 * - Enough 0-bytes to pad the action out to 24 bytes. */
1201 OFP_ASSERT(sizeof(struct nx_action_output_reg2
) == 24);
1204 decode_NXAST_RAW_OUTPUT_REG(const struct nx_action_output_reg
*naor
,
1205 enum ofp_version ofp_version OVS_UNUSED
,
1206 const struct vl_mff_map
*vl_mff_map
,
1207 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
1209 struct ofpact_output_reg
*output_reg
;
1212 if (!is_all_zeros(naor
->zero
, sizeof naor
->zero
)) {
1213 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1216 output_reg
= ofpact_put_OUTPUT_REG(out
);
1217 output_reg
->ofpact
.raw
= NXAST_RAW_OUTPUT_REG
;
1218 output_reg
->src
.ofs
= nxm_decode_ofs(naor
->ofs_nbits
);
1219 output_reg
->src
.n_bits
= nxm_decode_n_bits(naor
->ofs_nbits
);
1220 output_reg
->max_len
= ntohs(naor
->max_len
);
1221 error
= mf_vl_mff_mf_from_nxm_header(ntohl(naor
->src
), vl_mff_map
,
1222 &output_reg
->src
.field
, tlv_bitmap
);
1227 return mf_check_src(&output_reg
->src
, NULL
);
1231 decode_NXAST_RAW_OUTPUT_REG2(const struct nx_action_output_reg2
*naor
,
1232 enum ofp_version ofp_version OVS_UNUSED
,
1233 const struct vl_mff_map
*vl_mff_map
,
1234 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
1236 struct ofpact_output_reg
*output_reg
;
1239 output_reg
= ofpact_put_OUTPUT_REG(out
);
1240 output_reg
->ofpact
.raw
= NXAST_RAW_OUTPUT_REG2
;
1241 output_reg
->src
.ofs
= nxm_decode_ofs(naor
->ofs_nbits
);
1242 output_reg
->src
.n_bits
= nxm_decode_n_bits(naor
->ofs_nbits
);
1243 output_reg
->max_len
= ntohs(naor
->max_len
);
1245 struct ofpbuf b
= ofpbuf_const_initializer(naor
, ntohs(naor
->len
));
1246 ofpbuf_pull(&b
, OBJECT_OFFSETOF(naor
, pad
));
1248 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &output_reg
->src
.field
,
1254 if (!is_all_zeros(b
.data
, b
.size
)) {
1255 return OFPERR_NXBRC_MUST_BE_ZERO
;
1258 return mf_check_src(&output_reg
->src
, NULL
);
1262 encode_OUTPUT_REG(const struct ofpact_output_reg
*output_reg
,
1263 enum ofp_version ofp_version OVS_UNUSED
,
1266 /* If 'output_reg' came in as an NXAST_RAW_OUTPUT_REG2 action, or if it
1267 * cannot be encoded in the older form, encode it as
1268 * NXAST_RAW_OUTPUT_REG2. */
1269 if (output_reg
->ofpact
.raw
== NXAST_RAW_OUTPUT_REG2
1270 || !mf_nxm_header(output_reg
->src
.field
->id
)) {
1271 struct nx_action_output_reg2
*naor
= put_NXAST_OUTPUT_REG2(out
);
1272 size_t size
= out
->size
;
1274 naor
->ofs_nbits
= nxm_encode_ofs_nbits(output_reg
->src
.ofs
,
1275 output_reg
->src
.n_bits
);
1276 naor
->max_len
= htons(output_reg
->max_len
);
1278 out
->size
= size
- sizeof naor
->pad
;
1279 nx_put_mff_header(out
, output_reg
->src
.field
, 0, false);
1282 struct nx_action_output_reg
*naor
= put_NXAST_OUTPUT_REG(out
);
1284 naor
->ofs_nbits
= nxm_encode_ofs_nbits(output_reg
->src
.ofs
,
1285 output_reg
->src
.n_bits
);
1286 naor
->src
= htonl(nxm_header_from_mff(output_reg
->src
.field
));
1287 naor
->max_len
= htons(output_reg
->max_len
);
1291 static char * OVS_WARN_UNUSED_RESULT
1292 parse_OUTPUT_REG(const char *arg
, const struct ofpact_parse_params
*pp
)
1294 return parse_OUTPUT(arg
, pp
);
1298 format_OUTPUT_REG(const struct ofpact_output_reg
*a
,
1299 const struct ofpact_format_params
*fp
)
1301 ds_put_format(fp
->s
, "%soutput:%s", colors
.special
, colors
.end
);
1302 mf_format_subfield(&a
->src
, fp
->s
);
1306 check_OUTPUT_REG(const struct ofpact_output_reg
*a
,
1307 const struct ofpact_check_params
*cp
)
1309 return mf_check_src(&a
->src
, cp
->match
);
1312 /* Action structure for NXAST_BUNDLE and NXAST_BUNDLE_LOAD.
1314 * The bundle actions choose a slave from a supplied list of options.
1315 * NXAST_BUNDLE outputs to its selection. NXAST_BUNDLE_LOAD writes its
1316 * selection to a register.
1318 * The list of possible slaves follows the nx_action_bundle structure. The size
1319 * of each slave is governed by its type as indicated by the 'slave_type'
1320 * parameter. The list of slaves should be padded at its end with zeros to make
1321 * the total length of the action a multiple of 8.
1323 * Switches infer from the 'slave_type' parameter the size of each slave. All
1324 * implementations must support the NXM_OF_IN_PORT 'slave_type' which indicates
1325 * that the slaves are OpenFlow port numbers with NXM_LENGTH(NXM_OF_IN_PORT) ==
1326 * 2 byte width. Switches should reject actions which indicate unknown or
1327 * unsupported slave types.
1329 * Switches use a strategy dictated by the 'algorithm' parameter to choose a
1330 * slave. If the switch does not support the specified 'algorithm' parameter,
1331 * it should reject the action.
1333 * Several algorithms take into account liveness when selecting slaves. The
1334 * liveness of a slave is implementation defined (with one exception), but will
1335 * generally take into account things like its carrier status and the results
1336 * of any link monitoring protocols which happen to be running on it. In order
1337 * to give controllers a place-holder value, the OFPP_NONE port is always
1338 * considered live, that is, NXAST_BUNDLE_LOAD stores OFPP_NONE in the output
1339 * register if no slave is live.
1341 * Some slave selection strategies require the use of a hash function, in which
1342 * case the 'fields' and 'basis' parameters should be populated. The 'fields'
1343 * parameter (one of NX_HASH_FIELDS_*) designates which parts of the flow to
1344 * hash. Refer to the definition of "enum nx_hash_fields" for details. The
1345 * 'basis' parameter is used as a universal hash parameter. Different values
1346 * of 'basis' yield different hash results.
1348 * The 'zero' parameter at the end of the action structure is reserved for
1349 * future use. Switches are required to reject actions which have nonzero
1350 * bytes in the 'zero' field.
1352 * NXAST_BUNDLE actions should have 'ofs_nbits' and 'dst' zeroed. Switches
1353 * should reject actions which have nonzero bytes in either of these fields.
1355 * NXAST_BUNDLE_LOAD stores the OpenFlow port number of the selected slave in
1356 * dst[ofs:ofs+n_bits]. The format and semantics of 'dst' and 'ofs_nbits' are
1357 * similar to those for the NXAST_REG_LOAD action. */
1358 struct nx_action_bundle
{
1359 ovs_be16 type
; /* OFPAT_VENDOR. */
1360 ovs_be16 len
; /* Length including slaves. */
1361 ovs_be32 vendor
; /* NX_VENDOR_ID. */
1362 ovs_be16 subtype
; /* NXAST_BUNDLE or NXAST_BUNDLE_LOAD. */
1364 /* Slave choice algorithm to apply to hash value. */
1365 ovs_be16 algorithm
; /* One of NX_BD_ALG_*. */
1367 /* What fields to hash and how. */
1368 ovs_be16 fields
; /* One of NX_HASH_FIELDS_*. */
1369 ovs_be16 basis
; /* Universal hash parameter. */
1371 ovs_be32 slave_type
; /* NXM_OF_IN_PORT. */
1372 ovs_be16 n_slaves
; /* Number of slaves. */
1374 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
1375 ovs_be32 dst
; /* Destination. */
1377 uint8_t zero
[4]; /* Reserved. Must be zero. */
1379 OFP_ASSERT(sizeof(struct nx_action_bundle
) == 32);
1382 decode_bundle(bool load
, const struct nx_action_bundle
*nab
,
1383 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
1384 struct ofpbuf
*ofpacts
)
1386 static struct vlog_rate_limit rll
= VLOG_RATE_LIMIT_INIT(1, 5);
1387 struct ofpact_bundle
*bundle
;
1388 uint32_t slave_type
;
1389 size_t slaves_size
, i
;
1392 bundle
= ofpact_put_BUNDLE(ofpacts
);
1394 bundle
->n_slaves
= ntohs(nab
->n_slaves
);
1395 bundle
->basis
= ntohs(nab
->basis
);
1396 bundle
->fields
= ntohs(nab
->fields
);
1397 bundle
->algorithm
= ntohs(nab
->algorithm
);
1398 slave_type
= ntohl(nab
->slave_type
);
1399 slaves_size
= ntohs(nab
->len
) - sizeof *nab
;
1401 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1402 if (!flow_hash_fields_valid(bundle
->fields
)) {
1403 VLOG_WARN_RL(&rll
, "unsupported fields %d", (int) bundle
->fields
);
1404 } else if (bundle
->n_slaves
> BUNDLE_MAX_SLAVES
) {
1405 VLOG_WARN_RL(&rll
, "too many slaves");
1406 } else if (bundle
->algorithm
!= NX_BD_ALG_HRW
1407 && bundle
->algorithm
!= NX_BD_ALG_ACTIVE_BACKUP
) {
1408 VLOG_WARN_RL(&rll
, "unsupported algorithm %d", (int) bundle
->algorithm
);
1409 } else if (slave_type
!= mf_nxm_header(MFF_IN_PORT
)) {
1410 VLOG_WARN_RL(&rll
, "unsupported slave type %"PRIu32
, slave_type
);
1415 if (!is_all_zeros(nab
->zero
, sizeof nab
->zero
)) {
1416 VLOG_WARN_RL(&rll
, "reserved field is nonzero");
1417 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1421 bundle
->dst
.ofs
= nxm_decode_ofs(nab
->ofs_nbits
);
1422 bundle
->dst
.n_bits
= nxm_decode_n_bits(nab
->ofs_nbits
);
1423 error
= mf_vl_mff_mf_from_nxm_header(ntohl(nab
->dst
), vl_mff_map
,
1424 &bundle
->dst
.field
, tlv_bitmap
);
1429 if (bundle
->dst
.n_bits
< 16) {
1430 VLOG_WARN_RL(&rll
, "bundle_load action requires at least 16 bit "
1432 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1435 if (nab
->ofs_nbits
|| nab
->dst
) {
1436 VLOG_WARN_RL(&rll
, "bundle action has nonzero reserved fields");
1437 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1441 if (slaves_size
< bundle
->n_slaves
* sizeof(ovs_be16
)) {
1442 VLOG_WARN_RL(&rll
, "Nicira action %s only has %"PRIuSIZE
" bytes "
1443 "allocated for slaves. %"PRIuSIZE
" bytes are required "
1445 load
? "bundle_load" : "bundle", slaves_size
,
1446 bundle
->n_slaves
* sizeof(ovs_be16
), bundle
->n_slaves
);
1447 error
= OFPERR_OFPBAC_BAD_LEN
;
1449 for (i
= 0; i
< bundle
->n_slaves
; i
++) {
1451 = u16_to_ofp(ntohs(((ovs_be16
*)(nab
+ 1))[i
]));
1452 ofpbuf_put(ofpacts
, &ofp_port
, sizeof ofp_port
);
1453 bundle
= ofpacts
->header
;
1457 ofpact_finish_BUNDLE(ofpacts
, &bundle
);
1459 error
= bundle_check(bundle
, OFPP_MAX
, NULL
);
1465 decode_NXAST_RAW_BUNDLE(const struct nx_action_bundle
*nab
,
1466 enum ofp_version ofp_version OVS_UNUSED
,
1469 return decode_bundle(false, nab
, NULL
, NULL
, out
);
1473 decode_NXAST_RAW_BUNDLE_LOAD(const struct nx_action_bundle
*nab
,
1474 enum ofp_version ofp_version OVS_UNUSED
,
1475 const struct vl_mff_map
*vl_mff_map
,
1476 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
1478 return decode_bundle(true, nab
, vl_mff_map
, tlv_bitmap
, out
);
1482 encode_BUNDLE(const struct ofpact_bundle
*bundle
,
1483 enum ofp_version ofp_version OVS_UNUSED
,
1486 int slaves_len
= ROUND_UP(2 * bundle
->n_slaves
, OFP_ACTION_ALIGN
);
1487 struct nx_action_bundle
*nab
;
1491 nab
= (bundle
->dst
.field
1492 ? put_NXAST_BUNDLE_LOAD(out
)
1493 : put_NXAST_BUNDLE(out
));
1494 nab
->len
= htons(ntohs(nab
->len
) + slaves_len
);
1495 nab
->algorithm
= htons(bundle
->algorithm
);
1496 nab
->fields
= htons(bundle
->fields
);
1497 nab
->basis
= htons(bundle
->basis
);
1498 nab
->slave_type
= htonl(mf_nxm_header(MFF_IN_PORT
));
1499 nab
->n_slaves
= htons(bundle
->n_slaves
);
1500 if (bundle
->dst
.field
) {
1501 nab
->ofs_nbits
= nxm_encode_ofs_nbits(bundle
->dst
.ofs
,
1502 bundle
->dst
.n_bits
);
1503 nab
->dst
= htonl(nxm_header_from_mff(bundle
->dst
.field
));
1506 slaves
= ofpbuf_put_zeros(out
, slaves_len
);
1507 for (i
= 0; i
< bundle
->n_slaves
; i
++) {
1508 slaves
[i
] = htons(ofp_to_u16(bundle
->slaves
[i
]));
1512 static char * OVS_WARN_UNUSED_RESULT
1513 parse_BUNDLE(const char *arg
, const struct ofpact_parse_params
*pp
)
1515 return bundle_parse(arg
, pp
->port_map
, pp
->ofpacts
);
1518 static char * OVS_WARN_UNUSED_RESULT
1519 parse_bundle_load(const char *arg
, const struct ofpact_parse_params
*pp
)
1521 return bundle_parse_load(arg
, pp
->port_map
, pp
->ofpacts
);
1525 format_BUNDLE(const struct ofpact_bundle
*a
,
1526 const struct ofpact_format_params
*fp
)
1528 bundle_format(a
, fp
->port_map
, fp
->s
);
1532 check_BUNDLE(const struct ofpact_bundle
*a
,
1533 const struct ofpact_check_params
*cp
)
1535 return bundle_check(a
, cp
->max_ports
, cp
->match
);
1538 /* Set VLAN actions. */
1541 decode_set_vlan_vid(uint16_t vid
, bool push_vlan_if_needed
, struct ofpbuf
*out
)
1544 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1546 struct ofpact_vlan_vid
*vlan_vid
= ofpact_put_SET_VLAN_VID(out
);
1547 vlan_vid
->vlan_vid
= vid
;
1548 vlan_vid
->push_vlan_if_needed
= push_vlan_if_needed
;
1554 decode_OFPAT_RAW10_SET_VLAN_VID(uint16_t vid
,
1555 enum ofp_version ofp_version OVS_UNUSED
,
1558 return decode_set_vlan_vid(vid
, true, out
);
1562 decode_OFPAT_RAW11_SET_VLAN_VID(uint16_t vid
,
1563 enum ofp_version ofp_version OVS_UNUSED
,
1566 return decode_set_vlan_vid(vid
, false, out
);
1570 encode_SET_VLAN_VID(const struct ofpact_vlan_vid
*vlan_vid
,
1571 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1573 uint16_t vid
= vlan_vid
->vlan_vid
;
1575 /* Push a VLAN tag, if none is present and this form of the action calls
1576 * for such a feature. */
1577 if (ofp_version
> OFP10_VERSION
1578 && vlan_vid
->push_vlan_if_needed
1579 && !vlan_vid
->flow_has_vlan
) {
1580 put_OFPAT11_PUSH_VLAN(out
, htons(ETH_TYPE_VLAN_8021Q
));
1583 if (ofp_version
== OFP10_VERSION
) {
1584 put_OFPAT10_SET_VLAN_VID(out
, vid
);
1585 } else if (ofp_version
== OFP11_VERSION
) {
1586 put_OFPAT11_SET_VLAN_VID(out
, vid
);
1588 put_set_field(out
, ofp_version
, MFF_VLAN_VID
, vid
| OFPVID12_PRESENT
);
1592 static char * OVS_WARN_UNUSED_RESULT
1593 parse_set_vlan_vid(char *arg
, bool push_vlan_if_needed
,
1594 const struct ofpact_parse_params
*pp
)
1596 struct ofpact_vlan_vid
*vlan_vid
;
1600 error
= str_to_u16(arg
, "VLAN VID", &vid
);
1605 if (vid
& ~VLAN_VID_MASK
) {
1606 return xasprintf("%s: not a valid VLAN VID", arg
);
1608 vlan_vid
= ofpact_put_SET_VLAN_VID(pp
->ofpacts
);
1609 vlan_vid
->vlan_vid
= vid
;
1610 vlan_vid
->push_vlan_if_needed
= push_vlan_if_needed
;
1614 static char * OVS_WARN_UNUSED_RESULT
1615 parse_SET_VLAN_VID(char *arg
, const struct ofpact_parse_params
*pp
)
1617 return parse_set_vlan_vid(arg
, false, pp
);
1621 format_SET_VLAN_VID(const struct ofpact_vlan_vid
*a
,
1622 const struct ofpact_format_params
*fp
)
1624 ds_put_format(fp
->s
, "%s%s:%s%"PRIu16
, colors
.param
,
1625 a
->push_vlan_if_needed
? "mod_vlan_vid" : "set_vlan_vid",
1626 colors
.end
, a
->vlan_vid
);
1630 check_SET_VLAN_VID(struct ofpact_vlan_vid
*a
, struct ofpact_check_params
*cp
)
1632 /* Remember if we saw a vlan tag in the flow to aid translating to OpenFlow
1633 * 1.1+ if need be. */
1634 ovs_be16
*tci
= &cp
->match
->flow
.vlans
[0].tci
;
1635 a
->flow_has_vlan
= (*tci
& htons(VLAN_CFI
)) != 0;
1636 if (!a
->flow_has_vlan
&& !a
->push_vlan_if_needed
) {
1637 inconsistent_match(&cp
->usable_protocols
);
1640 /* Temporarily mark that we have a vlan tag. */
1641 *tci
|= htons(VLAN_CFI
);
1646 /* Set PCP actions. */
1649 decode_set_vlan_pcp(uint8_t pcp
, bool push_vlan_if_needed
, struct ofpbuf
*out
)
1652 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1654 struct ofpact_vlan_pcp
*vlan_pcp
= ofpact_put_SET_VLAN_PCP(out
);
1655 vlan_pcp
->vlan_pcp
= pcp
;
1656 vlan_pcp
->push_vlan_if_needed
= push_vlan_if_needed
;
1662 decode_OFPAT_RAW10_SET_VLAN_PCP(uint8_t pcp
,
1663 enum ofp_version ofp_version OVS_UNUSED
,
1666 return decode_set_vlan_pcp(pcp
, true, out
);
1670 decode_OFPAT_RAW11_SET_VLAN_PCP(uint8_t pcp
,
1671 enum ofp_version ofp_version OVS_UNUSED
,
1674 return decode_set_vlan_pcp(pcp
, false, out
);
1678 encode_SET_VLAN_PCP(const struct ofpact_vlan_pcp
*vlan_pcp
,
1679 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1681 uint8_t pcp
= vlan_pcp
->vlan_pcp
;
1683 /* Push a VLAN tag, if none is present and this form of the action calls
1684 * for such a feature. */
1685 if (ofp_version
> OFP10_VERSION
1686 && vlan_pcp
->push_vlan_if_needed
1687 && !vlan_pcp
->flow_has_vlan
) {
1688 put_OFPAT11_PUSH_VLAN(out
, htons(ETH_TYPE_VLAN_8021Q
));
1691 if (ofp_version
== OFP10_VERSION
) {
1692 put_OFPAT10_SET_VLAN_PCP(out
, pcp
);
1693 } else if (ofp_version
== OFP11_VERSION
) {
1694 put_OFPAT11_SET_VLAN_PCP(out
, pcp
);
1696 put_set_field(out
, ofp_version
, MFF_VLAN_PCP
, pcp
);
1700 static char * OVS_WARN_UNUSED_RESULT
1701 parse_set_vlan_pcp(char *arg
, bool push_vlan_if_needed
,
1702 const struct ofpact_parse_params
*pp
)
1704 struct ofpact_vlan_pcp
*vlan_pcp
;
1708 error
= str_to_u8(arg
, "VLAN PCP", &pcp
);
1714 return xasprintf("%s: not a valid VLAN PCP", arg
);
1716 vlan_pcp
= ofpact_put_SET_VLAN_PCP(pp
->ofpacts
);
1717 vlan_pcp
->vlan_pcp
= pcp
;
1718 vlan_pcp
->push_vlan_if_needed
= push_vlan_if_needed
;
1722 static char * OVS_WARN_UNUSED_RESULT
1723 parse_SET_VLAN_PCP(char *arg
, const struct ofpact_parse_params
*pp
)
1725 return parse_set_vlan_pcp(arg
, false, pp
);
1729 format_SET_VLAN_PCP(const struct ofpact_vlan_pcp
*a
,
1730 const struct ofpact_format_params
*fp
)
1732 ds_put_format(fp
->s
, "%s%s:%s%"PRIu8
, colors
.param
,
1733 a
->push_vlan_if_needed
? "mod_vlan_pcp" : "set_vlan_pcp",
1734 colors
.end
, a
->vlan_pcp
);
1738 check_SET_VLAN_PCP(struct ofpact_vlan_pcp
*a
, struct ofpact_check_params
*cp
)
1740 /* Remember if we saw a vlan tag in the flow to aid translating to OpenFlow
1741 * 1.1+ if need be. */
1742 ovs_be16
*tci
= &cp
->match
->flow
.vlans
[0].tci
;
1743 a
->flow_has_vlan
= (*tci
& htons(VLAN_CFI
)) != 0;
1744 if (!a
->flow_has_vlan
&& !a
->push_vlan_if_needed
) {
1745 inconsistent_match(&cp
->usable_protocols
);
1748 /* Temporarily mark that we have a vlan tag. */
1749 *tci
|= htons(VLAN_CFI
);
1754 /* Strip VLAN actions. */
1757 decode_OFPAT_RAW10_STRIP_VLAN(struct ofpbuf
*out
)
1759 ofpact_put_STRIP_VLAN(out
)->ofpact
.raw
= OFPAT_RAW10_STRIP_VLAN
;
1764 decode_OFPAT_RAW11_POP_VLAN(struct ofpbuf
*out
)
1766 ofpact_put_STRIP_VLAN(out
)->ofpact
.raw
= OFPAT_RAW11_POP_VLAN
;
1771 encode_STRIP_VLAN(const struct ofpact_null
*null OVS_UNUSED
,
1772 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1774 if (ofp_version
== OFP10_VERSION
) {
1775 put_OFPAT10_STRIP_VLAN(out
);
1777 put_OFPAT11_POP_VLAN(out
);
1781 static char * OVS_WARN_UNUSED_RESULT
1782 parse_STRIP_VLAN(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
1784 ofpact_put_STRIP_VLAN(pp
->ofpacts
)->ofpact
.raw
= OFPAT_RAW10_STRIP_VLAN
;
1788 static char * OVS_WARN_UNUSED_RESULT
1789 parse_pop_vlan(const struct ofpact_parse_params
*pp
)
1791 ofpact_put_STRIP_VLAN(pp
->ofpacts
)->ofpact
.raw
= OFPAT_RAW11_POP_VLAN
;
1796 format_STRIP_VLAN(const struct ofpact_null
*a
,
1797 const struct ofpact_format_params
*fp
)
1799 ds_put_format(fp
->s
, (a
->ofpact
.raw
== OFPAT_RAW11_POP_VLAN
1801 : "%sstrip_vlan%s"),
1802 colors
.value
, colors
.end
);
1806 check_STRIP_VLAN(const struct ofpact_null
*a OVS_UNUSED
,
1807 struct ofpact_check_params
*cp
)
1809 if (!(cp
->match
->flow
.vlans
[0].tci
& htons(VLAN_CFI
))) {
1810 inconsistent_match(&cp
->usable_protocols
);
1812 flow_pop_vlan(&cp
->match
->flow
, NULL
);
1816 /* Push VLAN action. */
1819 decode_OFPAT_RAW11_PUSH_VLAN(ovs_be16 eth_type
,
1820 enum ofp_version ofp_version OVS_UNUSED
,
1823 struct ofpact_push_vlan
*push_vlan
;
1824 if (!eth_type_vlan(eth_type
)) {
1825 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1827 push_vlan
= ofpact_put_PUSH_VLAN(out
);
1828 push_vlan
->ethertype
= eth_type
;
1833 encode_PUSH_VLAN(const struct ofpact_push_vlan
*push_vlan
,
1834 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1836 if (ofp_version
== OFP10_VERSION
) {
1837 /* PUSH is a side effect of a SET_VLAN_VID/PCP, which should
1838 * follow this action. */
1840 put_OFPAT11_PUSH_VLAN(out
, push_vlan
->ethertype
);
1844 static char * OVS_WARN_UNUSED_RESULT
1845 parse_PUSH_VLAN(char *arg
, const struct ofpact_parse_params
*pp
)
1847 struct ofpact_push_vlan
*push_vlan
;
1851 *pp
->usable_protocols
&= OFPUTIL_P_OF11_UP
;
1852 error
= str_to_u16(arg
, "ethertype", ðertype
);
1857 if (!eth_type_vlan(htons(ethertype
))) {
1858 return xasprintf("%s: not a valid VLAN ethertype", arg
);
1860 push_vlan
= ofpact_put_PUSH_VLAN(pp
->ofpacts
);
1861 push_vlan
->ethertype
= htons(ethertype
);
1866 format_PUSH_VLAN(const struct ofpact_push_vlan
*push_vlan
,
1867 const struct ofpact_format_params
*fp
)
1869 ds_put_format(fp
->s
, "%spush_vlan:%s%#"PRIx16
,
1870 colors
.param
, colors
.end
, ntohs(push_vlan
->ethertype
));
1874 check_PUSH_VLAN(const struct ofpact_push_vlan
*a OVS_UNUSED
,
1875 struct ofpact_check_params
*cp
)
1877 struct flow
*flow
= &cp
->match
->flow
;
1878 if (flow
->vlans
[FLOW_MAX_VLAN_HEADERS
- 1].tci
& htons(VLAN_CFI
)) {
1879 /* Support maximum (FLOW_MAX_VLAN_HEADERS) VLAN headers. */
1880 return OFPERR_OFPBAC_BAD_TAG
;
1882 /* Temporary mark that we have a vlan tag. */
1883 flow_push_vlan_uninit(flow
, NULL
);
1884 flow
->vlans
[0].tci
|= htons(VLAN_CFI
);
1888 /* Action structure for OFPAT10_SET_DL_SRC/DST and OFPAT11_SET_DL_SRC/DST. */
1889 struct ofp_action_dl_addr
{
1890 ovs_be16 type
; /* Type. */
1891 ovs_be16 len
; /* Length is 16. */
1892 struct eth_addr dl_addr
; /* Ethernet address. */
1895 OFP_ASSERT(sizeof(struct ofp_action_dl_addr
) == 16);
1898 decode_OFPAT_RAW_SET_DL_SRC(const struct ofp_action_dl_addr
*a
,
1899 enum ofp_version ofp_version OVS_UNUSED
,
1902 ofpact_put_SET_ETH_SRC(out
)->mac
= a
->dl_addr
;
1907 decode_OFPAT_RAW_SET_DL_DST(const struct ofp_action_dl_addr
*a
,
1908 enum ofp_version ofp_version OVS_UNUSED
,
1911 ofpact_put_SET_ETH_DST(out
)->mac
= a
->dl_addr
;
1916 encode_SET_ETH_addr(const struct ofpact_mac
*mac
, enum ofp_version ofp_version
,
1917 enum ofp_raw_action_type raw
, enum mf_field_id field
,
1920 if (ofp_version
< OFP12_VERSION
) {
1921 struct ofp_action_dl_addr
*oada
;
1923 oada
= ofpact_put_raw(out
, ofp_version
, raw
, 0);
1924 oada
->dl_addr
= mac
->mac
;
1926 put_set_field(out
, ofp_version
, field
, eth_addr_to_uint64(mac
->mac
));
1931 encode_SET_ETH_SRC(const struct ofpact_mac
*mac
, enum ofp_version ofp_version
,
1934 encode_SET_ETH_addr(mac
, ofp_version
, OFPAT_RAW_SET_DL_SRC
, MFF_ETH_SRC
,
1940 encode_SET_ETH_DST(const struct ofpact_mac
*mac
,
1941 enum ofp_version ofp_version
,
1944 encode_SET_ETH_addr(mac
, ofp_version
, OFPAT_RAW_SET_DL_DST
, MFF_ETH_DST
,
1949 static char * OVS_WARN_UNUSED_RESULT
1950 parse_SET_ETH_SRC(char *arg
, const struct ofpact_parse_params
*pp
)
1952 return str_to_mac(arg
, &ofpact_put_SET_ETH_SRC(pp
->ofpacts
)->mac
);
1955 static char * OVS_WARN_UNUSED_RESULT
1956 parse_SET_ETH_DST(char *arg
, const struct ofpact_parse_params
*pp
)
1958 return str_to_mac(arg
, &ofpact_put_SET_ETH_DST(pp
->ofpacts
)->mac
);
1962 format_SET_ETH_SRC(const struct ofpact_mac
*a
,
1963 const struct ofpact_format_params
*fp
)
1965 ds_put_format(fp
->s
, "%smod_dl_src:%s"ETH_ADDR_FMT
,
1966 colors
.param
, colors
.end
, ETH_ADDR_ARGS(a
->mac
));
1970 format_SET_ETH_DST(const struct ofpact_mac
*a
,
1971 const struct ofpact_format_params
*fp
)
1973 ds_put_format(fp
->s
, "%smod_dl_dst:%s"ETH_ADDR_FMT
,
1974 colors
.param
, colors
.end
, ETH_ADDR_ARGS(a
->mac
));
1978 check_SET_ETH_SRC(const struct ofpact_mac
*a OVS_UNUSED
,
1979 const struct ofpact_check_params
*cp OVS_UNUSED
)
1985 check_SET_ETH_DST(const struct ofpact_mac
*a OVS_UNUSED
,
1986 const struct ofpact_check_params
*cp OVS_UNUSED
)
1991 /* Set IPv4 address actions. */
1994 decode_OFPAT_RAW_SET_NW_SRC(ovs_be32 ipv4
,
1995 enum ofp_version ofp_version OVS_UNUSED
,
1998 ofpact_put_SET_IPV4_SRC(out
)->ipv4
= ipv4
;
2003 decode_OFPAT_RAW_SET_NW_DST(ovs_be32 ipv4
,
2004 enum ofp_version ofp_version OVS_UNUSED
,
2007 ofpact_put_SET_IPV4_DST(out
)->ipv4
= ipv4
;
2012 encode_SET_IPV4_addr(const struct ofpact_ipv4
*ipv4
,
2013 enum ofp_version ofp_version
,
2014 enum ofp_raw_action_type raw
, enum mf_field_id field
,
2017 ovs_be32 addr
= ipv4
->ipv4
;
2018 if (ofp_version
< OFP12_VERSION
) {
2019 ofpact_put_raw(out
, ofp_version
, raw
, ntohl(addr
));
2021 put_set_field(out
, ofp_version
, field
, ntohl(addr
));
2026 encode_SET_IPV4_SRC(const struct ofpact_ipv4
*ipv4
,
2027 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2029 encode_SET_IPV4_addr(ipv4
, ofp_version
, OFPAT_RAW_SET_NW_SRC
, MFF_IPV4_SRC
,
2034 encode_SET_IPV4_DST(const struct ofpact_ipv4
*ipv4
,
2035 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2037 encode_SET_IPV4_addr(ipv4
, ofp_version
, OFPAT_RAW_SET_NW_DST
, MFF_IPV4_DST
,
2041 static char * OVS_WARN_UNUSED_RESULT
2042 parse_SET_IPV4_SRC(char *arg
, const struct ofpact_parse_params
*pp
)
2044 return str_to_ip(arg
, &ofpact_put_SET_IPV4_SRC(pp
->ofpacts
)->ipv4
);
2047 static char * OVS_WARN_UNUSED_RESULT
2048 parse_SET_IPV4_DST(char *arg
, const struct ofpact_parse_params
*pp
)
2050 return str_to_ip(arg
, &ofpact_put_SET_IPV4_DST(pp
->ofpacts
)->ipv4
);
2054 format_SET_IPV4_SRC(const struct ofpact_ipv4
*a
,
2055 const struct ofpact_format_params
*fp
)
2057 ds_put_format(fp
->s
, "%smod_nw_src:%s"IP_FMT
,
2058 colors
.param
, colors
.end
, IP_ARGS(a
->ipv4
));
2062 format_SET_IPV4_DST(const struct ofpact_ipv4
*a
,
2063 const struct ofpact_format_params
*fp
)
2065 ds_put_format(fp
->s
, "%smod_nw_dst:%s"IP_FMT
,
2066 colors
.param
, colors
.end
, IP_ARGS(a
->ipv4
));
2070 check_set_ipv4(struct ofpact_check_params
*cp
)
2072 ovs_be16 dl_type
= get_dl_type(&cp
->match
->flow
);
2073 if (dl_type
!= htons(ETH_TYPE_IP
)) {
2074 inconsistent_match(&cp
->usable_protocols
);
2080 check_SET_IPV4_SRC(const struct ofpact_ipv4
*a OVS_UNUSED
,
2081 struct ofpact_check_params
*cp
)
2083 return check_set_ipv4(cp
);
2087 check_SET_IPV4_DST(const struct ofpact_ipv4
*a OVS_UNUSED
,
2088 struct ofpact_check_params
*cp
)
2090 return check_set_ipv4(cp
);
2093 /* Set IPv4/v6 TOS actions. */
2096 decode_OFPAT_RAW_SET_NW_TOS(uint8_t dscp
,
2097 enum ofp_version ofp_version OVS_UNUSED
,
2100 if (dscp
& ~IP_DSCP_MASK
) {
2101 return OFPERR_OFPBAC_BAD_ARGUMENT
;
2103 ofpact_put_SET_IP_DSCP(out
)->dscp
= dscp
;
2109 encode_SET_IP_DSCP(const struct ofpact_dscp
*dscp
,
2110 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2112 if (ofp_version
< OFP12_VERSION
) {
2113 put_OFPAT_SET_NW_TOS(out
, ofp_version
, dscp
->dscp
);
2115 put_set_field(out
, ofp_version
, MFF_IP_DSCP_SHIFTED
, dscp
->dscp
>> 2);
2119 static char * OVS_WARN_UNUSED_RESULT
2120 parse_SET_IP_DSCP(char *arg
, const struct ofpact_parse_params
*pp
)
2126 error
= str_to_u8(arg
, "TOS", &tos
);
2131 if (tos
& ~IP_DSCP_MASK
) {
2132 return xasprintf("%s: not a valid TOS", arg
);
2134 ofpact_put_SET_IP_DSCP(pp
->ofpacts
)->dscp
= tos
;
2139 format_SET_IP_DSCP(const struct ofpact_dscp
*a
,
2140 const struct ofpact_format_params
*fp
)
2142 ds_put_format(fp
->s
, "%smod_nw_tos:%s%d",
2143 colors
.param
, colors
.end
, a
->dscp
);
2147 check_set_ip(struct ofpact_check_params
*cp
)
2149 if (!is_ip_any(&cp
->match
->flow
)) {
2150 inconsistent_match(&cp
->usable_protocols
);
2156 check_SET_IP_DSCP(const struct ofpact_dscp
*a OVS_UNUSED
,
2157 struct ofpact_check_params
*cp
)
2159 return check_set_ip(cp
);
2162 /* Set IPv4/v6 ECN actions. */
2165 decode_OFPAT_RAW11_SET_NW_ECN(uint8_t ecn
,
2166 enum ofp_version ofp_version OVS_UNUSED
,
2169 if (ecn
& ~IP_ECN_MASK
) {
2170 return OFPERR_OFPBAC_BAD_ARGUMENT
;
2172 ofpact_put_SET_IP_ECN(out
)->ecn
= ecn
;
2178 encode_SET_IP_ECN(const struct ofpact_ecn
*ip_ecn
,
2179 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2181 uint8_t ecn
= ip_ecn
->ecn
;
2182 if (ofp_version
== OFP10_VERSION
) {
2183 struct mf_subfield dst
= { .field
= mf_from_id(MFF_IP_ECN
),
2184 .ofs
= 0, .n_bits
= 2 };
2185 put_reg_load(out
, &dst
, ecn
);
2186 } else if (ofp_version
== OFP11_VERSION
) {
2187 put_OFPAT11_SET_NW_ECN(out
, ecn
);
2189 put_set_field(out
, ofp_version
, MFF_IP_ECN
, ecn
);
2193 static char * OVS_WARN_UNUSED_RESULT
2194 parse_SET_IP_ECN(char *arg
, const struct ofpact_parse_params
*pp
)
2199 error
= str_to_u8(arg
, "ECN", &ecn
);
2204 if (ecn
& ~IP_ECN_MASK
) {
2205 return xasprintf("%s: not a valid ECN", arg
);
2207 ofpact_put_SET_IP_ECN(pp
->ofpacts
)->ecn
= ecn
;
2212 format_SET_IP_ECN(const struct ofpact_ecn
*a
,
2213 const struct ofpact_format_params
*fp
)
2215 ds_put_format(fp
->s
, "%smod_nw_ecn:%s%d",
2216 colors
.param
, colors
.end
, a
->ecn
);
2220 check_SET_IP_ECN(const struct ofpact_ecn
*a OVS_UNUSED
,
2221 struct ofpact_check_params
*cp
)
2223 return check_set_ip(cp
);
2226 /* Set IPv4/v6 TTL actions. */
2229 decode_OFPAT_RAW11_SET_NW_TTL(uint8_t ttl
,
2230 enum ofp_version ofp_version OVS_UNUSED
,
2233 ofpact_put_SET_IP_TTL(out
)->ttl
= ttl
;
2238 encode_SET_IP_TTL(const struct ofpact_ip_ttl
*ttl
,
2239 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2241 if (ofp_version
>= OFP11_VERSION
) {
2242 put_OFPAT11_SET_NW_TTL(out
, ttl
->ttl
);
2244 struct mf_subfield dst
= { .field
= mf_from_id(MFF_IP_TTL
),
2245 .ofs
= 0, .n_bits
= 8 };
2246 put_reg_load(out
, &dst
, ttl
->ttl
);
2250 static char * OVS_WARN_UNUSED_RESULT
2251 parse_SET_IP_TTL(char *arg
, const struct ofpact_parse_params
*pp
)
2257 error
= str_to_u8(arg
, "TTL", &ttl
);
2262 ofpact_put_SET_IP_TTL(pp
->ofpacts
)->ttl
= ttl
;
2267 format_SET_IP_TTL(const struct ofpact_ip_ttl
*a
,
2268 const struct ofpact_format_params
*fp
)
2270 ds_put_format(fp
->s
, "%smod_nw_ttl:%s%d",
2271 colors
.param
, colors
.end
, a
->ttl
);
2275 check_SET_IP_TTL(const struct ofpact_ip_ttl
*a OVS_UNUSED
,
2276 struct ofpact_check_params
*cp
)
2278 return check_set_ip(cp
);
2281 /* Set TCP/UDP/SCTP port actions. */
2284 decode_OFPAT_RAW_SET_TP_SRC(ovs_be16 port
,
2285 enum ofp_version ofp_version OVS_UNUSED
,
2288 ofpact_put_SET_L4_SRC_PORT(out
)->port
= ntohs(port
);
2293 decode_OFPAT_RAW_SET_TP_DST(ovs_be16 port
,
2294 enum ofp_version ofp_version OVS_UNUSED
,
2297 ofpact_put_SET_L4_DST_PORT(out
)->port
= ntohs(port
);
2302 encode_SET_L4_port(const struct ofpact_l4_port
*l4_port
,
2303 enum ofp_version ofp_version
, enum ofp_raw_action_type raw
,
2304 enum mf_field_id field
, struct ofpbuf
*out
)
2306 uint16_t port
= l4_port
->port
;
2308 if (ofp_version
>= OFP12_VERSION
&& field
!= MFF_N_IDS
) {
2309 put_set_field(out
, ofp_version
, field
, port
);
2311 ofpact_put_raw(out
, ofp_version
, raw
, port
);
2316 encode_SET_L4_SRC_PORT(const struct ofpact_l4_port
*l4_port
,
2317 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2319 uint8_t proto
= l4_port
->flow_ip_proto
;
2320 enum mf_field_id field
= (proto
== IPPROTO_TCP
? MFF_TCP_SRC
2321 : proto
== IPPROTO_UDP
? MFF_UDP_SRC
2322 : proto
== IPPROTO_SCTP
? MFF_SCTP_SRC
2325 encode_SET_L4_port(l4_port
, ofp_version
, OFPAT_RAW_SET_TP_SRC
, field
, out
);
2329 encode_SET_L4_DST_PORT(const struct ofpact_l4_port
*l4_port
,
2330 enum ofp_version ofp_version
,
2333 uint8_t proto
= l4_port
->flow_ip_proto
;
2334 enum mf_field_id field
= (proto
== IPPROTO_TCP
? MFF_TCP_DST
2335 : proto
== IPPROTO_UDP
? MFF_UDP_DST
2336 : proto
== IPPROTO_SCTP
? MFF_SCTP_DST
2339 encode_SET_L4_port(l4_port
, ofp_version
, OFPAT_RAW_SET_TP_DST
, field
, out
);
2342 static char * OVS_WARN_UNUSED_RESULT
2343 parse_SET_L4_SRC_PORT(char *arg
, const struct ofpact_parse_params
*pp
)
2345 return str_to_u16(arg
, "source port",
2346 &ofpact_put_SET_L4_SRC_PORT(pp
->ofpacts
)->port
);
2349 static char * OVS_WARN_UNUSED_RESULT
2350 parse_SET_L4_DST_PORT(char *arg
, const struct ofpact_parse_params
*pp
)
2352 return str_to_u16(arg
, "destination port",
2353 &ofpact_put_SET_L4_DST_PORT(pp
->ofpacts
)->port
);
2357 format_SET_L4_SRC_PORT(const struct ofpact_l4_port
*a
,
2358 const struct ofpact_format_params
*fp
)
2360 ds_put_format(fp
->s
, "%smod_tp_src:%s%d",
2361 colors
.param
, colors
.end
, a
->port
);
2365 format_SET_L4_DST_PORT(const struct ofpact_l4_port
*a
,
2366 const struct ofpact_format_params
*fp
)
2368 ds_put_format(fp
->s
, "%smod_tp_dst:%s%d",
2369 colors
.param
, colors
.end
, a
->port
);
2373 check_set_l4_port(struct ofpact_l4_port
*a
, struct ofpact_check_params
*cp
)
2375 const struct flow
*flow
= &cp
->match
->flow
;
2376 if (!is_ip_any(flow
)
2377 || flow
->nw_frag
& FLOW_NW_FRAG_LATER
2378 || (flow
->nw_proto
!= IPPROTO_TCP
&&
2379 flow
->nw_proto
!= IPPROTO_UDP
&&
2380 flow
->nw_proto
!= IPPROTO_SCTP
)) {
2381 inconsistent_match(&cp
->usable_protocols
);
2384 /* Note the transport protocol in use, to allow this action to be converted
2385 * to an OF1.2 set_field action later if necessary. */
2386 a
->flow_ip_proto
= flow
->nw_proto
;
2392 check_SET_L4_SRC_PORT(struct ofpact_l4_port
*a
, struct ofpact_check_params
*cp
)
2394 return check_set_l4_port(a
, cp
);
2398 check_SET_L4_DST_PORT(struct ofpact_l4_port
*a
, struct ofpact_check_params
*cp
)
2400 return check_set_l4_port(a
, cp
);
2403 /* Action structure for OFPAT_COPY_FIELD. */
2404 struct ofp15_action_copy_field
{
2405 ovs_be16 type
; /* OFPAT_COPY_FIELD. */
2406 ovs_be16 len
; /* Length is padded to 64 bits. */
2407 ovs_be16 n_bits
; /* Number of bits to copy. */
2408 ovs_be16 src_offset
; /* Starting bit offset in source. */
2409 ovs_be16 dst_offset
; /* Starting bit offset in destination. */
2412 * - OXM header for source field.
2413 * - OXM header for destination field.
2414 * - Padding with 0-bytes to a multiple of 8 bytes.
2415 * The "pad2" member is the beginning of the above. */
2418 OFP_ASSERT(sizeof(struct ofp15_action_copy_field
) == 16);
2420 /* Action structure for OpenFlow 1.3 extension copy-field action.. */
2421 struct onf_action_copy_field
{
2422 ovs_be16 type
; /* OFPAT_EXPERIMENTER. */
2423 ovs_be16 len
; /* Length is padded to 64 bits. */
2424 ovs_be32 experimenter
; /* ONF_VENDOR_ID. */
2425 ovs_be16 exp_type
; /* 3200. */
2426 uint8_t pad
[2]; /* Not used. */
2427 ovs_be16 n_bits
; /* Number of bits to copy. */
2428 ovs_be16 src_offset
; /* Starting bit offset in source. */
2429 ovs_be16 dst_offset
; /* Starting bit offset in destination. */
2430 uint8_t pad2
[2]; /* Not used. */
2432 * - OXM header for source field.
2433 * - OXM header for destination field.
2434 * - Padding with 0-bytes (either 0 or 4 of them) to a multiple of 8 bytes.
2435 * The "pad3" member is the beginning of the above. */
2436 uint8_t pad3
[4]; /* Not used. */
2438 OFP_ASSERT(sizeof(struct onf_action_copy_field
) == 24);
2440 /* Action structure for NXAST_REG_MOVE.
2442 * Copies src[src_ofs:src_ofs+n_bits] to dst[dst_ofs:dst_ofs+n_bits], where
2443 * a[b:c] denotes the bits within 'a' numbered 'b' through 'c' (not including
2444 * bit 'c'). Bit numbering starts at 0 for the least-significant bit, 1 for
2445 * the next most significant bit, and so on.
2447 * 'src' and 'dst' are nxm_header values with nxm_hasmask=0. (It doesn't make
2448 * sense to use nxm_hasmask=1 because the action does not do any kind of
2449 * matching; it uses the actual value of a field.)
2451 * The following nxm_header values are potentially acceptable as 'src':
2466 * - NXM_OF_ICMP_TYPE
2467 * - NXM_OF_ICMP_CODE
2474 * - NXM_NX_ICMPV6_TYPE
2475 * - NXM_NX_ICMPV6_CODE
2478 * - NXM_NX_REG(idx) for idx in the switch's accepted range.
2480 * - NXM_NX_TUN_IPV4_SRC
2481 * - NXM_NX_TUN_IPV4_DST
2483 * The following nxm_header values are potentially acceptable as 'dst':
2494 * - NXM_OF_ICMP_TYPE
2495 * - NXM_OF_ICMP_CODE
2496 * - NXM_NX_ICMPV6_TYPE
2497 * - NXM_NX_ICMPV6_CODE
2503 * Modifying any of the above fields changes the corresponding packet
2508 * - NXM_NX_REG(idx) for idx in the switch's accepted range.
2512 * - NXM_OF_VLAN_TCI. Modifying this field's value has side effects on the
2513 * packet's 802.1Q header. Setting a value with CFI=0 removes the 802.1Q
2514 * header (if any), ignoring the other bits. Setting a value with CFI=1
2515 * adds or modifies the 802.1Q header appropriately, setting the TCI field
2516 * to the field's new value (with the CFI bit masked out).
2518 * - NXM_NX_TUN_ID, NXM_NX_TUN_IPV4_SRC, NXM_NX_TUN_IPV4_DST. Modifying
2519 * any of these values modifies the corresponding tunnel header field used
2520 * for the packet's next tunnel encapsulation, if allowed by the
2521 * configuration of the output tunnel port.
2523 * A given nxm_header value may be used as 'src' or 'dst' only on a flow whose
2524 * nx_match satisfies its prerequisites. For example, NXM_OF_IP_TOS may be
2525 * used only if the flow's nx_match includes an nxm_entry that specifies
2526 * nxm_type=NXM_OF_ETH_TYPE, nxm_hasmask=0, and nxm_value=0x0800.
2528 * The switch will reject actions for which src_ofs+n_bits is greater than the
2529 * width of 'src' or dst_ofs+n_bits is greater than the width of 'dst' with
2530 * error type OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
2532 * This action behaves properly when 'src' overlaps with 'dst', that is, it
2533 * behaves as if 'src' were copied out to a temporary buffer, then the
2534 * temporary buffer copied to 'dst'.
2536 struct nx_action_reg_move
{
2537 ovs_be16 type
; /* OFPAT_VENDOR. */
2538 ovs_be16 len
; /* Length is 24. */
2539 ovs_be32 vendor
; /* NX_VENDOR_ID. */
2540 ovs_be16 subtype
; /* NXAST_REG_MOVE. */
2541 ovs_be16 n_bits
; /* Number of bits. */
2542 ovs_be16 src_ofs
; /* Starting bit offset in source. */
2543 ovs_be16 dst_ofs
; /* Starting bit offset in destination. */
2545 * - OXM/NXM header for source field (4 or 8 bytes).
2546 * - OXM/NXM header for destination field (4 or 8 bytes).
2547 * - Padding with 0-bytes to a multiple of 8 bytes, if necessary. */
2549 OFP_ASSERT(sizeof(struct nx_action_reg_move
) == 16);
2552 decode_copy_field__(ovs_be16 src_offset
, ovs_be16 dst_offset
, ovs_be16 n_bits
,
2553 const void *action
, ovs_be16 action_len
, size_t oxm_offset
,
2554 const struct vl_mff_map
*vl_mff_map
,
2555 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2557 struct ofpact_reg_move
*move
= ofpact_put_REG_MOVE(ofpacts
);
2560 move
->ofpact
.raw
= ONFACT_RAW13_COPY_FIELD
;
2561 move
->src
.ofs
= ntohs(src_offset
);
2562 move
->src
.n_bits
= ntohs(n_bits
);
2563 move
->dst
.ofs
= ntohs(dst_offset
);
2564 move
->dst
.n_bits
= ntohs(n_bits
);
2566 struct ofpbuf b
= ofpbuf_const_initializer(action
, ntohs(action_len
));
2567 ofpbuf_pull(&b
, oxm_offset
);
2569 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->src
.field
, NULL
,
2574 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->dst
.field
, NULL
,
2580 if (!is_all_zeros(b
.data
, b
.size
)) {
2581 return OFPERR_NXBRC_MUST_BE_ZERO
;
2584 return nxm_reg_move_check(move
, NULL
);
2588 decode_OFPAT_RAW15_COPY_FIELD(const struct ofp15_action_copy_field
*oacf
,
2589 enum ofp_version ofp_version OVS_UNUSED
,
2590 const struct vl_mff_map
*vl_mff_map
,
2591 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2593 return decode_copy_field__(oacf
->src_offset
, oacf
->dst_offset
,
2594 oacf
->n_bits
, oacf
, oacf
->len
,
2595 OBJECT_OFFSETOF(oacf
, pad2
), vl_mff_map
,
2596 tlv_bitmap
, ofpacts
);
2600 decode_ONFACT_RAW13_COPY_FIELD(const struct onf_action_copy_field
*oacf
,
2601 enum ofp_version ofp_version OVS_UNUSED
,
2602 const struct vl_mff_map
*vl_mff_map
,
2603 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2605 return decode_copy_field__(oacf
->src_offset
, oacf
->dst_offset
,
2606 oacf
->n_bits
, oacf
, oacf
->len
,
2607 OBJECT_OFFSETOF(oacf
, pad3
), vl_mff_map
,
2608 tlv_bitmap
, ofpacts
);
2612 decode_NXAST_RAW_REG_MOVE(const struct nx_action_reg_move
*narm
,
2613 enum ofp_version ofp_version OVS_UNUSED
,
2614 const struct vl_mff_map
*vl_mff_map
,
2615 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2617 struct ofpact_reg_move
*move
= ofpact_put_REG_MOVE(ofpacts
);
2620 move
->ofpact
.raw
= NXAST_RAW_REG_MOVE
;
2621 move
->src
.ofs
= ntohs(narm
->src_ofs
);
2622 move
->src
.n_bits
= ntohs(narm
->n_bits
);
2623 move
->dst
.ofs
= ntohs(narm
->dst_ofs
);
2624 move
->dst
.n_bits
= ntohs(narm
->n_bits
);
2626 struct ofpbuf b
= ofpbuf_const_initializer(narm
, ntohs(narm
->len
));
2627 ofpbuf_pull(&b
, sizeof *narm
);
2629 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->src
.field
, NULL
,
2635 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->dst
.field
, NULL
,
2641 if (!is_all_zeros(b
.data
, b
.size
)) {
2642 return OFPERR_NXBRC_MUST_BE_ZERO
;
2645 return nxm_reg_move_check(move
, NULL
);
2649 encode_REG_MOVE(const struct ofpact_reg_move
*move
,
2650 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2652 /* For OpenFlow 1.3, the choice of ONFACT_RAW13_COPY_FIELD versus
2653 * NXAST_RAW_REG_MOVE is somewhat difficult. Neither one is guaranteed to
2654 * be supported by every OpenFlow 1.3 implementation. It would be ideal to
2655 * probe for support. Until we have that ability, we currently prefer
2656 * NXAST_RAW_REG_MOVE for backward compatibility with older Open vSwitch
2658 size_t start_ofs
= out
->size
;
2659 if (ofp_version
>= OFP15_VERSION
) {
2660 struct ofp15_action_copy_field
*copy
= put_OFPAT15_COPY_FIELD(out
);
2661 copy
->n_bits
= htons(move
->dst
.n_bits
);
2662 copy
->src_offset
= htons(move
->src
.ofs
);
2663 copy
->dst_offset
= htons(move
->dst
.ofs
);
2664 out
->size
= out
->size
- sizeof copy
->pad2
;
2665 nx_put_mff_header(out
, move
->src
.field
, ofp_version
, false);
2666 nx_put_mff_header(out
, move
->dst
.field
, ofp_version
, false);
2667 } else if (ofp_version
== OFP13_VERSION
2668 && move
->ofpact
.raw
== ONFACT_RAW13_COPY_FIELD
) {
2669 struct onf_action_copy_field
*copy
= put_ONFACT13_COPY_FIELD(out
);
2670 copy
->n_bits
= htons(move
->dst
.n_bits
);
2671 copy
->src_offset
= htons(move
->src
.ofs
);
2672 copy
->dst_offset
= htons(move
->dst
.ofs
);
2673 out
->size
= out
->size
- sizeof copy
->pad3
;
2674 nx_put_mff_header(out
, move
->src
.field
, ofp_version
, false);
2675 nx_put_mff_header(out
, move
->dst
.field
, ofp_version
, false);
2677 struct nx_action_reg_move
*narm
= put_NXAST_REG_MOVE(out
);
2678 narm
->n_bits
= htons(move
->dst
.n_bits
);
2679 narm
->src_ofs
= htons(move
->src
.ofs
);
2680 narm
->dst_ofs
= htons(move
->dst
.ofs
);
2681 nx_put_mff_header(out
, move
->src
.field
, 0, false);
2682 nx_put_mff_header(out
, move
->dst
.field
, 0, false);
2684 pad_ofpat(out
, start_ofs
);
2687 static char * OVS_WARN_UNUSED_RESULT
2688 parse_REG_MOVE(const char *arg
, const struct ofpact_parse_params
*pp
)
2690 struct ofpact_reg_move
*move
= ofpact_put_REG_MOVE(pp
->ofpacts
);
2691 return nxm_parse_reg_move(move
, arg
);
2695 format_REG_MOVE(const struct ofpact_reg_move
*a
,
2696 const struct ofpact_format_params
*fp
)
2698 nxm_format_reg_move(a
, fp
->s
);
2702 check_REG_MOVE(const struct ofpact_reg_move
*a
,
2703 const struct ofpact_check_params
*cp
)
2705 return nxm_reg_move_check(a
, cp
->match
);
2708 /* Action structure for OFPAT12_SET_FIELD. */
2709 struct ofp12_action_set_field
{
2710 ovs_be16 type
; /* OFPAT12_SET_FIELD. */
2711 ovs_be16 len
; /* Length is padded to 64 bits. */
2714 * - An OXM header, value, and (in OpenFlow 1.5+) optionally a mask.
2715 * - Enough 0-bytes to pad out to a multiple of 64 bits.
2717 * The "pad" member is the beginning of the above. */
2720 OFP_ASSERT(sizeof(struct ofp12_action_set_field
) == 8);
2722 /* Action structure for NXAST_REG_LOAD.
2724 * Copies value[0:n_bits] to dst[ofs:ofs+n_bits], where a[b:c] denotes the bits
2725 * within 'a' numbered 'b' through 'c' (not including bit 'c'). Bit numbering
2726 * starts at 0 for the least-significant bit, 1 for the next most significant
2729 * 'dst' is an nxm_header with nxm_hasmask=0. See the documentation for
2730 * NXAST_REG_MOVE, above, for the permitted fields and for the side effects of
2733 * The 'ofs' and 'n_bits' fields are combined into a single 'ofs_nbits' field
2734 * to avoid enlarging the structure by another 8 bytes. To allow 'n_bits' to
2735 * take a value between 1 and 64 (inclusive) while taking up only 6 bits, it is
2736 * also stored as one less than its true value:
2739 * +------------------------------+------------------+
2740 * | ofs | n_bits - 1 |
2741 * +------------------------------+------------------+
2743 * The switch will reject actions for which ofs+n_bits is greater than the
2744 * width of 'dst', or in which any bits in 'value' with value 2**n_bits or
2745 * greater are set to 1, with error type OFPET_BAD_ACTION, code
2746 * OFPBAC_BAD_ARGUMENT.
2748 struct nx_action_reg_load
{
2749 ovs_be16 type
; /* OFPAT_VENDOR. */
2750 ovs_be16 len
; /* Length is 24. */
2751 ovs_be32 vendor
; /* NX_VENDOR_ID. */
2752 ovs_be16 subtype
; /* NXAST_REG_LOAD. */
2753 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
2754 ovs_be32 dst
; /* Destination register. */
2755 ovs_be64 value
; /* Immediate value. */
2757 OFP_ASSERT(sizeof(struct nx_action_reg_load
) == 24);
2759 /* The NXAST_REG_LOAD2 action structure is "struct ext_action_header",
2762 * - An NXM/OXM header, value, and optionally a mask.
2763 * - Enough 0-bytes to pad out to a multiple of 64 bits.
2765 * The "pad" member is the beginning of the above. */
2768 decode_ofpat_set_field(const struct ofp12_action_set_field
*oasf
,
2769 bool may_mask
, const struct vl_mff_map
*vl_mff_map
,
2770 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2772 struct ofpbuf b
= ofpbuf_const_initializer(oasf
, ntohs(oasf
->len
));
2773 ofpbuf_pull(&b
, OBJECT_OFFSETOF(oasf
, pad
));
2775 union mf_value value
, mask
;
2776 const struct mf_field
*field
;
2778 error
= mf_vl_mff_nx_pull_entry(&b
, vl_mff_map
, &field
, &value
,
2779 may_mask
? &mask
: NULL
, tlv_bitmap
);
2781 return (error
== OFPERR_OFPBMC_BAD_MASK
2782 ? OFPERR_OFPBAC_BAD_SET_MASK
2787 memset(&mask
, 0xff, field
->n_bytes
);
2790 if (!is_all_zeros(b
.data
, b
.size
)) {
2791 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2794 /* OpenFlow says specifically that one may not set OXM_OF_IN_PORT via
2796 if (field
->id
== MFF_IN_PORT_OXM
) {
2797 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2800 /* oxm_length is now validated to be compatible with mf_value. */
2801 if (!field
->writable
) {
2802 VLOG_WARN_RL(&rl
, "destination field %s is not writable",
2804 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2807 /* The value must be valid for match. OpenFlow 1.5 also says,
2808 * "In an OXM_OF_VLAN_VID set-field action, the OFPVID_PRESENT bit must be
2809 * a 1-bit in oxm_value and in oxm_mask." */
2810 if (!mf_is_value_valid(field
, &value
)
2811 || (field
->id
== MFF_VLAN_VID
2812 && (!(mask
.be16
& htons(OFPVID12_PRESENT
))
2813 || !(value
.be16
& htons(OFPVID12_PRESENT
))))) {
2814 struct ds ds
= DS_EMPTY_INITIALIZER
;
2815 mf_format(field
, &value
, NULL
, NULL
, &ds
);
2816 VLOG_WARN_RL(&rl
, "Invalid value for set field %s: %s",
2817 field
->name
, ds_cstr(&ds
));
2820 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2823 ofpact_put_set_field(ofpacts
, field
, &value
, &mask
);
2828 decode_OFPAT_RAW12_SET_FIELD(const struct ofp12_action_set_field
*oasf
,
2829 enum ofp_version ofp_version OVS_UNUSED
,
2830 const struct vl_mff_map
*vl_mff_map
,
2831 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2833 return decode_ofpat_set_field(oasf
, false, vl_mff_map
, tlv_bitmap
,
2838 decode_OFPAT_RAW15_SET_FIELD(const struct ofp12_action_set_field
*oasf
,
2839 enum ofp_version ofp_version OVS_UNUSED
,
2840 const struct vl_mff_map
*vl_mff_map
,
2841 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2843 return decode_ofpat_set_field(oasf
, true, vl_mff_map
, tlv_bitmap
, ofpacts
);
2847 decode_NXAST_RAW_REG_LOAD(const struct nx_action_reg_load
*narl
,
2848 enum ofp_version ofp_version OVS_UNUSED
,
2849 const struct vl_mff_map
*vl_mff_map
,
2850 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
2852 struct mf_subfield dst
;
2855 dst
.ofs
= nxm_decode_ofs(narl
->ofs_nbits
);
2856 dst
.n_bits
= nxm_decode_n_bits(narl
->ofs_nbits
);
2857 error
= mf_vl_mff_mf_from_nxm_header(ntohl(narl
->dst
), vl_mff_map
,
2858 &dst
.field
, tlv_bitmap
);
2863 error
= mf_check_dst(&dst
, NULL
);
2868 /* Reject 'narl' if a bit numbered 'n_bits' or higher is set to 1 in
2870 if (dst
.n_bits
< 64 && ntohll(narl
->value
) >> dst
.n_bits
) {
2871 return OFPERR_OFPBAC_BAD_ARGUMENT
;
2874 struct ofpact_set_field
*sf
= ofpact_put_reg_load(out
, dst
.field
, NULL
,
2876 bitwise_put(ntohll(narl
->value
),
2877 sf
->value
, dst
.field
->n_bytes
, dst
.ofs
,
2879 bitwise_put(UINT64_MAX
,
2880 ofpact_set_field_mask(sf
), dst
.field
->n_bytes
, dst
.ofs
,
2886 decode_NXAST_RAW_REG_LOAD2(const struct ext_action_header
*eah
,
2887 enum ofp_version ofp_version OVS_UNUSED
,
2888 const struct vl_mff_map
*vl_mff_map
,
2889 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
2891 struct ofpbuf b
= ofpbuf_const_initializer(eah
, ntohs(eah
->len
));
2892 ofpbuf_pull(&b
, OBJECT_OFFSETOF(eah
, pad
));
2894 union mf_value value
, mask
;
2895 const struct mf_field
*field
;
2897 error
= mf_vl_mff_nx_pull_entry(&b
, vl_mff_map
, &field
, &value
, &mask
,
2903 if (!is_all_zeros(b
.data
, b
.size
)) {
2904 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2907 if (!field
->writable
) {
2908 VLOG_WARN_RL(&rl
, "destination field %s is not writable", field
->name
);
2909 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2912 /* Put value and mask. */
2913 ofpact_put_reg_load2(out
, field
, &value
, &mask
);
2918 put_set_field(struct ofpbuf
*openflow
, enum ofp_version ofp_version
,
2919 enum mf_field_id field
, uint64_t value_
)
2921 struct ofp12_action_set_field
*oasf OVS_UNUSED
;
2922 int n_bytes
= mf_from_id(field
)->n_bytes
;
2923 size_t start_ofs
= openflow
->size
;
2924 union mf_value value
;
2926 value
.be64
= htonll(value_
<< (8 * (8 - n_bytes
)));
2928 oasf
= put_OFPAT12_SET_FIELD(openflow
);
2929 openflow
->size
= openflow
->size
- sizeof oasf
->pad
;
2930 nx_put_entry(openflow
, mf_from_id(field
), ofp_version
, &value
, NULL
);
2931 pad_ofpat(openflow
, start_ofs
);
2935 put_reg_load(struct ofpbuf
*openflow
,
2936 const struct mf_subfield
*dst
, uint64_t value
)
2938 ovs_assert(dst
->n_bits
<= 64);
2940 struct nx_action_reg_load
*narl
= put_NXAST_REG_LOAD(openflow
);
2941 narl
->ofs_nbits
= nxm_encode_ofs_nbits(dst
->ofs
, dst
->n_bits
);
2942 narl
->dst
= htonl(nxm_header_from_mff(dst
->field
));
2943 narl
->value
= htonll(value
);
2947 next_load_segment(const struct ofpact_set_field
*sf
,
2948 struct mf_subfield
*dst
, uint64_t *value
)
2950 int n_bits
= sf
->field
->n_bits
;
2951 int n_bytes
= sf
->field
->n_bytes
;
2952 int start
= dst
->ofs
+ dst
->n_bits
;
2954 if (start
< n_bits
) {
2955 dst
->field
= sf
->field
;
2956 dst
->ofs
= bitwise_scan(ofpact_set_field_mask(sf
), n_bytes
, 1, start
,
2958 if (dst
->ofs
< n_bits
) {
2959 dst
->n_bits
= bitwise_scan(ofpact_set_field_mask(sf
), n_bytes
, 0,
2961 MIN(dst
->ofs
+ 64, n_bits
)) - dst
->ofs
;
2962 *value
= bitwise_get(sf
->value
, n_bytes
, dst
->ofs
, dst
->n_bits
);
2969 /* Convert 'sf' to a series of REG_LOADs. */
2971 set_field_to_nxast(const struct ofpact_set_field
*sf
, struct ofpbuf
*openflow
)
2973 /* If 'sf' cannot be encoded as NXAST_REG_LOAD because it requires an
2974 * experimenter OXM or is variable length (or if it came in as
2975 * NXAST_REG_LOAD2), encode as NXAST_REG_LOAD2. Otherwise use
2976 * NXAST_REG_LOAD, which is backward compatible. */
2977 if (sf
->ofpact
.raw
== NXAST_RAW_REG_LOAD2
2978 || !mf_nxm_header(sf
->field
->id
) || sf
->field
->variable_len
) {
2979 struct ext_action_header
*eah OVS_UNUSED
;
2980 size_t start_ofs
= openflow
->size
;
2982 eah
= put_NXAST_REG_LOAD2(openflow
);
2983 openflow
->size
= openflow
->size
- sizeof eah
->pad
;
2984 nx_put_entry(openflow
, sf
->field
, 0, sf
->value
,
2985 ofpact_set_field_mask(sf
));
2986 pad_ofpat(openflow
, start_ofs
);
2988 struct mf_subfield dst
;
2991 dst
.ofs
= dst
.n_bits
= 0;
2992 while (next_load_segment(sf
, &dst
, &value
)) {
2993 put_reg_load(openflow
, &dst
, value
);
2998 /* Convert 'sf', which must set an entire field, to standard OpenFlow 1.0/1.1
2999 * actions, if we can, falling back to Nicira extensions if we must.
3001 * We check only meta-flow types that can appear within set field actions and
3002 * that have a mapping to compatible action types. These struct mf_field
3003 * definitions have a defined OXM or NXM header value and specify the field as
3006 set_field_to_legacy_openflow(const struct ofpact_set_field
*sf
,
3007 enum ofp_version ofp_version
,
3010 switch ((int) sf
->field
->id
) {
3011 case MFF_VLAN_TCI
: {
3012 ovs_be16 tci
= sf
->value
->be16
;
3013 bool cfi
= (tci
& htons(VLAN_CFI
)) != 0;
3014 uint16_t vid
= vlan_tci_to_vid(tci
);
3015 uint8_t pcp
= vlan_tci_to_pcp(tci
);
3017 if (ofp_version
< OFP11_VERSION
) {
3018 /* NXM_OF_VLAN_TCI to OpenFlow 1.0 mapping:
3020 * If CFI=1, Add or modify VLAN VID & PCP.
3021 * If CFI=0, strip VLAN header, if any.
3024 put_OFPAT10_SET_VLAN_VID(out
, vid
);
3025 put_OFPAT10_SET_VLAN_PCP(out
, pcp
);
3027 put_OFPAT10_STRIP_VLAN(out
);
3030 /* NXM_OF_VLAN_TCI to OpenFlow 1.1 mapping:
3032 * If CFI=1, Add or modify VLAN VID & PCP.
3033 * OpenFlow 1.1 set actions only apply if the packet
3034 * already has VLAN tags. To be sure that is the case
3035 * we have to push a VLAN header. As we do not support
3036 * multiple layers of VLANs, this is a no-op, if a VLAN
3037 * header already exists. This may backfire, however,
3038 * when we start supporting multiple layers of VLANs.
3039 * If CFI=0, strip VLAN header, if any.
3042 /* Push a VLAN tag, if one was not seen at action validation
3044 if (!sf
->flow_has_vlan
) {
3045 put_OFPAT11_PUSH_VLAN(out
, htons(ETH_TYPE_VLAN_8021Q
));
3047 put_OFPAT11_SET_VLAN_VID(out
, vid
);
3048 put_OFPAT11_SET_VLAN_PCP(out
, pcp
);
3050 /* If the flow did not match on vlan, we have no way of
3051 * knowing if the vlan tag exists, so we must POP just to be
3053 put_OFPAT11_POP_VLAN(out
);
3059 case MFF_VLAN_VID
: {
3060 uint16_t vid
= ntohs(sf
->value
->be16
) & VLAN_VID_MASK
;
3061 if (ofp_version
== OFP10_VERSION
) {
3062 put_OFPAT10_SET_VLAN_VID(out
, vid
);
3064 put_OFPAT11_SET_VLAN_VID(out
, vid
);
3070 if (ofp_version
== OFP10_VERSION
) {
3071 put_OFPAT10_SET_VLAN_PCP(out
, sf
->value
->u8
);
3073 put_OFPAT11_SET_VLAN_PCP(out
, sf
->value
->u8
);
3078 put_OFPAT_SET_DL_SRC(out
, ofp_version
)->dl_addr
= sf
->value
->mac
;
3082 put_OFPAT_SET_DL_DST(out
, ofp_version
)->dl_addr
= sf
->value
->mac
;
3086 put_OFPAT_SET_NW_SRC(out
, ofp_version
, sf
->value
->be32
);
3090 put_OFPAT_SET_NW_DST(out
, ofp_version
, sf
->value
->be32
);
3094 put_OFPAT_SET_NW_TOS(out
, ofp_version
, sf
->value
->u8
);
3097 case MFF_IP_DSCP_SHIFTED
:
3098 put_OFPAT_SET_NW_TOS(out
, ofp_version
, sf
->value
->u8
<< 2);
3102 struct ofpact_ecn ip_ecn
= { .ecn
= sf
->value
->u8
};
3103 encode_SET_IP_ECN(&ip_ecn
, ofp_version
, out
);
3109 put_OFPAT_SET_TP_SRC(out
, sf
->value
->be16
);
3114 put_OFPAT_SET_TP_DST(out
, sf
->value
->be16
);
3118 set_field_to_nxast(sf
, out
);
3124 set_field_to_set_field(const struct ofpact_set_field
*sf
,
3125 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3127 struct ofp12_action_set_field
*oasf OVS_UNUSED
;
3128 size_t start_ofs
= out
->size
;
3130 oasf
= put_OFPAT12_SET_FIELD(out
);
3131 out
->size
= out
->size
- sizeof oasf
->pad
;
3132 nx_put_entry(out
, sf
->field
, ofp_version
, sf
->value
,
3133 ofpact_set_field_mask(sf
));
3134 pad_ofpat(out
, start_ofs
);
3138 encode_SET_FIELD(const struct ofpact_set_field
*sf
,
3139 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3141 if (ofp_version
>= OFP15_VERSION
) {
3142 /* OF1.5+ only has Set-Field (reg_load is redundant so we drop it
3144 set_field_to_set_field(sf
, ofp_version
, out
);
3145 } else if (sf
->ofpact
.raw
== NXAST_RAW_REG_LOAD
||
3146 sf
->ofpact
.raw
== NXAST_RAW_REG_LOAD2
) {
3147 /* It came in as reg_load, send it out the same way. */
3148 set_field_to_nxast(sf
, out
);
3149 } else if (ofp_version
< OFP12_VERSION
) {
3150 /* OpenFlow 1.0 and 1.1 don't have Set-Field. */
3151 set_field_to_legacy_openflow(sf
, ofp_version
, out
);
3152 } else if (is_all_ones(ofpact_set_field_mask(sf
), sf
->field
->n_bytes
)) {
3153 /* We're encoding to OpenFlow 1.2, 1.3, or 1.4. The action sets an
3154 * entire field, so encode it as OFPAT_SET_FIELD. */
3155 set_field_to_set_field(sf
, ofp_version
, out
);
3157 /* We're encoding to OpenFlow 1.2, 1.3, or 1.4. The action cannot be
3158 * encoded as OFPAT_SET_FIELD because it does not set an entire field,
3159 * so encode it as reg_load. */
3160 set_field_to_nxast(sf
, out
);
3164 /* Parses the input argument 'arg' into the key, value, and delimiter
3165 * components that are common across the reg_load and set_field action format.
3167 * With an argument like "1->metadata", sets the following pointers to
3168 * point within 'arg':
3173 * Returns NULL if successful, otherwise a malloc()'d string describing the
3174 * error. The caller is responsible for freeing the returned string. */
3175 static char * OVS_WARN_UNUSED_RESULT
3176 set_field_split_str(char *arg
, char **key
, char **value
, char **delim
)
3181 value_end
= strstr(arg
, "->");
3182 *key
= value_end
+ strlen("->");
3188 return xasprintf("%s: missing `->'", arg
);
3190 if (strlen(value_end
) <= strlen("->")) {
3191 return xasprintf("%s: missing field name following `->'", arg
);
3197 /* Parses a "set_field" action with argument 'arg', appending the parsed
3198 * action to 'pp->ofpacts'.
3200 * Returns NULL if successful, otherwise a malloc()'d string describing the
3201 * error. The caller is responsible for freeing the returned string. */
3202 static char * OVS_WARN_UNUSED_RESULT
3203 set_field_parse__(char *arg
, const struct ofpact_parse_params
*pp
)
3208 const struct mf_field
*mf
;
3209 union mf_value sf_value
, sf_mask
;
3212 error
= set_field_split_str(arg
, &key
, &value
, &delim
);
3217 mf
= mf_from_name(key
);
3219 return xasprintf("%s is not a valid OXM field name", key
);
3221 if (!mf
->writable
) {
3222 return xasprintf("%s is read-only", key
);
3226 error
= mf_parse(mf
, value
, pp
->port_map
, &sf_value
, &sf_mask
);
3231 if (!mf_is_value_valid(mf
, &sf_value
)) {
3232 return xasprintf("%s is not a valid value for field %s", value
, key
);
3235 *pp
->usable_protocols
&= mf
->usable_protocols_exact
;
3237 ofpact_put_set_field(pp
->ofpacts
, mf
, &sf_value
, &sf_mask
);
3241 /* Parses 'arg' as the argument to a "set_field" action, and appends such an
3242 * action to 'pp->ofpacts'.
3244 * Returns NULL if successful, otherwise a malloc()'d string describing the
3245 * error. The caller is responsible for freeing the returned string. */
3246 static char * OVS_WARN_UNUSED_RESULT
3247 parse_SET_FIELD(const char *arg
, const struct ofpact_parse_params
*pp
)
3249 char *copy
= xstrdup(arg
);
3250 char *error
= set_field_parse__(copy
, pp
);
3255 static char * OVS_WARN_UNUSED_RESULT
3256 parse_reg_load(char *arg
, const struct ofpact_parse_params
*pp
)
3258 struct mf_subfield dst
;
3259 char *key
, *value_str
;
3260 union mf_value value
;
3263 error
= set_field_split_str(arg
, &key
, &value_str
, NULL
);
3268 error
= mf_parse_subfield(&dst
, key
);
3273 if (parse_int_string(value_str
, (uint8_t *)&value
, dst
.field
->n_bytes
,
3275 return xasprintf("%s: cannot parse integer value", arg
);
3278 if (!bitwise_is_all_zeros(&value
, dst
.field
->n_bytes
, dst
.n_bits
,
3279 dst
.field
->n_bytes
* 8 - dst
.n_bits
)) {
3283 mf_format(dst
.field
, &value
, NULL
, NULL
, &ds
);
3284 error
= xasprintf("%s: value %s does not fit into %d bits",
3285 arg
, ds_cstr(&ds
), dst
.n_bits
);
3290 struct ofpact_set_field
*sf
= ofpact_put_reg_load(pp
->ofpacts
, dst
.field
,
3293 bitwise_copy(&value
, dst
.field
->n_bytes
, 0, sf
->value
,
3294 dst
.field
->n_bytes
, dst
.ofs
, dst
.n_bits
);
3295 bitwise_one(ofpact_set_field_mask(sf
), dst
.field
->n_bytes
, dst
.ofs
,
3301 format_SET_FIELD(const struct ofpact_set_field
*a
,
3302 const struct ofpact_format_params
*fp
)
3304 if (a
->ofpact
.raw
== NXAST_RAW_REG_LOAD
) {
3305 struct mf_subfield dst
;
3308 dst
.ofs
= dst
.n_bits
= 0;
3309 while (next_load_segment(a
, &dst
, &value
)) {
3310 ds_put_format(fp
->s
, "%sload:%s%#"PRIx64
"%s->%s",
3311 colors
.special
, colors
.end
, value
,
3312 colors
.special
, colors
.end
);
3313 mf_format_subfield(&dst
, fp
->s
);
3314 ds_put_char(fp
->s
, ',');
3316 ds_chomp(fp
->s
, ',');
3318 ds_put_format(fp
->s
, "%sset_field:%s", colors
.special
, colors
.end
);
3319 mf_format(a
->field
, a
->value
, ofpact_set_field_mask(a
),
3320 fp
->port_map
, fp
->s
);
3321 ds_put_format(fp
->s
, "%s->%s%s",
3322 colors
.special
, colors
.end
, a
->field
->name
);
3327 check_SET_FIELD(struct ofpact_set_field
*a
,
3328 const struct ofpact_check_params
*cp
)
3330 const struct mf_field
*mf
= a
->field
;
3331 struct flow
*flow
= &cp
->match
->flow
;
3332 ovs_be16
*tci
= &flow
->vlans
[0].tci
;
3334 /* Require OXM_OF_VLAN_VID to have an existing VLAN header. */
3335 if (!mf_are_prereqs_ok(mf
, flow
, NULL
)
3336 || (mf
->id
== MFF_VLAN_VID
&& !(*tci
& htons(VLAN_CFI
)))) {
3337 VLOG_WARN_RL(&rl
, "set_field %s lacks correct prerequisites",
3339 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
3342 /* Remember if we saw a VLAN tag in the flow, to aid translating to
3343 * OpenFlow 1.1 if need be. */
3344 a
->flow_has_vlan
= (*tci
& htons(VLAN_CFI
)) != 0;
3345 if (mf
->id
== MFF_VLAN_TCI
) {
3346 /* The set field may add or remove the VLAN tag,
3347 * Mark the status temporarily. */
3348 *tci
= a
->value
->be16
;
3354 /* Appends an OFPACT_SET_FIELD ofpact with enough space for the value and mask
3355 * for the 'field' to 'ofpacts' and returns it. Fills in the value from
3356 * 'value', if non-NULL, and mask from 'mask' if non-NULL. If 'value' is
3357 * non-NULL and 'mask' is NULL, an all-ones mask will be filled in. */
3358 struct ofpact_set_field
*
3359 ofpact_put_set_field(struct ofpbuf
*ofpacts
, const struct mf_field
*field
,
3360 const void *value
, const void *mask
)
3362 struct ofpact_set_field
*sf
= ofpact_put_SET_FIELD(ofpacts
);
3365 /* Fill in the value and mask if given, otherwise put zeroes so that the
3366 * caller may fill in the value and mask itself. */
3368 ofpbuf_put_uninit(ofpacts
, 2 * field
->n_bytes
);
3369 sf
= ofpacts
->header
;
3370 memcpy(sf
->value
, value
, field
->n_bytes
);
3372 memcpy(ofpact_set_field_mask(sf
), mask
, field
->n_bytes
);
3374 memset(ofpact_set_field_mask(sf
), 0xff, field
->n_bytes
);
3377 ofpbuf_put_zeros(ofpacts
, 2 * field
->n_bytes
);
3378 sf
= ofpacts
->header
;
3380 /* Update length. */
3381 ofpact_finish_SET_FIELD(ofpacts
, &sf
);
3386 /* Appends an OFPACT_SET_FIELD ofpact to 'ofpacts' and returns it. The ofpact
3387 * is marked such that, if possible, it will be translated to OpenFlow as
3388 * NXAST_REG_LOAD extension actions rather than OFPAT_SET_FIELD, either because
3389 * that was the way that the action was expressed when it came into OVS or for
3390 * backward compatibility. */
3391 struct ofpact_set_field
*
3392 ofpact_put_reg_load(struct ofpbuf
*ofpacts
, const struct mf_field
*field
,
3393 const void *value
, const void *mask
)
3395 struct ofpact_set_field
*sf
= ofpact_put_set_field(ofpacts
, field
, value
,
3397 sf
->ofpact
.raw
= NXAST_RAW_REG_LOAD
;
3402 struct ofpact_set_field
*
3403 ofpact_put_reg_load2(struct ofpbuf
*ofpacts
, const struct mf_field
*field
,
3404 const void *value
, const void *mask
)
3406 struct ofpact_set_field
*sf
= ofpact_put_set_field(ofpacts
, field
, value
,
3408 sf
->ofpact
.raw
= NXAST_RAW_REG_LOAD2
;
3414 /* Action structure for NXAST_STACK_PUSH and NXAST_STACK_POP.
3416 * Pushes (or pops) field[offset: offset + n_bits] to (or from)
3419 struct nx_action_stack
{
3420 ovs_be16 type
; /* OFPAT_VENDOR. */
3421 ovs_be16 len
; /* Length is 16. */
3422 ovs_be32 vendor
; /* NX_VENDOR_ID. */
3423 ovs_be16 subtype
; /* NXAST_STACK_PUSH or NXAST_STACK_POP. */
3424 ovs_be16 offset
; /* Bit offset into the field. */
3426 * - OXM/NXM header for field to push or pop (4 or 8 bytes).
3427 * - ovs_be16 'n_bits', the number of bits to extract from the field.
3428 * - Enough 0-bytes to pad out the action to 24 bytes. */
3429 uint8_t pad
[12]; /* See above. */
3431 OFP_ASSERT(sizeof(struct nx_action_stack
) == 24);
3434 decode_stack_action(const struct nx_action_stack
*nasp
,
3435 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
3436 struct ofpact_stack
*stack_action
)
3439 stack_action
->subfield
.ofs
= ntohs(nasp
->offset
);
3441 struct ofpbuf b
= ofpbuf_const_initializer(nasp
, sizeof *nasp
);
3442 ofpbuf_pull(&b
, OBJECT_OFFSETOF(nasp
, pad
));
3443 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
,
3444 &stack_action
->subfield
.field
, NULL
,
3450 stack_action
->subfield
.n_bits
= ntohs(*(const ovs_be16
*) b
.data
);
3452 if (!is_all_zeros(b
.data
, b
.size
)) {
3453 return OFPERR_NXBRC_MUST_BE_ZERO
;
3460 decode_NXAST_RAW_STACK_PUSH(const struct nx_action_stack
*nasp
,
3461 enum ofp_version ofp_version OVS_UNUSED
,
3462 const struct vl_mff_map
*vl_mff_map
,
3463 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
3465 struct ofpact_stack
*push
= ofpact_put_STACK_PUSH(ofpacts
);
3466 enum ofperr error
= decode_stack_action(nasp
, vl_mff_map
, tlv_bitmap
,
3468 return error
? error
: nxm_stack_push_check(push
, NULL
);
3472 decode_NXAST_RAW_STACK_POP(const struct nx_action_stack
*nasp
,
3473 enum ofp_version ofp_version OVS_UNUSED
,
3474 const struct vl_mff_map
*vl_mff_map
,
3475 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
3477 struct ofpact_stack
*pop
= ofpact_put_STACK_POP(ofpacts
);
3478 enum ofperr error
= decode_stack_action(nasp
, vl_mff_map
, tlv_bitmap
,
3480 return error
? error
: nxm_stack_pop_check(pop
, NULL
);
3484 encode_STACK_op(const struct ofpact_stack
*stack_action
,
3485 struct nx_action_stack
*nasp
)
3490 nasp
->offset
= htons(stack_action
->subfield
.ofs
);
3492 ofpbuf_use_stack(&b
, nasp
, ntohs(nasp
->len
));
3493 ofpbuf_put_uninit(&b
, OBJECT_OFFSETOF(nasp
, pad
));
3494 nx_put_mff_header(&b
, stack_action
->subfield
.field
, 0, false);
3495 n_bits
= htons(stack_action
->subfield
.n_bits
);
3496 ofpbuf_put(&b
, &n_bits
, sizeof n_bits
);
3500 encode_STACK_PUSH(const struct ofpact_stack
*stack
,
3501 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
3503 encode_STACK_op(stack
, put_NXAST_STACK_PUSH(out
));
3507 encode_STACK_POP(const struct ofpact_stack
*stack
,
3508 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
3510 encode_STACK_op(stack
, put_NXAST_STACK_POP(out
));
3513 static char * OVS_WARN_UNUSED_RESULT
3514 parse_STACK_PUSH(char *arg
, const struct ofpact_parse_params
*pp
)
3516 return nxm_parse_stack_action(ofpact_put_STACK_PUSH(pp
->ofpacts
), arg
);
3519 static char * OVS_WARN_UNUSED_RESULT
3520 parse_STACK_POP(char *arg
, const struct ofpact_parse_params
*pp
)
3522 return nxm_parse_stack_action(ofpact_put_STACK_POP(pp
->ofpacts
), arg
);
3526 format_STACK_PUSH(const struct ofpact_stack
*a
,
3527 const struct ofpact_format_params
*fp
)
3529 nxm_format_stack_push(a
, fp
->s
);
3533 format_STACK_POP(const struct ofpact_stack
*a
,
3534 const struct ofpact_format_params
*fp
)
3536 nxm_format_stack_pop(a
, fp
->s
);
3540 check_STACK_PUSH(const struct ofpact_stack
*a
,
3541 const struct ofpact_check_params
*cp
)
3543 return nxm_stack_push_check(a
, cp
->match
);
3547 check_STACK_POP(const struct ofpact_stack
*a
,
3548 const struct ofpact_check_params
*cp
)
3550 return nxm_stack_pop_check(a
, cp
->match
);
3553 /* Action structure for NXAST_DEC_TTL_CNT_IDS.
3555 * If the packet is not IPv4 or IPv6, does nothing. For IPv4 or IPv6, if the
3556 * TTL or hop limit is at least 2, decrements it by 1. Otherwise, if TTL or
3557 * hop limit is 0 or 1, sends a packet-in to the controllers with each of the
3558 * 'n_controllers' controller IDs specified in 'cnt_ids'.
3560 * (This differs from NXAST_DEC_TTL in that for NXAST_DEC_TTL the packet-in is
3561 * sent only to controllers with id 0.)
3563 struct nx_action_cnt_ids
{
3564 ovs_be16 type
; /* OFPAT_VENDOR. */
3565 ovs_be16 len
; /* Length including slaves. */
3566 ovs_be32 vendor
; /* NX_VENDOR_ID. */
3567 ovs_be16 subtype
; /* NXAST_DEC_TTL_CNT_IDS. */
3569 ovs_be16 n_controllers
; /* Number of controllers. */
3570 uint8_t zeros
[4]; /* Must be zero. */
3572 /* Followed by 1 or more controller ids:
3574 * uint16_t cnt_ids[]; -- Controller ids.
3575 * uint8_t pad[]; -- Must be 0 to 8-byte align cnt_ids[].
3578 OFP_ASSERT(sizeof(struct nx_action_cnt_ids
) == 16);
3581 decode_OFPAT_RAW_DEC_NW_TTL(struct ofpbuf
*out
)
3584 struct ofpact_cnt_ids
*ids
;
3585 enum ofperr error
= 0;
3587 ids
= ofpact_put_DEC_TTL(out
);
3588 ids
->n_controllers
= 1;
3589 ofpbuf_put(out
, &id
, sizeof id
);
3591 ofpact_finish_DEC_TTL(out
, &ids
);
3596 decode_NXAST_RAW_DEC_TTL_CNT_IDS(const struct nx_action_cnt_ids
*nac_ids
,
3597 enum ofp_version ofp_version OVS_UNUSED
,
3600 struct ofpact_cnt_ids
*ids
;
3604 ids
= ofpact_put_DEC_TTL(out
);
3605 ids
->ofpact
.raw
= NXAST_RAW_DEC_TTL_CNT_IDS
;
3606 ids
->n_controllers
= ntohs(nac_ids
->n_controllers
);
3607 ids_size
= ntohs(nac_ids
->len
) - sizeof *nac_ids
;
3609 if (!is_all_zeros(nac_ids
->zeros
, sizeof nac_ids
->zeros
)) {
3610 return OFPERR_NXBRC_MUST_BE_ZERO
;
3613 if (ids_size
< ids
->n_controllers
* sizeof(ovs_be16
)) {
3614 VLOG_WARN_RL(&rl
, "Nicira action dec_ttl_cnt_ids only has %"PRIuSIZE
" "
3615 "bytes allocated for controller ids. %"PRIuSIZE
" bytes "
3616 "are required for %u controllers.",
3617 ids_size
, ids
->n_controllers
* sizeof(ovs_be16
),
3618 ids
->n_controllers
);
3619 return OFPERR_OFPBAC_BAD_LEN
;
3622 for (i
= 0; i
< ids
->n_controllers
; i
++) {
3623 uint16_t id
= ntohs(((ovs_be16
*)(nac_ids
+ 1))[i
]);
3624 ofpbuf_put(out
, &id
, sizeof id
);
3628 ofpact_finish_DEC_TTL(out
, &ids
);
3634 encode_DEC_TTL(const struct ofpact_cnt_ids
*dec_ttl
,
3635 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3637 if (dec_ttl
->ofpact
.raw
== NXAST_RAW_DEC_TTL_CNT_IDS
3638 || dec_ttl
->n_controllers
!= 1
3639 || dec_ttl
->cnt_ids
[0] != 0) {
3640 struct nx_action_cnt_ids
*nac_ids
= put_NXAST_DEC_TTL_CNT_IDS(out
);
3641 int ids_len
= ROUND_UP(2 * dec_ttl
->n_controllers
, OFP_ACTION_ALIGN
);
3645 nac_ids
->len
= htons(ntohs(nac_ids
->len
) + ids_len
);
3646 nac_ids
->n_controllers
= htons(dec_ttl
->n_controllers
);
3648 ids
= ofpbuf_put_zeros(out
, ids_len
);
3649 for (i
= 0; i
< dec_ttl
->n_controllers
; i
++) {
3650 ids
[i
] = htons(dec_ttl
->cnt_ids
[i
]);
3653 put_OFPAT_DEC_NW_TTL(out
, ofp_version
);
3658 parse_noargs_dec_ttl(const struct ofpact_parse_params
*pp
)
3660 struct ofpact_cnt_ids
*ids
;
3663 ofpact_put_DEC_TTL(pp
->ofpacts
);
3664 ofpbuf_put(pp
->ofpacts
, &id
, sizeof id
);
3665 ids
= pp
->ofpacts
->header
;
3666 ids
->n_controllers
++;
3667 ofpact_finish_DEC_TTL(pp
->ofpacts
, &ids
);
3670 static char * OVS_WARN_UNUSED_RESULT
3671 parse_DEC_TTL(char *arg
, const struct ofpact_parse_params
*pp
)
3674 parse_noargs_dec_ttl(pp
);
3676 struct ofpact_cnt_ids
*ids
;
3679 ids
= ofpact_put_DEC_TTL(pp
->ofpacts
);
3680 ids
->ofpact
.raw
= NXAST_RAW_DEC_TTL_CNT_IDS
;
3681 for (cntr
= strtok_r(arg
, ", ", &arg
); cntr
!= NULL
;
3682 cntr
= strtok_r(NULL
, ", ", &arg
)) {
3683 uint16_t id
= atoi(cntr
);
3685 ofpbuf_put(pp
->ofpacts
, &id
, sizeof id
);
3686 ids
= pp
->ofpacts
->header
;
3687 ids
->n_controllers
++;
3689 if (!ids
->n_controllers
) {
3690 return xstrdup("dec_ttl_cnt_ids: expected at least one controller "
3693 ofpact_finish_DEC_TTL(pp
->ofpacts
, &ids
);
3699 format_DEC_TTL(const struct ofpact_cnt_ids
*a
,
3700 const struct ofpact_format_params
*fp
)
3704 ds_put_format(fp
->s
, "%sdec_ttl%s", colors
.paren
, colors
.end
);
3705 if (a
->ofpact
.raw
== NXAST_RAW_DEC_TTL_CNT_IDS
) {
3706 ds_put_format(fp
->s
, "%s(%s", colors
.paren
, colors
.end
);
3707 for (i
= 0; i
< a
->n_controllers
; i
++) {
3709 ds_put_cstr(fp
->s
, ",");
3711 ds_put_format(fp
->s
, "%"PRIu16
, a
->cnt_ids
[i
]);
3713 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
3718 check_DEC_TTL(const struct ofpact_cnt_ids
*a OVS_UNUSED
,
3719 struct ofpact_check_params
*cp
)
3721 return check_set_ip(cp
);
3724 /* Set MPLS label actions. */
3727 decode_OFPAT_RAW_SET_MPLS_LABEL(ovs_be32 label
,
3728 enum ofp_version ofp_version OVS_UNUSED
,
3731 ofpact_put_SET_MPLS_LABEL(out
)->label
= label
;
3736 encode_SET_MPLS_LABEL(const struct ofpact_mpls_label
*label
,
3737 enum ofp_version ofp_version
,
3740 if (ofp_version
< OFP12_VERSION
) {
3741 put_OFPAT_SET_MPLS_LABEL(out
, ofp_version
, label
->label
);
3743 put_set_field(out
, ofp_version
, MFF_MPLS_LABEL
, ntohl(label
->label
));
3747 static char * OVS_WARN_UNUSED_RESULT
3748 parse_SET_MPLS_LABEL(char *arg
, const struct ofpact_parse_params
*pp
)
3750 struct ofpact_mpls_label
*mpls_label
3751 = ofpact_put_SET_MPLS_LABEL(pp
->ofpacts
);
3753 return xstrdup("set_mpls_label: expected label.");
3756 mpls_label
->label
= htonl(atoi(arg
));
3761 format_SET_MPLS_LABEL(const struct ofpact_mpls_label
*a
,
3762 const struct ofpact_format_params
*fp
)
3764 ds_put_format(fp
->s
, "%sset_mpls_label(%s%"PRIu32
"%s)%s",
3765 colors
.paren
, colors
.end
, ntohl(a
->label
),
3766 colors
.paren
, colors
.end
);
3770 check_set_mpls(struct ofpact_check_params
*cp
)
3772 ovs_be16 dl_type
= get_dl_type(&cp
->match
->flow
);
3773 if (!eth_type_mpls(dl_type
)) {
3774 inconsistent_match(&cp
->usable_protocols
);
3780 check_SET_MPLS_LABEL(const struct ofpact_mpls_label
*a OVS_UNUSED
,
3781 struct ofpact_check_params
*cp
)
3783 return check_set_mpls(cp
);
3786 /* Set MPLS TC actions. */
3789 decode_OFPAT_RAW_SET_MPLS_TC(uint8_t tc
,
3790 enum ofp_version ofp_version OVS_UNUSED
,
3793 ofpact_put_SET_MPLS_TC(out
)->tc
= tc
;
3798 encode_SET_MPLS_TC(const struct ofpact_mpls_tc
*tc
,
3799 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3801 if (ofp_version
< OFP12_VERSION
) {
3802 put_OFPAT_SET_MPLS_TC(out
, ofp_version
, tc
->tc
);
3804 put_set_field(out
, ofp_version
, MFF_MPLS_TC
, tc
->tc
);
3808 static char * OVS_WARN_UNUSED_RESULT
3809 parse_SET_MPLS_TC(char *arg
, const struct ofpact_parse_params
*pp
)
3811 struct ofpact_mpls_tc
*mpls_tc
= ofpact_put_SET_MPLS_TC(pp
->ofpacts
);
3814 return xstrdup("set_mpls_tc: expected tc.");
3817 mpls_tc
->tc
= atoi(arg
);
3822 format_SET_MPLS_TC(const struct ofpact_mpls_tc
*a
,
3823 const struct ofpact_format_params
*fp
)
3825 ds_put_format(fp
->s
, "%sset_mpls_ttl(%s%"PRIu8
"%s)%s",
3826 colors
.paren
, colors
.end
, a
->tc
,
3827 colors
.paren
, colors
.end
);
3831 check_SET_MPLS_TC(const struct ofpact_mpls_tc
*a OVS_UNUSED
,
3832 struct ofpact_check_params
*cp
)
3834 return check_set_mpls(cp
);
3837 /* Set MPLS TTL actions. */
3840 decode_OFPAT_RAW_SET_MPLS_TTL(uint8_t ttl
,
3841 enum ofp_version ofp_version OVS_UNUSED
,
3844 ofpact_put_SET_MPLS_TTL(out
)->ttl
= ttl
;
3849 encode_SET_MPLS_TTL(const struct ofpact_mpls_ttl
*ttl
,
3850 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3852 put_OFPAT_SET_MPLS_TTL(out
, ofp_version
, ttl
->ttl
);
3855 /* Parses 'arg' as the argument to a "set_mpls_ttl" action, and appends such an
3856 * action to 'pp->ofpacts'.
3858 * Returns NULL if successful, otherwise a malloc()'d string describing the
3859 * error. The caller is responsible for freeing the returned string. */
3860 static char * OVS_WARN_UNUSED_RESULT
3861 parse_SET_MPLS_TTL(char *arg
, const struct ofpact_parse_params
*pp
)
3863 struct ofpact_mpls_ttl
*mpls_ttl
= ofpact_put_SET_MPLS_TTL(pp
->ofpacts
);
3866 return xstrdup("set_mpls_ttl: expected ttl.");
3869 mpls_ttl
->ttl
= atoi(arg
);
3874 format_SET_MPLS_TTL(const struct ofpact_mpls_ttl
*a
,
3875 const struct ofpact_format_params
*fp
)
3877 ds_put_format(fp
->s
, "%sset_mpls_ttl(%s%"PRIu8
"%s)%s",
3878 colors
.paren
, colors
.end
, a
->ttl
,
3879 colors
.paren
, colors
.end
);
3883 check_SET_MPLS_TTL(const struct ofpact_mpls_ttl
*a OVS_UNUSED
,
3884 struct ofpact_check_params
*cp
)
3886 return check_set_mpls(cp
);
3889 /* Decrement MPLS TTL actions. */
3892 decode_OFPAT_RAW_DEC_MPLS_TTL(struct ofpbuf
*out
)
3894 ofpact_put_DEC_MPLS_TTL(out
);
3899 encode_DEC_MPLS_TTL(const struct ofpact_null
*null OVS_UNUSED
,
3900 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3902 put_OFPAT_DEC_MPLS_TTL(out
, ofp_version
);
3905 static char * OVS_WARN_UNUSED_RESULT
3906 parse_DEC_MPLS_TTL(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
3908 ofpact_put_DEC_MPLS_TTL(pp
->ofpacts
);
3913 format_DEC_MPLS_TTL(const struct ofpact_null
*a OVS_UNUSED
,
3914 const struct ofpact_format_params
*fp
)
3916 ds_put_format(fp
->s
, "%sdec_mpls_ttl%s", colors
.value
, colors
.end
);
3920 check_DEC_MPLS_TTL(const struct ofpact_null
*a OVS_UNUSED
,
3921 struct ofpact_check_params
*cp
)
3923 return check_set_mpls(cp
);
3926 /* Push MPLS label action. */
3929 decode_OFPAT_RAW_PUSH_MPLS(ovs_be16 ethertype
,
3930 enum ofp_version ofp_version OVS_UNUSED
,
3933 struct ofpact_push_mpls
*oam
;
3935 if (!eth_type_mpls(ethertype
)) {
3936 return OFPERR_OFPBAC_BAD_ARGUMENT
;
3938 oam
= ofpact_put_PUSH_MPLS(out
);
3939 oam
->ethertype
= ethertype
;
3945 encode_PUSH_MPLS(const struct ofpact_push_mpls
*push_mpls
,
3946 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3948 put_OFPAT_PUSH_MPLS(out
, ofp_version
, push_mpls
->ethertype
);
3951 static char * OVS_WARN_UNUSED_RESULT
3952 parse_PUSH_MPLS(char *arg
, const struct ofpact_parse_params
*pp
)
3957 error
= str_to_u16(arg
, "push_mpls", ðertype
);
3959 ofpact_put_PUSH_MPLS(pp
->ofpacts
)->ethertype
= htons(ethertype
);
3965 format_PUSH_MPLS(const struct ofpact_push_mpls
*a
,
3966 const struct ofpact_format_params
*fp
)
3968 ds_put_format(fp
->s
, "%spush_mpls:%s0x%04"PRIx16
,
3969 colors
.param
, colors
.end
, ntohs(a
->ethertype
));
3973 check_PUSH_MPLS(const struct ofpact_push_mpls
*a
,
3974 struct ofpact_check_params
*cp
)
3976 struct flow
*flow
= &cp
->match
->flow
;
3978 if (flow
->packet_type
!= htonl(PT_ETH
)) {
3979 inconsistent_match(&cp
->usable_protocols
);
3981 flow
->dl_type
= a
->ethertype
;
3983 /* The packet is now MPLS and the MPLS payload is opaque.
3984 * Thus nothing can be assumed about the network protocol.
3985 * Temporarily mark that we have no nw_proto. */
3991 /* Pop MPLS label action. */
3994 decode_OFPAT_RAW_POP_MPLS(ovs_be16 ethertype
,
3995 enum ofp_version ofp_version OVS_UNUSED
,
3998 ofpact_put_POP_MPLS(out
)->ethertype
= ethertype
;
4003 encode_POP_MPLS(const struct ofpact_pop_mpls
*pop_mpls
,
4004 enum ofp_version ofp_version
, struct ofpbuf
*out
)
4006 put_OFPAT_POP_MPLS(out
, ofp_version
, pop_mpls
->ethertype
);
4009 static char * OVS_WARN_UNUSED_RESULT
4010 parse_POP_MPLS(char *arg
, const struct ofpact_parse_params
*pp
)
4015 error
= str_to_u16(arg
, "pop_mpls", ðertype
);
4017 ofpact_put_POP_MPLS(pp
->ofpacts
)->ethertype
= htons(ethertype
);
4023 format_POP_MPLS(const struct ofpact_pop_mpls
*a
,
4024 const struct ofpact_format_params
*fp
)
4026 ds_put_format(fp
->s
, "%spop_mpls:%s0x%04"PRIx16
,
4027 colors
.param
, colors
.end
, ntohs(a
->ethertype
));
4031 check_POP_MPLS(const struct ofpact_pop_mpls
*a
, struct ofpact_check_params
*cp
)
4033 struct flow
*flow
= &cp
->match
->flow
;
4034 ovs_be16 dl_type
= get_dl_type(flow
);
4036 if (flow
->packet_type
!= htonl(PT_ETH
) || !eth_type_mpls(dl_type
)) {
4037 inconsistent_match(&cp
->usable_protocols
);
4039 flow
->dl_type
= a
->ethertype
;
4043 /* Set tunnel ID actions. */
4046 decode_NXAST_RAW_SET_TUNNEL(uint32_t tun_id
,
4047 enum ofp_version ofp_version OVS_UNUSED
,
4050 struct ofpact_tunnel
*tunnel
= ofpact_put_SET_TUNNEL(out
);
4051 tunnel
->ofpact
.raw
= NXAST_RAW_SET_TUNNEL
;
4052 tunnel
->tun_id
= tun_id
;
4057 decode_NXAST_RAW_SET_TUNNEL64(uint64_t tun_id
,
4058 enum ofp_version ofp_version OVS_UNUSED
,
4061 struct ofpact_tunnel
*tunnel
= ofpact_put_SET_TUNNEL(out
);
4062 tunnel
->ofpact
.raw
= NXAST_RAW_SET_TUNNEL64
;
4063 tunnel
->tun_id
= tun_id
;
4068 encode_SET_TUNNEL(const struct ofpact_tunnel
*tunnel
,
4069 enum ofp_version ofp_version
, struct ofpbuf
*out
)
4071 uint64_t tun_id
= tunnel
->tun_id
;
4073 if (ofp_version
< OFP12_VERSION
) {
4074 if (tun_id
<= UINT32_MAX
4075 && tunnel
->ofpact
.raw
!= NXAST_RAW_SET_TUNNEL64
) {
4076 put_NXAST_SET_TUNNEL(out
, tun_id
);
4078 put_NXAST_SET_TUNNEL64(out
, tun_id
);
4081 put_set_field(out
, ofp_version
, MFF_TUN_ID
, tun_id
);
4085 static char * OVS_WARN_UNUSED_RESULT
4086 parse_set_tunnel(char *arg
, enum ofp_raw_action_type raw
,
4087 const struct ofpact_parse_params
*pp
)
4089 struct ofpact_tunnel
*tunnel
;
4091 tunnel
= ofpact_put_SET_TUNNEL(pp
->ofpacts
);
4092 tunnel
->ofpact
.raw
= raw
;
4093 return str_to_u64(arg
, &tunnel
->tun_id
);
4096 static char * OVS_WARN_UNUSED_RESULT
4097 parse_SET_TUNNEL(char *arg
, const struct ofpact_parse_params
*pp
)
4099 return parse_set_tunnel(arg
, NXAST_RAW_SET_TUNNEL
, pp
);
4103 format_SET_TUNNEL(const struct ofpact_tunnel
*a
,
4104 const struct ofpact_format_params
*fp
)
4106 ds_put_format(fp
->s
, "%sset_tunnel%s:%s%#"PRIx64
, colors
.param
,
4107 (a
->tun_id
> UINT32_MAX
4108 || a
->ofpact
.raw
== NXAST_RAW_SET_TUNNEL64
? "64" : ""),
4109 colors
.end
, a
->tun_id
);
4113 check_SET_TUNNEL(const struct ofpact_tunnel
*a OVS_UNUSED
,
4114 const struct ofpact_check_params
*cp OVS_UNUSED
)
4119 /* Set queue action. */
4122 decode_OFPAT_RAW_SET_QUEUE(uint32_t queue_id
,
4123 enum ofp_version ofp_version OVS_UNUSED
,
4126 ofpact_put_SET_QUEUE(out
)->queue_id
= queue_id
;
4131 encode_SET_QUEUE(const struct ofpact_queue
*queue
,
4132 enum ofp_version ofp_version
, struct ofpbuf
*out
)
4134 put_OFPAT_SET_QUEUE(out
, ofp_version
, queue
->queue_id
);
4137 static char * OVS_WARN_UNUSED_RESULT
4138 parse_SET_QUEUE(char *arg
, const struct ofpact_parse_params
*pp
)
4140 return str_to_u32(arg
, &ofpact_put_SET_QUEUE(pp
->ofpacts
)->queue_id
);
4144 format_SET_QUEUE(const struct ofpact_queue
*a
,
4145 const struct ofpact_format_params
*fp
)
4147 ds_put_format(fp
->s
, "%sset_queue:%s%"PRIu32
,
4148 colors
.param
, colors
.end
, a
->queue_id
);
4152 check_SET_QUEUE(const struct ofpact_queue
*a OVS_UNUSED
,
4153 const struct ofpact_check_params
*cp OVS_UNUSED
)
4158 /* Pop queue action. */
4161 decode_NXAST_RAW_POP_QUEUE(struct ofpbuf
*out
)
4163 ofpact_put_POP_QUEUE(out
);
4168 encode_POP_QUEUE(const struct ofpact_null
*null OVS_UNUSED
,
4169 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
4171 put_NXAST_POP_QUEUE(out
);
4174 static char * OVS_WARN_UNUSED_RESULT
4175 parse_POP_QUEUE(const char *arg OVS_UNUSED
,
4176 const struct ofpact_parse_params
*pp
)
4178 ofpact_put_POP_QUEUE(pp
->ofpacts
);
4183 format_POP_QUEUE(const struct ofpact_null
*a OVS_UNUSED
,
4184 const struct ofpact_format_params
*fp
)
4186 ds_put_format(fp
->s
, "%spop_queue%s", colors
.value
, colors
.end
);
4190 check_POP_QUEUE(const struct ofpact_null
*a OVS_UNUSED
,
4191 const struct ofpact_check_params
*cp OVS_UNUSED
)
4196 /* Action structure for NXAST_FIN_TIMEOUT.
4198 * This action changes the idle timeout or hard timeout, or both, of this
4199 * OpenFlow rule when the rule matches a TCP packet with the FIN or RST flag.
4200 * When such a packet is observed, the action reduces the rule's idle timeout
4201 * to 'fin_idle_timeout' and its hard timeout to 'fin_hard_timeout'. This
4202 * action has no effect on an existing timeout that is already shorter than the
4203 * one that the action specifies. A 'fin_idle_timeout' or 'fin_hard_timeout'
4204 * of zero has no effect on the respective timeout.
4206 * 'fin_idle_timeout' and 'fin_hard_timeout' are measured in seconds.
4207 * 'fin_hard_timeout' specifies time since the flow's creation, not since the
4208 * receipt of the FIN or RST.
4210 * This is useful for quickly discarding learned TCP flows that otherwise will
4211 * take a long time to expire.
4213 * This action is intended for use with an OpenFlow rule that matches only a
4214 * single TCP flow. If the rule matches multiple TCP flows (e.g. it wildcards
4215 * all TCP traffic, or all TCP traffic to a particular port), then any FIN or
4216 * RST in any of those flows will cause the entire OpenFlow rule to expire
4217 * early, which is not normally desirable.
4219 struct nx_action_fin_timeout
{
4220 ovs_be16 type
; /* OFPAT_VENDOR. */
4221 ovs_be16 len
; /* 16. */
4222 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4223 ovs_be16 subtype
; /* NXAST_FIN_TIMEOUT. */
4224 ovs_be16 fin_idle_timeout
; /* New idle timeout, if nonzero. */
4225 ovs_be16 fin_hard_timeout
; /* New hard timeout, if nonzero. */
4226 ovs_be16 pad
; /* Must be zero. */
4228 OFP_ASSERT(sizeof(struct nx_action_fin_timeout
) == 16);
4231 decode_NXAST_RAW_FIN_TIMEOUT(const struct nx_action_fin_timeout
*naft
,
4232 enum ofp_version ofp_version OVS_UNUSED
,
4235 struct ofpact_fin_timeout
*oft
;
4237 oft
= ofpact_put_FIN_TIMEOUT(out
);
4238 oft
->fin_idle_timeout
= ntohs(naft
->fin_idle_timeout
);
4239 oft
->fin_hard_timeout
= ntohs(naft
->fin_hard_timeout
);
4244 encode_FIN_TIMEOUT(const struct ofpact_fin_timeout
*fin_timeout
,
4245 enum ofp_version ofp_version OVS_UNUSED
,
4248 struct nx_action_fin_timeout
*naft
= put_NXAST_FIN_TIMEOUT(out
);
4249 naft
->fin_idle_timeout
= htons(fin_timeout
->fin_idle_timeout
);
4250 naft
->fin_hard_timeout
= htons(fin_timeout
->fin_hard_timeout
);
4253 static char * OVS_WARN_UNUSED_RESULT
4254 parse_FIN_TIMEOUT(char *arg
, const struct ofpact_parse_params
*pp
)
4256 struct ofpact_fin_timeout
*oft
= ofpact_put_FIN_TIMEOUT(pp
->ofpacts
);
4259 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
4262 if (!strcmp(key
, "idle_timeout")) {
4263 error
= str_to_u16(value
, key
, &oft
->fin_idle_timeout
);
4264 } else if (!strcmp(key
, "hard_timeout")) {
4265 error
= str_to_u16(value
, key
, &oft
->fin_hard_timeout
);
4267 error
= xasprintf("invalid key '%s' in 'fin_timeout' argument",
4279 format_FIN_TIMEOUT(const struct ofpact_fin_timeout
*a
,
4280 const struct ofpact_format_params
*fp
)
4282 ds_put_format(fp
->s
, "%sfin_timeout(%s", colors
.paren
, colors
.end
);
4283 if (a
->fin_idle_timeout
) {
4284 ds_put_format(fp
->s
, "%sidle_timeout=%s%"PRIu16
",",
4285 colors
.param
, colors
.end
, a
->fin_idle_timeout
);
4287 if (a
->fin_hard_timeout
) {
4288 ds_put_format(fp
->s
, "%shard_timeout=%s%"PRIu16
",",
4289 colors
.param
, colors
.end
, a
->fin_hard_timeout
);
4291 ds_chomp(fp
->s
, ',');
4292 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
4297 check_FIN_TIMEOUT(const struct ofpact_fin_timeout
*a OVS_UNUSED
,
4298 struct ofpact_check_params
*cp
)
4300 if (cp
->match
->flow
.nw_proto
!= IPPROTO_TCP
) {
4301 inconsistent_match(&cp
->usable_protocols
);
4306 /* Action structure for NXAST_ENCAP */
4307 struct nx_action_encap
{
4308 ovs_be16 type
; /* OFPAT_VENDOR. */
4309 ovs_be16 len
; /* Total size including any property TLVs. */
4310 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4311 ovs_be16 subtype
; /* NXAST_ENCAP. */
4312 ovs_be16 hdr_size
; /* Header size in bytes, 0 = 'not specified'.*/
4313 ovs_be32 new_pkt_type
; /* Header type to add and PACKET_TYPE of result. */
4314 struct ofp_ed_prop_header props
[]; /* Encap TLV properties. */
4316 OFP_ASSERT(sizeof(struct nx_action_encap
) == 16);
4319 decode_NXAST_RAW_ENCAP(const struct nx_action_encap
*nae
,
4320 enum ofp_version ofp_version OVS_UNUSED
,
4323 struct ofpact_encap
*encap
;
4324 const struct ofp_ed_prop_header
*ofp_prop
;
4326 uint16_t n_props
= 0;
4329 encap
= ofpact_put_ENCAP(out
);
4330 encap
->ofpact
.raw
= NXAST_RAW_ENCAP
;
4331 switch (ntohl(nae
->new_pkt_type
)) {
4334 /* Add supported encap header types here. */
4337 return OFPERR_NXBAC_BAD_HEADER_TYPE
;
4339 encap
->new_pkt_type
= nae
->new_pkt_type
;
4340 encap
->hdr_size
= ntohs(nae
->hdr_size
);
4342 ofp_prop
= nae
->props
;
4343 props_len
= ntohs(nae
->len
) - offsetof(struct nx_action_encap
, props
);
4345 while (props_len
> 0) {
4346 err
= decode_ed_prop(&ofp_prop
, out
, &props_len
);
4352 encap
->n_props
= n_props
;
4353 out
->header
= &encap
->ofpact
;
4354 ofpact_finish_ENCAP(out
, &encap
);
4360 encode_ENCAP(const struct ofpact_encap
*encap
,
4361 enum ofp_version ofp_version OVS_UNUSED
,
4364 size_t start_ofs
= out
->size
;
4365 struct nx_action_encap
*nae
= put_NXAST_ENCAP(out
);
4368 nae
->new_pkt_type
= encap
->new_pkt_type
;
4369 nae
->hdr_size
= htons(encap
->hdr_size
);
4370 const struct ofpact_ed_prop
*prop
= encap
->props
;
4371 for (i
= 0; i
< encap
->n_props
; i
++) {
4372 encode_ed_prop(&prop
, out
);
4374 pad_ofpat(out
, start_ofs
);
4378 parse_encap_header(const char *hdr
, ovs_be32
*packet_type
)
4380 if (strcmp(hdr
, "ethernet") == 0) {
4381 *packet_type
= htonl(PT_ETH
);
4382 } else if (strcmp(hdr
, "nsh") == 0) {
4383 *packet_type
= htonl(PT_NSH
);
4391 parse_ed_props(const uint16_t prop_class
, char **arg
, int *n_props
, struct ofpbuf
*out
)
4393 char *key
, *value
, *err
;
4396 while (ofputil_parse_key_value(arg
, &key
, &value
)) {
4397 if (!parse_ed_prop_type(prop_class
, key
, &prop_type
)) {
4398 return xasprintf("Invalid property: %s", key
);
4400 if (value
== NULL
) {
4401 return xasprintf("Missing the value for property: %s", key
);
4403 err
= parse_ed_prop_value(prop_class
, prop_type
, value
, out
);
4412 /* The string representation of the encap action is
4413 * encap(header_type(prop=<value>,tlv(<class>,<type>,<value>),...))
4416 static char * OVS_WARN_UNUSED_RESULT
4417 parse_ENCAP(char *arg
, const struct ofpact_parse_params
*pp
)
4419 struct ofpact_encap
*encap
;
4420 char *key
, *value
, *str
;
4422 uint16_t prop_class
;
4425 encap
= ofpact_put_ENCAP(pp
->ofpacts
);
4426 encap
->hdr_size
= 0;
4427 /* Parse encap header type. */
4429 if (!ofputil_parse_key_value(&arg
, &key
, &value
)) {
4430 return xasprintf("Missing encap hdr: %s", str
);
4432 if (!parse_encap_header(key
, &encap
->new_pkt_type
)) {
4433 return xasprintf("Encap hdr not supported: %s", value
);
4435 if (!parse_ed_prop_class(key
, &prop_class
)) {
4436 return xasprintf("Invalid encap prop class: %s", key
);
4438 /* Parse encap properties. */
4439 error
= parse_ed_props(prop_class
, &value
, &n_props
, pp
->ofpacts
);
4440 if (error
!= NULL
) {
4443 /* ofpbuf may have been re-allocated. */
4444 encap
= pp
->ofpacts
->header
;
4445 encap
->n_props
= n_props
;
4446 ofpact_finish_ENCAP(pp
->ofpacts
, &encap
);
4451 format_encap_pkt_type(const ovs_be32 pkt_type
)
4453 switch (ntohl(pkt_type
)) {
4464 format_ed_props(struct ds
*s
, uint16_t n_props
,
4465 const struct ofpact_ed_prop
*prop
)
4467 const uint8_t *p
= (uint8_t *) prop
;
4473 for (i
= 0; i
< n_props
; i
++) {
4474 format_ed_prop(s
, prop
);
4475 ds_put_char(s
, ',');
4476 p
+= ROUND_UP(prop
->len
, 8);
4477 prop
= ALIGNED_CAST(const struct ofpact_ed_prop
*, p
);
4485 format_ENCAP(const struct ofpact_encap
*a
,
4486 const struct ofpact_format_params
*fp
)
4488 ds_put_format(fp
->s
, "%sencap(%s", colors
.paren
, colors
.end
);
4489 ds_put_format(fp
->s
, "%s", format_encap_pkt_type(a
->new_pkt_type
));
4490 if (a
->n_props
> 0) {
4491 ds_put_format(fp
->s
, "%s(%s", colors
.paren
, colors
.end
);
4492 format_ed_props(fp
->s
, a
->n_props
, a
->props
);
4493 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
4495 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
4499 check_ENCAP(const struct ofpact_encap
*a
, struct ofpact_check_params
*cp
)
4501 struct flow
*flow
= &cp
->match
->flow
;
4502 flow
->packet_type
= a
->new_pkt_type
;
4503 if (pt_ns(flow
->packet_type
) == OFPHTN_ETHERTYPE
) {
4504 flow
->dl_type
= htons(pt_ns_type(flow
->packet_type
));
4506 if (!is_ip_any(flow
)) {
4512 /* Action structure for NXAST_DECAP */
4513 struct nx_action_decap
{
4514 ovs_be16 type
; /* OFPAT_VENDOR. */
4515 ovs_be16 len
; /* Total size including any property TLVs. */
4516 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4517 ovs_be16 subtype
; /* NXAST_DECAP. */
4518 uint8_t pad
[2]; /* 2 bytes padding */
4520 /* Packet type or result.
4522 * The special value (0,0xFFFE) "Use next proto"
4523 * is used to request OVS to automatically set the new packet type based
4524 * on the decap'ed header's next protocol.
4526 ovs_be32 new_pkt_type
;
4528 OFP_ASSERT(sizeof(struct nx_action_decap
) == 16);
4531 decode_NXAST_RAW_DECAP(const struct nx_action_decap
*nad
,
4532 enum ofp_version ofp_version OVS_UNUSED
,
4533 struct ofpbuf
*ofpacts
)
4535 struct ofpact_decap
* decap
;
4537 if (ntohs(nad
->len
) > sizeof *nad
) {
4538 /* No properties supported yet. */
4539 return OFPERR_NXBAC_UNKNOWN_ED_PROP
;
4542 decap
= ofpact_put_DECAP(ofpacts
);
4543 decap
->ofpact
.raw
= NXAST_RAW_DECAP
;
4544 decap
->new_pkt_type
= nad
->new_pkt_type
;
4549 encode_DECAP(const struct ofpact_decap
*decap
,
4550 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
4552 struct nx_action_decap
*nad
= put_NXAST_DECAP(out
);
4554 nad
->len
= htons(sizeof(struct nx_action_decap
));
4555 nad
->new_pkt_type
= decap
->new_pkt_type
;
4558 static char * OVS_WARN_UNUSED_RESULT
4559 parse_DECAP(char *arg
, const struct ofpact_parse_params
*pp
)
4561 struct ofpact_decap
*decap
;
4562 char *key
, *value
, *pos
;
4566 decap
= ofpact_put_DECAP(pp
->ofpacts
);
4567 /* Default next packet_type is PT_USE_NEXT_PROTO. */
4568 decap
->new_pkt_type
= htonl(PT_USE_NEXT_PROTO
);
4570 /* Parse decap packet_type if given. */
4571 if (ofputil_parse_key_value(&arg
, &key
, &value
)) {
4572 if (strcmp(key
, "packet_type") == 0) {
4574 if (!ofputil_parse_key_value(&pos
, &key
, &value
)
4575 || strcmp(key
, "ns") != 0) {
4576 return xstrdup("Missing packet_type attribute ns");
4578 error
= str_to_u16(value
, "ns", &ns
);
4582 if (ns
>= OFPHTN_N_TYPES
) {
4583 return xasprintf("Unsupported ns value: %"PRIu16
, ns
);
4585 if (!ofputil_parse_key_value(&pos
, &key
, &value
)
4586 || strcmp(key
, "type") != 0) {
4587 return xstrdup("Missing packet_type attribute type");
4589 error
= str_to_u16(value
, "type", &type
);
4593 decap
->new_pkt_type
= htonl(PACKET_TYPE(ns
, type
));
4595 return xasprintf("Invalid decap argument: %s", key
);
4602 format_DECAP(const struct ofpact_decap
*a
,
4603 const struct ofpact_format_params
*fp
)
4605 ds_put_format(fp
->s
, "%sdecap(%s", colors
.paren
, colors
.end
);
4606 if (a
->new_pkt_type
!= htonl(PT_USE_NEXT_PROTO
)) {
4607 ds_put_format(fp
->s
, "packet_type(ns=%"PRIu16
",id=%#"PRIx16
")",
4608 pt_ns(a
->new_pkt_type
),
4609 pt_ns_type(a
->new_pkt_type
));
4611 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
4615 check_DECAP(const struct ofpact_decap
*a OVS_UNUSED
,
4616 struct ofpact_check_params
*cp
)
4618 struct flow
*flow
= &cp
->match
->flow
;
4619 if (flow
->packet_type
== htonl(PT_ETH
)) {
4620 /* Adjust the packet_type to allow subsequent actions. */
4621 flow
->packet_type
= PACKET_TYPE_BE(OFPHTN_ETHERTYPE
,
4622 ntohs(flow
->dl_type
));
4624 /* The actual packet_type is only known after decapsulation.
4625 * Do not allow subsequent actions that depend on packet headers. */
4626 flow
->packet_type
= htonl(PT_UNKNOWN
);
4627 flow
->dl_type
= OVS_BE16_MAX
;
4632 /* Action dec_nsh_ttl */
4635 decode_NXAST_RAW_DEC_NSH_TTL(struct ofpbuf
*out
)
4637 ofpact_put_DEC_NSH_TTL(out
);
4642 encode_DEC_NSH_TTL(const struct ofpact_null
*null OVS_UNUSED
,
4643 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
4645 put_NXAST_DEC_NSH_TTL(out
);
4648 static char * OVS_WARN_UNUSED_RESULT
4649 parse_DEC_NSH_TTL(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
4651 ofpact_put_DEC_NSH_TTL(pp
->ofpacts
);
4656 format_DEC_NSH_TTL(const struct ofpact_null
*a OVS_UNUSED
,
4657 const struct ofpact_format_params
*fp
)
4659 ds_put_format(fp
->s
, "%sdec_nsh_ttl%s", colors
.special
, colors
.end
);
4663 check_DEC_NSH_TTL(const struct ofpact_null
*a OVS_UNUSED
,
4664 struct ofpact_check_params
*cp
)
4666 struct flow
*flow
= &cp
->match
->flow
;
4667 if (flow
->packet_type
!= htonl(PT_NSH
) &&
4668 flow
->dl_type
!= htons(ETH_TYPE_NSH
)) {
4669 inconsistent_match(&cp
->usable_protocols
);
4674 /* Action structures for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE, and
4675 * NXAST_RESUBMIT_TABLE_CT.
4677 * These actions search one of the switch's flow tables:
4679 * - For NXAST_RESUBMIT_TABLE and NXAST_RESUBMIT_TABLE_CT, if the
4680 * 'table' member is not 255, then it specifies the table to search.
4682 * - Otherwise (for NXAST_RESUBMIT_TABLE or NXAST_RESUBMIT_TABLE_CT with a
4683 * 'table' of 255, or for NXAST_RESUBMIT regardless of 'table'), it
4684 * searches the current flow table, that is, the OpenFlow flow table that
4685 * contains the flow from which this action was obtained. If this action
4686 * did not come from a flow table (e.g. it came from an OFPT_PACKET_OUT
4687 * message), then table 0 is the current table.
4689 * The flow table lookup uses a flow that may be slightly modified from the
4692 * - For NXAST_RESUBMIT, the 'in_port' member of struct nx_action_resubmit
4693 * is used as the flow's in_port.
4695 * - For NXAST_RESUBMIT_TABLE and NXAST_RESUBMIT_TABLE_CT, if the 'in_port'
4696 * member is not OFPP_IN_PORT, then its value is used as the flow's
4697 * in_port. Otherwise, the original in_port is used.
4699 * - For NXAST_RESUBMIT_TABLE_CT the Conntrack 5-tuple fields are used as
4700 * the packets IP header fields during the lookup.
4702 * - If actions that modify the flow (e.g. OFPAT_SET_VLAN_VID) precede the
4703 * resubmit action, then the flow is updated with the new values.
4705 * Following the lookup, the original in_port is restored.
4707 * If the modified flow matched in the flow table, then the corresponding
4708 * actions are executed. Afterward, actions following the resubmit in the
4709 * original set of actions, if any, are executed; any changes made to the
4710 * packet (e.g. changes to VLAN) by secondary actions persist when those
4711 * actions are executed, although the original in_port is restored.
4713 * Resubmit actions may be used any number of times within a set of actions.
4715 * Resubmit actions may nest. To prevent infinite loops and excessive resource
4716 * use, the implementation may limit nesting depth and the total number of
4719 * - Open vSwitch 1.0.1 and earlier did not support recursion.
4721 * - Open vSwitch 1.0.2 and 1.0.3 limited recursion to 8 levels.
4723 * - Open vSwitch 1.1 and 1.2 limited recursion to 16 levels.
4725 * - Open vSwitch 1.2 through 1.8 limited recursion to 32 levels.
4727 * - Open vSwitch 1.9 through 2.0 limited recursion to 64 levels.
4729 * - Open vSwitch 2.1 through 2.5 limited recursion to 64 levels and impose
4730 * a total limit of 4,096 resubmits per flow translation (earlier versions
4731 * did not impose any total limit).
4733 * NXAST_RESUBMIT ignores 'table' and 'pad'. NXAST_RESUBMIT_TABLE and
4734 * NXAST_RESUBMIT_TABLE_CT require 'pad' to be all-bits-zero.
4736 * Open vSwitch 1.0.1 and earlier did not support recursion. Open vSwitch
4737 * before 1.2.90 did not support NXAST_RESUBMIT_TABLE. Open vSwitch before
4738 * 2.8.0 did not support NXAST_RESUBMIT_TABLE_CT.
4740 struct nx_action_resubmit
{
4741 ovs_be16 type
; /* OFPAT_VENDOR. */
4742 ovs_be16 len
; /* Length is 16. */
4743 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4744 ovs_be16 subtype
; /* NXAST_RESUBMIT. */
4745 ovs_be16 in_port
; /* New in_port for checking flow table. */
4746 uint8_t table
; /* NXAST_RESUBMIT_TABLE: table to use. */
4749 OFP_ASSERT(sizeof(struct nx_action_resubmit
) == 16);
4752 decode_NXAST_RAW_RESUBMIT(uint16_t port
,
4753 enum ofp_version ofp_version OVS_UNUSED
,
4756 struct ofpact_resubmit
*resubmit
;
4758 resubmit
= ofpact_put_RESUBMIT(out
);
4759 resubmit
->ofpact
.raw
= NXAST_RAW_RESUBMIT
;
4760 resubmit
->in_port
= u16_to_ofp(port
);
4761 resubmit
->table_id
= 0xff;
4766 decode_NXAST_RAW_RESUBMIT_TABLE(const struct nx_action_resubmit
*nar
,
4767 enum ofp_version ofp_version OVS_UNUSED
,
4770 struct ofpact_resubmit
*resubmit
;
4772 if (nar
->pad
[0] || nar
->pad
[1] || nar
->pad
[2]) {
4773 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4776 resubmit
= ofpact_put_RESUBMIT(out
);
4777 resubmit
->ofpact
.raw
= NXAST_RAW_RESUBMIT_TABLE
;
4778 resubmit
->in_port
= u16_to_ofp(ntohs(nar
->in_port
));
4779 resubmit
->table_id
= nar
->table
;
4784 decode_NXAST_RAW_RESUBMIT_TABLE_CT(const struct nx_action_resubmit
*nar
,
4785 enum ofp_version ofp_version OVS_UNUSED
,
4788 enum ofperr error
= decode_NXAST_RAW_RESUBMIT_TABLE(nar
, ofp_version
, out
);
4792 struct ofpact_resubmit
*resubmit
= out
->header
;
4793 resubmit
->ofpact
.raw
= NXAST_RAW_RESUBMIT_TABLE_CT
;
4794 resubmit
->with_ct_orig
= true;
4799 encode_RESUBMIT(const struct ofpact_resubmit
*resubmit
,
4800 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
4802 uint16_t in_port
= ofp_to_u16(resubmit
->in_port
);
4804 if (resubmit
->table_id
== 0xff
4805 && resubmit
->ofpact
.raw
== NXAST_RAW_RESUBMIT
) {
4806 put_NXAST_RESUBMIT(out
, in_port
);
4808 struct nx_action_resubmit
*nar
;
4809 nar
= resubmit
->with_ct_orig
4810 ? put_NXAST_RESUBMIT_TABLE_CT(out
) : put_NXAST_RESUBMIT_TABLE(out
);
4811 nar
->table
= resubmit
->table_id
;
4812 nar
->in_port
= htons(in_port
);
4816 static char * OVS_WARN_UNUSED_RESULT
4817 parse_RESUBMIT(char *arg
, const struct ofpact_parse_params
*pp
)
4819 struct ofpact_resubmit
*resubmit
;
4820 char *in_port_s
, *table_s
, *ct_s
;
4822 resubmit
= ofpact_put_RESUBMIT(pp
->ofpacts
);
4824 in_port_s
= strsep(&arg
, ",");
4825 if (in_port_s
&& in_port_s
[0]) {
4826 if (!ofputil_port_from_string(in_port_s
, pp
->port_map
,
4827 &resubmit
->in_port
)) {
4828 return xasprintf("%s: resubmit to unknown port", in_port_s
);
4831 resubmit
->in_port
= OFPP_IN_PORT
;
4834 table_s
= strsep(&arg
, ",");
4835 if (table_s
&& table_s
[0]) {
4836 if (!ofputil_table_from_string(table_s
, pp
->table_map
,
4837 &resubmit
->table_id
)) {
4838 return xasprintf("%s: resubmit to unknown table", table_s
);
4841 resubmit
->table_id
= 255;
4844 ct_s
= strsep(&arg
, ",");
4845 if (ct_s
&& ct_s
[0]) {
4846 if (strcmp(ct_s
, "ct")) {
4847 return xasprintf("%s: unknown parameter", ct_s
);
4849 resubmit
->with_ct_orig
= true;
4851 resubmit
->with_ct_orig
= false;
4854 if (resubmit
->in_port
== OFPP_IN_PORT
&& resubmit
->table_id
== 255) {
4855 return xstrdup("at least one \"in_port\" or \"table\" must be "
4856 "specified on resubmit");
4862 format_RESUBMIT(const struct ofpact_resubmit
*a
,
4863 const struct ofpact_format_params
*fp
)
4865 if (a
->in_port
!= OFPP_IN_PORT
&& a
->table_id
== 255) {
4866 ds_put_format(fp
->s
, "%sresubmit:%s", colors
.special
, colors
.end
);
4867 ofputil_format_port(a
->in_port
, fp
->port_map
, fp
->s
);
4869 ds_put_format(fp
->s
, "%sresubmit(%s", colors
.paren
, colors
.end
);
4870 if (a
->in_port
!= OFPP_IN_PORT
) {
4871 ofputil_format_port(a
->in_port
, fp
->port_map
, fp
->s
);
4873 ds_put_char(fp
->s
, ',');
4874 if (a
->table_id
!= 255) {
4875 ofputil_format_table(a
->table_id
, fp
->table_map
, fp
->s
);
4877 if (a
->with_ct_orig
) {
4878 ds_put_cstr(fp
->s
, ",ct");
4880 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
4885 check_RESUBMIT(const struct ofpact_resubmit
*a
,
4886 const struct ofpact_check_params
*cp
)
4888 if (a
->with_ct_orig
&& !is_ct_valid(&cp
->match
->flow
, &cp
->match
->wc
,
4890 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
4895 /* Action structure for NXAST_LEARN and NXAST_LEARN2.
4897 * This action adds or modifies a flow in an OpenFlow table, similar to
4898 * OFPT_FLOW_MOD with OFPFC_MODIFY_STRICT as 'command'. The new flow has the
4899 * specified idle timeout, hard timeout, priority, cookie, and flags. The new
4900 * flow's match criteria and actions are built by applying each of the series
4901 * of flow_mod_spec elements included as part of the action.
4903 * A flow_mod_spec starts with a 16-bit header. A header that is all-bits-0 is
4904 * a no-op used for padding the action as a whole to a multiple of 8 bytes in
4905 * length. Otherwise, the flow_mod_spec can be thought of as copying 'n_bits'
4906 * bits from a source to a destination. In this case, the header contains
4909 * 15 14 13 12 11 10 0
4910 * +------+---+------+---------------------------------+
4911 * | 0 |src| dst | n_bits |
4912 * +------+---+------+---------------------------------+
4914 * The meaning and format of a flow_mod_spec depends on 'src' and 'dst'. The
4915 * following table summarizes the meaning of each possible combination.
4916 * Details follow the table:
4919 * --- --- ----------------------------------------------------------
4920 * 0 0 Add match criteria based on value in a field.
4921 * 1 0 Add match criteria based on an immediate value.
4922 * 0 1 Add NXAST_REG_LOAD action to copy field into a different field.
4923 * 1 1 Add NXAST_REG_LOAD action to load immediate value into a field.
4924 * 0 2 Add OFPAT_OUTPUT action to output to port from specified field.
4925 * All other combinations are undefined and not allowed.
4927 * The flow_mod_spec header is followed by a source specification and a
4928 * destination specification. The format and meaning of the source
4929 * specification depends on 'src':
4931 * - If 'src' is 0, the source bits are taken from a field in the flow to
4932 * which this action is attached. (This should be a wildcarded field. If
4933 * its value is fully specified then the source bits being copied have
4936 * The source specification is an ovs_be32 'field' and an ovs_be16 'ofs'.
4937 * 'field' is an nxm_header with nxm_hasmask=0, and 'ofs' the starting bit
4938 * offset within that field. The source bits are field[ofs:ofs+n_bits-1].
4939 * 'field' and 'ofs' are subject to the same restrictions as the source
4940 * field in NXAST_REG_MOVE.
4942 * - If 'src' is 1, the source bits are a constant value. The source
4943 * specification is (n_bits+15)/16*2 bytes long. Taking those bytes as a
4944 * number in network order, the source bits are the 'n_bits'
4945 * least-significant bits. The switch will report an error if other bits
4946 * in the constant are nonzero.
4948 * The flow_mod_spec destination specification, for 'dst' of 0 or 1, is an
4949 * ovs_be32 'field' and an ovs_be16 'ofs'. 'field' is an nxm_header with
4950 * nxm_hasmask=0 and 'ofs' is a starting bit offset within that field. The
4951 * meaning of the flow_mod_spec depends on 'dst':
4953 * - If 'dst' is 0, the flow_mod_spec specifies match criteria for the new
4954 * flow. The new flow matches only if bits field[ofs:ofs+n_bits-1] in a
4955 * packet equal the source bits. 'field' may be any nxm_header with
4956 * nxm_hasmask=0 that is allowed in NXT_FLOW_MOD.
4958 * Order is significant. Earlier flow_mod_specs must satisfy any
4959 * prerequisites for matching fields specified later, by copying constant
4960 * values into prerequisite fields.
4962 * The switch will reject flow_mod_specs that do not satisfy NXM masking
4965 * - If 'dst' is 1, the flow_mod_spec specifies an NXAST_REG_LOAD action for
4966 * the new flow. The new flow copies the source bits into
4967 * field[ofs:ofs+n_bits-1]. Actions are executed in the same order as the
4970 * A single NXAST_REG_LOAD action writes no more than 64 bits, so n_bits
4971 * greater than 64 yields multiple NXAST_REG_LOAD actions.
4973 * The flow_mod_spec destination spec for 'dst' of 2 (when 'src' is 0) is
4974 * empty. It has the following meaning:
4976 * - The flow_mod_spec specifies an OFPAT_OUTPUT action for the new flow.
4977 * The new flow outputs to the OpenFlow port specified by the source field.
4978 * Of the special output ports with value OFPP_MAX or larger, OFPP_IN_PORT,
4979 * OFPP_FLOOD, OFPP_LOCAL, and OFPP_ALL are supported. Other special ports
4982 * Resource Management
4983 * -------------------
4985 * A switch has a finite amount of flow table space available for learning.
4986 * When this space is exhausted, no new learning table entries will be learned
4987 * until some existing flow table entries expire. The controller should be
4988 * prepared to handle this by flooding (which can be implemented as a
4989 * low-priority flow).
4991 * If a learned flow matches a single TCP stream with a relatively long
4992 * timeout, one may make the best of resource constraints by setting
4993 * 'fin_idle_timeout' or 'fin_hard_timeout' (both measured in seconds), or
4994 * both, to shorter timeouts. When either of these is specified as a nonzero
4995 * value, OVS adds a NXAST_FIN_TIMEOUT action, with the specified timeouts, to
5001 * The following examples give a prose description of the flow_mod_specs along
5002 * with informal notation for how those would be represented and a hex dump of
5003 * the bytes that would be required.
5005 * These examples could work with various nx_action_learn parameters. Typical
5006 * values would be idle_timeout=OFP_FLOW_PERMANENT, hard_timeout=60,
5007 * priority=OFP_DEFAULT_PRIORITY, flags=0, table_id=10.
5009 * 1. Learn input port based on the source MAC, with lookup into
5010 * NXM_NX_REG1[16:31] by resubmit to in_port=99:
5012 * Match on in_port=99:
5013 * ovs_be16(src=1, dst=0, n_bits=16), 20 10
5014 * ovs_be16(99), 00 63
5015 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
5017 * Match Ethernet destination on Ethernet source from packet:
5018 * ovs_be16(src=0, dst=0, n_bits=48), 00 30
5019 * ovs_be32(NXM_OF_ETH_SRC), ovs_be16(0) 00 00 04 06 00 00
5020 * ovs_be32(NXM_OF_ETH_DST), ovs_be16(0) 00 00 02 06 00 00
5022 * Set NXM_NX_REG1[16:31] to the packet's input port:
5023 * ovs_be16(src=0, dst=1, n_bits=16), 08 10
5024 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
5025 * ovs_be32(NXM_NX_REG1), ovs_be16(16) 00 01 02 04 00 10
5027 * Given a packet that arrived on port A with Ethernet source address B,
5028 * this would set up the flow "in_port=99, dl_dst=B,
5029 * actions=load:A->NXM_NX_REG1[16..31]".
5031 * In syntax accepted by ovs-ofctl, this action is: learn(in_port=99,
5032 * NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
5033 * load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
5035 * 2. Output to input port based on the source MAC and VLAN VID, with lookup
5036 * into NXM_NX_REG1[16:31]:
5038 * Match on same VLAN ID as packet:
5039 * ovs_be16(src=0, dst=0, n_bits=12), 00 0c
5040 * ovs_be32(NXM_OF_VLAN_TCI), ovs_be16(0) 00 00 08 02 00 00
5041 * ovs_be32(NXM_OF_VLAN_TCI), ovs_be16(0) 00 00 08 02 00 00
5043 * Match Ethernet destination on Ethernet source from packet:
5044 * ovs_be16(src=0, dst=0, n_bits=48), 00 30
5045 * ovs_be32(NXM_OF_ETH_SRC), ovs_be16(0) 00 00 04 06 00 00
5046 * ovs_be32(NXM_OF_ETH_DST), ovs_be16(0) 00 00 02 06 00 00
5048 * Output to the packet's input port:
5049 * ovs_be16(src=0, dst=2, n_bits=16), 10 10
5050 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
5052 * Given a packet that arrived on port A with Ethernet source address B in
5053 * VLAN C, this would set up the flow "dl_dst=B, vlan_vid=C,
5054 * actions=output:A".
5056 * In syntax accepted by ovs-ofctl, this action is:
5057 * learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
5058 * output:NXM_OF_IN_PORT[])
5060 * 3. Here's a recipe for a very simple-minded MAC learning switch. It uses a
5061 * 10-second MAC expiration time to make it easier to see what's going on
5063 * ovs-vsctl del-controller br0
5064 * ovs-ofctl del-flows br0
5065 * ovs-ofctl add-flow br0 "table=0 actions=learn(table=1, \
5066 hard_timeout=10, NXM_OF_VLAN_TCI[0..11], \
5067 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
5068 output:NXM_OF_IN_PORT[]), resubmit(,1)"
5069 * ovs-ofctl add-flow br0 "table=1 priority=0 actions=flood"
5071 * You can then dump the MAC learning table with:
5073 * ovs-ofctl dump-flows br0 table=1
5078 * For best performance, segregate learned flows into a table that is not used
5079 * for any other flows except possibly for a lowest-priority "catch-all" flow
5080 * (a flow with no match criteria). If different learning actions specify
5081 * different match criteria, use different tables for the learned flows.
5083 * The meaning of 'hard_timeout' and 'idle_timeout' can be counterintuitive.
5084 * These timeouts apply to the flow that is added, which means that a flow with
5085 * an idle timeout will expire when no traffic has been sent *to* the learned
5086 * address. This is not usually the intent in MAC learning; instead, we want
5087 * the MAC learn entry to expire when no traffic has been sent *from* the
5088 * learned address. Use a hard timeout for that.
5091 * Visibility of Changes
5092 * ---------------------
5094 * Prior to Open vSwitch 2.4, any changes made by a "learn" action in a given
5095 * flow translation are visible to flow table lookups made later in the flow
5096 * translation. This means that, in the example above, a MAC learned by the
5097 * learn action in table 0 would be found in table 1 (if the packet being
5098 * processed had the same source and destination MAC address).
5100 * In Open vSwitch 2.4 and later, changes to a flow table (whether to add or
5101 * modify a flow) by a "learn" action are visible only for later flow
5102 * translations, not for later lookups within the same flow translation. In
5103 * the MAC learning example, a MAC learned by the learn action in table 0 would
5104 * not be found in table 1 if the flow translation would resubmit to table 1
5105 * after the processing of the learn action, meaning that if this MAC had not
5106 * been learned before then the packet would be flooded. */
5107 struct nx_action_learn
{
5108 ovs_be16 type
; /* OFPAT_VENDOR. */
5109 ovs_be16 len
; /* At least 24. */
5110 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5111 ovs_be16 subtype
; /* NXAST_LEARN. */
5112 ovs_be16 idle_timeout
; /* Idle time before discarding (seconds). */
5113 ovs_be16 hard_timeout
; /* Max time before discarding (seconds). */
5114 ovs_be16 priority
; /* Priority level of flow entry. */
5115 ovs_be64 cookie
; /* Cookie for new flow. */
5116 ovs_be16 flags
; /* NX_LEARN_F_*. */
5117 uint8_t table_id
; /* Table to insert flow entry. */
5118 uint8_t pad
; /* Must be zero. */
5119 ovs_be16 fin_idle_timeout
; /* Idle timeout after FIN, if nonzero. */
5120 ovs_be16 fin_hard_timeout
; /* Hard timeout after FIN, if nonzero. */
5121 /* Followed by a sequence of flow_mod_spec elements, as described above,
5122 * until the end of the action is reached. */
5124 OFP_ASSERT(sizeof(struct nx_action_learn
) == 32);
5126 struct nx_action_learn2
{
5127 struct nx_action_learn up
; /* The wire format includes nx_action_learn. */
5128 ovs_be32 limit
; /* Maximum number of learned flows.
5129 * 0 indicates unlimited. */
5131 /* Where to store the result. */
5132 ovs_be16 result_dst_ofs
; /* Starting bit offset in destination. */
5134 ovs_be16 pad2
; /* Must be zero. */
5136 * - OXM/NXM header for destination field (4 or 8 bytes),
5137 * if NX_LEARN_F_WRITE_RESULT is set in 'flags'
5138 * - a sequence of flow_mod_spec elements, as described above,
5139 * until the end of the action is reached. */
5141 OFP_ASSERT(sizeof(struct nx_action_learn2
) == 40);
5144 get_be16(const void **pp
)
5146 const ovs_be16
*p
= *pp
;
5147 ovs_be16 value
= *p
;
5153 get_be32(const void **pp
)
5155 const ovs_be32
*p
= *pp
;
5156 ovs_be32 value
= get_unaligned_be32(p
);
5162 get_subfield(int n_bits
, const void **p
, struct mf_subfield
*sf
,
5163 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
)
5167 error
= mf_vl_mff_mf_from_nxm_header(ntohl(get_be32(p
)), vl_mff_map
,
5168 &sf
->field
, tlv_bitmap
);
5169 sf
->ofs
= ntohs(get_be16(p
));
5170 sf
->n_bits
= n_bits
;
5175 learn_min_len(uint16_t header
)
5177 int n_bits
= header
& NX_LEARN_N_BITS_MASK
;
5178 int src_type
= header
& NX_LEARN_SRC_MASK
;
5179 int dst_type
= header
& NX_LEARN_DST_MASK
;
5180 unsigned int min_len
;
5183 if (src_type
== NX_LEARN_SRC_FIELD
) {
5184 min_len
+= sizeof(ovs_be32
); /* src_field */
5185 min_len
+= sizeof(ovs_be16
); /* src_ofs */
5187 min_len
+= 2 * DIV_ROUND_UP(n_bits
, 16);
5189 if (dst_type
== NX_LEARN_DST_MATCH
||
5190 dst_type
== NX_LEARN_DST_LOAD
) {
5191 min_len
+= sizeof(ovs_be32
); /* dst_field */
5192 min_len
+= sizeof(ovs_be16
); /* dst_ofs */
5198 decode_LEARN_common(const struct nx_action_learn
*nal
,
5199 enum ofp_raw_action_type raw
,
5200 struct ofpact_learn
*learn
)
5203 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5206 learn
->ofpact
.raw
= raw
;
5207 learn
->idle_timeout
= ntohs(nal
->idle_timeout
);
5208 learn
->hard_timeout
= ntohs(nal
->hard_timeout
);
5209 learn
->priority
= ntohs(nal
->priority
);
5210 learn
->cookie
= nal
->cookie
;
5211 learn
->table_id
= nal
->table_id
;
5212 learn
->fin_idle_timeout
= ntohs(nal
->fin_idle_timeout
);
5213 learn
->fin_hard_timeout
= ntohs(nal
->fin_hard_timeout
);
5214 learn
->flags
= ntohs(nal
->flags
);
5216 if (learn
->table_id
== 0xff) {
5217 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5224 decode_LEARN_specs(const void *p
, const void *end
,
5225 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
5226 struct ofpbuf
*ofpacts
)
5228 struct ofpact_learn
*learn
= ofpacts
->header
;
5231 struct ofpact_learn_spec
*spec
;
5232 uint16_t header
= ntohs(get_be16(&p
));
5238 spec
= ofpbuf_put_zeros(ofpacts
, sizeof *spec
);
5239 learn
= ofpacts
->header
;
5241 spec
->src_type
= header
& NX_LEARN_SRC_MASK
;
5242 spec
->dst_type
= header
& NX_LEARN_DST_MASK
;
5243 spec
->n_bits
= header
& NX_LEARN_N_BITS_MASK
;
5245 /* Check for valid src and dst type combination. */
5246 if (spec
->dst_type
== NX_LEARN_DST_MATCH
||
5247 spec
->dst_type
== NX_LEARN_DST_LOAD
||
5248 (spec
->dst_type
== NX_LEARN_DST_OUTPUT
&&
5249 spec
->src_type
== NX_LEARN_SRC_FIELD
)) {
5252 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5255 /* Check that the arguments don't overrun the end of the action. */
5256 if ((char *) end
- (char *) p
< learn_min_len(header
)) {
5257 return OFPERR_OFPBAC_BAD_LEN
;
5260 /* Get the source. */
5261 const uint8_t *imm
= NULL
;
5262 unsigned int imm_bytes
= 0;
5264 if (spec
->src_type
== NX_LEARN_SRC_FIELD
) {
5265 error
= get_subfield(spec
->n_bits
, &p
, &spec
->src
, vl_mff_map
,
5271 int p_bytes
= 2 * DIV_ROUND_UP(spec
->n_bits
, 16);
5272 p
= (const uint8_t *) p
+ p_bytes
;
5274 imm_bytes
= DIV_ROUND_UP(spec
->n_bits
, 8);
5275 imm
= (const uint8_t *) p
- imm_bytes
;
5278 /* Get the destination. */
5279 if (spec
->dst_type
== NX_LEARN_DST_MATCH
||
5280 spec
->dst_type
== NX_LEARN_DST_LOAD
) {
5281 error
= get_subfield(spec
->n_bits
, &p
, &spec
->dst
, vl_mff_map
,
5289 uint8_t *src_imm
= ofpbuf_put_zeros(ofpacts
,
5290 OFPACT_ALIGN(imm_bytes
));
5291 memcpy(src_imm
, imm
, imm_bytes
);
5293 learn
= ofpacts
->header
;
5296 ofpact_finish_LEARN(ofpacts
, &learn
);
5298 if (!is_all_zeros(p
, (char *) end
- (char *) p
)) {
5299 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5305 /* Converts 'nal' into a "struct ofpact_learn" and appends that struct to
5306 * 'ofpacts'. Returns 0 if successful, otherwise an OFPERR_*. */
5308 decode_NXAST_RAW_LEARN(const struct nx_action_learn
*nal
,
5309 enum ofp_version ofp_version OVS_UNUSED
,
5310 const struct vl_mff_map
*vl_mff_map
,
5311 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
5313 struct ofpact_learn
*learn
;
5316 learn
= ofpact_put_LEARN(ofpacts
);
5318 error
= decode_LEARN_common(nal
, NXAST_RAW_LEARN
, learn
);
5323 if (learn
->flags
& ~(NX_LEARN_F_SEND_FLOW_REM
|
5324 NX_LEARN_F_DELETE_LEARNED
)) {
5325 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5328 return decode_LEARN_specs(nal
+ 1, (char *) nal
+ ntohs(nal
->len
),
5329 vl_mff_map
, tlv_bitmap
, ofpacts
);
5332 /* Converts 'nal' into a "struct ofpact_learn" and appends that struct to
5333 * 'ofpacts'. Returns 0 if successful, otherwise an OFPERR_*. */
5335 decode_NXAST_RAW_LEARN2(const struct nx_action_learn2
*nal
,
5336 enum ofp_version ofp_version OVS_UNUSED
,
5337 const struct vl_mff_map
*vl_mff_map
,
5338 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
5340 struct ofpbuf b
= ofpbuf_const_initializer(nal
, ntohs(nal
->up
.len
));
5341 struct ofpact_learn
*learn
;
5345 return OFPERR_NXBAC_MUST_BE_ZERO
;
5348 learn
= ofpact_put_LEARN(ofpacts
);
5349 error
= decode_LEARN_common(&nal
->up
, NXAST_RAW_LEARN2
, learn
);
5354 learn
->limit
= ntohl(nal
->limit
);
5356 if (learn
->flags
& ~(NX_LEARN_F_SEND_FLOW_REM
|
5357 NX_LEARN_F_DELETE_LEARNED
|
5358 NX_LEARN_F_WRITE_RESULT
)) {
5359 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5362 ofpbuf_pull(&b
, sizeof *nal
);
5364 if (learn
->flags
& NX_LEARN_F_WRITE_RESULT
) {
5365 error
= nx_pull_header(&b
, vl_mff_map
, &learn
->result_dst
.field
, NULL
);
5369 if (!learn
->result_dst
.field
->writable
) {
5370 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
5372 learn
->result_dst
.ofs
= ntohs(nal
->result_dst_ofs
);
5373 learn
->result_dst
.n_bits
= 1;
5374 } else if (nal
->result_dst_ofs
) {
5375 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5378 return decode_LEARN_specs(b
.data
, (char *) nal
+ ntohs(nal
->up
.len
),
5379 vl_mff_map
, tlv_bitmap
, ofpacts
);
5383 put_be16(struct ofpbuf
*b
, ovs_be16 x
)
5385 ofpbuf_put(b
, &x
, sizeof x
);
5389 put_be32(struct ofpbuf
*b
, ovs_be32 x
)
5391 ofpbuf_put(b
, &x
, sizeof x
);
5395 put_u16(struct ofpbuf
*b
, uint16_t x
)
5397 put_be16(b
, htons(x
));
5401 put_u32(struct ofpbuf
*b
, uint32_t x
)
5403 put_be32(b
, htonl(x
));
5407 encode_LEARN(const struct ofpact_learn
*learn
,
5408 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5410 const struct ofpact_learn_spec
*spec
;
5411 struct nx_action_learn
*nal
;
5414 start_ofs
= out
->size
;
5416 if (learn
->ofpact
.raw
== NXAST_RAW_LEARN2
5417 || learn
->limit
!= 0
5418 || learn
->flags
& NX_LEARN_F_WRITE_RESULT
) {
5419 struct nx_action_learn2
*nal2
;
5421 nal2
= put_NXAST_LEARN2(out
);
5422 nal2
->limit
= htonl(learn
->limit
);
5423 nal2
->result_dst_ofs
= htons(learn
->result_dst
.ofs
);
5426 nal
= put_NXAST_LEARN(out
);
5428 nal
->idle_timeout
= htons(learn
->idle_timeout
);
5429 nal
->hard_timeout
= htons(learn
->hard_timeout
);
5430 nal
->fin_idle_timeout
= htons(learn
->fin_idle_timeout
);
5431 nal
->fin_hard_timeout
= htons(learn
->fin_hard_timeout
);
5432 nal
->priority
= htons(learn
->priority
);
5433 nal
->cookie
= learn
->cookie
;
5434 nal
->flags
= htons(learn
->flags
);
5435 nal
->table_id
= learn
->table_id
;
5437 if (learn
->flags
& NX_LEARN_F_WRITE_RESULT
) {
5438 nx_put_header(out
, learn
->result_dst
.field
->id
, 0, false);
5441 OFPACT_LEARN_SPEC_FOR_EACH (spec
, learn
) {
5442 put_u16(out
, spec
->n_bits
| spec
->dst_type
| spec
->src_type
);
5444 if (spec
->src_type
== NX_LEARN_SRC_FIELD
) {
5445 put_u32(out
, nxm_header_from_mff(spec
->src
.field
));
5446 put_u16(out
, spec
->src
.ofs
);
5448 size_t n_dst_bytes
= 2 * DIV_ROUND_UP(spec
->n_bits
, 16);
5449 uint8_t *bits
= ofpbuf_put_zeros(out
, n_dst_bytes
);
5450 unsigned int n_bytes
= DIV_ROUND_UP(spec
->n_bits
, 8);
5452 memcpy(bits
+ n_dst_bytes
- n_bytes
, ofpact_learn_spec_imm(spec
),
5456 if (spec
->dst_type
== NX_LEARN_DST_MATCH
||
5457 spec
->dst_type
== NX_LEARN_DST_LOAD
) {
5458 put_u32(out
, nxm_header_from_mff(spec
->dst
.field
));
5459 put_u16(out
, spec
->dst
.ofs
);
5463 pad_ofpat(out
, start_ofs
);
5466 static char * OVS_WARN_UNUSED_RESULT
5467 parse_LEARN(char *arg
, const struct ofpact_parse_params
*pp
)
5469 return learn_parse(arg
, pp
->port_map
, pp
->table_map
, pp
->ofpacts
);
5473 format_LEARN(const struct ofpact_learn
*a
,
5474 const struct ofpact_format_params
*fp
)
5476 learn_format(a
, fp
->port_map
, fp
->table_map
, fp
->s
);
5480 check_LEARN(const struct ofpact_learn
*a
,
5481 const struct ofpact_check_params
*cp
)
5483 return learn_check(a
, cp
->match
);
5486 /* Action structure for NXAST_CONJUNCTION. */
5487 struct nx_action_conjunction
{
5488 ovs_be16 type
; /* OFPAT_VENDOR. */
5489 ovs_be16 len
; /* At least 16. */
5490 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5491 ovs_be16 subtype
; /* See enum ofp_raw_action_type. */
5496 OFP_ASSERT(sizeof(struct nx_action_conjunction
) == 16);
5499 add_conjunction(struct ofpbuf
*out
,
5500 uint32_t id
, uint8_t clause
, uint8_t n_clauses
)
5502 struct ofpact_conjunction
*oc
;
5504 oc
= ofpact_put_CONJUNCTION(out
);
5506 oc
->clause
= clause
;
5507 oc
->n_clauses
= n_clauses
;
5511 decode_NXAST_RAW_CONJUNCTION(const struct nx_action_conjunction
*nac
,
5512 enum ofp_version ofp_version OVS_UNUSED
,
5515 if (nac
->n_clauses
< 2 || nac
->n_clauses
> 64
5516 || nac
->clause
>= nac
->n_clauses
) {
5517 return OFPERR_NXBAC_BAD_CONJUNCTION
;
5519 add_conjunction(out
, ntohl(nac
->id
), nac
->clause
, nac
->n_clauses
);
5525 encode_CONJUNCTION(const struct ofpact_conjunction
*oc
,
5526 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5528 struct nx_action_conjunction
*nac
= put_NXAST_CONJUNCTION(out
);
5529 nac
->clause
= oc
->clause
;
5530 nac
->n_clauses
= oc
->n_clauses
;
5531 nac
->id
= htonl(oc
->id
);
5535 format_CONJUNCTION(const struct ofpact_conjunction
*oc
,
5536 const struct ofpact_format_params
*fp
)
5538 ds_put_format(fp
->s
, "%sconjunction(%s%"PRIu32
",%d/%"PRIu8
"%s)%s",
5539 colors
.paren
, colors
.end
,
5540 oc
->id
, oc
->clause
+ 1, oc
->n_clauses
,
5541 colors
.paren
, colors
.end
);
5544 static char * OVS_WARN_UNUSED_RESULT
5545 parse_CONJUNCTION(const char *arg
, const struct ofpact_parse_params
*pp
)
5552 if (!ovs_scan(arg
, "%"SCNi32
" , %"SCNu8
" / %"SCNu8
" %n",
5553 &id
, &clause
, &n_clauses
, &n
) || n
!= strlen(arg
)) {
5554 return xstrdup("\"conjunction\" syntax is \"conjunction(id,i/n)\"");
5557 if (n_clauses
< 2) {
5558 return xstrdup("conjunction must have at least 2 clauses");
5559 } else if (n_clauses
> 64) {
5560 return xstrdup("conjunction must have at most 64 clauses");
5561 } else if (clause
< 1) {
5562 return xstrdup("clause index must be positive");
5563 } else if (clause
> n_clauses
) {
5564 return xstrdup("clause index must be less than or equal to "
5565 "number of clauses");
5568 add_conjunction(pp
->ofpacts
, id
, clause
- 1, n_clauses
);
5573 check_CONJUNCTION(const struct ofpact_conjunction
*a OVS_UNUSED
,
5574 const struct ofpact_check_params
*cp OVS_UNUSED
)
5579 /* Action structure for NXAST_MULTIPATH.
5581 * This action performs the following steps in sequence:
5583 * 1. Hashes the fields designated by 'fields', one of NX_HASH_FIELDS_*.
5584 * Refer to the definition of "enum nx_mp_fields" for details.
5586 * The 'basis' value is used as a universal hash parameter, that is,
5587 * different values of 'basis' yield different hash functions. The
5588 * particular universal hash function used is implementation-defined.
5590 * The hashed fields' values are drawn from the current state of the
5591 * flow, including all modifications that have been made by actions up to
5594 * 2. Applies the multipath link choice algorithm specified by 'algorithm',
5595 * one of NX_MP_ALG_*. Refer to the definition of "enum nx_mp_algorithm"
5598 * The output of the algorithm is 'link', an unsigned integer less than
5599 * or equal to 'max_link'.
5601 * Some algorithms use 'arg' as an additional argument.
5603 * 3. Stores 'link' in dst[ofs:ofs+n_bits]. The format and semantics of
5604 * 'dst' and 'ofs_nbits' are similar to those for the NXAST_REG_LOAD
5607 * The switch will reject actions that have an unknown 'fields', or an unknown
5608 * 'algorithm', or in which ofs+n_bits is greater than the width of 'dst', or
5609 * in which 'max_link' is greater than or equal to 2**n_bits, with error type
5610 * OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
5612 struct nx_action_multipath
{
5613 ovs_be16 type
; /* OFPAT_VENDOR. */
5614 ovs_be16 len
; /* Length is 32. */
5615 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5616 ovs_be16 subtype
; /* NXAST_MULTIPATH. */
5618 /* What fields to hash and how. */
5619 ovs_be16 fields
; /* One of NX_HASH_FIELDS_*. */
5620 ovs_be16 basis
; /* Universal hash parameter. */
5623 /* Multipath link choice algorithm to apply to hash value. */
5624 ovs_be16 algorithm
; /* One of NX_MP_ALG_*. */
5625 ovs_be16 max_link
; /* Number of output links, minus 1. */
5626 ovs_be32 arg
; /* Algorithm-specific argument. */
5629 /* Where to store the result. */
5630 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
5631 ovs_be32 dst
; /* Destination. */
5633 OFP_ASSERT(sizeof(struct nx_action_multipath
) == 32);
5636 decode_NXAST_RAW_MULTIPATH(const struct nx_action_multipath
*nam
,
5637 enum ofp_version ofp_version OVS_UNUSED
,
5638 const struct vl_mff_map
*vl_mff_map
,
5639 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
5641 uint32_t n_links
= ntohs(nam
->max_link
) + 1;
5642 size_t min_n_bits
= log_2_ceil(n_links
);
5643 struct ofpact_multipath
*mp
;
5646 mp
= ofpact_put_MULTIPATH(out
);
5647 mp
->fields
= ntohs(nam
->fields
);
5648 mp
->basis
= ntohs(nam
->basis
);
5649 mp
->algorithm
= ntohs(nam
->algorithm
);
5650 mp
->max_link
= ntohs(nam
->max_link
);
5651 mp
->arg
= ntohl(nam
->arg
);
5652 mp
->dst
.ofs
= nxm_decode_ofs(nam
->ofs_nbits
);
5653 mp
->dst
.n_bits
= nxm_decode_n_bits(nam
->ofs_nbits
);
5654 error
= mf_vl_mff_mf_from_nxm_header(ntohl(nam
->dst
), vl_mff_map
,
5655 &mp
->dst
.field
, tlv_bitmap
);
5660 if (!flow_hash_fields_valid(mp
->fields
)) {
5661 VLOG_WARN_RL(&rl
, "unsupported fields %d", (int) mp
->fields
);
5662 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5663 } else if (mp
->algorithm
!= NX_MP_ALG_MODULO_N
5664 && mp
->algorithm
!= NX_MP_ALG_HASH_THRESHOLD
5665 && mp
->algorithm
!= NX_MP_ALG_HRW
5666 && mp
->algorithm
!= NX_MP_ALG_ITER_HASH
) {
5667 VLOG_WARN_RL(&rl
, "unsupported algorithm %d", (int) mp
->algorithm
);
5668 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5669 } else if (mp
->dst
.n_bits
< min_n_bits
) {
5670 VLOG_WARN_RL(&rl
, "multipath action requires at least %"PRIuSIZE
" bits for "
5671 "%"PRIu32
" links", min_n_bits
, n_links
);
5672 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5675 return multipath_check(mp
, NULL
);
5679 encode_MULTIPATH(const struct ofpact_multipath
*mp
,
5680 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5682 struct nx_action_multipath
*nam
= put_NXAST_MULTIPATH(out
);
5684 nam
->fields
= htons(mp
->fields
);
5685 nam
->basis
= htons(mp
->basis
);
5686 nam
->algorithm
= htons(mp
->algorithm
);
5687 nam
->max_link
= htons(mp
->max_link
);
5688 nam
->arg
= htonl(mp
->arg
);
5689 nam
->ofs_nbits
= nxm_encode_ofs_nbits(mp
->dst
.ofs
, mp
->dst
.n_bits
);
5690 nam
->dst
= htonl(nxm_header_from_mff(mp
->dst
.field
));
5693 static char * OVS_WARN_UNUSED_RESULT
5694 parse_MULTIPATH(const char *arg
, const struct ofpact_parse_params
*pp
)
5696 return multipath_parse(ofpact_put_MULTIPATH(pp
->ofpacts
), arg
);
5700 format_MULTIPATH(const struct ofpact_multipath
*a
,
5701 const struct ofpact_format_params
*fp
)
5703 multipath_format(a
, fp
->s
);
5707 check_MULTIPATH(const struct ofpact_multipath
*a
,
5708 const struct ofpact_check_params
*cp
)
5710 return multipath_check(a
, cp
->match
);
5713 /* Action structure for NXAST_NOTE.
5715 * This action has no effect. It is variable length. The switch does not
5716 * attempt to interpret the user-defined 'note' data in any way. A controller
5717 * can use this action to attach arbitrary metadata to a flow.
5719 * This action might go away in the future.
5721 struct nx_action_note
{
5722 ovs_be16 type
; /* OFPAT_VENDOR. */
5723 ovs_be16 len
; /* A multiple of 8, but at least 16. */
5724 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5725 ovs_be16 subtype
; /* NXAST_NOTE. */
5726 uint8_t note
[6]; /* Start of user-defined data. */
5727 /* Possibly followed by additional user-defined data. */
5729 OFP_ASSERT(sizeof(struct nx_action_note
) == 16);
5732 decode_NXAST_RAW_NOTE(const struct nx_action_note
*nan
,
5733 enum ofp_version ofp_version OVS_UNUSED
,
5736 struct ofpact_note
*note
;
5737 unsigned int length
;
5739 length
= ntohs(nan
->len
) - offsetof(struct nx_action_note
, note
);
5740 note
= ofpact_put_NOTE(out
);
5741 note
->length
= length
;
5742 ofpbuf_put(out
, nan
->note
, length
);
5744 ofpact_finish_NOTE(out
, ¬e
);
5750 encode_NOTE(const struct ofpact_note
*note
,
5751 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5753 size_t start_ofs
= out
->size
;
5754 struct nx_action_note
*nan
;
5756 put_NXAST_NOTE(out
);
5757 out
->size
= out
->size
- sizeof nan
->note
;
5759 ofpbuf_put(out
, note
->data
, note
->length
);
5760 pad_ofpat(out
, start_ofs
);
5763 static char * OVS_WARN_UNUSED_RESULT
5764 parse_NOTE(const char *arg
, const struct ofpact_parse_params
*pp
)
5766 size_t start_ofs
= pp
->ofpacts
->size
;
5767 ofpact_put_NOTE(pp
->ofpacts
);
5768 arg
= ofpbuf_put_hex(pp
->ofpacts
, arg
, NULL
);
5770 return xstrdup("bad hex digit in `note' argument");
5772 struct ofpact_note
*note
= ofpbuf_at_assert(pp
->ofpacts
, start_ofs
,
5774 note
->length
= pp
->ofpacts
->size
- (start_ofs
+ sizeof *note
);
5775 ofpact_finish_NOTE(pp
->ofpacts
, ¬e
);
5780 format_NOTE(const struct ofpact_note
*a
,
5781 const struct ofpact_format_params
*fp
)
5783 ds_put_format(fp
->s
, "%snote:%s", colors
.param
, colors
.end
);
5784 format_hex_arg(fp
->s
, a
->data
, a
->length
);
5788 check_NOTE(const struct ofpact_note
*a OVS_UNUSED
,
5789 const struct ofpact_check_params
*cp OVS_UNUSED
)
5797 decode_NXAST_RAW_EXIT(struct ofpbuf
*out
)
5799 ofpact_put_EXIT(out
);
5804 encode_EXIT(const struct ofpact_null
*null OVS_UNUSED
,
5805 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5807 put_NXAST_EXIT(out
);
5810 static char * OVS_WARN_UNUSED_RESULT
5811 parse_EXIT(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
5813 ofpact_put_EXIT(pp
->ofpacts
);
5818 format_EXIT(const struct ofpact_null
*a OVS_UNUSED
,
5819 const struct ofpact_format_params
*fp
)
5821 ds_put_format(fp
->s
, "%sexit%s", colors
.special
, colors
.end
);
5825 check_EXIT(const struct ofpact_null
*a OVS_UNUSED
,
5826 const struct ofpact_check_params
*cp OVS_UNUSED
)
5831 /* Unroll xlate action. */
5834 encode_UNROLL_XLATE(const struct ofpact_unroll_xlate
*unroll OVS_UNUSED
,
5835 enum ofp_version ofp_version OVS_UNUSED
,
5836 struct ofpbuf
*out OVS_UNUSED
)
5841 static char * OVS_WARN_UNUSED_RESULT
5842 parse_UNROLL_XLATE(char *arg OVS_UNUSED
,
5843 const struct ofpact_parse_params
*pp OVS_UNUSED
)
5845 return xasprintf("UNROLL is an internal action "
5846 "that shouldn't be used via OpenFlow");
5850 format_UNROLL_XLATE(const struct ofpact_unroll_xlate
*a
,
5851 const struct ofpact_format_params
*fp
)
5853 ds_put_format(fp
->s
, "%sunroll_xlate(%s%stable=%s",
5854 colors
.paren
, colors
.end
,
5855 colors
.special
, colors
.end
);
5856 ofputil_format_table(a
->rule_table_id
, fp
->table_map
, fp
->s
);
5857 ds_put_format(fp
->s
, ", %scookie=%s%"PRIu64
"%s)%s",
5858 colors
.param
, colors
.end
, ntohll(a
->rule_cookie
),
5859 colors
.paren
, colors
.end
);
5863 check_UNROLL_XLATE(const struct ofpact_unroll_xlate
*a OVS_UNUSED
,
5864 const struct ofpact_check_params
*cp OVS_UNUSED
)
5866 /* UNROLL is an internal action that should never be seen via OpenFlow. */
5867 return OFPERR_OFPBAC_BAD_TYPE
;
5870 /* The NXAST_CLONE action is "struct ext_action_header", followed by zero or
5871 * more embedded OpenFlow actions. */
5874 decode_NXAST_RAW_CLONE(const struct ext_action_header
*eah
,
5875 enum ofp_version ofp_version
,
5876 const struct vl_mff_map
*vl_mff_map
,
5877 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
5880 struct ofpbuf openflow
;
5881 const size_t clone_offset
= ofpacts_pull(out
);
5882 struct ofpact_nest
*clone
= ofpact_put_CLONE(out
);
5884 /* decode action list */
5885 ofpbuf_pull(out
, sizeof(*clone
));
5886 openflow
= ofpbuf_const_initializer(
5887 eah
+ 1, ntohs(eah
->len
) - sizeof *eah
);
5888 error
= ofpacts_pull_openflow_actions__(&openflow
, openflow
.size
,
5890 1u << OVSINST_OFPIT11_APPLY_ACTIONS
,
5891 out
, 0, vl_mff_map
, tlv_bitmap
);
5895 clone
= ofpbuf_push_uninit(out
, sizeof *clone
);
5896 out
->header
= &clone
->ofpact
;
5897 ofpact_finish_CLONE(out
, &clone
);
5898 ofpbuf_push_uninit(out
, clone_offset
);
5903 encode_CLONE(const struct ofpact_nest
*clone
,
5904 enum ofp_version ofp_version
, struct ofpbuf
*out
)
5907 const size_t ofs
= out
->size
;
5908 struct ext_action_header
*eah
;
5910 put_NXAST_CLONE(out
);
5911 len
= ofpacts_put_openflow_actions(clone
->actions
,
5912 ofpact_nest_get_action_len(clone
),
5915 eah
= ofpbuf_at(out
, ofs
, sizeof *eah
);
5916 eah
->len
= htons(len
);
5919 static char * OVS_WARN_UNUSED_RESULT
5920 parse_CLONE(char *arg
, const struct ofpact_parse_params
*pp
)
5922 const size_t clone_offset
= ofpacts_pull(pp
->ofpacts
);
5923 struct ofpact_nest
*clone
= ofpact_put_CLONE(pp
->ofpacts
);
5926 ofpbuf_pull(pp
->ofpacts
, sizeof *clone
);
5927 error
= ofpacts_parse_copy(arg
, pp
, false, 0);
5928 /* header points to the action list */
5929 pp
->ofpacts
->header
= ofpbuf_push_uninit(pp
->ofpacts
, sizeof *clone
);
5930 clone
= pp
->ofpacts
->header
;
5932 ofpact_finish_CLONE(pp
->ofpacts
, &clone
);
5933 ofpbuf_push_uninit(pp
->ofpacts
, clone_offset
);
5938 format_CLONE(const struct ofpact_nest
*a
,
5939 const struct ofpact_format_params
*fp
)
5941 ds_put_format(fp
->s
, "%sclone(%s", colors
.paren
, colors
.end
);
5942 ofpacts_format(a
->actions
, ofpact_nest_get_action_len(a
), fp
);
5943 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
5947 check_subactions(struct ofpact
*ofpacts
, size_t ofpacts_len
,
5948 struct ofpact_check_params
*cp
)
5950 struct ofpact_check_params sub
= *cp
;
5951 enum ofperr error
= ofpacts_check(ofpacts
, ofpacts_len
, &sub
);
5952 cp
->usable_protocols
&= sub
.usable_protocols
;
5957 check_CLONE(struct ofpact_nest
*a
, struct ofpact_check_params
*cp
)
5959 return check_subactions(a
->actions
, ofpact_nest_get_action_len(a
), cp
);
5962 /* Action structure for NXAST_SAMPLE.
5964 * Samples matching packets with the given probability and sends them
5965 * each to the set of collectors identified with the given ID. The
5966 * probability is expressed as a number of packets to be sampled out
5967 * of USHRT_MAX packets, and must be >0.
5969 * When sending packet samples to IPFIX collectors, the IPFIX flow
5970 * record sent for each sampled packet is associated with the given
5971 * observation domain ID and observation point ID. Each IPFIX flow
5972 * record contain the sampled packet's headers when executing this
5973 * rule. If a sampled packet's headers are modified by previous
5974 * actions in the flow, those modified headers are sent. */
5975 struct nx_action_sample
{
5976 ovs_be16 type
; /* OFPAT_VENDOR. */
5977 ovs_be16 len
; /* Length is 24. */
5978 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5979 ovs_be16 subtype
; /* NXAST_SAMPLE. */
5980 ovs_be16 probability
; /* Fraction of packets to sample. */
5981 ovs_be32 collector_set_id
; /* ID of collector set in OVSDB. */
5982 ovs_be32 obs_domain_id
; /* ID of sampling observation domain. */
5983 ovs_be32 obs_point_id
; /* ID of sampling observation point. */
5985 OFP_ASSERT(sizeof(struct nx_action_sample
) == 24);
5987 /* Action structure for NXAST_SAMPLE2 and NXAST_SAMPLE3.
5989 * NXAST_SAMPLE2 was added in Open vSwitch 2.5.90. Compared to NXAST_SAMPLE,
5990 * it adds support for exporting egress tunnel information.
5992 * NXAST_SAMPLE3 was added in Open vSwitch 2.6.90. Compared to NXAST_SAMPLE2,
5993 * it adds support for the 'direction' field. */
5994 struct nx_action_sample2
{
5995 ovs_be16 type
; /* OFPAT_VENDOR. */
5996 ovs_be16 len
; /* Length is 32. */
5997 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5998 ovs_be16 subtype
; /* NXAST_SAMPLE. */
5999 ovs_be16 probability
; /* Fraction of packets to sample. */
6000 ovs_be32 collector_set_id
; /* ID of collector set in OVSDB. */
6001 ovs_be32 obs_domain_id
; /* ID of sampling observation domain. */
6002 ovs_be32 obs_point_id
; /* ID of sampling observation point. */
6003 ovs_be16 sampling_port
; /* Sampling port. */
6004 uint8_t direction
; /* NXAST_SAMPLE3 only. */
6005 uint8_t zeros
[5]; /* Pad to a multiple of 8 bytes */
6007 OFP_ASSERT(sizeof(struct nx_action_sample2
) == 32);
6010 decode_NXAST_RAW_SAMPLE(const struct nx_action_sample
*nas
,
6011 enum ofp_version ofp_version OVS_UNUSED
,
6014 struct ofpact_sample
*sample
;
6016 sample
= ofpact_put_SAMPLE(out
);
6017 sample
->ofpact
.raw
= NXAST_RAW_SAMPLE
;
6018 sample
->probability
= ntohs(nas
->probability
);
6019 sample
->collector_set_id
= ntohl(nas
->collector_set_id
);
6020 sample
->obs_domain_id
= ntohl(nas
->obs_domain_id
);
6021 sample
->obs_point_id
= ntohl(nas
->obs_point_id
);
6022 sample
->sampling_port
= OFPP_NONE
;
6023 sample
->direction
= NX_ACTION_SAMPLE_DEFAULT
;
6025 if (sample
->probability
== 0) {
6026 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6033 decode_SAMPLE2(const struct nx_action_sample2
*nas
,
6034 enum ofp_raw_action_type raw
,
6035 enum nx_action_sample_direction direction
,
6036 struct ofpact_sample
*sample
)
6038 sample
->ofpact
.raw
= raw
;
6039 sample
->probability
= ntohs(nas
->probability
);
6040 sample
->collector_set_id
= ntohl(nas
->collector_set_id
);
6041 sample
->obs_domain_id
= ntohl(nas
->obs_domain_id
);
6042 sample
->obs_point_id
= ntohl(nas
->obs_point_id
);
6043 sample
->sampling_port
= u16_to_ofp(ntohs(nas
->sampling_port
));
6044 sample
->direction
= direction
;
6046 if (sample
->probability
== 0) {
6047 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6054 decode_NXAST_RAW_SAMPLE2(const struct nx_action_sample2
*nas
,
6055 enum ofp_version ofp_version OVS_UNUSED
,
6058 return decode_SAMPLE2(nas
, NXAST_RAW_SAMPLE2
, NX_ACTION_SAMPLE_DEFAULT
,
6059 ofpact_put_SAMPLE(out
));
6063 decode_NXAST_RAW_SAMPLE3(const struct nx_action_sample2
*nas
,
6064 enum ofp_version ofp_version OVS_UNUSED
,
6067 struct ofpact_sample
*sample
= ofpact_put_SAMPLE(out
);
6068 if (!is_all_zeros(nas
->zeros
, sizeof nas
->zeros
)) {
6069 return OFPERR_NXBRC_MUST_BE_ZERO
;
6071 if (nas
->direction
!= NX_ACTION_SAMPLE_DEFAULT
&&
6072 nas
->direction
!= NX_ACTION_SAMPLE_INGRESS
&&
6073 nas
->direction
!= NX_ACTION_SAMPLE_EGRESS
) {
6074 VLOG_WARN_RL(&rl
, "invalid sample direction %"PRIu8
, nas
->direction
);
6075 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6077 return decode_SAMPLE2(nas
, NXAST_RAW_SAMPLE3
, nas
->direction
, sample
);
6081 encode_SAMPLE2(const struct ofpact_sample
*sample
,
6082 struct nx_action_sample2
*nas
)
6084 nas
->probability
= htons(sample
->probability
);
6085 nas
->collector_set_id
= htonl(sample
->collector_set_id
);
6086 nas
->obs_domain_id
= htonl(sample
->obs_domain_id
);
6087 nas
->obs_point_id
= htonl(sample
->obs_point_id
);
6088 nas
->sampling_port
= htons(ofp_to_u16(sample
->sampling_port
));
6089 nas
->direction
= sample
->direction
;
6093 encode_SAMPLE(const struct ofpact_sample
*sample
,
6094 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
6096 if (sample
->ofpact
.raw
== NXAST_RAW_SAMPLE3
6097 || sample
->direction
!= NX_ACTION_SAMPLE_DEFAULT
) {
6098 encode_SAMPLE2(sample
, put_NXAST_SAMPLE3(out
));
6099 } else if (sample
->ofpact
.raw
== NXAST_RAW_SAMPLE2
6100 || sample
->sampling_port
!= OFPP_NONE
) {
6101 encode_SAMPLE2(sample
, put_NXAST_SAMPLE2(out
));
6103 struct nx_action_sample
*nas
= put_NXAST_SAMPLE(out
);
6104 nas
->probability
= htons(sample
->probability
);
6105 nas
->collector_set_id
= htonl(sample
->collector_set_id
);
6106 nas
->obs_domain_id
= htonl(sample
->obs_domain_id
);
6107 nas
->obs_point_id
= htonl(sample
->obs_point_id
);
6111 /* Parses 'arg' as the argument to a "sample" action, and appends such an
6112 * action to 'pp->ofpacts'.
6114 * Returns NULL if successful, otherwise a malloc()'d string describing the
6115 * error. The caller is responsible for freeing the returned string. */
6116 static char * OVS_WARN_UNUSED_RESULT
6117 parse_SAMPLE(char *arg
, const struct ofpact_parse_params
*pp
)
6119 struct ofpact_sample
*os
= ofpact_put_SAMPLE(pp
->ofpacts
);
6120 os
->sampling_port
= OFPP_NONE
;
6121 os
->direction
= NX_ACTION_SAMPLE_DEFAULT
;
6124 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
6127 if (!strcmp(key
, "probability")) {
6128 error
= str_to_u16(value
, "probability", &os
->probability
);
6129 if (!error
&& os
->probability
== 0) {
6130 error
= xasprintf("invalid probability value \"%s\"", value
);
6132 } else if (!strcmp(key
, "collector_set_id")) {
6133 error
= str_to_u32(value
, &os
->collector_set_id
);
6134 } else if (!strcmp(key
, "obs_domain_id")) {
6135 error
= str_to_u32(value
, &os
->obs_domain_id
);
6136 } else if (!strcmp(key
, "obs_point_id")) {
6137 error
= str_to_u32(value
, &os
->obs_point_id
);
6138 } else if (!strcmp(key
, "sampling_port")) {
6139 if (!ofputil_port_from_string(value
, pp
->port_map
,
6140 &os
->sampling_port
)) {
6141 error
= xasprintf("%s: unknown port", value
);
6143 } else if (!strcmp(key
, "ingress")) {
6144 os
->direction
= NX_ACTION_SAMPLE_INGRESS
;
6145 } else if (!strcmp(key
, "egress")) {
6146 os
->direction
= NX_ACTION_SAMPLE_EGRESS
;
6148 error
= xasprintf("invalid key \"%s\" in \"sample\" argument",
6155 if (os
->probability
== 0) {
6156 return xstrdup("non-zero \"probability\" must be specified on sample");
6163 format_SAMPLE(const struct ofpact_sample
*a
,
6164 const struct ofpact_format_params
*fp
)
6166 ds_put_format(fp
->s
, "%ssample(%s%sprobability=%s%"PRIu16
6167 ",%scollector_set_id=%s%"PRIu32
6168 ",%sobs_domain_id=%s%"PRIu32
6169 ",%sobs_point_id=%s%"PRIu32
,
6170 colors
.paren
, colors
.end
,
6171 colors
.param
, colors
.end
, a
->probability
,
6172 colors
.param
, colors
.end
, a
->collector_set_id
,
6173 colors
.param
, colors
.end
, a
->obs_domain_id
,
6174 colors
.param
, colors
.end
, a
->obs_point_id
);
6175 if (a
->sampling_port
!= OFPP_NONE
) {
6176 ds_put_format(fp
->s
, ",%ssampling_port=%s", colors
.param
, colors
.end
);
6177 ofputil_format_port(a
->sampling_port
, fp
->port_map
, fp
->s
);
6179 if (a
->direction
== NX_ACTION_SAMPLE_INGRESS
) {
6180 ds_put_format(fp
->s
, ",%singress%s", colors
.param
, colors
.end
);
6181 } else if (a
->direction
== NX_ACTION_SAMPLE_EGRESS
) {
6182 ds_put_format(fp
->s
, ",%segress%s", colors
.param
, colors
.end
);
6184 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
6188 check_SAMPLE(const struct ofpact_sample
*a OVS_UNUSED
,
6189 const struct ofpact_check_params
*cp OVS_UNUSED
)
6194 /* debug instructions. */
6196 static bool enable_debug
;
6199 ofpact_dummy_enable(void)
6201 enable_debug
= true;
6205 decode_NXAST_RAW_DEBUG_RECIRC(struct ofpbuf
*out
)
6207 if (!enable_debug
) {
6208 return OFPERR_OFPBAC_BAD_VENDOR_TYPE
;
6211 ofpact_put_DEBUG_RECIRC(out
);
6216 encode_DEBUG_RECIRC(const struct ofpact_null
*n OVS_UNUSED
,
6217 enum ofp_version ofp_version OVS_UNUSED
,
6220 put_NXAST_DEBUG_RECIRC(out
);
6223 static char * OVS_WARN_UNUSED_RESULT
6224 parse_DEBUG_RECIRC(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
6226 ofpact_put_DEBUG_RECIRC(pp
->ofpacts
);
6231 format_DEBUG_RECIRC(const struct ofpact_null
*a OVS_UNUSED
,
6232 const struct ofpact_format_params
*fp
)
6234 ds_put_format(fp
->s
, "%sdebug_recirc%s", colors
.value
, colors
.end
);
6238 check_DEBUG_RECIRC(const struct ofpact_null
*a OVS_UNUSED
,
6239 const struct ofpact_check_params
*cp OVS_UNUSED
)
6245 decode_NXAST_RAW_DEBUG_SLOW(struct ofpbuf
*out
)
6247 if (!enable_debug
) {
6248 return OFPERR_OFPBAC_BAD_VENDOR_TYPE
;
6251 ofpact_put_DEBUG_SLOW(out
);
6256 encode_DEBUG_SLOW(const struct ofpact_null
*n OVS_UNUSED
,
6257 enum ofp_version ofp_version OVS_UNUSED
,
6260 put_NXAST_DEBUG_SLOW(out
);
6263 static char * OVS_WARN_UNUSED_RESULT
6264 parse_DEBUG_SLOW(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
6266 ofpact_put_DEBUG_SLOW(pp
->ofpacts
);
6271 format_DEBUG_SLOW(const struct ofpact_null
*a OVS_UNUSED
,
6272 const struct ofpact_format_params
*fp
)
6274 ds_put_format(fp
->s
, "%sdebug_slow%s", colors
.value
, colors
.end
);
6278 check_DEBUG_SLOW(const struct ofpact_null
*a OVS_UNUSED
,
6279 const struct ofpact_check_params
*cp OVS_UNUSED
)
6284 /* Action structure for NXAST_CT.
6286 * Pass traffic to the connection tracker.
6288 * There are two important concepts to understanding the connection tracking
6289 * interface: Packet state and Connection state. Packets may be "Untracked" or
6290 * "Tracked". Connections may be "Uncommitted" or "Committed".
6294 * Untracked packets have an unknown connection state. In most
6295 * cases, packets entering the OpenFlow pipeline will initially be
6296 * in the untracked state. Untracked packets may become tracked by
6297 * executing NXAST_CT with a "recirc_table" specified. This makes
6298 * various aspects about the connection available, in particular
6299 * the connection state.
6301 * An NXAST_CT action always puts the packet into an untracked
6302 * state for the current processing path. If "recirc_table" is
6303 * set, execution is forked and the packet passes through the
6304 * connection tracker. The specified table's processing path is
6305 * able to match on Connection state until the end of the OpenFlow
6306 * pipeline or NXAST_CT is called again.
6308 * - Connection State:
6310 * Multiple packets may be associated with a single connection. Initially,
6311 * all connections are uncommitted. The connection state corresponding to
6312 * a packet is available in the NXM_NX_CT_STATE field for tracked packets.
6314 * Uncommitted connections have no state stored about them. Uncommitted
6315 * connections may transition into the committed state by executing
6316 * NXAST_CT with the NX_CT_F_COMMIT flag.
6318 * Once a connection becomes committed, information may be gathered about
6319 * the connection by passing subsequent packets through the connection
6320 * tracker, and the state of the connection will be stored beyond the
6321 * lifetime of packet processing.
6323 * A committed connection always has the directionality of the packet that
6324 * caused the connection to be committed in the first place. This is the
6325 * "original direction" of the connection, and the opposite direction is
6326 * the "reply direction". If a connection is already committed, but it is
6327 * then decided that the original direction should be the opposite of the
6328 * existing connection, NX_CT_F_FORCE flag may be used in addition to
6329 * NX_CT_F_COMMIT flag to in effect terminate the existing connection and
6330 * start a new one in the current direction.
6332 * Connections may transition back into the uncommitted state due to
6333 * external timers, or due to the contents of packets that are sent to the
6334 * connection tracker. This behaviour is outside of the scope of the
6335 * OpenFlow interface.
6337 * The "zone" specifies a context within which the tracking is done:
6339 * The connection tracking zone is a 16-bit number. Each zone is an
6340 * independent connection tracking context. The connection state for each
6341 * connection is completely separate for each zone, so if a connection
6342 * is committed to zone A, then it will remain uncommitted in zone B.
6343 * If NXAST_CT is executed with the same zone multiple times, later
6344 * executions have no effect.
6346 * If 'zone_src' is nonzero, this specifies that the zone should be
6347 * sourced from a field zone_src[ofs:ofs+nbits]. The format and semantics
6348 * of 'zone_src' and 'zone_ofs_nbits' are similar to those for the
6349 * NXAST_REG_LOAD action. The acceptable nxm_header values for 'zone_src'
6350 * are the same as the acceptable nxm_header values for the 'src' field of
6353 * If 'zone_src' is zero, then the value of 'zone_imm' will be used as the
6354 * connection tracking zone.
6356 * The "recirc_table" allows NXM_NX_CT_* fields to become available:
6358 * If "recirc_table" has a value other than NX_CT_RECIRC_NONE, then the
6359 * packet will be logically cloned prior to executing this action. One
6360 * copy will be sent to the connection tracker, then will be re-injected
6361 * into the OpenFlow pipeline beginning at the OpenFlow table specified in
6362 * this field. When the packet re-enters the pipeline, the NXM_NX_CT_*
6363 * fields will be populated. The original instance of the packet will
6364 * continue the current actions list. This can be thought of as similar to
6365 * the effect of the "output" action: One copy is sent out (in this case,
6366 * to the connection tracker), but the current copy continues processing.
6368 * It is strongly recommended that this table is later than the current
6369 * table, to prevent loops.
6371 * The "alg" attaches protocol-specific behaviour to this action:
6373 * The ALG is a 16-bit number which specifies that additional
6374 * processing should be applied to this traffic.
6376 * Protocol | Value | Meaning
6377 * --------------------------------------------------------------------
6378 * None | 0 | No protocol-specific behaviour.
6379 * FTP | 21 | Parse FTP control connections and observe the
6380 * | | negotiation of related data connections.
6381 * Other | Other | Unsupported protocols.
6383 * By way of example, if FTP control connections have this action applied
6384 * with the ALG set to FTP (21), then the connection tracker will observe
6385 * the negotiation of data connections. This allows the connection
6386 * tracker to identify subsequent data connections as "related" to this
6387 * existing connection. The "related" flag will be populated in the
6388 * NXM_NX_CT_STATE field for such connections if the 'recirc_table' is
6391 * Zero or more actions may immediately follow this action. These actions will
6392 * be executed within the context of the connection tracker, and they require
6393 * NX_CT_F_COMMIT flag be set.
6395 struct nx_action_conntrack
{
6396 ovs_be16 type
; /* OFPAT_VENDOR. */
6397 ovs_be16 len
; /* At least 24. */
6398 ovs_be32 vendor
; /* NX_VENDOR_ID. */
6399 ovs_be16 subtype
; /* NXAST_CT. */
6400 ovs_be16 flags
; /* Zero or more NX_CT_F_* flags.
6401 * Unspecified flag bits must be zero. */
6402 ovs_be32 zone_src
; /* Connection tracking context. */
6404 ovs_be16 zone_ofs_nbits
;/* Range to use from source field. */
6405 ovs_be16 zone_imm
; /* Immediate value for zone. */
6407 uint8_t recirc_table
; /* Recirculate to a specific table, or
6408 NX_CT_RECIRC_NONE for no recirculation. */
6409 uint8_t pad
[3]; /* Zeroes */
6410 ovs_be16 alg
; /* Well-known port number for the protocol.
6411 * 0 indicates no ALG is required. */
6412 /* Followed by a sequence of zero or more OpenFlow actions. The length of
6413 * these is included in 'len'. */
6415 OFP_ASSERT(sizeof(struct nx_action_conntrack
) == 24);
6418 decode_ct_zone(const struct nx_action_conntrack
*nac
,
6419 struct ofpact_conntrack
*out
,
6420 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
)
6422 if (nac
->zone_src
) {
6425 out
->zone_src
.ofs
= nxm_decode_ofs(nac
->zone_ofs_nbits
);
6426 out
->zone_src
.n_bits
= nxm_decode_n_bits(nac
->zone_ofs_nbits
);
6427 error
= mf_vl_mff_mf_from_nxm_header(ntohl(nac
->zone_src
),
6428 vl_mff_map
, &out
->zone_src
.field
,
6434 error
= mf_check_src(&out
->zone_src
, NULL
);
6439 if (out
->zone_src
.n_bits
!= 16) {
6440 VLOG_WARN_RL(&rl
, "zone n_bits %d not within valid range [16..16]",
6441 out
->zone_src
.n_bits
);
6442 return OFPERR_OFPBAC_BAD_SET_LEN
;
6445 out
->zone_src
.field
= NULL
;
6446 out
->zone_imm
= ntohs(nac
->zone_imm
);
6453 decode_NXAST_RAW_CT(const struct nx_action_conntrack
*nac
,
6454 enum ofp_version ofp_version
,
6455 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
6458 const size_t ct_offset
= ofpacts_pull(out
);
6459 struct ofpact_conntrack
*conntrack
= ofpact_put_CT(out
);
6462 conntrack
->flags
= ntohs(nac
->flags
);
6463 if (conntrack
->flags
& NX_CT_F_FORCE
&&
6464 !(conntrack
->flags
& NX_CT_F_COMMIT
)) {
6465 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
6469 error
= decode_ct_zone(nac
, conntrack
, vl_mff_map
, tlv_bitmap
);
6473 conntrack
->recirc_table
= nac
->recirc_table
;
6474 conntrack
->alg
= ntohs(nac
->alg
);
6476 ofpbuf_pull(out
, sizeof(*conntrack
));
6478 struct ofpbuf openflow
= ofpbuf_const_initializer(
6479 nac
+ 1, ntohs(nac
->len
) - sizeof(*nac
));
6480 error
= ofpacts_pull_openflow_actions__(&openflow
, openflow
.size
,
6482 1u << OVSINST_OFPIT11_APPLY_ACTIONS
,
6483 out
, OFPACT_CT
, vl_mff_map
,
6489 conntrack
= ofpbuf_push_uninit(out
, sizeof(*conntrack
));
6490 out
->header
= &conntrack
->ofpact
;
6491 ofpact_finish_CT(out
, &conntrack
);
6493 if (conntrack
->ofpact
.len
> sizeof(*conntrack
)
6494 && !(conntrack
->flags
& NX_CT_F_COMMIT
)) {
6495 const struct ofpact
*a
;
6496 size_t ofpacts_len
= conntrack
->ofpact
.len
- sizeof(*conntrack
);
6498 OFPACT_FOR_EACH (a
, conntrack
->actions
, ofpacts_len
) {
6499 if (a
->type
!= OFPACT_NAT
|| ofpact_get_NAT(a
)->flags
6500 || ofpact_get_NAT(a
)->range_af
!= AF_UNSPEC
) {
6501 VLOG_WARN_RL(&rl
, "CT action requires commit flag if actions "
6502 "other than NAT without arguments are specified.");
6503 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
6510 ofpbuf_push_uninit(out
, ct_offset
);
6515 encode_CT(const struct ofpact_conntrack
*conntrack
,
6516 enum ofp_version ofp_version
, struct ofpbuf
*out
)
6518 struct nx_action_conntrack
*nac
;
6519 const size_t ofs
= out
->size
;
6522 nac
= put_NXAST_CT(out
);
6523 nac
->flags
= htons(conntrack
->flags
);
6524 if (conntrack
->zone_src
.field
) {
6525 nac
->zone_src
= htonl(nxm_header_from_mff(conntrack
->zone_src
.field
));
6526 nac
->zone_ofs_nbits
= nxm_encode_ofs_nbits(conntrack
->zone_src
.ofs
,
6527 conntrack
->zone_src
.n_bits
);
6529 nac
->zone_src
= htonl(0);
6530 nac
->zone_imm
= htons(conntrack
->zone_imm
);
6532 nac
->recirc_table
= conntrack
->recirc_table
;
6533 nac
->alg
= htons(conntrack
->alg
);
6535 len
= ofpacts_put_openflow_actions(conntrack
->actions
,
6536 ofpact_ct_get_action_len(conntrack
),
6538 len
+= sizeof(*nac
);
6539 nac
= ofpbuf_at(out
, ofs
, sizeof(*nac
));
6540 nac
->len
= htons(len
);
6543 static char *OVS_WARN_UNUSED_RESULT
6544 parse_NAT(char *arg
, const struct ofpact_parse_params
*pp
);
6546 /* Parses 'arg' as the argument to a "ct" action, and appends such an
6547 * action to 'pp->ofpacts'.
6549 * Returns NULL if successful, otherwise a malloc()'d string describing the
6550 * error. The caller is responsible for freeing the returned string. */
6551 static char * OVS_WARN_UNUSED_RESULT
6552 parse_CT(char *arg
, const struct ofpact_parse_params
*pp
)
6554 const size_t ct_offset
= ofpacts_pull(pp
->ofpacts
);
6555 struct ofpact_conntrack
*oc
;
6559 oc
= ofpact_put_CT(pp
->ofpacts
);
6561 oc
->recirc_table
= NX_CT_RECIRC_NONE
;
6562 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
6563 if (!strcmp(key
, "commit")) {
6564 oc
->flags
|= NX_CT_F_COMMIT
;
6565 } else if (!strcmp(key
, "force")) {
6566 oc
->flags
|= NX_CT_F_FORCE
;
6567 } else if (!strcmp(key
, "table")) {
6568 if (!ofputil_table_from_string(value
, pp
->table_map
,
6569 &oc
->recirc_table
)) {
6570 error
= xasprintf("unknown table %s", value
);
6571 } else if (oc
->recirc_table
== NX_CT_RECIRC_NONE
) {
6572 error
= xasprintf("invalid table %#"PRIx8
, oc
->recirc_table
);
6574 } else if (!strcmp(key
, "zone")) {
6575 error
= str_to_u16(value
, "zone", &oc
->zone_imm
);
6579 error
= mf_parse_subfield(&oc
->zone_src
, value
);
6584 } else if (!strcmp(key
, "alg")) {
6585 error
= str_to_connhelper(value
, &oc
->alg
);
6586 } else if (!strcmp(key
, "nat")) {
6587 const size_t nat_offset
= ofpacts_pull(pp
->ofpacts
);
6589 error
= parse_NAT(value
, pp
);
6590 /* Update CT action pointer and length. */
6591 pp
->ofpacts
->header
= ofpbuf_push_uninit(pp
->ofpacts
, nat_offset
);
6592 oc
= pp
->ofpacts
->header
;
6593 } else if (!strcmp(key
, "exec")) {
6594 /* Hide existing actions from ofpacts_parse_copy(), so the
6595 * nesting can be handled transparently. */
6596 enum ofputil_protocol usable_protocols2
;
6597 const size_t exec_offset
= ofpacts_pull(pp
->ofpacts
);
6599 /* Initializes 'usable_protocol2', fold it back to
6600 * '*usable_protocols' afterwards, so that we do not lose
6601 * restrictions already in there. */
6602 struct ofpact_parse_params pp2
= *pp
;
6603 pp2
.usable_protocols
= &usable_protocols2
;
6604 error
= ofpacts_parse_copy(value
, &pp2
, false, OFPACT_CT
);
6605 *pp
->usable_protocols
&= usable_protocols2
;
6606 pp
->ofpacts
->header
= ofpbuf_push_uninit(pp
->ofpacts
, exec_offset
);
6607 oc
= pp
->ofpacts
->header
;
6609 error
= xasprintf("invalid argument to \"ct\" action: `%s'", key
);
6615 if (!error
&& oc
->flags
& NX_CT_F_FORCE
&& !(oc
->flags
& NX_CT_F_COMMIT
)) {
6616 error
= xasprintf("\"force\" flag requires \"commit\" flag.");
6618 ofpact_finish_CT(pp
->ofpacts
, &oc
);
6619 ofpbuf_push_uninit(pp
->ofpacts
, ct_offset
);
6624 format_alg(int port
, struct ds
*s
)
6628 ds_put_format(s
, "%salg=%sftp,", colors
.param
, colors
.end
);
6631 ds_put_format(s
, "%salg=%stftp,", colors
.param
, colors
.end
);
6637 ds_put_format(s
, "%salg=%s%d,", colors
.param
, colors
.end
, port
);
6642 static void format_NAT(const struct ofpact_nat
*,
6643 const struct ofpact_format_params
*fp
);
6646 format_CT(const struct ofpact_conntrack
*a
,
6647 const struct ofpact_format_params
*fp
)
6649 ds_put_format(fp
->s
, "%sct(%s", colors
.paren
, colors
.end
);
6650 if (a
->flags
& NX_CT_F_COMMIT
) {
6651 ds_put_format(fp
->s
, "%scommit%s,", colors
.value
, colors
.end
);
6653 if (a
->flags
& NX_CT_F_FORCE
) {
6654 ds_put_format(fp
->s
, "%sforce%s,", colors
.value
, colors
.end
);
6656 if (a
->recirc_table
!= NX_CT_RECIRC_NONE
) {
6657 ds_put_format(fp
->s
, "%stable=%s", colors
.special
, colors
.end
);
6658 ofputil_format_table(a
->recirc_table
, fp
->table_map
, fp
->s
);
6659 ds_put_char(fp
->s
, ',');
6661 if (a
->zone_src
.field
) {
6662 ds_put_format(fp
->s
, "%szone=%s", colors
.param
, colors
.end
);
6663 mf_format_subfield(&a
->zone_src
, fp
->s
);
6664 ds_put_char(fp
->s
, ',');
6665 } else if (a
->zone_imm
) {
6666 ds_put_format(fp
->s
, "%szone=%s%"PRIu16
",",
6667 colors
.param
, colors
.end
, a
->zone_imm
);
6669 /* If the first action is a NAT action, format it outside of the 'exec'
6671 const struct ofpact
*action
= a
->actions
;
6672 size_t actions_len
= ofpact_ct_get_action_len(a
);
6673 if (actions_len
&& action
->type
== OFPACT_NAT
) {
6674 format_NAT(ofpact_get_NAT(action
), fp
);
6675 ds_put_char(fp
->s
, ',');
6676 actions_len
-= OFPACT_ALIGN(action
->len
);
6677 action
= ofpact_next(action
);
6680 ds_put_format(fp
->s
, "%sexec(%s", colors
.paren
, colors
.end
);
6681 ofpacts_format(action
, actions_len
, fp
);
6682 ds_put_format(fp
->s
, "%s),%s", colors
.paren
, colors
.end
);
6684 format_alg(a
->alg
, fp
->s
);
6685 ds_chomp(fp
->s
, ',');
6686 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
6690 check_CT(struct ofpact_conntrack
*a
, struct ofpact_check_params
*cp
)
6692 struct flow
*flow
= &cp
->match
->flow
;
6694 if (!dl_type_is_ip_any(get_dl_type(flow
))
6695 || (flow
->ct_state
& CS_INVALID
&& a
->flags
& NX_CT_F_COMMIT
)
6696 || (a
->alg
== IPPORT_FTP
&& flow
->nw_proto
!= IPPROTO_TCP
)
6697 || (a
->alg
== IPPORT_TFTP
&& flow
->nw_proto
!= IPPROTO_UDP
)) {
6698 /* We can't downgrade to OF1.0 and expect inconsistent CT actions
6699 * be silently discarded. Instead, datapath flow install fails, so
6700 * it is better to flag inconsistent CT actions as hard errors. */
6701 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
6704 if (a
->zone_src
.field
) {
6705 return mf_check_src(&a
->zone_src
, cp
->match
);
6708 return check_subactions(a
->actions
, ofpact_ct_get_action_len(a
), cp
);
6711 /* ct_clear action. */
6714 decode_NXAST_RAW_CT_CLEAR(struct ofpbuf
*out
)
6716 ofpact_put_CT_CLEAR(out
);
6721 encode_CT_CLEAR(const struct ofpact_null
*null OVS_UNUSED
,
6722 enum ofp_version ofp_version OVS_UNUSED
,
6725 put_NXAST_CT_CLEAR(out
);
6728 static char * OVS_WARN_UNUSED_RESULT
6729 parse_CT_CLEAR(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
6731 ofpact_put_CT_CLEAR(pp
->ofpacts
);
6736 format_CT_CLEAR(const struct ofpact_null
*a OVS_UNUSED
,
6737 const struct ofpact_format_params
*fp
)
6739 ds_put_format(fp
->s
, "%sct_clear%s", colors
.value
, colors
.end
);
6743 check_CT_CLEAR(const struct ofpact_null
*a OVS_UNUSED
,
6744 const struct ofpact_check_params
*cp OVS_UNUSED
)
6751 /* Which optional fields are present? */
6753 NX_NAT_RANGE_IPV4_MIN
= 1 << 0, /* ovs_be32 */
6754 NX_NAT_RANGE_IPV4_MAX
= 1 << 1, /* ovs_be32 */
6755 NX_NAT_RANGE_IPV6_MIN
= 1 << 2, /* struct in6_addr */
6756 NX_NAT_RANGE_IPV6_MAX
= 1 << 3, /* struct in6_addr */
6757 NX_NAT_RANGE_PROTO_MIN
= 1 << 4, /* ovs_be16 */
6758 NX_NAT_RANGE_PROTO_MAX
= 1 << 5, /* ovs_be16 */
6761 /* Action structure for NXAST_NAT. */
6762 struct nx_action_nat
{
6763 ovs_be16 type
; /* OFPAT_VENDOR. */
6764 ovs_be16 len
; /* At least 16. */
6765 ovs_be32 vendor
; /* NX_VENDOR_ID. */
6766 ovs_be16 subtype
; /* NXAST_NAT. */
6767 uint8_t pad
[2]; /* Must be zero. */
6768 ovs_be16 flags
; /* Zero or more NX_NAT_F_* flags.
6769 * Unspecified flag bits must be zero. */
6770 ovs_be16 range_present
; /* NX_NAT_RANGE_* */
6771 /* Followed by optional parameters as specified by 'range_present' */
6773 OFP_ASSERT(sizeof(struct nx_action_nat
) == 16);
6776 encode_NAT(const struct ofpact_nat
*nat
,
6777 enum ofp_version ofp_version OVS_UNUSED
,
6780 struct nx_action_nat
*nan
;
6781 const size_t ofs
= out
->size
;
6782 uint16_t range_present
= 0;
6784 nan
= put_NXAST_NAT(out
);
6785 nan
->flags
= htons(nat
->flags
);
6786 if (nat
->range_af
== AF_INET
) {
6787 if (nat
->range
.addr
.ipv4
.min
) {
6788 ovs_be32
*min
= ofpbuf_put_uninit(out
, sizeof *min
);
6789 *min
= nat
->range
.addr
.ipv4
.min
;
6790 range_present
|= NX_NAT_RANGE_IPV4_MIN
;
6792 if (nat
->range
.addr
.ipv4
.max
) {
6793 ovs_be32
*max
= ofpbuf_put_uninit(out
, sizeof *max
);
6794 *max
= nat
->range
.addr
.ipv4
.max
;
6795 range_present
|= NX_NAT_RANGE_IPV4_MAX
;
6797 } else if (nat
->range_af
== AF_INET6
) {
6798 if (!ipv6_mask_is_any(&nat
->range
.addr
.ipv6
.min
)) {
6799 struct in6_addr
*min
= ofpbuf_put_uninit(out
, sizeof *min
);
6800 *min
= nat
->range
.addr
.ipv6
.min
;
6801 range_present
|= NX_NAT_RANGE_IPV6_MIN
;
6803 if (!ipv6_mask_is_any(&nat
->range
.addr
.ipv6
.max
)) {
6804 struct in6_addr
*max
= ofpbuf_put_uninit(out
, sizeof *max
);
6805 *max
= nat
->range
.addr
.ipv6
.max
;
6806 range_present
|= NX_NAT_RANGE_IPV6_MAX
;
6809 if (nat
->range_af
!= AF_UNSPEC
) {
6810 if (nat
->range
.proto
.min
) {
6811 ovs_be16
*min
= ofpbuf_put_uninit(out
, sizeof *min
);
6812 *min
= htons(nat
->range
.proto
.min
);
6813 range_present
|= NX_NAT_RANGE_PROTO_MIN
;
6815 if (nat
->range
.proto
.max
) {
6816 ovs_be16
*max
= ofpbuf_put_uninit(out
, sizeof *max
);
6817 *max
= htons(nat
->range
.proto
.max
);
6818 range_present
|= NX_NAT_RANGE_PROTO_MAX
;
6821 pad_ofpat(out
, ofs
);
6822 nan
= ofpbuf_at(out
, ofs
, sizeof *nan
);
6823 nan
->range_present
= htons(range_present
);
6827 decode_NXAST_RAW_NAT(const struct nx_action_nat
*nan
,
6828 enum ofp_version ofp_version OVS_UNUSED
,
6831 struct ofpact_nat
*nat
;
6832 uint16_t range_present
= ntohs(nan
->range_present
);
6833 const char *opts
= (char *)(nan
+ 1);
6834 uint16_t len
= ntohs(nan
->len
) - sizeof *nan
;
6836 nat
= ofpact_put_NAT(out
);
6837 nat
->flags
= ntohs(nan
->flags
);
6839 /* Check for unknown or mutually exclusive flags. */
6840 if ((nat
->flags
& ~NX_NAT_F_MASK
)
6841 || (nat
->flags
& NX_NAT_F_SRC
&& nat
->flags
& NX_NAT_F_DST
)
6842 || (nat
->flags
& NX_NAT_F_PROTO_HASH
6843 && nat
->flags
& NX_NAT_F_PROTO_RANDOM
)) {
6844 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6847 #define NX_NAT_GET_OPT(DST, SRC, LEN, TYPE) \
6848 (LEN >= sizeof(TYPE) \
6849 ? (memcpy(DST, SRC, sizeof(TYPE)), LEN -= sizeof(TYPE), \
6850 SRC += sizeof(TYPE)) \
6853 nat
->range_af
= AF_UNSPEC
;
6854 if (range_present
& NX_NAT_RANGE_IPV4_MIN
) {
6855 if (range_present
& (NX_NAT_RANGE_IPV6_MIN
| NX_NAT_RANGE_IPV6_MAX
)) {
6856 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6859 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv4
.min
, opts
, len
, ovs_be32
)
6860 || !nat
->range
.addr
.ipv4
.min
) {
6861 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6864 nat
->range_af
= AF_INET
;
6866 if (range_present
& NX_NAT_RANGE_IPV4_MAX
) {
6867 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv4
.max
, opts
, len
,
6869 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6871 if (ntohl(nat
->range
.addr
.ipv4
.max
)
6872 < ntohl(nat
->range
.addr
.ipv4
.min
)) {
6873 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6876 } else if (range_present
& NX_NAT_RANGE_IPV4_MAX
) {
6877 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6878 } else if (range_present
& NX_NAT_RANGE_IPV6_MIN
) {
6879 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv6
.min
, opts
, len
,
6881 || ipv6_mask_is_any(&nat
->range
.addr
.ipv6
.min
)) {
6882 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6885 nat
->range_af
= AF_INET6
;
6887 if (range_present
& NX_NAT_RANGE_IPV6_MAX
) {
6888 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv6
.max
, opts
, len
,
6890 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6892 if (memcmp(&nat
->range
.addr
.ipv6
.max
, &nat
->range
.addr
.ipv6
.min
,
6893 sizeof(struct in6_addr
)) < 0) {
6894 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6897 } else if (range_present
& NX_NAT_RANGE_IPV6_MAX
) {
6898 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6901 if (range_present
& NX_NAT_RANGE_PROTO_MIN
) {
6904 if (nat
->range_af
== AF_UNSPEC
) {
6905 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6907 if (!NX_NAT_GET_OPT(&proto
, opts
, len
, ovs_be16
) || proto
== 0) {
6908 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6910 nat
->range
.proto
.min
= ntohs(proto
);
6911 if (range_present
& NX_NAT_RANGE_PROTO_MAX
) {
6912 if (!NX_NAT_GET_OPT(&proto
, opts
, len
, ovs_be16
)) {
6913 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6915 nat
->range
.proto
.max
= ntohs(proto
);
6916 if (nat
->range
.proto
.max
< nat
->range
.proto
.min
) {
6917 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6920 } else if (range_present
& NX_NAT_RANGE_PROTO_MAX
) {
6921 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6928 format_NAT(const struct ofpact_nat
*a
, const struct ofpact_format_params
*fp
)
6930 ds_put_format(fp
->s
, "%snat%s", colors
.paren
, colors
.end
);
6932 if (a
->flags
& (NX_NAT_F_SRC
| NX_NAT_F_DST
)) {
6933 ds_put_format(fp
->s
, "%s(%s", colors
.paren
, colors
.end
);
6934 ds_put_format(fp
->s
, a
->flags
& NX_NAT_F_SRC
? "%ssrc%s" : "%sdst%s",
6935 colors
.param
, colors
.end
);
6937 if (a
->range_af
!= AF_UNSPEC
) {
6938 ds_put_format(fp
->s
, "%s=%s", colors
.param
, colors
.end
);
6940 if (a
->range_af
== AF_INET
) {
6941 ds_put_format(fp
->s
, IP_FMT
, IP_ARGS(a
->range
.addr
.ipv4
.min
));
6943 if (a
->range
.addr
.ipv4
.max
6944 && a
->range
.addr
.ipv4
.max
!= a
->range
.addr
.ipv4
.min
) {
6945 ds_put_format(fp
->s
, "-"IP_FMT
,
6946 IP_ARGS(a
->range
.addr
.ipv4
.max
));
6948 } else if (a
->range_af
== AF_INET6
) {
6949 ipv6_format_addr_bracket(&a
->range
.addr
.ipv6
.min
, fp
->s
,
6950 a
->range
.proto
.min
);
6952 if (!ipv6_mask_is_any(&a
->range
.addr
.ipv6
.max
)
6953 && memcmp(&a
->range
.addr
.ipv6
.max
, &a
->range
.addr
.ipv6
.min
,
6954 sizeof(struct in6_addr
)) != 0) {
6955 ds_put_char(fp
->s
, '-');
6956 ipv6_format_addr_bracket(&a
->range
.addr
.ipv6
.max
, fp
->s
,
6957 a
->range
.proto
.min
);
6960 if (a
->range
.proto
.min
) {
6961 ds_put_char(fp
->s
, ':');
6962 ds_put_format(fp
->s
, "%"PRIu16
, a
->range
.proto
.min
);
6964 if (a
->range
.proto
.max
6965 && a
->range
.proto
.max
!= a
->range
.proto
.min
) {
6966 ds_put_format(fp
->s
, "-%"PRIu16
, a
->range
.proto
.max
);
6969 ds_put_char(fp
->s
, ',');
6971 if (a
->flags
& NX_NAT_F_PERSISTENT
) {
6972 ds_put_format(fp
->s
, "%spersistent%s,",
6973 colors
.value
, colors
.end
);
6975 if (a
->flags
& NX_NAT_F_PROTO_HASH
) {
6976 ds_put_format(fp
->s
, "%shash%s,", colors
.value
, colors
.end
);
6978 if (a
->flags
& NX_NAT_F_PROTO_RANDOM
) {
6979 ds_put_format(fp
->s
, "%srandom%s,", colors
.value
, colors
.end
);
6982 ds_chomp(fp
->s
, ',');
6983 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
6987 static char * OVS_WARN_UNUSED_RESULT
6988 str_to_nat_range(const char *s
, struct ofpact_nat
*on
)
6990 char ipv6_s
[IPV6_SCAN_LEN
+ 1];
6993 on
->range_af
= AF_UNSPEC
;
6994 if (ovs_scan_len(s
, &n
, IP_SCAN_FMT
,
6995 IP_SCAN_ARGS(&on
->range
.addr
.ipv4
.min
))) {
6996 on
->range_af
= AF_INET
;
7000 if (!ovs_scan_len(s
, &n
, IP_SCAN_FMT
,
7001 IP_SCAN_ARGS(&on
->range
.addr
.ipv4
.max
))
7002 || (ntohl(on
->range
.addr
.ipv4
.max
)
7003 < ntohl(on
->range
.addr
.ipv4
.min
))) {
7007 } else if ((ovs_scan_len(s
, &n
, IPV6_SCAN_FMT
, ipv6_s
)
7008 || ovs_scan_len(s
, &n
, "["IPV6_SCAN_FMT
"]", ipv6_s
))
7009 && inet_pton(AF_INET6
, ipv6_s
, &on
->range
.addr
.ipv6
.min
) == 1) {
7010 on
->range_af
= AF_INET6
;
7014 if (!(ovs_scan_len(s
, &n
, IPV6_SCAN_FMT
, ipv6_s
)
7015 || ovs_scan_len(s
, &n
, "["IPV6_SCAN_FMT
"]", ipv6_s
))
7016 || inet_pton(AF_INET6
, ipv6_s
, &on
->range
.addr
.ipv6
.max
) != 1
7017 || memcmp(&on
->range
.addr
.ipv6
.max
, &on
->range
.addr
.ipv6
.min
,
7018 sizeof on
->range
.addr
.ipv6
.max
) < 0) {
7023 if (on
->range_af
!= AF_UNSPEC
&& s
[n
] == ':') {
7025 if (!ovs_scan_len(s
, &n
, "%"SCNu16
, &on
->range
.proto
.min
)) {
7030 if (!ovs_scan_len(s
, &n
, "%"SCNu16
, &on
->range
.proto
.max
)
7031 || on
->range
.proto
.max
< on
->range
.proto
.min
) {
7036 if (strlen(s
) != n
) {
7037 return xasprintf("garbage (%s) after nat range \"%s\" (pos: %d)",
7042 return xasprintf("invalid nat range \"%s\"", s
);
7046 /* Parses 'arg' as the argument to a "nat" action, and appends such an
7047 * action to 'pp->ofpacts'.
7049 * Returns NULL if successful, otherwise a malloc()'d string describing the
7050 * error. The caller is responsible for freeing the returned string. */
7051 static char * OVS_WARN_UNUSED_RESULT
7052 parse_NAT(char *arg
, const struct ofpact_parse_params
*pp
)
7054 struct ofpact_nat
*on
= ofpact_put_NAT(pp
->ofpacts
);
7058 on
->range_af
= AF_UNSPEC
;
7060 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
7063 if (!strcmp(key
, "src")) {
7064 on
->flags
|= NX_NAT_F_SRC
;
7065 error
= str_to_nat_range(value
, on
);
7066 } else if (!strcmp(key
, "dst")) {
7067 on
->flags
|= NX_NAT_F_DST
;
7068 error
= str_to_nat_range(value
, on
);
7069 } else if (!strcmp(key
, "persistent")) {
7070 on
->flags
|= NX_NAT_F_PERSISTENT
;
7071 } else if (!strcmp(key
, "hash")) {
7072 on
->flags
|= NX_NAT_F_PROTO_HASH
;
7073 } else if (!strcmp(key
, "random")) {
7074 on
->flags
|= NX_NAT_F_PROTO_RANDOM
;
7076 error
= xasprintf("invalid key \"%s\" in \"nat\" argument",
7083 if (on
->flags
& NX_NAT_F_SRC
&& on
->flags
& NX_NAT_F_DST
) {
7084 return xasprintf("May only specify one of \"src\" or \"dst\".");
7086 if (!(on
->flags
& NX_NAT_F_SRC
|| on
->flags
& NX_NAT_F_DST
)) {
7088 return xasprintf("Flags allowed only with \"src\" or \"dst\".");
7090 if (on
->range_af
!= AF_UNSPEC
) {
7091 return xasprintf("Range allowed only with \"src\" or \"dst\".");
7094 if (on
->flags
& NX_NAT_F_PROTO_HASH
&& on
->flags
& NX_NAT_F_PROTO_RANDOM
) {
7095 return xasprintf("Both \"hash\" and \"random\" are not allowed.");
7102 check_NAT(const struct ofpact_nat
*a
, const struct ofpact_check_params
*cp
)
7104 ovs_be16 dl_type
= get_dl_type(&cp
->match
->flow
);
7105 if (!dl_type_is_ip_any(dl_type
) ||
7106 (a
->range_af
== AF_INET
&& dl_type
!= htons(ETH_TYPE_IP
)) ||
7107 (a
->range_af
== AF_INET6
&& dl_type
!= htons(ETH_TYPE_IPV6
))) {
7108 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
7113 /* Truncate output action. */
7114 struct nx_action_output_trunc
{
7115 ovs_be16 type
; /* OFPAT_VENDOR. */
7116 ovs_be16 len
; /* At least 16. */
7117 ovs_be32 vendor
; /* NX_VENDOR_ID. */
7118 ovs_be16 subtype
; /* NXAST_OUTPUT_TRUNC. */
7119 ovs_be16 port
; /* Output port */
7120 ovs_be32 max_len
; /* Truncate packet to size bytes */
7122 OFP_ASSERT(sizeof(struct nx_action_output_trunc
) == 16);
7125 decode_NXAST_RAW_OUTPUT_TRUNC(const struct nx_action_output_trunc
*natrc
,
7126 enum ofp_version ofp_version OVS_UNUSED
,
7129 struct ofpact_output_trunc
*output_trunc
;
7131 output_trunc
= ofpact_put_OUTPUT_TRUNC(out
);
7132 output_trunc
->max_len
= ntohl(natrc
->max_len
);
7133 output_trunc
->port
= u16_to_ofp(ntohs(natrc
->port
));
7135 if (output_trunc
->max_len
< ETH_HEADER_LEN
) {
7136 return OFPERR_OFPBAC_BAD_ARGUMENT
;
7142 encode_OUTPUT_TRUNC(const struct ofpact_output_trunc
*output_trunc
,
7143 enum ofp_version ofp_version OVS_UNUSED
,
7146 struct nx_action_output_trunc
*natrc
= put_NXAST_OUTPUT_TRUNC(out
);
7148 natrc
->max_len
= htonl(output_trunc
->max_len
);
7149 natrc
->port
= htons(ofp_to_u16(output_trunc
->port
));
7152 static char * OVS_WARN_UNUSED_RESULT
7153 parse_OUTPUT_TRUNC(const char *arg
,
7154 const struct ofpact_parse_params
*pp OVS_UNUSED
)
7156 /* Disable output_trunc parsing. Expose as output(port=N,max_len=M) and
7157 * reuse parse_OUTPUT to parse output_trunc action. */
7158 return xasprintf("unknown action %s", arg
);
7162 format_OUTPUT_TRUNC(const struct ofpact_output_trunc
*a
,
7163 const struct ofpact_format_params
*fp
)
7165 ds_put_format(fp
->s
, "%soutput%s(port=", colors
.special
, colors
.end
);
7166 ofputil_format_port(a
->port
, fp
->port_map
, fp
->s
);
7167 ds_put_format(fp
->s
, ",max_len=%"PRIu32
")", a
->max_len
);
7171 check_OUTPUT_TRUNC(const struct ofpact_output_trunc
*a
,
7172 const struct ofpact_check_params
*cp
)
7174 return ofpact_check_output_port(a
->port
, cp
->max_ports
);
7177 /* Meter instruction. */
7180 encode_METER(const struct ofpact_meter
*meter
,
7181 enum ofp_version ofp_version
, struct ofpbuf
*out
)
7183 if (ofp_version
>= OFP13_VERSION
) {
7184 instruction_put_OFPIT13_METER(out
)->meter_id
= htonl(meter
->meter_id
);
7188 static char * OVS_WARN_UNUSED_RESULT
7189 parse_METER(char *arg
, const struct ofpact_parse_params
*pp
)
7191 *pp
->usable_protocols
&= OFPUTIL_P_OF13_UP
;
7192 return str_to_u32(arg
, &ofpact_put_METER(pp
->ofpacts
)->meter_id
);
7196 format_METER(const struct ofpact_meter
*a
,
7197 const struct ofpact_format_params
*fp
)
7199 ds_put_format(fp
->s
, "%smeter:%s%"PRIu32
,
7200 colors
.param
, colors
.end
, a
->meter_id
);
7204 check_METER(const struct ofpact_meter
*a
,
7205 const struct ofpact_check_params
*cp OVS_UNUSED
)
7207 uint32_t mid
= a
->meter_id
;
7208 return mid
== 0 || mid
> OFPM13_MAX
? OFPERR_OFPMMFC_INVALID_METER
: 0;
7211 /* Clear-Actions instruction. */
7214 encode_CLEAR_ACTIONS(const struct ofpact_null
*null OVS_UNUSED
,
7215 enum ofp_version ofp_version OVS_UNUSED
,
7216 struct ofpbuf
*out OVS_UNUSED
)
7218 if (ofp_version
> OFP10_VERSION
) {
7219 instruction_put_OFPIT11_CLEAR_ACTIONS(out
);
7223 static char * OVS_WARN_UNUSED_RESULT
7224 parse_CLEAR_ACTIONS(char *arg OVS_UNUSED
, const struct ofpact_parse_params
*pp
)
7226 ofpact_put_CLEAR_ACTIONS(pp
->ofpacts
);
7231 format_CLEAR_ACTIONS(const struct ofpact_null
*a OVS_UNUSED
,
7232 const struct ofpact_format_params
*fp
)
7234 ds_put_format(fp
->s
, "%sclear_actions%s", colors
.value
, colors
.end
);
7238 check_CLEAR_ACTIONS(const struct ofpact_null
*a OVS_UNUSED
,
7239 const struct ofpact_check_params
*cp OVS_UNUSED
)
7244 /* Write-Actions instruction. */
7247 encode_WRITE_ACTIONS(const struct ofpact_nest
*actions
,
7248 enum ofp_version ofp_version
, struct ofpbuf
*out
)
7250 if (ofp_version
> OFP10_VERSION
) {
7251 const size_t ofs
= out
->size
;
7253 instruction_put_OFPIT11_WRITE_ACTIONS(out
);
7254 ofpacts_put_openflow_actions(actions
->actions
,
7255 ofpact_nest_get_action_len(actions
),
7257 ofpacts_update_instruction_actions(out
, ofs
);
7261 static char * OVS_WARN_UNUSED_RESULT
7262 parse_WRITE_ACTIONS(char *arg
, const struct ofpact_parse_params
*pp
)
7264 size_t ofs
= ofpacts_pull(pp
->ofpacts
);
7265 struct ofpact_nest
*on
;
7268 /* Add a Write-Actions instruction and then pull it off. */
7269 ofpact_put(pp
->ofpacts
, OFPACT_WRITE_ACTIONS
, sizeof *on
);
7270 ofpbuf_pull(pp
->ofpacts
, sizeof *on
);
7272 /* Parse nested actions.
7274 * We pulled off "write-actions" and the previous actions because the
7275 * OFPACT_WRITE_ACTIONS is only partially constructed: its length is such
7276 * that it doesn't actually include the nested actions. That means that
7277 * ofpacts_parse() would reject them as being part of an Apply-Actions that
7278 * follows a Write-Actions, which is an invalid order. */
7279 error
= ofpacts_parse(arg
, pp
, false, OFPACT_WRITE_ACTIONS
);
7281 /* Put the Write-Actions back on and update its length. */
7282 on
= ofpbuf_push_uninit(pp
->ofpacts
, sizeof *on
);
7283 on
->ofpact
.len
= pp
->ofpacts
->size
;
7285 /* Put any previous actions or instructions back on. */
7286 ofpbuf_push_uninit(pp
->ofpacts
, ofs
);
7292 format_WRITE_ACTIONS(const struct ofpact_nest
*a
,
7293 const struct ofpact_format_params
*fp
)
7295 ds_put_format(fp
->s
, "%swrite_actions(%s", colors
.paren
, colors
.end
);
7296 ofpacts_format(a
->actions
, ofpact_nest_get_action_len(a
), fp
);
7297 ds_put_format(fp
->s
, "%s)%s", colors
.paren
, colors
.end
);
7301 check_WRITE_ACTIONS(struct ofpact_nest
*a
,
7302 const struct ofpact_check_params
*cp
)
7304 /* Use a temporary copy of 'cp' to avoid updating 'cp->usable_protocols',
7305 * since we can't check consistency of an action set. */
7306 struct ofpact_check_params tmp
= *cp
;
7307 return ofpacts_check(a
->actions
, ofpact_nest_get_action_len(a
), &tmp
);
7310 /* Action structure for NXAST_WRITE_METADATA.
7312 * Modifies the 'mask' bits of the metadata value. */
7313 struct nx_action_write_metadata
{
7314 ovs_be16 type
; /* OFPAT_VENDOR. */
7315 ovs_be16 len
; /* Length is 32. */
7316 ovs_be32 vendor
; /* NX_VENDOR_ID. */
7317 ovs_be16 subtype
; /* NXAST_WRITE_METADATA. */
7318 uint8_t zeros
[6]; /* Must be zero. */
7319 ovs_be64 metadata
; /* Metadata register. */
7320 ovs_be64 mask
; /* Metadata mask. */
7322 OFP_ASSERT(sizeof(struct nx_action_write_metadata
) == 32);
7325 decode_NXAST_RAW_WRITE_METADATA(const struct nx_action_write_metadata
*nawm
,
7326 enum ofp_version ofp_version OVS_UNUSED
,
7329 struct ofpact_metadata
*om
;
7331 if (!is_all_zeros(nawm
->zeros
, sizeof nawm
->zeros
)) {
7332 return OFPERR_NXBRC_MUST_BE_ZERO
;
7335 om
= ofpact_put_WRITE_METADATA(out
);
7336 om
->metadata
= nawm
->metadata
;
7337 om
->mask
= nawm
->mask
;
7343 encode_WRITE_METADATA(const struct ofpact_metadata
*metadata
,
7344 enum ofp_version ofp_version
, struct ofpbuf
*out
)
7346 if (ofp_version
== OFP10_VERSION
) {
7347 struct nx_action_write_metadata
*nawm
;
7349 nawm
= put_NXAST_WRITE_METADATA(out
);
7350 nawm
->metadata
= metadata
->metadata
;
7351 nawm
->mask
= metadata
->mask
;
7353 struct ofp11_instruction_write_metadata
*oiwm
;
7355 oiwm
= instruction_put_OFPIT11_WRITE_METADATA(out
);
7356 oiwm
->metadata
= metadata
->metadata
;
7357 oiwm
->metadata_mask
= metadata
->mask
;
7361 static char * OVS_WARN_UNUSED_RESULT
7362 parse_WRITE_METADATA(char *arg
, const struct ofpact_parse_params
*pp
)
7364 struct ofpact_metadata
*om
;
7365 char *mask
= strchr(arg
, '/');
7367 *pp
->usable_protocols
&= OFPUTIL_P_NXM_OF11_UP
;
7369 om
= ofpact_put_WRITE_METADATA(pp
->ofpacts
);
7374 error
= str_to_be64(mask
+ 1, &om
->mask
);
7379 om
->mask
= OVS_BE64_MAX
;
7382 return str_to_be64(arg
, &om
->metadata
);
7386 format_WRITE_METADATA(const struct ofpact_metadata
*a
,
7387 const struct ofpact_format_params
*fp
)
7389 ds_put_format(fp
->s
, "%swrite_metadata:%s%#"PRIx64
,
7390 colors
.param
, colors
.end
, ntohll(a
->metadata
));
7391 if (a
->mask
!= OVS_BE64_MAX
) {
7392 ds_put_format(fp
->s
, "/%#"PRIx64
, ntohll(a
->mask
));
7397 check_WRITE_METADATA(const struct ofpact_metadata
*a OVS_UNUSED
,
7398 const struct ofpact_check_params
*cp OVS_UNUSED
)
7403 /* Goto-Table instruction. */
7406 encode_GOTO_TABLE(const struct ofpact_goto_table
*goto_table
,
7407 enum ofp_version ofp_version
, struct ofpbuf
*out
)
7409 if (ofp_version
== OFP10_VERSION
) {
7410 struct nx_action_resubmit
*nar
;
7412 nar
= put_NXAST_RESUBMIT_TABLE(out
);
7413 nar
->table
= goto_table
->table_id
;
7414 nar
->in_port
= htons(ofp_to_u16(OFPP_IN_PORT
));
7416 struct ofp11_instruction_goto_table
*oigt
;
7418 oigt
= instruction_put_OFPIT11_GOTO_TABLE(out
);
7419 oigt
->table_id
= goto_table
->table_id
;
7420 memset(oigt
->pad
, 0, sizeof oigt
->pad
);
7424 static char * OVS_WARN_UNUSED_RESULT
7425 parse_GOTO_TABLE(char *arg
, const struct ofpact_parse_params
*pp
)
7427 struct ofpact_goto_table
*ogt
= ofpact_put_GOTO_TABLE(pp
->ofpacts
);
7428 if (!ofputil_table_from_string(arg
, pp
->table_map
, &ogt
->table_id
)) {
7429 return xasprintf("unknown table \"%s\"", arg
);
7435 format_GOTO_TABLE(const struct ofpact_goto_table
*a
,
7436 const struct ofpact_format_params
*fp
)
7438 ds_put_format(fp
->s
, "%sgoto_table:%s", colors
.param
, colors
.end
);
7439 ofputil_format_table(a
->table_id
, fp
->table_map
, fp
->s
);
7443 check_GOTO_TABLE(const struct ofpact_goto_table
*a
,
7444 const struct ofpact_check_params
*cp
)
7446 if ((cp
->table_id
!= 255 && a
->table_id
<= cp
->table_id
)
7447 || (cp
->n_tables
!= 255 && a
->table_id
>= cp
->n_tables
)) {
7448 return OFPERR_OFPBIC_BAD_TABLE_ID
;
7454 log_bad_action(const struct ofp_action_header
*actions
, size_t actions_len
,
7455 const struct ofp_action_header
*bad_action
, enum ofperr error
)
7457 if (!VLOG_DROP_WARN(&rl
)) {
7461 ds_put_hex_dump(&s
, actions
, actions_len
, 0, false);
7462 VLOG_WARN("bad action at offset %#"PRIxPTR
" (%s):\n%s",
7463 (char *)bad_action
- (char *)actions
,
7464 ofperr_get_name(error
), ds_cstr(&s
));
7470 ofpacts_decode(const void *actions
, size_t actions_len
,
7471 enum ofp_version ofp_version
,
7472 const struct vl_mff_map
*vl_mff_map
,
7473 uint64_t *ofpacts_tlv_bitmap
, struct ofpbuf
*ofpacts
)
7475 struct ofpbuf openflow
= ofpbuf_const_initializer(actions
, actions_len
);
7476 while (openflow
.size
) {
7477 const struct ofp_action_header
*action
= openflow
.data
;
7478 enum ofp_raw_action_type raw
;
7482 error
= ofpact_pull_raw(&openflow
, ofp_version
, &raw
, &arg
);
7484 error
= ofpact_decode(action
, raw
, ofp_version
, arg
, vl_mff_map
,
7485 ofpacts_tlv_bitmap
, ofpacts
);
7489 log_bad_action(actions
, actions_len
, action
, error
);
7497 ofpacts_pull_openflow_actions__(struct ofpbuf
*openflow
,
7498 unsigned int actions_len
,
7499 enum ofp_version version
,
7500 uint32_t allowed_ovsinsts
,
7501 struct ofpbuf
*ofpacts
,
7502 enum ofpact_type outer_action
,
7503 const struct vl_mff_map
*vl_mff_map
,
7504 uint64_t *ofpacts_tlv_bitmap
)
7506 const struct ofp_action_header
*actions
;
7509 if (actions_len
% OFP_ACTION_ALIGN
!= 0) {
7510 VLOG_WARN_RL(&rl
, "OpenFlow message actions length %u is not a "
7511 "multiple of %d", actions_len
, OFP_ACTION_ALIGN
);
7512 return OFPERR_OFPBRC_BAD_LEN
;
7515 actions
= ofpbuf_try_pull(openflow
, actions_len
);
7516 if (actions
== NULL
) {
7517 VLOG_WARN_RL(&rl
, "OpenFlow message actions length %u exceeds "
7518 "remaining message length (%"PRIu32
")",
7519 actions_len
, openflow
->size
);
7520 return OFPERR_OFPBRC_BAD_LEN
;
7523 error
= ofpacts_decode(actions
, actions_len
, version
, vl_mff_map
,
7524 ofpacts_tlv_bitmap
, ofpacts
);
7526 error
= ofpacts_verify(ofpacts
->data
, ofpacts
->size
, allowed_ovsinsts
,
7530 ofpbuf_clear(ofpacts
);
7535 /* Attempts to convert 'actions_len' bytes of OpenFlow actions from the front
7536 * of 'openflow' into ofpacts. On success, appends the converted actions to
7537 * 'ofpacts'; on failure, clears 'ofpacts'. Returns 0 if successful, otherwise
7538 * an OpenFlow error.
7540 * Actions are processed according to their OpenFlow version which
7541 * is provided in the 'version' parameter.
7543 * In most places in OpenFlow, actions appear encapsulated in instructions, so
7544 * you should call ofpacts_pull_openflow_instructions() instead of this
7547 * 'vl_mff_map' and 'ofpacts_tlv_bitmap' are optional. If 'vl_mff_map' is
7548 * provided, it is used to get variable length mf_fields with configured
7549 * length in the actions. If an action uses a variable length mf_field,
7550 * 'ofpacts_tlv_bitmap' is updated accordingly for ref counting. If
7551 * 'vl_mff_map' is not provided, the default mf_fields with maximum length
7554 * The parsed actions are valid generically, but they may not be valid in a
7555 * specific context. For example, port numbers up to OFPP_MAX are valid
7556 * generically, but specific datapaths may only support port numbers in a
7557 * smaller range. Use ofpacts_check() to additional check whether actions are
7558 * valid in a specific context. */
7560 ofpacts_pull_openflow_actions(struct ofpbuf
*openflow
,
7561 unsigned int actions_len
,
7562 enum ofp_version version
,
7563 const struct vl_mff_map
*vl_mff_map
,
7564 uint64_t *ofpacts_tlv_bitmap
,
7565 struct ofpbuf
*ofpacts
)
7567 return ofpacts_pull_openflow_actions__(openflow
, actions_len
, version
,
7568 1u << OVSINST_OFPIT11_APPLY_ACTIONS
,
7569 ofpacts
, 0, vl_mff_map
,
7570 ofpacts_tlv_bitmap
);
7573 /* OpenFlow 1.1 action sets. */
7575 /* Append ofpact 'a' onto the tail of 'out' */
7577 ofpact_copy(struct ofpbuf
*out
, const struct ofpact
*a
)
7579 ofpbuf_put(out
, a
, OFPACT_ALIGN(a
->len
));
7582 /* The order in which actions in an action set get executed. This is only for
7583 * the actions where only the last instance added is used. */
7584 #define ACTION_SET_ORDER \
7585 SLOT(OFPACT_STRIP_VLAN) \
7586 SLOT(OFPACT_POP_MPLS) \
7587 SLOT(OFPACT_DECAP) \
7588 SLOT(OFPACT_ENCAP) \
7589 SLOT(OFPACT_PUSH_MPLS) \
7590 SLOT(OFPACT_PUSH_VLAN) \
7591 SLOT(OFPACT_DEC_TTL) \
7592 SLOT(OFPACT_DEC_MPLS_TTL) \
7593 SLOT(OFPACT_DEC_NSH_TTL)
7595 /* Priority for "final actions" in an action set. An action set only gets
7596 * executed at all if at least one of these actions is present. If more than
7597 * one is present, then only the one later in this list is executed (and if
7598 * more than one of a given type, the one later in the action set). */
7599 #define ACTION_SET_FINAL_PRIORITY \
7601 FINAL(OFPACT_CT_CLEAR) \
7602 FINAL(OFPACT_RESUBMIT) \
7603 FINAL(OFPACT_OUTPUT) \
7606 enum action_set_class
{
7607 /* Actions that individually can usefully appear only once in an action
7608 * set. If they do appear more than once, then only the last instance is
7610 #define SLOT(OFPACT) ACTION_SLOT_##OFPACT,
7614 /* Final actions. */
7615 #define FINAL(OFPACT) ACTION_SLOT_##OFPACT,
7616 ACTION_SET_FINAL_PRIORITY
7619 /* Actions that can appear in an action set more than once and are executed
7621 ACTION_SLOT_SET_OR_MOVE
,
7623 /* Actions that shouldn't appear in the action set at all. */
7627 /* Count the action set slots. */
7628 #define SLOT(OFPACT) +1
7629 enum { N_ACTION_SLOTS
= ACTION_SET_ORDER
};
7632 static enum action_set_class
7633 action_set_classify(const struct ofpact
*a
)
7636 #define SLOT(OFPACT) case OFPACT: return ACTION_SLOT_##OFPACT;
7640 #define FINAL(OFPACT) case OFPACT: return ACTION_SLOT_##OFPACT;
7641 ACTION_SET_FINAL_PRIORITY
7644 case OFPACT_SET_FIELD
:
7645 case OFPACT_REG_MOVE
:
7646 case OFPACT_SET_ETH_DST
:
7647 case OFPACT_SET_ETH_SRC
:
7648 case OFPACT_SET_IP_DSCP
:
7649 case OFPACT_SET_IP_ECN
:
7650 case OFPACT_SET_IP_TTL
:
7651 case OFPACT_SET_IPV4_DST
:
7652 case OFPACT_SET_IPV4_SRC
:
7653 case OFPACT_SET_L4_DST_PORT
:
7654 case OFPACT_SET_L4_SRC_PORT
:
7655 case OFPACT_SET_MPLS_LABEL
:
7656 case OFPACT_SET_MPLS_TC
:
7657 case OFPACT_SET_MPLS_TTL
:
7658 case OFPACT_SET_QUEUE
:
7659 case OFPACT_SET_TUNNEL
:
7660 case OFPACT_SET_VLAN_PCP
:
7661 case OFPACT_SET_VLAN_VID
:
7662 return ACTION_SLOT_SET_OR_MOVE
;
7665 case OFPACT_CLEAR_ACTIONS
:
7668 case OFPACT_CONTROLLER
:
7669 case OFPACT_ENQUEUE
:
7671 case OFPACT_UNROLL_XLATE
:
7672 case OFPACT_FIN_TIMEOUT
:
7673 case OFPACT_GOTO_TABLE
:
7675 case OFPACT_CONJUNCTION
:
7677 case OFPACT_MULTIPATH
:
7679 case OFPACT_OUTPUT_REG
:
7680 case OFPACT_OUTPUT_TRUNC
:
7681 case OFPACT_POP_QUEUE
:
7683 case OFPACT_STACK_POP
:
7684 case OFPACT_STACK_PUSH
:
7685 case OFPACT_WRITE_ACTIONS
:
7686 case OFPACT_WRITE_METADATA
:
7687 case OFPACT_DEBUG_RECIRC
:
7688 case OFPACT_DEBUG_SLOW
:
7689 return ACTION_SLOT_INVALID
;
7696 /* True if an action is allowed in the action set.
7697 * False otherwise. */
7699 ofpact_is_allowed_in_actions_set(const struct ofpact
*a
)
7701 return action_set_classify(a
) != ACTION_SLOT_INVALID
;
7704 /* Reads 'action_set', which contains ofpacts accumulated by
7705 * OFPACT_WRITE_ACTIONS instructions, and writes equivalent actions to be
7706 * executed directly into 'action_list'. (These names correspond to the
7707 * "Action Set" and "Action List" terms used in OpenFlow 1.1+.)
7709 * In general this involves appending the last instance of each action that is
7710 * admissible in the action set in the order described in the OpenFlow
7714 * + output action is only appended if no group action was present in 'in'.
7715 * + As a simplification all set actions are copied in the order the are
7716 * provided in 'in' as many set actions applied to a field has the same
7717 * affect as only applying the last action that sets a field and
7718 * duplicates are removed by do_xlate_actions().
7719 * This has an unwanted side-effect of compsoting multiple
7720 * LOAD_REG actions that touch different regions of the same field. */
7722 ofpacts_execute_action_set(struct ofpbuf
*action_list
,
7723 const struct ofpbuf
*action_set
)
7725 const struct ofpact
*slots
[N_ACTION_SLOTS
] = {NULL
, };
7727 struct ofpbuf set_or_move
;
7728 ofpbuf_init(&set_or_move
, 0);
7730 const struct ofpact
*final_action
= NULL
;
7731 enum action_set_class final_class
= 0;
7733 const struct ofpact
*cursor
;
7734 OFPACT_FOR_EACH (cursor
, action_set
->data
, action_set
->size
) {
7735 int class = action_set_classify(cursor
);
7736 if (class < N_ACTION_SLOTS
) {
7737 slots
[class] = cursor
;
7738 } else if (class < ACTION_SLOT_SET_OR_MOVE
) {
7739 if (class >= final_class
) {
7740 final_action
= cursor
;
7741 final_class
= class;
7743 } else if (class == ACTION_SLOT_SET_OR_MOVE
) {
7744 ofpact_copy(&set_or_move
, cursor
);
7746 ovs_assert(class == ACTION_SLOT_INVALID
);
7751 for (int i
= 0; i
< N_ACTION_SLOTS
; i
++) {
7753 ofpact_copy(action_list
, slots
[i
]);
7756 ofpbuf_put(action_list
, set_or_move
.data
, set_or_move
.size
);
7757 ofpact_copy(action_list
, final_action
);
7759 ofpbuf_uninit(&set_or_move
);
7764 ofpacts_decode_for_action_set(const struct ofp_action_header
*in
,
7765 size_t n_in
, enum ofp_version version
,
7766 const struct vl_mff_map
*vl_mff_map
,
7767 uint64_t *ofpacts_tlv_bitmap
,
7772 size_t start
= out
->size
;
7774 error
= ofpacts_decode(in
, n_in
, version
, vl_mff_map
, ofpacts_tlv_bitmap
,
7781 OFPACT_FOR_EACH (a
, ofpact_end(out
->data
, start
), out
->size
- start
) {
7782 if (!ofpact_is_allowed_in_actions_set(a
)) {
7783 VLOG_WARN_RL(&rl
, "disallowed action in action set");
7784 return OFPERR_OFPBAC_BAD_TYPE
;
7791 /* OpenFlow 1.1 instructions. */
7793 struct instruction_type_info
{
7794 enum ovs_instruction_type type
;
7798 static const struct instruction_type_info inst_info
[] = {
7799 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) {OVSINST_##ENUM, NAME},
7805 ovs_instruction_name_from_type(enum ovs_instruction_type type
)
7807 return type
< ARRAY_SIZE(inst_info
) ? inst_info
[type
].name
: NULL
;
7811 ovs_instruction_type_from_name(const char *name
)
7813 const struct instruction_type_info
*p
;
7814 for (p
= inst_info
; p
< &inst_info
[ARRAY_SIZE(inst_info
)]; p
++) {
7815 if (!strcasecmp(name
, p
->name
)) {
7822 enum ovs_instruction_type
7823 ovs_instruction_type_from_ofpact_type(enum ofpact_type type
)
7827 return OVSINST_OFPIT13_METER
;
7828 case OFPACT_CLEAR_ACTIONS
:
7829 return OVSINST_OFPIT11_CLEAR_ACTIONS
;
7830 case OFPACT_WRITE_ACTIONS
:
7831 return OVSINST_OFPIT11_WRITE_ACTIONS
;
7832 case OFPACT_WRITE_METADATA
:
7833 return OVSINST_OFPIT11_WRITE_METADATA
;
7834 case OFPACT_GOTO_TABLE
:
7835 return OVSINST_OFPIT11_GOTO_TABLE
;
7839 case OFPACT_CONTROLLER
:
7840 case OFPACT_ENQUEUE
:
7841 case OFPACT_OUTPUT_REG
:
7842 case OFPACT_OUTPUT_TRUNC
:
7844 case OFPACT_SET_VLAN_VID
:
7845 case OFPACT_SET_VLAN_PCP
:
7846 case OFPACT_STRIP_VLAN
:
7847 case OFPACT_PUSH_VLAN
:
7848 case OFPACT_SET_ETH_SRC
:
7849 case OFPACT_SET_ETH_DST
:
7850 case OFPACT_SET_IPV4_SRC
:
7851 case OFPACT_SET_IPV4_DST
:
7852 case OFPACT_SET_IP_DSCP
:
7853 case OFPACT_SET_IP_ECN
:
7854 case OFPACT_SET_IP_TTL
:
7855 case OFPACT_SET_L4_SRC_PORT
:
7856 case OFPACT_SET_L4_DST_PORT
:
7857 case OFPACT_REG_MOVE
:
7858 case OFPACT_SET_FIELD
:
7859 case OFPACT_STACK_PUSH
:
7860 case OFPACT_STACK_POP
:
7861 case OFPACT_DEC_TTL
:
7862 case OFPACT_SET_MPLS_LABEL
:
7863 case OFPACT_SET_MPLS_TC
:
7864 case OFPACT_SET_MPLS_TTL
:
7865 case OFPACT_DEC_MPLS_TTL
:
7866 case OFPACT_PUSH_MPLS
:
7867 case OFPACT_POP_MPLS
:
7868 case OFPACT_SET_TUNNEL
:
7869 case OFPACT_SET_QUEUE
:
7870 case OFPACT_POP_QUEUE
:
7871 case OFPACT_FIN_TIMEOUT
:
7872 case OFPACT_RESUBMIT
:
7874 case OFPACT_CONJUNCTION
:
7875 case OFPACT_MULTIPATH
:
7878 case OFPACT_UNROLL_XLATE
:
7880 case OFPACT_DEBUG_RECIRC
:
7881 case OFPACT_DEBUG_SLOW
:
7883 case OFPACT_CT_CLEAR
:
7887 case OFPACT_DEC_NSH_TTL
:
7889 return OVSINST_OFPIT11_APPLY_ACTIONS
;
7894 ovs_instruction_type_from_inst_type(enum ovs_instruction_type
*instruction_type
,
7895 const uint16_t inst_type
)
7897 switch (inst_type
) {
7899 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
7901 *instruction_type = OVSINST_##ENUM; \
7907 return OFPERR_OFPBIC_UNKNOWN_INST
;
7911 /* Two-way translation between OVS's internal "OVSINST_*" representation of
7912 * instructions and the "OFPIT_*" representation used in OpenFlow. */
7913 struct ovsinst_map
{
7914 enum ovs_instruction_type ovsinst
; /* Internal name for instruction. */
7915 int ofpit
; /* OFPIT_* number from OpenFlow spec. */
7918 static const struct ovsinst_map
*
7919 get_ovsinst_map(enum ofp_version version
)
7921 /* OpenFlow 1.1 and 1.2 instructions. */
7922 static const struct ovsinst_map of11
[] = {
7923 { OVSINST_OFPIT11_GOTO_TABLE
, 1 },
7924 { OVSINST_OFPIT11_WRITE_METADATA
, 2 },
7925 { OVSINST_OFPIT11_WRITE_ACTIONS
, 3 },
7926 { OVSINST_OFPIT11_APPLY_ACTIONS
, 4 },
7927 { OVSINST_OFPIT11_CLEAR_ACTIONS
, 5 },
7931 /* OpenFlow 1.3+ instructions. */
7932 static const struct ovsinst_map of13
[] = {
7933 { OVSINST_OFPIT11_GOTO_TABLE
, 1 },
7934 { OVSINST_OFPIT11_WRITE_METADATA
, 2 },
7935 { OVSINST_OFPIT11_WRITE_ACTIONS
, 3 },
7936 { OVSINST_OFPIT11_APPLY_ACTIONS
, 4 },
7937 { OVSINST_OFPIT11_CLEAR_ACTIONS
, 5 },
7938 { OVSINST_OFPIT13_METER
, 6 },
7942 return version
< OFP13_VERSION
? of11
: of13
;
7945 /* Converts 'ovsinst_bitmap', a bitmap whose bits correspond to OVSINST_*
7946 * values, into a bitmap of instructions suitable for OpenFlow 'version'
7947 * (OFP11_VERSION or later), and returns the result. */
7949 ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap
, enum ofp_version version
)
7951 uint32_t ofpit_bitmap
= 0;
7952 const struct ovsinst_map
*x
;
7954 for (x
= get_ovsinst_map(version
); x
->ofpit
>= 0; x
++) {
7955 if (ovsinst_bitmap
& (1u << x
->ovsinst
)) {
7956 ofpit_bitmap
|= 1u << x
->ofpit
;
7959 return htonl(ofpit_bitmap
);
7962 /* Converts 'ofpit_bitmap', a bitmap of instructions from an OpenFlow message
7963 * with the given 'version' (OFP11_VERSION or later) into a bitmap whose bits
7964 * correspond to OVSINST_* values, and returns the result. */
7966 ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap
, enum ofp_version version
)
7968 uint32_t ovsinst_bitmap
= 0;
7969 const struct ovsinst_map
*x
;
7971 for (x
= get_ovsinst_map(version
); x
->ofpit
>= 0; x
++) {
7972 if (ofpit_bitmap
& htonl(1u << x
->ofpit
)) {
7973 ovsinst_bitmap
|= 1u << x
->ovsinst
;
7976 return ovsinst_bitmap
;
7979 static inline struct ofp11_instruction
*
7980 instruction_next(const struct ofp11_instruction
*inst
)
7982 return ((struct ofp11_instruction
*) (void *)
7983 ((uint8_t *) inst
+ ntohs(inst
->len
)));
7987 instruction_is_valid(const struct ofp11_instruction
*inst
,
7988 size_t n_instructions
)
7990 uint16_t len
= ntohs(inst
->len
);
7991 return (!(len
% OFP11_INSTRUCTION_ALIGN
)
7992 && len
>= sizeof *inst
7993 && len
/ sizeof *inst
<= n_instructions
);
7996 /* This macro is careful to check for instructions with bad lengths. */
7997 #define INSTRUCTION_FOR_EACH(ITER, LEFT, INSTRUCTIONS, N_INSTRUCTIONS) \
7998 for ((ITER) = (INSTRUCTIONS), (LEFT) = (N_INSTRUCTIONS); \
7999 (LEFT) > 0 && instruction_is_valid(ITER, LEFT); \
8000 ((LEFT) -= (ntohs((ITER)->len) \
8001 / sizeof(struct ofp11_instruction)), \
8002 (ITER) = instruction_next(ITER)))
8005 decode_openflow11_instruction(const struct ofp11_instruction
*inst
,
8006 enum ovs_instruction_type
*type
)
8008 uint16_t len
= ntohs(inst
->len
);
8010 switch (inst
->type
) {
8011 case CONSTANT_HTONS(OFPIT11_EXPERIMENTER
):
8012 return OFPERR_OFPBIC_BAD_EXPERIMENTER
;
8014 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
8015 case CONSTANT_HTONS(ENUM): \
8017 ? len >= sizeof(struct STRUCT) \
8018 : len == sizeof(struct STRUCT)) { \
8019 *type = OVSINST_##ENUM; \
8022 return OFPERR_OFPBIC_BAD_LEN; \
8028 return OFPERR_OFPBIC_UNKNOWN_INST
;
8033 decode_openflow11_instructions(const struct ofp11_instruction insts
[],
8035 const struct ofp11_instruction
*out
[])
8037 const struct ofp11_instruction
*inst
;
8040 memset(out
, 0, N_OVS_INSTRUCTIONS
* sizeof *out
);
8041 INSTRUCTION_FOR_EACH (inst
, left
, insts
, n_insts
) {
8042 enum ovs_instruction_type type
;
8045 error
= decode_openflow11_instruction(inst
, &type
);
8051 return OFPERR_OFPBIC_DUP_INST
;
8057 VLOG_WARN_RL(&rl
, "bad instruction format at offset %"PRIuSIZE
,
8058 (n_insts
- left
) * sizeof *inst
);
8059 return OFPERR_OFPBIC_BAD_LEN
;
8065 get_actions_from_instruction(const struct ofp11_instruction
*inst
,
8066 const struct ofp_action_header
**actions
,
8067 size_t *actions_len
)
8069 *actions
= ALIGNED_CAST(const struct ofp_action_header
*, inst
+ 1);
8070 *actions_len
= ntohs(inst
->len
) - sizeof *inst
;
8074 ofpacts_pull_openflow_instructions(struct ofpbuf
*openflow
,
8075 unsigned int instructions_len
,
8076 enum ofp_version version
,
8077 const struct vl_mff_map
*vl_mff_map
,
8078 uint64_t *ofpacts_tlv_bitmap
,
8079 struct ofpbuf
*ofpacts
)
8081 const struct ofp11_instruction
*instructions
;
8082 const struct ofp11_instruction
*insts
[N_OVS_INSTRUCTIONS
];
8085 ofpbuf_clear(ofpacts
);
8086 if (version
== OFP10_VERSION
) {
8087 return ofpacts_pull_openflow_actions__(openflow
, instructions_len
,
8089 (1u << N_OVS_INSTRUCTIONS
) - 1,
8090 ofpacts
, 0, vl_mff_map
,
8091 ofpacts_tlv_bitmap
);
8094 if (instructions_len
% OFP11_INSTRUCTION_ALIGN
!= 0) {
8095 VLOG_WARN_RL(&rl
, "OpenFlow message instructions length %u is not a "
8097 instructions_len
, OFP11_INSTRUCTION_ALIGN
);
8098 error
= OFPERR_OFPBIC_BAD_LEN
;
8102 instructions
= ofpbuf_try_pull(openflow
, instructions_len
);
8103 if (instructions
== NULL
) {
8104 VLOG_WARN_RL(&rl
, "OpenFlow message instructions length %u exceeds "
8105 "remaining message length (%"PRIu32
")",
8106 instructions_len
, openflow
->size
);
8107 error
= OFPERR_OFPBIC_BAD_LEN
;
8111 error
= decode_openflow11_instructions(
8112 instructions
, instructions_len
/ OFP11_INSTRUCTION_ALIGN
,
8118 if (insts
[OVSINST_OFPIT13_METER
]) {
8119 const struct ofp13_instruction_meter
*oim
;
8120 struct ofpact_meter
*om
;
8122 oim
= ALIGNED_CAST(const struct ofp13_instruction_meter
*,
8123 insts
[OVSINST_OFPIT13_METER
]);
8125 om
= ofpact_put_METER(ofpacts
);
8126 om
->meter_id
= ntohl(oim
->meter_id
);
8127 om
->provider_meter_id
= UINT32_MAX
; /* No provider meter ID. */
8129 if (insts
[OVSINST_OFPIT11_APPLY_ACTIONS
]) {
8130 const struct ofp_action_header
*actions
;
8133 get_actions_from_instruction(insts
[OVSINST_OFPIT11_APPLY_ACTIONS
],
8134 &actions
, &actions_len
);
8135 error
= ofpacts_decode(actions
, actions_len
, version
, vl_mff_map
,
8136 ofpacts_tlv_bitmap
, ofpacts
);
8141 if (insts
[OVSINST_OFPIT11_CLEAR_ACTIONS
]) {
8142 instruction_get_OFPIT11_CLEAR_ACTIONS(
8143 insts
[OVSINST_OFPIT11_CLEAR_ACTIONS
]);
8144 ofpact_put_CLEAR_ACTIONS(ofpacts
);
8146 if (insts
[OVSINST_OFPIT11_WRITE_ACTIONS
]) {
8147 struct ofpact_nest
*on
;
8148 const struct ofp_action_header
*actions
;
8150 size_t start
= ofpacts
->size
;
8151 ofpact_put(ofpacts
, OFPACT_WRITE_ACTIONS
,
8152 offsetof(struct ofpact_nest
, actions
));
8153 get_actions_from_instruction(insts
[OVSINST_OFPIT11_WRITE_ACTIONS
],
8154 &actions
, &actions_len
);
8155 error
= ofpacts_decode_for_action_set(actions
, actions_len
,
8156 version
, vl_mff_map
,
8157 ofpacts_tlv_bitmap
, ofpacts
);
8161 on
= ofpbuf_at_assert(ofpacts
, start
, sizeof *on
);
8162 on
->ofpact
.len
= ofpacts
->size
- start
;
8164 if (insts
[OVSINST_OFPIT11_WRITE_METADATA
]) {
8165 const struct ofp11_instruction_write_metadata
*oiwm
;
8166 struct ofpact_metadata
*om
;
8168 oiwm
= ALIGNED_CAST(const struct ofp11_instruction_write_metadata
*,
8169 insts
[OVSINST_OFPIT11_WRITE_METADATA
]);
8171 om
= ofpact_put_WRITE_METADATA(ofpacts
);
8172 om
->metadata
= oiwm
->metadata
;
8173 om
->mask
= oiwm
->metadata_mask
;
8175 if (insts
[OVSINST_OFPIT11_GOTO_TABLE
]) {
8176 const struct ofp11_instruction_goto_table
*oigt
;
8177 struct ofpact_goto_table
*ogt
;
8179 oigt
= instruction_get_OFPIT11_GOTO_TABLE(
8180 insts
[OVSINST_OFPIT11_GOTO_TABLE
]);
8181 ogt
= ofpact_put_GOTO_TABLE(ofpacts
);
8182 ogt
->table_id
= oigt
->table_id
;
8185 error
= ofpacts_verify(ofpacts
->data
, ofpacts
->size
,
8186 (1u << N_OVS_INSTRUCTIONS
) - 1, 0);
8189 ofpbuf_clear(ofpacts
);
8194 /* Update the length of the instruction that begins at offset 'ofs' within
8195 * 'openflow' and contains nested actions that extend to the end of 'openflow'.
8196 * If the instruction contains no nested actions, deletes it entirely. */
8198 ofpacts_update_instruction_actions(struct ofpbuf
*openflow
, size_t ofs
)
8200 struct ofp11_instruction_actions
*oia
;
8202 oia
= ofpbuf_at_assert(openflow
, ofs
, sizeof *oia
);
8203 if (openflow
->size
> ofs
+ sizeof *oia
) {
8204 oia
->len
= htons(openflow
->size
- ofs
);
8206 openflow
->size
= ofs
;
8210 /* Checks that 'port' is a valid output port for OFPACT_OUTPUT, given that the
8211 * switch will never have more than 'max_ports' ports. Returns 0 if 'port' is
8212 * valid, otherwise an OpenFlow error code. */
8214 ofpact_check_output_port(ofp_port_t port
, ofp_port_t max_ports
)
8222 case OFPP_CONTROLLER
:
8227 return OFPERR_OFPBAC_BAD_OUT_PORT
;
8230 if (ofp_to_u16(port
) < ofp_to_u16(max_ports
)) {
8233 return OFPERR_OFPBAC_BAD_OUT_PORT
;
8237 /* Removes the protocols that require consistency between match and actions
8238 * (that's everything but OpenFlow 1.0) from '*usable_protocols'.
8240 * (An example of an inconsistency between match and actions is a flow that
8241 * does not match on an MPLS Ethertype but has an action that pops an MPLS
8244 inconsistent_match(enum ofputil_protocol
*usable_protocols
)
8246 *usable_protocols
&= OFPUTIL_P_OF10_ANY
;
8249 /* May modify flow->packet_type, flow->dl_type, flow->nw_proto and
8250 * flow->vlan_tci, caller must restore them.
8252 * Modifies some actions, filling in fields that could not be properly set
8253 * without context. */
8255 ofpact_check__(struct ofpact
*a
, struct ofpact_check_params
*cp
)
8258 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8259 case OFPACT_##ENUM: \
8260 return check_##ENUM(ofpact_get_##ENUM(a), cp);
8268 /* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are
8269 * appropriate for a packet with the prerequisites satisfied by 'flow' in a
8270 * switch with no more than 'max_ports' ports.
8272 * If 'ofpacts' and 'flow' are inconsistent with one another, un-sets in
8273 * '*usable_protocols' the protocols that forbid the inconsistency. (An
8274 * example of an inconsistency between match and actions is a flow that does
8275 * not match on an MPLS Ethertype but has an action that pops an MPLS label.)
8277 * May annotate ofpacts with information gathered from the 'match'.
8279 * May temporarily modify 'match', but restores the changes before
8282 ofpacts_check(struct ofpact ofpacts
[], size_t ofpacts_len
,
8283 struct ofpact_check_params
*cp
)
8285 /* Save fields that might temporarily be modified. */
8286 struct flow
*flow
= &cp
->match
->flow
;
8287 ovs_be32 packet_type
= flow
->packet_type
;
8288 ovs_be16 dl_type
= flow
->dl_type
;
8289 uint8_t nw_proto
= flow
->nw_proto
;
8290 union flow_vlan_hdr vlans
[FLOW_MAX_VLAN_HEADERS
];
8291 memcpy(vlans
, flow
->vlans
, sizeof vlans
);
8293 /* Check all the actions. */
8294 cp
->usable_protocols
= OFPUTIL_P_ANY
;
8295 enum ofperr error
= 0;
8297 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8298 error
= ofpact_check__(a
, cp
);
8304 /* Restore fields that may have been modified. */
8305 flow
->packet_type
= packet_type
;
8306 flow
->dl_type
= dl_type
;
8307 memcpy(flow
->vlans
, vlans
, sizeof vlans
);
8308 flow
->nw_proto
= nw_proto
;
8313 /* Like ofpacts_check(), but reports inconsistencies as
8314 * OFPERR_OFPBAC_MATCH_INCONSISTENT rather than clearing bits. */
8316 ofpacts_check_consistency(struct ofpact ofpacts
[], size_t ofpacts_len
,
8317 enum ofputil_protocol needed_protocols
,
8318 struct ofpact_check_params
*cp
)
8320 enum ofperr error
= ofpacts_check(ofpacts
, ofpacts_len
, cp
);
8321 if (!error
&& needed_protocols
& ~cp
->usable_protocols
) {
8322 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
8327 /* Returns the destination field that 'ofpact' would write to, or NULL
8328 * if the action would not write to an mf_field. */
8329 const struct mf_field
*
8330 ofpact_get_mf_dst(const struct ofpact
*ofpact
)
8332 if (ofpact
->type
== OFPACT_SET_FIELD
) {
8333 const struct ofpact_set_field
*orl
;
8335 orl
= CONTAINER_OF(ofpact
, struct ofpact_set_field
, ofpact
);
8337 } else if (ofpact
->type
== OFPACT_REG_MOVE
) {
8338 const struct ofpact_reg_move
*orm
;
8340 orm
= CONTAINER_OF(ofpact
, struct ofpact_reg_move
, ofpact
);
8341 return orm
->dst
.field
;
8348 unsupported_nesting(enum ofpact_type action
, enum ofpact_type outer_action
)
8350 VLOG_WARN("%s action doesn't support nested action %s",
8351 ofpact_name(outer_action
), ofpact_name(action
));
8352 return OFPERR_OFPBAC_BAD_ARGUMENT
;
8356 field_requires_ct(enum mf_field_id field
)
8358 return field
== MFF_CT_MARK
|| field
== MFF_CT_LABEL
;
8361 /* Apply nesting constraints for actions */
8363 ofpacts_verify_nested(const struct ofpact
*a
, enum ofpact_type outer_action
)
8365 const struct mf_field
*field
= ofpact_get_mf_dst(a
);
8367 if (field
&& field_requires_ct(field
->id
) && outer_action
!= OFPACT_CT
) {
8368 VLOG_WARN("cannot set CT fields outside of ct action");
8369 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
8371 if (a
->type
== OFPACT_NAT
) {
8372 if (outer_action
!= OFPACT_CT
) {
8373 VLOG_WARN("Cannot have NAT action outside of \"ct\" action");
8374 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
8380 ovs_assert(outer_action
== OFPACT_WRITE_ACTIONS
8381 || outer_action
== OFPACT_CT
);
8383 if (outer_action
== OFPACT_CT
) {
8385 return unsupported_nesting(a
->type
, outer_action
);
8386 } else if (!field_requires_ct(field
->id
)) {
8387 VLOG_WARN("%s action doesn't support nested modification "
8388 "of %s", ofpact_name(outer_action
), field
->name
);
8389 return OFPERR_OFPBAC_BAD_ARGUMENT
;
8397 /* Verifies that the 'ofpacts_len' bytes of actions in 'ofpacts' are in the
8398 * appropriate order as defined by the OpenFlow spec and as required by Open
8401 * 'allowed_ovsinsts' is a bitmap of OVSINST_* values, in which 1-bits indicate
8402 * instructions that are allowed within 'ofpacts[]'.
8404 * If 'outer_action' is not zero, it specifies that the actions are nested
8405 * within another action of type 'outer_action'. */
8407 ofpacts_verify(const struct ofpact ofpacts
[], size_t ofpacts_len
,
8408 uint32_t allowed_ovsinsts
, enum ofpact_type outer_action
)
8410 const struct ofpact
*a
;
8411 enum ovs_instruction_type inst
;
8413 inst
= OVSINST_OFPIT13_METER
;
8414 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8415 enum ovs_instruction_type next
;
8418 if (a
->type
== OFPACT_CONJUNCTION
) {
8419 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8420 if (a
->type
!= OFPACT_CONJUNCTION
&& a
->type
!= OFPACT_NOTE
) {
8421 VLOG_WARN("\"conjunction\" actions may be used along with "
8422 "\"note\" but not any other kind of action "
8423 "(such as the \"%s\" action used here)",
8424 ofpact_name(a
->type
));
8425 return OFPERR_NXBAC_BAD_CONJUNCTION
;
8431 error
= ofpacts_verify_nested(a
, outer_action
);
8436 next
= ovs_instruction_type_from_ofpact_type(a
->type
);
8438 && (inst
== OVSINST_OFPIT11_APPLY_ACTIONS
8441 const char *name
= ovs_instruction_name_from_type(inst
);
8442 const char *next_name
= ovs_instruction_name_from_type(next
);
8445 VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
8446 "1.1+ compatibility", name
);
8448 VLOG_WARN("invalid instruction ordering: %s must appear "
8449 "before %s, for OpenFlow 1.1+ compatibility",
8452 return OFPERR_OFPBAC_UNSUPPORTED_ORDER
;
8454 if (!((1u << next
) & allowed_ovsinsts
)) {
8455 const char *name
= ovs_instruction_name_from_type(next
);
8457 VLOG_WARN("%s instruction not allowed here", name
);
8458 return OFPERR_OFPBIC_UNSUP_INST
;
8467 /* Converting ofpacts to OpenFlow. */
8470 encode_ofpact(const struct ofpact
*a
, enum ofp_version ofp_version
,
8474 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8475 case OFPACT_##ENUM: \
8476 encode_##ENUM(ofpact_get_##ENUM(a), ofp_version, out); \
8485 /* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow
8486 * actions in 'openflow', appending the actions to any existing data in
8489 ofpacts_put_openflow_actions(const struct ofpact ofpacts
[], size_t ofpacts_len
,
8490 struct ofpbuf
*openflow
,
8491 enum ofp_version ofp_version
)
8493 const struct ofpact
*a
;
8494 size_t start_size
= openflow
->size
;
8496 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8497 encode_ofpact(a
, ofp_version
, openflow
);
8499 return openflow
->size
- start_size
;
8502 static enum ovs_instruction_type
8503 ofpact_is_apply_actions(const struct ofpact
*a
)
8505 return (ovs_instruction_type_from_ofpact_type(a
->type
)
8506 == OVSINST_OFPIT11_APPLY_ACTIONS
);
8510 ofpacts_put_openflow_instructions(const struct ofpact ofpacts
[],
8512 struct ofpbuf
*openflow
,
8513 enum ofp_version ofp_version
)
8515 const struct ofpact
*end
= ofpact_end(ofpacts
, ofpacts_len
);
8516 const struct ofpact
*a
;
8518 if (ofp_version
== OFP10_VERSION
) {
8519 ofpacts_put_openflow_actions(ofpacts
, ofpacts_len
, openflow
,
8526 if (ofpact_is_apply_actions(a
)) {
8527 size_t ofs
= openflow
->size
;
8529 instruction_put_OFPIT11_APPLY_ACTIONS(openflow
);
8531 encode_ofpact(a
, ofp_version
, openflow
);
8533 } while (a
< end
&& ofpact_is_apply_actions(a
));
8534 ofpacts_update_instruction_actions(openflow
, ofs
);
8536 encode_ofpact(a
, ofp_version
, openflow
);
8542 /* Sets of supported actions. */
8544 /* Two-way translation between OVS's internal "OFPACT_*" representation of
8545 * actions and the "OFPAT_*" representation used in some OpenFlow version.
8546 * (OFPAT_* numbering varies from one OpenFlow version to another, so a given
8547 * instance is specific to one OpenFlow version.) */
8549 enum ofpact_type ofpact
; /* Internal name for action type. */
8550 int ofpat
; /* OFPAT_* number from OpenFlow spec. */
8553 static const struct ofpact_map
*
8554 get_ofpact_map(enum ofp_version version
)
8556 /* OpenFlow 1.0 actions. */
8557 static const struct ofpact_map of10
[] = {
8558 { OFPACT_OUTPUT
, 0 },
8559 { OFPACT_SET_VLAN_VID
, 1 },
8560 { OFPACT_SET_VLAN_PCP
, 2 },
8561 { OFPACT_STRIP_VLAN
, 3 },
8562 { OFPACT_SET_ETH_SRC
, 4 },
8563 { OFPACT_SET_ETH_DST
, 5 },
8564 { OFPACT_SET_IPV4_SRC
, 6 },
8565 { OFPACT_SET_IPV4_DST
, 7 },
8566 { OFPACT_SET_IP_DSCP
, 8 },
8567 { OFPACT_SET_L4_SRC_PORT
, 9 },
8568 { OFPACT_SET_L4_DST_PORT
, 10 },
8569 { OFPACT_ENQUEUE
, 11 },
8573 /* OpenFlow 1.1 actions. */
8574 static const struct ofpact_map of11
[] = {
8575 { OFPACT_OUTPUT
, 0 },
8576 { OFPACT_SET_VLAN_VID
, 1 },
8577 { OFPACT_SET_VLAN_PCP
, 2 },
8578 { OFPACT_SET_ETH_SRC
, 3 },
8579 { OFPACT_SET_ETH_DST
, 4 },
8580 { OFPACT_SET_IPV4_SRC
, 5 },
8581 { OFPACT_SET_IPV4_DST
, 6 },
8582 { OFPACT_SET_IP_DSCP
, 7 },
8583 { OFPACT_SET_IP_ECN
, 8 },
8584 { OFPACT_SET_L4_SRC_PORT
, 9 },
8585 { OFPACT_SET_L4_DST_PORT
, 10 },
8586 /* OFPAT_COPY_TTL_OUT (11) not supported. */
8587 /* OFPAT_COPY_TTL_IN (12) not supported. */
8588 { OFPACT_SET_MPLS_LABEL
, 13 },
8589 { OFPACT_SET_MPLS_TC
, 14 },
8590 { OFPACT_SET_MPLS_TTL
, 15 },
8591 { OFPACT_DEC_MPLS_TTL
, 16 },
8592 { OFPACT_PUSH_VLAN
, 17 },
8593 { OFPACT_STRIP_VLAN
, 18 },
8594 { OFPACT_PUSH_MPLS
, 19 },
8595 { OFPACT_POP_MPLS
, 20 },
8596 { OFPACT_SET_QUEUE
, 21 },
8597 { OFPACT_GROUP
, 22 },
8598 { OFPACT_SET_IP_TTL
, 23 },
8599 { OFPACT_DEC_TTL
, 24 },
8603 /* OpenFlow 1.2, 1.3, and 1.4 actions. */
8604 static const struct ofpact_map of12
[] = {
8605 { OFPACT_OUTPUT
, 0 },
8606 /* OFPAT_COPY_TTL_OUT (11) not supported. */
8607 /* OFPAT_COPY_TTL_IN (12) not supported. */
8608 { OFPACT_SET_MPLS_TTL
, 15 },
8609 { OFPACT_DEC_MPLS_TTL
, 16 },
8610 { OFPACT_PUSH_VLAN
, 17 },
8611 { OFPACT_STRIP_VLAN
, 18 },
8612 { OFPACT_PUSH_MPLS
, 19 },
8613 { OFPACT_POP_MPLS
, 20 },
8614 { OFPACT_SET_QUEUE
, 21 },
8615 { OFPACT_GROUP
, 22 },
8616 { OFPACT_SET_IP_TTL
, 23 },
8617 { OFPACT_DEC_TTL
, 24 },
8618 { OFPACT_SET_FIELD
, 25 },
8619 /* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
8620 /* OF1.3+ OFPAT_POP_PBB (27) not supported. */
8641 /* Converts 'ofpacts_bitmap', a bitmap whose bits correspond to OFPACT_*
8642 * values, into a bitmap of actions suitable for OpenFlow 'version', and
8643 * returns the result. */
8645 ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap
, enum ofp_version version
)
8647 uint32_t openflow_bitmap
= 0;
8648 const struct ofpact_map
*x
;
8650 for (x
= get_ofpact_map(version
); x
->ofpat
>= 0; x
++) {
8651 if (ofpacts_bitmap
& (UINT64_C(1) << x
->ofpact
)) {
8652 openflow_bitmap
|= 1u << x
->ofpat
;
8655 return htonl(openflow_bitmap
);
8658 /* Converts 'ofpat_bitmap', a bitmap of actions from an OpenFlow message with
8659 * the given 'version' into a bitmap whose bits correspond to OFPACT_* values,
8660 * and returns the result. */
8662 ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap
, enum ofp_version version
)
8664 uint64_t ofpact_bitmap
= 0;
8665 const struct ofpact_map
*x
;
8667 for (x
= get_ofpact_map(version
); x
->ofpat
>= 0; x
++) {
8668 if (ofpat_bitmap
& htonl(1u << x
->ofpat
)) {
8669 ofpact_bitmap
|= UINT64_C(1) << x
->ofpact
;
8672 return ofpact_bitmap
;
8675 /* Appends to 's' a string representation of the set of OFPACT_* represented
8676 * by 'ofpacts_bitmap'. */
8678 ofpact_bitmap_format(uint64_t ofpacts_bitmap
, struct ds
*s
)
8680 if (!ofpacts_bitmap
) {
8681 ds_put_cstr(s
, "<none>");
8683 while (ofpacts_bitmap
) {
8684 ds_put_format(s
, "%s ",
8685 ofpact_name(rightmost_1bit_idx(ofpacts_bitmap
)));
8686 ofpacts_bitmap
= zero_rightmost_1bit(ofpacts_bitmap
);
8692 /* Returns true if 'action' outputs to 'port', false otherwise. */
8694 ofpact_outputs_to_port(const struct ofpact
*ofpact
, ofp_port_t port
)
8696 switch (ofpact
->type
) {
8698 return ofpact_get_OUTPUT(ofpact
)->port
== port
;
8699 case OFPACT_ENQUEUE
:
8700 return ofpact_get_ENQUEUE(ofpact
)->port
== port
;
8701 case OFPACT_CONTROLLER
:
8702 return port
== OFPP_CONTROLLER
;
8704 case OFPACT_OUTPUT_REG
:
8705 case OFPACT_OUTPUT_TRUNC
:
8707 case OFPACT_SET_VLAN_VID
:
8708 case OFPACT_SET_VLAN_PCP
:
8709 case OFPACT_STRIP_VLAN
:
8710 case OFPACT_PUSH_VLAN
:
8711 case OFPACT_SET_ETH_SRC
:
8712 case OFPACT_SET_ETH_DST
:
8713 case OFPACT_SET_IPV4_SRC
:
8714 case OFPACT_SET_IPV4_DST
:
8715 case OFPACT_SET_IP_DSCP
:
8716 case OFPACT_SET_IP_ECN
:
8717 case OFPACT_SET_IP_TTL
:
8718 case OFPACT_SET_L4_SRC_PORT
:
8719 case OFPACT_SET_L4_DST_PORT
:
8720 case OFPACT_REG_MOVE
:
8721 case OFPACT_SET_FIELD
:
8722 case OFPACT_STACK_PUSH
:
8723 case OFPACT_STACK_POP
:
8724 case OFPACT_DEC_TTL
:
8725 case OFPACT_SET_MPLS_LABEL
:
8726 case OFPACT_SET_MPLS_TC
:
8727 case OFPACT_SET_MPLS_TTL
:
8728 case OFPACT_DEC_MPLS_TTL
:
8729 case OFPACT_SET_TUNNEL
:
8730 case OFPACT_WRITE_METADATA
:
8731 case OFPACT_SET_QUEUE
:
8732 case OFPACT_POP_QUEUE
:
8733 case OFPACT_FIN_TIMEOUT
:
8734 case OFPACT_RESUBMIT
:
8736 case OFPACT_CONJUNCTION
:
8737 case OFPACT_MULTIPATH
:
8740 case OFPACT_UNROLL_XLATE
:
8741 case OFPACT_PUSH_MPLS
:
8742 case OFPACT_POP_MPLS
:
8744 case OFPACT_CLEAR_ACTIONS
:
8746 case OFPACT_WRITE_ACTIONS
:
8747 case OFPACT_GOTO_TABLE
:
8750 case OFPACT_DEBUG_RECIRC
:
8751 case OFPACT_DEBUG_SLOW
:
8753 case OFPACT_CT_CLEAR
:
8757 case OFPACT_DEC_NSH_TTL
:
8763 /* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
8764 * to 'port', false otherwise. */
8766 ofpacts_output_to_port(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
8769 const struct ofpact
*a
;
8771 OFPACT_FOR_EACH_FLATTENED (a
, ofpacts
, ofpacts_len
) {
8772 if (ofpact_outputs_to_port(a
, port
)) {
8780 /* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
8781 * to 'group', false otherwise. */
8783 ofpacts_output_to_group(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
8786 const struct ofpact
*a
;
8788 OFPACT_FOR_EACH_FLATTENED (a
, ofpacts
, ofpacts_len
) {
8789 if (a
->type
== OFPACT_GROUP
8790 && ofpact_get_GROUP(a
)->group_id
== group_id
) {
8798 /* Returns true if the 'a_len' bytes of actions in 'a' and the 'b_len' bytes of
8799 * actions in 'b' are bytewise identical. */
8801 ofpacts_equal(const struct ofpact
*a
, size_t a_len
,
8802 const struct ofpact
*b
, size_t b_len
)
8804 return a_len
== b_len
&& !memcmp(a
, b
, a_len
);
8807 /* Returns true if the 'a_len' bytes of actions in 'a' and the 'b_len' bytes of
8808 * actions in 'b' are identical when formatted as strings. (Converting actions
8809 * to string form suppresses some rarely meaningful differences, such as the
8810 * 'compat' member of actions.) */
8812 ofpacts_equal_stringwise(const struct ofpact
*a
, size_t a_len
,
8813 const struct ofpact
*b
, size_t b_len
)
8815 struct ds a_s
= DS_EMPTY_INITIALIZER
;
8816 struct ofpact_format_params a_fp
= { .s
= &a_s
};
8817 ofpacts_format(a
, a_len
, &a_fp
);
8819 struct ds b_s
= DS_EMPTY_INITIALIZER
;
8820 struct ofpact_format_params b_fp
= { .s
= &b_s
};
8821 ofpacts_format(b
, b_len
, &b_fp
);
8823 bool equal
= !strcmp(ds_cstr(&a_s
), ds_cstr(&b_s
));
8831 /* Finds the OFPACT_METER action, if any, in the 'ofpacts_len' bytes of
8832 * 'ofpacts'. If found, returns its meter ID; if not, returns 0.
8834 * This function relies on the order of 'ofpacts' being correct (as checked by
8835 * ofpacts_verify()). */
8837 ofpacts_get_meter(const struct ofpact ofpacts
[], size_t ofpacts_len
)
8839 const struct ofpact
*a
;
8841 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8842 enum ovs_instruction_type inst
;
8844 inst
= ovs_instruction_type_from_ofpact_type(a
->type
);
8845 if (a
->type
== OFPACT_METER
) {
8846 return ofpact_get_METER(a
)->meter_id
;
8847 } else if (inst
> OVSINST_OFPIT13_METER
) {
8855 /* Formatting ofpacts. */
8858 ofpact_format(const struct ofpact
*a
,
8859 const struct ofpact_format_params
*fp
)
8862 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8863 case OFPACT_##ENUM: \
8864 format_##ENUM(ALIGNED_CAST(const struct STRUCT *, a), fp); \
8873 /* Appends a string representing the 'ofpacts_len' bytes of ofpacts in
8874 * 'ofpacts' to 'fp->s'. If 'port_map' is nonnull, uses it to translate port
8875 * numbers to names in output. */
8877 ofpacts_format(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
8878 const struct ofpact_format_params
*fp
)
8881 ds_put_format(fp
->s
, "%sdrop%s", colors
.drop
, colors
.end
);
8883 const struct ofpact
*a
;
8885 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8887 ds_put_char(fp
->s
, ',');
8890 ofpact_format(a
, fp
);
8895 /* Internal use by helpers. */
8897 /* Implementation of ofpact_put_<ENUM>(). */
8899 ofpact_put(struct ofpbuf
*ofpacts
, enum ofpact_type type
, size_t len
)
8901 struct ofpact
*ofpact
;
8903 ofpacts
->header
= ofpbuf_put_uninit(ofpacts
, len
);
8904 ofpact
= ofpacts
->header
;
8905 ofpact_init(ofpact
, type
, len
);
8909 /* Implementation of ofpact_init_<ENUM>(). */
8911 ofpact_init(struct ofpact
*ofpact
, enum ofpact_type type
, size_t len
)
8913 memset(ofpact
, 0, len
);
8914 ofpact
->type
= type
;
8919 /* Implementation of ofpact_finish_<ENUM>().
8921 * Finishes composing a variable-length action (begun using
8922 * ofpact_put_<NAME>()), by padding the action to a multiple of OFPACT_ALIGNTO
8923 * bytes and updating its embedded length field. See the large comment near
8924 * the end of ofp-actions.h for more information.
8926 * May reallocate 'ofpacts'. Callers should consider updating their 'ofpact'
8927 * pointer to the return value of this function. */
8929 ofpact_finish(struct ofpbuf
*ofpacts
, struct ofpact
*ofpact
)
8933 ovs_assert(ofpact
== ofpacts
->header
);
8934 len
= (char *) ofpbuf_tail(ofpacts
) - (char *) ofpact
;
8935 ovs_assert(len
> 0 && len
<= UINT16_MAX
);
8937 ofpbuf_padto(ofpacts
, OFPACT_ALIGN(ofpacts
->size
));
8939 return ofpacts
->header
;
8942 static char * OVS_WARN_UNUSED_RESULT
8943 ofpact_parse(enum ofpact_type type
, char *value
,
8944 const struct ofpact_parse_params
*pp
)
8947 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8948 case OFPACT_##ENUM: \
8949 return parse_##ENUM(value, pp);
8958 ofpact_type_from_name(const char *name
, enum ofpact_type
*type
)
8960 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8961 if (!strcasecmp(name, NAME)) { \
8962 *type = OFPACT_##ENUM; \
8971 /* Parses 'str' as a series of instructions, and appends them to 'ofpacts'.
8973 * Returns NULL if successful, otherwise a malloc()'d string describing the
8974 * error. The caller is responsible for freeing the returned string.
8976 * If 'outer_action' is specified, indicates that the actions being parsed
8977 * are nested within another action of the type specified in 'outer_action'. */
8978 static char * OVS_WARN_UNUSED_RESULT
8979 ofpacts_parse__(char *str
, const struct ofpact_parse_params
*pp
,
8980 bool allow_instructions
, enum ofpact_type outer_action
)
8989 while (ofputil_parse_key_value(&pos
, &key
, &value
)) {
8990 enum ovs_instruction_type inst
= OVSINST_OFPIT11_APPLY_ACTIONS
;
8991 enum ofpact_type type
;
8995 if (ofpact_type_from_name(key
, &type
)) {
8996 error
= ofpact_parse(type
, value
, pp
);
8997 inst
= ovs_instruction_type_from_ofpact_type(type
);
8998 } else if (!strcasecmp(key
, "mod_vlan_vid")) {
8999 error
= parse_set_vlan_vid(value
, true, pp
);
9000 } else if (!strcasecmp(key
, "mod_vlan_pcp")) {
9001 error
= parse_set_vlan_pcp(value
, true, pp
);
9002 } else if (!strcasecmp(key
, "set_nw_ttl")) {
9003 error
= parse_SET_IP_TTL(value
, pp
);
9004 } else if (!strcasecmp(key
, "pop_vlan")) {
9005 error
= parse_pop_vlan(pp
);
9006 } else if (!strcasecmp(key
, "set_tunnel64")) {
9007 error
= parse_set_tunnel(value
, NXAST_RAW_SET_TUNNEL64
, pp
);
9008 } else if (!strcasecmp(key
, "load")) {
9009 error
= parse_reg_load(value
, pp
);
9010 } else if (!strcasecmp(key
, "bundle_load")) {
9011 error
= parse_bundle_load(value
, pp
);
9012 } else if (!strcasecmp(key
, "drop")) {
9014 } else if (!strcasecmp(key
, "apply_actions")) {
9015 return xstrdup("apply_actions is the default instruction");
9016 } else if (ofputil_port_from_string(key
, pp
->port_map
, &port
)) {
9017 ofpact_put_OUTPUT(pp
->ofpacts
)->port
= port
;
9019 return xasprintf("unknown action %s", key
);
9025 if (inst
!= OVSINST_OFPIT11_APPLY_ACTIONS
) {
9026 if (!allow_instructions
) {
9027 return xasprintf("only actions are allowed here (not "
9029 ovs_instruction_name_from_type(inst
));
9031 if (inst
== prev_inst
) {
9032 return xasprintf("instruction %s may be specified only once",
9033 ovs_instruction_name_from_type(inst
));
9036 if (prev_inst
!= -1 && inst
< prev_inst
) {
9037 return xasprintf("instruction %s must be specified before %s",
9038 ovs_instruction_name_from_type(inst
),
9039 ovs_instruction_name_from_type(prev_inst
));
9044 if (drop
&& pp
->ofpacts
->size
) {
9045 return xstrdup("\"drop\" must not be accompanied by any other action "
9049 retval
= ofpacts_verify(pp
->ofpacts
->data
, pp
->ofpacts
->size
,
9051 ? (1u << N_OVS_INSTRUCTIONS
) - 1
9052 : 1u << OVSINST_OFPIT11_APPLY_ACTIONS
),
9055 return xstrdup("Incorrect instruction ordering");
9061 static char * OVS_WARN_UNUSED_RESULT
9062 ofpacts_parse(char *str
, const struct ofpact_parse_params
*pp
,
9063 bool allow_instructions
, enum ofpact_type outer_action
)
9065 uint32_t orig_size
= pp
->ofpacts
->size
;
9066 char *error
= ofpacts_parse__(str
, pp
, allow_instructions
, outer_action
);
9068 pp
->ofpacts
->size
= orig_size
;
9073 static char * OVS_WARN_UNUSED_RESULT
9074 ofpacts_parse_copy(const char *s_
, const struct ofpact_parse_params
*pp
,
9075 bool allow_instructions
, enum ofpact_type outer_action
)
9079 *pp
->usable_protocols
= OFPUTIL_P_ANY
;
9082 error
= ofpacts_parse(s
, pp
, allow_instructions
, outer_action
);
9088 /* Parses 's' as a set of OpenFlow actions and appends the actions to
9089 * 'ofpacts'. 'outer_action', if nonzero, specifies that 's' contains actions
9090 * that are nested within the action of type 'outer_action'.
9092 * Returns NULL if successful, otherwise a malloc()'d string describing the
9093 * error. The caller is responsible for freeing the returned string. */
9094 char * OVS_WARN_UNUSED_RESULT
9095 ofpacts_parse_actions(const char *s
, const struct ofpact_parse_params
*pp
)
9097 return ofpacts_parse_copy(s
, pp
, false, 0);
9100 /* Parses 's' as a set of OpenFlow instructions and appends the instructions to
9103 * Returns NULL if successful, otherwise a malloc()'d string describing the
9104 * error. The caller is responsible for freeing the returned string. */
9105 char * OVS_WARN_UNUSED_RESULT
9106 ofpacts_parse_instructions(const char *s
, const struct ofpact_parse_params
*pp
)
9108 return ofpacts_parse_copy(s
, pp
, true, 0);
9112 ofpact_name(enum ofpact_type type
)
9115 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) case OFPACT_##ENUM: return NAME;
9122 /* Low-level action decoding and encoding functions. */
9124 /* Everything needed to identify a particular OpenFlow action. */
9125 struct ofpact_hdrs
{
9126 uint32_t vendor
; /* 0 if standard, otherwise a vendor code. */
9127 uint16_t type
; /* Type if standard, otherwise subtype. */
9128 uint8_t ofp_version
; /* From ofp_header. */
9131 /* Information about a particular OpenFlow action. */
9132 struct ofpact_raw_instance
{
9133 /* The action's identity. */
9134 struct ofpact_hdrs hdrs
;
9135 enum ofp_raw_action_type raw
;
9137 /* Looking up the action. */
9138 struct hmap_node decode_node
; /* Based on 'hdrs'. */
9139 struct hmap_node encode_node
; /* Based on 'raw' + 'hdrs.ofp_version'. */
9141 /* The action's encoded size.
9143 * If this action is fixed-length, 'min_length' == 'max_length'.
9144 * If it is variable length, then 'max_length' is ROUND_DOWN(UINT16_MAX,
9145 * OFP_ACTION_ALIGN) == 65528. */
9146 unsigned short int min_length
;
9147 unsigned short int max_length
;
9149 /* For actions with a simple integer numeric argument, 'arg_ofs' is the
9150 * offset of that argument from the beginning of the action and 'arg_len'
9151 * its length, both in bytes.
9153 * For actions that take other forms, these are both zero. */
9154 unsigned short int arg_ofs
;
9155 unsigned short int arg_len
;
9157 /* The name of the action, e.g. "OFPAT_OUTPUT" or "NXAST_RESUBMIT". */
9160 /* If this action is deprecated, a human-readable string with a brief
9162 const char *deprecation
;
9165 /* Action header. */
9166 struct ofp_action_header
{
9167 /* The meaning of other values of 'type' generally depends on the OpenFlow
9168 * version (see enum ofp_raw_action_type).
9170 * Across all OpenFlow versions, OFPAT_VENDOR indicates that 'vendor'
9171 * designates an OpenFlow vendor ID and that the remainder of the action
9172 * structure has a vendor-defined meaning.
9174 #define OFPAT_VENDOR 0xffff
9177 /* Always a multiple of 8. */
9180 /* For type == OFPAT_VENDOR only, this is a vendor ID, e.g. NX_VENDOR_ID or
9181 * ONF_VENDOR_ID. Other 'type's use this space for some other purpose. */
9184 OFP_ASSERT(sizeof(struct ofp_action_header
) == 8);
9187 ofpact_hdrs_equal(const struct ofpact_hdrs
*a
,
9188 const struct ofpact_hdrs
*b
)
9190 return (a
->vendor
== b
->vendor
9191 && a
->type
== b
->type
9192 && a
->ofp_version
== b
->ofp_version
);
9196 ofpact_hdrs_hash(const struct ofpact_hdrs
*hdrs
)
9198 return hash_2words(hdrs
->vendor
,
9199 ((uint32_t) hdrs
->type
<< 16) | hdrs
->ofp_version
);
9202 #include "ofp-actions.inc2"
9204 static struct hmap
*
9205 ofpact_decode_hmap(void)
9207 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
9208 static struct hmap hmap
;
9210 if (ovsthread_once_start(&once
)) {
9211 struct ofpact_raw_instance
*inst
;
9214 for (inst
= all_raw_instances
;
9215 inst
< &all_raw_instances
[ARRAY_SIZE(all_raw_instances
)];
9217 hmap_insert(&hmap
, &inst
->decode_node
,
9218 ofpact_hdrs_hash(&inst
->hdrs
));
9220 ovsthread_once_done(&once
);
9225 static struct hmap
*
9226 ofpact_encode_hmap(void)
9228 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
9229 static struct hmap hmap
;
9231 if (ovsthread_once_start(&once
)) {
9232 struct ofpact_raw_instance
*inst
;
9235 for (inst
= all_raw_instances
;
9236 inst
< &all_raw_instances
[ARRAY_SIZE(all_raw_instances
)];
9238 hmap_insert(&hmap
, &inst
->encode_node
,
9239 hash_2words(inst
->raw
, inst
->hdrs
.ofp_version
));
9241 ovsthread_once_done(&once
);
9247 ofpact_decode_raw(enum ofp_version ofp_version
,
9248 const struct ofp_action_header
*oah
, size_t length
,
9249 const struct ofpact_raw_instance
**instp
)
9251 const struct ofpact_raw_instance
*inst
;
9252 struct ofpact_hdrs hdrs
;
9255 if (length
< sizeof *oah
) {
9256 return OFPERR_OFPBAC_BAD_LEN
;
9259 /* Get base action type. */
9260 if (oah
->type
== htons(OFPAT_VENDOR
)) {
9262 hdrs
.vendor
= ntohl(oah
->vendor
);
9263 if (hdrs
.vendor
== NX_VENDOR_ID
|| hdrs
.vendor
== ONF_VENDOR_ID
) {
9264 /* Get extension subtype. */
9265 const struct ext_action_header
*nah
;
9267 nah
= ALIGNED_CAST(const struct ext_action_header
*, oah
);
9268 if (length
< sizeof *nah
) {
9269 return OFPERR_OFPBAC_BAD_LEN
;
9271 hdrs
.type
= ntohs(nah
->subtype
);
9273 VLOG_WARN_RL(&rl
, "OpenFlow action has unknown vendor %#"PRIx32
,
9275 return OFPERR_OFPBAC_BAD_VENDOR
;
9279 hdrs
.type
= ntohs(oah
->type
);
9282 hdrs
.ofp_version
= ofp_version
;
9283 HMAP_FOR_EACH_WITH_HASH (inst
, decode_node
, ofpact_hdrs_hash(&hdrs
),
9284 ofpact_decode_hmap()) {
9285 if (ofpact_hdrs_equal(&hdrs
, &inst
->hdrs
)) {
9291 VLOG_WARN_RL(&rl
, "unknown %s action for vendor %#"PRIx32
" and "
9292 "type %"PRIu16
, ofputil_version_to_string(ofp_version
),
9293 hdrs
.vendor
, hdrs
.type
);
9295 ? OFPERR_OFPBAC_BAD_VENDOR_TYPE
9296 : OFPERR_OFPBAC_BAD_TYPE
);
9300 ofpact_pull_raw(struct ofpbuf
*buf
, enum ofp_version ofp_version
,
9301 enum ofp_raw_action_type
*raw
, uint64_t *arg
)
9303 const struct ofp_action_header
*oah
= buf
->data
;
9304 const struct ofpact_raw_instance
*action
;
9305 unsigned int length
;
9309 error
= ofpact_decode_raw(ofp_version
, oah
, buf
->size
, &action
);
9314 if (action
->deprecation
) {
9315 VLOG_INFO_RL(&rl
, "%s is deprecated in %s (%s)",
9316 action
->name
, ofputil_version_to_string(ofp_version
),
9317 action
->deprecation
);
9320 length
= ntohs(oah
->len
);
9321 if (length
> buf
->size
) {
9322 VLOG_WARN_RL(&rl
, "OpenFlow action %s length %u exceeds action buffer "
9323 "length %"PRIu32
, action
->name
, length
, buf
->size
);
9324 return OFPERR_OFPBAC_BAD_LEN
;
9326 if (length
< action
->min_length
|| length
> action
->max_length
) {
9327 VLOG_WARN_RL(&rl
, "OpenFlow action %s length %u not in valid range "
9328 "[%hu,%hu]", action
->name
, length
,
9329 action
->min_length
, action
->max_length
);
9330 return OFPERR_OFPBAC_BAD_LEN
;
9333 VLOG_WARN_RL(&rl
, "OpenFlow action %s length %u is not a multiple "
9334 "of 8", action
->name
, length
);
9335 return OFPERR_OFPBAC_BAD_LEN
;
9340 if (action
->arg_len
) {
9344 p
= ofpbuf_at_assert(buf
, action
->arg_ofs
, action
->arg_len
);
9345 for (i
= 0; i
< action
->arg_len
; i
++) {
9346 *arg
= (*arg
<< 8) | p
[i
];
9350 ofpbuf_pull(buf
, length
);
9355 static const struct ofpact_raw_instance
*
9356 ofpact_raw_lookup(enum ofp_version ofp_version
, enum ofp_raw_action_type raw
)
9358 const struct ofpact_raw_instance
*inst
;
9360 HMAP_FOR_EACH_WITH_HASH (inst
, encode_node
, hash_2words(raw
, ofp_version
),
9361 ofpact_encode_hmap()) {
9362 if (inst
->raw
== raw
&& inst
->hdrs
.ofp_version
== ofp_version
) {
9370 ofpact_put_raw(struct ofpbuf
*buf
, enum ofp_version ofp_version
,
9371 enum ofp_raw_action_type raw
, uint64_t arg
)
9373 const struct ofpact_raw_instance
*inst
;
9374 struct ofp_action_header
*oah
;
9375 const struct ofpact_hdrs
*hdrs
;
9377 inst
= ofpact_raw_lookup(ofp_version
, raw
);
9380 oah
= ofpbuf_put_zeros(buf
, inst
->min_length
);
9381 oah
->type
= htons(hdrs
->vendor
? OFPAT_VENDOR
: hdrs
->type
);
9382 oah
->len
= htons(inst
->min_length
);
9383 oah
->vendor
= htonl(hdrs
->vendor
);
9385 switch (hdrs
->vendor
) {
9390 case ONF_VENDOR_ID
: {
9391 struct ext_action_header
*nah
= (struct ext_action_header
*) oah
;
9392 nah
->subtype
= htons(hdrs
->type
);
9400 if (inst
->arg_len
) {
9401 uint8_t *p
= (uint8_t *) oah
+ inst
->arg_ofs
+ inst
->arg_len
;
9404 for (i
= 0; i
< inst
->arg_len
; i
++) {
9416 pad_ofpat(struct ofpbuf
*openflow
, size_t start_ofs
)
9418 struct ofp_action_header
*oah
;
9420 ofpbuf_put_zeros(openflow
, PAD_SIZE(openflow
->size
- start_ofs
,
9423 oah
= ofpbuf_at_assert(openflow
, start_ofs
, sizeof *oah
);
9424 oah
->len
= htons(openflow
->size
- start_ofs
);