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.
18 #include <netinet/in.h>
21 #include "byte-order.h"
25 #include "openvswitch/hmap.h"
27 #include "multipath.h"
29 #include "odp-netlink.h"
30 #include "openvswitch/dynamic-string.h"
31 #include "openvswitch/meta-flow.h"
32 #include "openvswitch/ofp-actions.h"
33 #include "openvswitch/ofp-util.h"
34 #include "openvswitch/ofp-parse.h"
35 #include "openvswitch/ofp-prop.h"
36 #include "openvswitch/ofpbuf.h"
37 #include "openvswitch/vlog.h"
38 #include "unaligned.h"
40 #include "vl-mff-map.h"
42 VLOG_DEFINE_THIS_MODULE(ofp_actions
);
44 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
46 struct ofp_action_header
;
48 /* Header for Open vSwitch and ONF vendor extension actions.
50 * This is the entire header for a few Open vSwitch vendor extension actions,
51 * the ones that either have no arguments or for which variable-length
52 * arguments follow the header.
54 * This cannot be used as an entirely generic vendor extension action header,
55 * because OpenFlow does not specify the location or size of the action
56 * subtype; it just happens that ONF extensions and Nicira extensions share
58 struct ext_action_header
{
59 ovs_be16 type
; /* OFPAT_VENDOR. */
60 ovs_be16 len
; /* At least 16. */
61 ovs_be32 vendor
; /* NX_VENDOR_ID or ONF_VENDOR_ID. */
62 ovs_be16 subtype
; /* See enum ofp_raw_action_type. */
65 OFP_ASSERT(sizeof(struct ext_action_header
) == 16);
67 /* Raw identifiers for OpenFlow actions.
69 * Decoding and encoding OpenFlow actions across multiple versions is difficult
70 * to do in a clean, consistent way. This enumeration lays out all of the
71 * forms of actions that Open vSwitch supports.
73 * The comments here must follow a stylized form because the
74 * "extract-ofp-actions" program parses them at build time to generate data
77 * - The first part of each comment specifies the vendor, OpenFlow versions,
78 * and type for each protocol that supports the action:
80 * # The vendor is OF for standard OpenFlow actions, NX for Nicira
81 * extension actions. (Support for other vendors can be added, but
82 * it can't be done just based on a vendor ID definition alone
83 * because OpenFlow doesn't define a standard way to specify a
84 * subtype for vendor actions, so other vendors might do it different
87 * # The version can specify a specific OpenFlow version, a version
88 * range delimited by "-", or an open-ended range with "+".
90 * # The type, in parentheses, is the action type number (for standard
91 * OpenFlow actions) or subtype (for vendor extension actions).
93 * # Optionally one may add "is deprecated" followed by a
94 * human-readable reason in parentheses (which will be used in log
95 * messages), if a particular action should no longer be used.
97 * Multiple such specifications may be separated by commas.
99 * - The second part describes the action's wire format. It may be:
101 * # "struct <name>": The struct fully specifies the wire format. The
102 * action is exactly the size of the struct. (Thus, the struct must
103 * be an exact multiple of 8 bytes in size.)
105 * # "struct <name>, ...": The struct specifies the beginning of the
106 * wire format. An instance of the action is either the struct's
107 * exact size, or a multiple of 8 bytes longer.
109 * # "uint<N>_t" or "ovs_be<N>": The action consists of a (standard or
110 * vendor extension) header, followed by 0 or more pad bytes to align
111 * to a multiple of <N> bits, followed by an argument of the given
112 * type, followed by 0 or more pad bytes to bring the total action up
113 * to a multiple of 8 bytes.
115 * # "void": The action is just a (standard or vendor extension)
118 * # Optionally, one may add "VLMFF" in the end of the second part if
119 * the Openflow action may use a variable length meta-flow field
120 * (i.e. tun_metadata). Adding "VLMFF" will pass the per-switch based
121 * variable length meta-flow field mapping map (struct vl_mff_map) to
122 * the corresponding action decoding function.
124 * - Optional additional text enclosed in square brackets is commentary for
127 enum ofp_raw_action_type
{
128 /* ## ----------------- ## */
129 /* ## Standard actions. ## */
130 /* ## ----------------- ## */
132 /* OF1.0(0): struct ofp10_action_output. */
134 /* OF1.1+(0): struct ofp11_action_output. */
137 /* OF1.0(1): uint16_t. */
138 OFPAT_RAW10_SET_VLAN_VID
,
139 /* OF1.0(2): uint8_t. */
140 OFPAT_RAW10_SET_VLAN_PCP
,
142 /* OF1.1(1), OF1.2+(1) is deprecated (use Set-Field): uint16_t.
144 * [Semantics differ slightly between the 1.0 and 1.1 versions of the VLAN
145 * modification actions: the 1.0 versions push a VLAN header if none is
146 * present, but the 1.1 versions do not. That is the only reason that we
147 * distinguish their raw action types.] */
148 OFPAT_RAW11_SET_VLAN_VID
,
149 /* OF1.1(2), OF1.2+(2) is deprecated (use Set-Field): uint8_t. */
150 OFPAT_RAW11_SET_VLAN_PCP
,
152 /* OF1.1+(17): ovs_be16.
154 * [The argument is the Ethertype, e.g. ETH_TYPE_VLAN_8021Q, not the VID or
156 OFPAT_RAW11_PUSH_VLAN
,
158 /* OF1.0(3): void. */
159 OFPAT_RAW10_STRIP_VLAN
,
160 /* OF1.1+(18): void. */
161 OFPAT_RAW11_POP_VLAN
,
163 /* OF1.0(4), OF1.1(3), OF1.2+(3) is deprecated (use Set-Field): struct
164 * ofp_action_dl_addr. */
165 OFPAT_RAW_SET_DL_SRC
,
167 /* OF1.0(5), OF1.1(4), OF1.2+(4) is deprecated (use Set-Field): struct
168 * ofp_action_dl_addr. */
169 OFPAT_RAW_SET_DL_DST
,
171 /* OF1.0(6), OF1.1(5), OF1.2+(5) is deprecated (use Set-Field):
173 OFPAT_RAW_SET_NW_SRC
,
175 /* OF1.0(7), OF1.1(6), OF1.2+(6) is deprecated (use Set-Field):
177 OFPAT_RAW_SET_NW_DST
,
179 /* OF1.0(8), OF1.1(7), OF1.2+(7) is deprecated (use Set-Field): uint8_t. */
180 OFPAT_RAW_SET_NW_TOS
,
182 /* OF1.1(8), OF1.2+(8) is deprecated (use Set-Field): uint8_t. */
183 OFPAT_RAW11_SET_NW_ECN
,
185 /* OF1.0(9), OF1.1(9), OF1.2+(9) is deprecated (use Set-Field):
187 OFPAT_RAW_SET_TP_SRC
,
189 /* OF1.0(10), OF1.1(10), OF1.2+(10) is deprecated (use Set-Field):
191 OFPAT_RAW_SET_TP_DST
,
193 /* OF1.0(11): struct ofp10_action_enqueue. */
196 /* NX1.0(30), OF1.1(13), OF1.2+(13) is deprecated (use Set-Field):
198 OFPAT_RAW_SET_MPLS_LABEL
,
200 /* NX1.0(31), OF1.1(14), OF1.2+(14) is deprecated (use Set-Field):
202 OFPAT_RAW_SET_MPLS_TC
,
204 /* NX1.0(25), OF1.1(15), OF1.2+(15) is deprecated (use Set-Field):
206 OFPAT_RAW_SET_MPLS_TTL
,
208 /* NX1.0(26), OF1.1+(16): void. */
209 OFPAT_RAW_DEC_MPLS_TTL
,
211 /* NX1.0(23), OF1.1+(19): ovs_be16.
213 * [The argument is the Ethertype, e.g. ETH_TYPE_MPLS, not the label.] */
216 /* NX1.0(24), OF1.1+(20): ovs_be16.
218 * [The argument is the Ethertype, e.g. ETH_TYPE_IPV4 if at BoS or
219 * ETH_TYPE_MPLS otherwise, not the label.] */
222 /* NX1.0(4), OF1.1+(21): uint32_t. */
225 /* NX1.0(40), OF1.1+(22): uint32_t. */
228 /* OF1.1+(23): uint8_t. */
229 OFPAT_RAW11_SET_NW_TTL
,
231 /* NX1.0(18), OF1.1+(24): void. */
232 OFPAT_RAW_DEC_NW_TTL
,
233 /* NX1.0+(21): struct nx_action_cnt_ids, ... */
234 NXAST_RAW_DEC_TTL_CNT_IDS
,
236 /* OF1.2-1.4(25): struct ofp12_action_set_field, ... VLMFF */
237 OFPAT_RAW12_SET_FIELD
,
238 /* OF1.5+(25): struct ofp12_action_set_field, ... VLMFF */
239 OFPAT_RAW15_SET_FIELD
,
240 /* NX1.0-1.4(7): struct nx_action_reg_load. VLMFF
242 * [In OpenFlow 1.5, set_field is a superset of reg_load functionality, so
243 * we drop reg_load.] */
245 /* NX1.0-1.4(33): struct ext_action_header, ... VLMFF
247 * [In OpenFlow 1.5, set_field is a superset of reg_load2 functionality, so
248 * we drop reg_load2.] */
251 /* OF1.5+(28): struct ofp15_action_copy_field, ... VLMFF */
252 OFPAT_RAW15_COPY_FIELD
,
253 /* ONF1.3-1.4(3200): struct onf_action_copy_field, ... VLMFF */
254 ONFACT_RAW13_COPY_FIELD
,
255 /* NX1.0-1.4(6): struct nx_action_reg_move, ... VLMFF */
258 /* ## ------------------------- ## */
259 /* ## Nicira extension actions. ## */
260 /* ## ------------------------- ## */
262 /* Actions similar to standard actions are listed with the standard actions. */
264 /* NX1.0+(1): uint16_t. */
266 /* NX1.0+(14): struct nx_action_resubmit. */
267 NXAST_RAW_RESUBMIT_TABLE
,
268 /* NX1.0+(44): struct nx_action_resubmit. */
269 NXAST_RAW_RESUBMIT_TABLE_CT
,
271 /* NX1.0+(2): uint32_t. */
272 NXAST_RAW_SET_TUNNEL
,
273 /* NX1.0+(9): uint64_t. */
274 NXAST_RAW_SET_TUNNEL64
,
276 /* NX1.0+(5): void. */
279 /* NX1.0+(8): struct nx_action_note, ... */
282 /* NX1.0+(10): struct nx_action_multipath. VLMFF */
285 /* NX1.0+(12): struct nx_action_bundle, ... */
287 /* NX1.0+(13): struct nx_action_bundle, ... VLMFF */
288 NXAST_RAW_BUNDLE_LOAD
,
290 /* NX1.0+(15): struct nx_action_output_reg. VLMFF */
291 NXAST_RAW_OUTPUT_REG
,
292 /* NX1.0+(32): struct nx_action_output_reg2. VLMFF */
293 NXAST_RAW_OUTPUT_REG2
,
295 /* NX1.0+(16): struct nx_action_learn, ... VLMFF */
297 /* NX1.0+(45): struct nx_action_learn2, ... VLMFF */
300 /* NX1.0+(17): void. */
303 /* NX1.0+(19): struct nx_action_fin_timeout. */
304 NXAST_RAW_FIN_TIMEOUT
,
306 /* NX1.0+(20): struct nx_action_controller. */
307 NXAST_RAW_CONTROLLER
,
308 /* NX1.0+(37): struct ext_action_header, ... */
309 NXAST_RAW_CONTROLLER2
,
311 /* NX1.0+(22): struct nx_action_write_metadata. */
312 NXAST_RAW_WRITE_METADATA
,
314 /* NX1.0+(27): struct nx_action_stack. VLMFF */
315 NXAST_RAW_STACK_PUSH
,
317 /* NX1.0+(28): struct nx_action_stack. VLMFF */
320 /* NX1.0+(29): struct nx_action_sample. */
322 /* NX1.0+(38): struct nx_action_sample2. */
324 /* NX1.0+(41): struct nx_action_sample2. */
327 /* NX1.0+(34): struct nx_action_conjunction. */
328 NXAST_RAW_CONJUNCTION
,
330 /* NX1.0+(35): struct nx_action_conntrack, ... VLMFF */
333 /* NX1.0+(36): struct nx_action_nat, ... */
336 /* NX1.0+(39): struct nx_action_output_trunc. */
337 NXAST_RAW_OUTPUT_TRUNC
,
339 /* NX1.0+(42): struct ext_action_header, ... VLMFF */
342 /* NX1.0+(43): void. */
345 /* NX1.3+(46): struct nx_action_encap, ... */
348 /* NX1.3+(47): struct nx_action_decap, ... */
351 /* ## ------------------ ## */
352 /* ## Debugging actions. ## */
353 /* ## ------------------ ## */
355 /* These are intentionally undocumented, subject to change, and ovs-vswitchd */
356 /* accepts them only if started with --enable-dummy. */
358 /* NX1.0+(255): void. */
359 NXAST_RAW_DEBUG_RECIRC
,
362 /* OpenFlow actions are always a multiple of 8 bytes in length. */
363 #define OFP_ACTION_ALIGN 8
365 /* Define a few functions for working with instructions. */
366 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
367 static inline const struct STRUCT * OVS_UNUSED \
368 instruction_get_##ENUM(const struct ofp11_instruction *inst)\
370 ovs_assert(inst->type == htons(ENUM)); \
371 return ALIGNED_CAST(struct STRUCT *, inst); \
374 static inline void OVS_UNUSED \
375 instruction_init_##ENUM(struct STRUCT *s) \
377 memset(s, 0, sizeof *s); \
378 s->type = htons(ENUM); \
379 s->len = htons(sizeof *s); \
382 static inline struct STRUCT * OVS_UNUSED \
383 instruction_put_##ENUM(struct ofpbuf *buf) \
385 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
386 instruction_init_##ENUM(s); \
392 static void ofpacts_update_instruction_actions(struct ofpbuf
*openflow
,
394 static void pad_ofpat(struct ofpbuf
*openflow
, size_t start_ofs
);
396 static enum ofperr
ofpacts_verify(const struct ofpact
[], size_t ofpacts_len
,
397 uint32_t allowed_ovsinsts
,
398 enum ofpact_type outer_action
);
400 static void put_set_field(struct ofpbuf
*openflow
, enum ofp_version
,
401 enum mf_field_id
, uint64_t value
);
403 static void put_reg_load(struct ofpbuf
*openflow
,
404 const struct mf_subfield
*, uint64_t value
);
406 static enum ofperr
ofpact_pull_raw(struct ofpbuf
*, enum ofp_version
,
407 enum ofp_raw_action_type
*, uint64_t *arg
);
408 static void *ofpact_put_raw(struct ofpbuf
*, enum ofp_version
,
409 enum ofp_raw_action_type
, uint64_t arg
);
411 static char *OVS_WARN_UNUSED_RESULT
ofpacts_parse(
412 char *str
, const struct ofputil_port_map
*,
413 struct ofpbuf
*ofpacts
, enum ofputil_protocol
*usable_protocols
,
414 bool allow_instructions
, enum ofpact_type outer_action
);
415 static enum ofperr
ofpacts_pull_openflow_actions__(
416 struct ofpbuf
*openflow
, unsigned int actions_len
,
417 enum ofp_version version
, uint32_t allowed_ovsinsts
,
418 struct ofpbuf
*ofpacts
, enum ofpact_type outer_action
,
419 const struct vl_mff_map
*vl_mff_map
, uint64_t *ofpacts_tlv_bitmap
);
420 static char * OVS_WARN_UNUSED_RESULT
ofpacts_parse_copy(
421 const char *s_
, const struct ofputil_port_map
*, struct ofpbuf
*ofpacts
,
422 enum ofputil_protocol
*usable_protocols
,
423 bool allow_instructions
, enum ofpact_type outer_action
);
425 /* Returns the ofpact following 'ofpact', except that if 'ofpact' contains
426 * nested ofpacts it returns the first one. */
428 ofpact_next_flattened(const struct ofpact
*ofpact
)
430 switch (ofpact
->type
) {
433 case OFPACT_CONTROLLER
:
435 case OFPACT_OUTPUT_REG
:
436 case OFPACT_OUTPUT_TRUNC
:
438 case OFPACT_SET_FIELD
:
439 case OFPACT_SET_VLAN_VID
:
440 case OFPACT_SET_VLAN_PCP
:
441 case OFPACT_STRIP_VLAN
:
442 case OFPACT_PUSH_VLAN
:
443 case OFPACT_SET_ETH_SRC
:
444 case OFPACT_SET_ETH_DST
:
445 case OFPACT_SET_IPV4_SRC
:
446 case OFPACT_SET_IPV4_DST
:
447 case OFPACT_SET_IP_DSCP
:
448 case OFPACT_SET_IP_ECN
:
449 case OFPACT_SET_IP_TTL
:
450 case OFPACT_SET_L4_SRC_PORT
:
451 case OFPACT_SET_L4_DST_PORT
:
452 case OFPACT_REG_MOVE
:
453 case OFPACT_STACK_PUSH
:
454 case OFPACT_STACK_POP
:
456 case OFPACT_SET_MPLS_LABEL
:
457 case OFPACT_SET_MPLS_TC
:
458 case OFPACT_SET_MPLS_TTL
:
459 case OFPACT_DEC_MPLS_TTL
:
460 case OFPACT_PUSH_MPLS
:
461 case OFPACT_POP_MPLS
:
462 case OFPACT_SET_TUNNEL
:
463 case OFPACT_SET_QUEUE
:
464 case OFPACT_POP_QUEUE
:
465 case OFPACT_FIN_TIMEOUT
:
466 case OFPACT_RESUBMIT
:
468 case OFPACT_CONJUNCTION
:
469 case OFPACT_MULTIPATH
:
473 case OFPACT_UNROLL_XLATE
:
474 case OFPACT_CT_CLEAR
:
475 case OFPACT_DEBUG_RECIRC
:
477 case OFPACT_CLEAR_ACTIONS
:
478 case OFPACT_WRITE_METADATA
:
479 case OFPACT_GOTO_TABLE
:
483 return ofpact_next(ofpact
);
486 return ofpact_get_CLONE(ofpact
)->actions
;
489 return ofpact_get_CT(ofpact
)->actions
;
491 case OFPACT_WRITE_ACTIONS
:
492 return ofpact_get_WRITE_ACTIONS(ofpact
)->actions
;
498 /* Pull off existing actions or instructions. Used by nesting actions to keep
499 * ofpacts_parse() oblivious of actions nesting.
501 * Push the actions back on after nested parsing, e.g.:
503 * size_t ofs = ofpacts_pull(ofpacts);
504 * ...nested parsing...
505 * ofpbuf_push_uninit(ofpacts, ofs);
508 ofpacts_pull(struct ofpbuf
*ofpacts
)
513 ofpbuf_pull(ofpacts
, ofs
);
518 #include "ofp-actions.inc1"
520 /* Output actions. */
522 /* Action structure for OFPAT10_OUTPUT, which sends packets out 'port'.
523 * When the 'port' is the OFPP_CONTROLLER, 'max_len' indicates the max
524 * number of bytes to send. A 'max_len' of zero means no bytes of the
525 * packet should be sent. */
526 struct ofp10_action_output
{
527 ovs_be16 type
; /* OFPAT10_OUTPUT. */
528 ovs_be16 len
; /* Length is 8. */
529 ovs_be16 port
; /* Output port. */
530 ovs_be16 max_len
; /* Max length to send to controller. */
532 OFP_ASSERT(sizeof(struct ofp10_action_output
) == 8);
534 /* Action structure for OFPAT_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 ofp11_action_output
{
539 ovs_be16 type
; /* OFPAT11_OUTPUT. */
540 ovs_be16 len
; /* Length is 16. */
541 ovs_be32 port
; /* Output port. */
542 ovs_be16 max_len
; /* Max length to send to controller. */
543 uint8_t pad
[6]; /* Pad to 64 bits. */
545 OFP_ASSERT(sizeof(struct ofp11_action_output
) == 16);
548 decode_OFPAT_RAW10_OUTPUT(const struct ofp10_action_output
*oao
,
549 enum ofp_version ofp_version OVS_UNUSED
,
552 struct ofpact_output
*output
;
554 output
= ofpact_put_OUTPUT(out
);
555 output
->port
= u16_to_ofp(ntohs(oao
->port
));
556 output
->max_len
= ntohs(oao
->max_len
);
558 return ofpact_check_output_port(output
->port
, OFPP_MAX
);
562 decode_OFPAT_RAW11_OUTPUT(const struct ofp11_action_output
*oao
,
563 enum ofp_version ofp_version OVS_UNUSED
,
566 struct ofpact_output
*output
;
569 output
= ofpact_put_OUTPUT(out
);
570 output
->max_len
= ntohs(oao
->max_len
);
572 error
= ofputil_port_from_ofp11(oao
->port
, &output
->port
);
577 return ofpact_check_output_port(output
->port
, OFPP_MAX
);
581 encode_OUTPUT(const struct ofpact_output
*output
,
582 enum ofp_version ofp_version
, struct ofpbuf
*out
)
584 if (ofp_version
== OFP10_VERSION
) {
585 struct ofp10_action_output
*oao
;
587 oao
= put_OFPAT10_OUTPUT(out
);
588 oao
->port
= htons(ofp_to_u16(output
->port
));
589 oao
->max_len
= htons(output
->max_len
);
591 struct ofp11_action_output
*oao
;
593 oao
= put_OFPAT11_OUTPUT(out
);
594 oao
->port
= ofputil_port_to_ofp11(output
->port
);
595 oao
->max_len
= htons(output
->max_len
);
599 static char * OVS_WARN_UNUSED_RESULT
600 parse_truncate_subfield(struct ofpact_output_trunc
*output_trunc
,
602 const struct ofputil_port_map
*port_map
)
605 char *arg
= CONST_CAST(char *, arg_
);
607 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
608 if (!strcmp(key
, "port")) {
609 if (!ofputil_port_from_string(value
, port_map
,
610 &output_trunc
->port
)) {
611 return xasprintf("output to unknown truncate port: %s",
614 if (ofp_to_u16(output_trunc
->port
) > ofp_to_u16(OFPP_MAX
)) {
615 if (output_trunc
->port
!= OFPP_LOCAL
&&
616 output_trunc
->port
!= OFPP_IN_PORT
)
617 return xasprintf("output to unsupported truncate port: %s",
620 } else if (!strcmp(key
, "max_len")) {
623 err
= str_to_u32(value
, &output_trunc
->max_len
);
628 return xasprintf("invalid key '%s' in output_trunc argument",
635 static char * OVS_WARN_UNUSED_RESULT
636 parse_OUTPUT(const char *arg
,
637 const struct ofputil_port_map
*port_map
,
638 struct ofpbuf
*ofpacts
,
639 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
641 if (strstr(arg
, "port") && strstr(arg
, "max_len")) {
642 struct ofpact_output_trunc
*output_trunc
;
644 output_trunc
= ofpact_put_OUTPUT_TRUNC(ofpacts
);
645 return parse_truncate_subfield(output_trunc
, arg
, port_map
);
649 if (ofputil_port_from_string(arg
, port_map
, &port
)) {
650 struct ofpact_output
*output
= ofpact_put_OUTPUT(ofpacts
);
652 output
->max_len
= output
->port
== OFPP_CONTROLLER
? UINT16_MAX
: 0;
656 struct mf_subfield src
;
657 char *error
= mf_parse_subfield(&src
, arg
);
659 struct ofpact_output_reg
*output_reg
;
661 output_reg
= ofpact_put_OUTPUT_REG(ofpacts
);
662 output_reg
->max_len
= UINT16_MAX
;
663 output_reg
->src
= src
;
668 return xasprintf("%s: output to unknown port", arg
);
672 format_OUTPUT(const struct ofpact_output
*a
,
673 const struct ofputil_port_map
*port_map
, struct ds
*s
)
675 if (ofp_to_u16(a
->port
) < ofp_to_u16(OFPP_MAX
)) {
676 ds_put_format(s
, "%soutput:%s", colors
.special
, colors
.end
);
678 ofputil_format_port(a
->port
, port_map
, s
);
679 if (a
->port
== OFPP_CONTROLLER
) {
680 ds_put_format(s
, ":%"PRIu16
, a
->max_len
);
687 decode_OFPAT_RAW_GROUP(uint32_t group_id
,
688 enum ofp_version ofp_version OVS_UNUSED
,
691 ofpact_put_GROUP(out
)->group_id
= group_id
;
696 encode_GROUP(const struct ofpact_group
*group
,
697 enum ofp_version ofp_version
, struct ofpbuf
*out
)
699 put_OFPAT_GROUP(out
, ofp_version
, group
->group_id
);
702 static char * OVS_WARN_UNUSED_RESULT
703 parse_GROUP(char *arg
,
704 const struct ofputil_port_map
*port_map OVS_UNUSED
,
705 struct ofpbuf
*ofpacts
,
706 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
708 return str_to_u32(arg
, &ofpact_put_GROUP(ofpacts
)->group_id
);
712 format_GROUP(const struct ofpact_group
*a
,
713 const struct ofputil_port_map
*port_map OVS_UNUSED
,
716 ds_put_format(s
, "%sgroup:%s%"PRIu32
,
717 colors
.special
, colors
.end
, a
->group_id
);
720 /* Action structure for NXAST_CONTROLLER.
722 * This generalizes using OFPAT_OUTPUT to send a packet to OFPP_CONTROLLER. In
723 * addition to the 'max_len' that OFPAT_OUTPUT supports, it also allows
726 * - 'reason': The reason code to use in the ofp_packet_in or nx_packet_in.
728 * - 'controller_id': The ID of the controller connection to which the
729 * ofp_packet_in should be sent. The ofp_packet_in or nx_packet_in is
730 * sent only to controllers that have the specified controller connection
731 * ID. See "struct nx_controller_id" for more information. */
732 struct nx_action_controller
{
733 ovs_be16 type
; /* OFPAT_VENDOR. */
734 ovs_be16 len
; /* Length is 16. */
735 ovs_be32 vendor
; /* NX_VENDOR_ID. */
736 ovs_be16 subtype
; /* NXAST_CONTROLLER. */
737 ovs_be16 max_len
; /* Maximum length to send to controller. */
738 ovs_be16 controller_id
; /* Controller ID to send packet-in. */
739 uint8_t reason
; /* enum ofp_packet_in_reason (OFPR_*). */
740 uint8_t zero
; /* Must be zero. */
742 OFP_ASSERT(sizeof(struct nx_action_controller
) == 16);
744 /* Properties for NXAST_CONTROLLER2.
746 * For more information on the effect of NXAC2PT_PAUSE, see the large comment
747 * on NXT_PACKET_IN2 in nicira-ext.h */
748 enum nx_action_controller2_prop_type
{
749 NXAC2PT_MAX_LEN
, /* ovs_be16 max bytes to send (default all). */
750 NXAC2PT_CONTROLLER_ID
, /* ovs_be16 dest controller ID (default 0). */
751 NXAC2PT_REASON
, /* uint8_t reason (OFPR_*), default 0. */
752 NXAC2PT_USERDATA
, /* Data to copy into NXPINT_USERDATA. */
753 NXAC2PT_PAUSE
, /* Flag to pause pipeline to resume later. */
756 /* The action structure for NXAST_CONTROLLER2 is "struct ext_action_header",
757 * followed by NXAC2PT_* properties. */
760 decode_NXAST_RAW_CONTROLLER(const struct nx_action_controller
*nac
,
761 enum ofp_version ofp_version OVS_UNUSED
,
764 struct ofpact_controller
*oc
;
766 oc
= ofpact_put_CONTROLLER(out
);
767 oc
->ofpact
.raw
= NXAST_RAW_CONTROLLER
;
768 oc
->max_len
= ntohs(nac
->max_len
);
769 oc
->controller_id
= ntohs(nac
->controller_id
);
770 oc
->reason
= nac
->reason
;
771 ofpact_finish_CONTROLLER(out
, &oc
);
777 decode_NXAST_RAW_CONTROLLER2(const struct ext_action_header
*eah
,
778 enum ofp_version ofp_version OVS_UNUSED
,
781 if (!is_all_zeros(eah
->pad
, sizeof eah
->pad
)) {
782 return OFPERR_NXBRC_MUST_BE_ZERO
;
785 size_t start_ofs
= out
->size
;
786 struct ofpact_controller
*oc
= ofpact_put_CONTROLLER(out
);
787 oc
->ofpact
.raw
= NXAST_RAW_CONTROLLER2
;
788 oc
->max_len
= UINT16_MAX
;
789 oc
->reason
= OFPR_ACTION
;
791 struct ofpbuf properties
;
792 ofpbuf_use_const(&properties
, eah
, ntohs(eah
->len
));
793 ofpbuf_pull(&properties
, sizeof *eah
);
795 while (properties
.size
> 0) {
796 struct ofpbuf payload
;
799 enum ofperr error
= ofpprop_pull(&properties
, &payload
, &type
);
805 case NXAC2PT_MAX_LEN
:
806 error
= ofpprop_parse_u16(&payload
, &oc
->max_len
);
809 case NXAC2PT_CONTROLLER_ID
:
810 error
= ofpprop_parse_u16(&payload
, &oc
->controller_id
);
813 case NXAC2PT_REASON
: {
815 error
= ofpprop_parse_u8(&payload
, &u8
);
820 case NXAC2PT_USERDATA
:
821 out
->size
= start_ofs
+ OFPACT_CONTROLLER_SIZE
;
822 ofpbuf_put(out
, payload
.msg
, ofpbuf_msgsize(&payload
));
823 oc
= ofpbuf_at_assert(out
, start_ofs
, sizeof *oc
);
824 oc
->userdata_len
= ofpbuf_msgsize(&payload
);
832 error
= OFPPROP_UNKNOWN(false, "NXAST_RAW_CONTROLLER2", type
);
840 ofpact_finish_CONTROLLER(out
, &oc
);
846 encode_CONTROLLER(const struct ofpact_controller
*controller
,
847 enum ofp_version ofp_version OVS_UNUSED
,
850 if (controller
->userdata_len
852 || controller
->ofpact
.raw
== NXAST_RAW_CONTROLLER2
) {
853 size_t start_ofs
= out
->size
;
854 put_NXAST_CONTROLLER2(out
);
855 if (controller
->max_len
!= UINT16_MAX
) {
856 ofpprop_put_u16(out
, NXAC2PT_MAX_LEN
, controller
->max_len
);
858 if (controller
->controller_id
!= 0) {
859 ofpprop_put_u16(out
, NXAC2PT_CONTROLLER_ID
,
860 controller
->controller_id
);
862 if (controller
->reason
!= OFPR_ACTION
) {
863 ofpprop_put_u8(out
, NXAC2PT_REASON
, controller
->reason
);
865 if (controller
->userdata_len
!= 0) {
866 ofpprop_put(out
, NXAC2PT_USERDATA
, controller
->userdata
,
867 controller
->userdata_len
);
869 if (controller
->pause
) {
870 ofpprop_put_flag(out
, NXAC2PT_PAUSE
);
872 pad_ofpat(out
, start_ofs
);
874 struct nx_action_controller
*nac
;
876 nac
= put_NXAST_CONTROLLER(out
);
877 nac
->max_len
= htons(controller
->max_len
);
878 nac
->controller_id
= htons(controller
->controller_id
);
879 nac
->reason
= controller
->reason
;
883 static char * OVS_WARN_UNUSED_RESULT
884 parse_CONTROLLER(char *arg
,
885 const struct ofputil_port_map
*port_map OVS_UNUSED
,
886 struct ofpbuf
*ofpacts
,
887 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
889 enum ofp_packet_in_reason reason
= OFPR_ACTION
;
890 uint16_t controller_id
= 0;
891 uint16_t max_len
= UINT16_MAX
;
892 const char *userdata
= NULL
;
897 } else if (strspn(arg
, "0123456789") == strlen(arg
)) {
898 char *error
= str_to_u16(arg
, "max_len", &max_len
);
905 while (ofputil_parse_key_value(&arg
, &name
, &value
)) {
906 if (!strcmp(name
, "reason")) {
907 if (!ofputil_packet_in_reason_from_string(value
, &reason
)) {
908 return xasprintf("unknown reason \"%s\"", value
);
910 } else if (!strcmp(name
, "max_len")) {
911 char *error
= str_to_u16(value
, "max_len", &max_len
);
915 } else if (!strcmp(name
, "id")) {
916 char *error
= str_to_u16(value
, "id", &controller_id
);
920 } else if (!strcmp(name
, "userdata")) {
922 } else if (!strcmp(name
, "pause")) {
925 return xasprintf("unknown key \"%s\" parsing controller "
931 if (reason
== OFPR_ACTION
&& controller_id
== 0 && !userdata
&& !pause
) {
932 struct ofpact_output
*output
;
934 output
= ofpact_put_OUTPUT(ofpacts
);
935 output
->port
= OFPP_CONTROLLER
;
936 output
->max_len
= max_len
;
938 struct ofpact_controller
*controller
;
940 controller
= ofpact_put_CONTROLLER(ofpacts
);
941 controller
->max_len
= max_len
;
942 controller
->reason
= reason
;
943 controller
->controller_id
= controller_id
;
944 controller
->pause
= pause
;
947 size_t start_ofs
= ofpacts
->size
;
948 const char *end
= ofpbuf_put_hex(ofpacts
, userdata
, NULL
);
950 return xstrdup("bad hex digit in `controller' "
951 "action `userdata'");
953 size_t userdata_len
= ofpacts
->size
- start_ofs
;
954 controller
= ofpacts
->header
;
955 controller
->userdata_len
= userdata_len
;
957 ofpact_finish_CONTROLLER(ofpacts
, &controller
);
964 format_hex_arg(struct ds
*s
, const uint8_t *data
, size_t len
)
966 for (size_t i
= 0; i
< len
; i
++) {
970 ds_put_format(s
, "%02"PRIx8
, data
[i
]);
975 format_CONTROLLER(const struct ofpact_controller
*a
,
976 const struct ofputil_port_map
*port_map OVS_UNUSED
,
979 if (a
->reason
== OFPR_ACTION
&& !a
->controller_id
&& !a
->userdata_len
981 ds_put_format(s
, "%sCONTROLLER:%s%"PRIu16
,
982 colors
.special
, colors
.end
, a
->max_len
);
984 enum ofp_packet_in_reason reason
= a
->reason
;
986 ds_put_format(s
, "%scontroller(%s", colors
.paren
, colors
.end
);
987 if (reason
!= OFPR_ACTION
) {
988 char reasonbuf
[OFPUTIL_PACKET_IN_REASON_BUFSIZE
];
990 ds_put_format(s
, "%sreason=%s%s,", colors
.param
, colors
.end
,
991 ofputil_packet_in_reason_to_string(
992 reason
, reasonbuf
, sizeof reasonbuf
));
994 if (a
->max_len
!= UINT16_MAX
) {
995 ds_put_format(s
, "%smax_len=%s%"PRIu16
",",
996 colors
.param
, colors
.end
, a
->max_len
);
998 if (a
->controller_id
!= 0) {
999 ds_put_format(s
, "%sid=%s%"PRIu16
",",
1000 colors
.param
, colors
.end
, a
->controller_id
);
1002 if (a
->userdata_len
) {
1003 ds_put_format(s
, "%suserdata=%s", colors
.param
, colors
.end
);
1004 format_hex_arg(s
, a
->userdata
, a
->userdata_len
);
1005 ds_put_char(s
, ',');
1008 ds_put_format(s
, "%spause%s,", colors
.value
, colors
.end
);
1011 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
1015 /* Enqueue action. */
1016 struct ofp10_action_enqueue
{
1017 ovs_be16 type
; /* OFPAT10_ENQUEUE. */
1018 ovs_be16 len
; /* Len is 16. */
1019 ovs_be16 port
; /* Port that queue belongs. Should
1020 refer to a valid physical port
1021 (i.e. < OFPP_MAX) or OFPP_IN_PORT. */
1022 uint8_t pad
[6]; /* Pad for 64-bit alignment. */
1023 ovs_be32 queue_id
; /* Where to enqueue the packets. */
1025 OFP_ASSERT(sizeof(struct ofp10_action_enqueue
) == 16);
1028 decode_OFPAT_RAW10_ENQUEUE(const struct ofp10_action_enqueue
*oae
,
1029 enum ofp_version ofp_version OVS_UNUSED
,
1032 struct ofpact_enqueue
*enqueue
;
1034 enqueue
= ofpact_put_ENQUEUE(out
);
1035 enqueue
->port
= u16_to_ofp(ntohs(oae
->port
));
1036 enqueue
->queue
= ntohl(oae
->queue_id
);
1037 if (ofp_to_u16(enqueue
->port
) >= ofp_to_u16(OFPP_MAX
)
1038 && enqueue
->port
!= OFPP_IN_PORT
1039 && enqueue
->port
!= OFPP_LOCAL
) {
1040 return OFPERR_OFPBAC_BAD_OUT_PORT
;
1046 encode_ENQUEUE(const struct ofpact_enqueue
*enqueue
,
1047 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1049 if (ofp_version
== OFP10_VERSION
) {
1050 struct ofp10_action_enqueue
*oae
;
1052 oae
= put_OFPAT10_ENQUEUE(out
);
1053 oae
->port
= htons(ofp_to_u16(enqueue
->port
));
1054 oae
->queue_id
= htonl(enqueue
->queue
);
1056 put_OFPAT_SET_QUEUE(out
, ofp_version
, enqueue
->queue
);
1058 struct ofp11_action_output
*oao
= put_OFPAT11_OUTPUT(out
);
1059 oao
->port
= ofputil_port_to_ofp11(enqueue
->port
);
1060 oao
->max_len
= OVS_BE16_MAX
;
1062 put_NXAST_POP_QUEUE(out
);
1066 static char * OVS_WARN_UNUSED_RESULT
1067 parse_ENQUEUE(char *arg
,
1068 const struct ofputil_port_map
*port_map
,
1069 struct ofpbuf
*ofpacts
,
1070 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1073 char *port
= strtok_r(arg
, ":q,", &sp
);
1074 char *queue
= strtok_r(NULL
, "", &sp
);
1075 struct ofpact_enqueue
*enqueue
;
1077 if (port
== NULL
|| queue
== NULL
) {
1078 return xstrdup("\"enqueue\" syntax is \"enqueue:PORT:QUEUE\" or "
1079 "\"enqueue(PORT,QUEUE)\"");
1082 enqueue
= ofpact_put_ENQUEUE(ofpacts
);
1083 if (!ofputil_port_from_string(port
, port_map
, &enqueue
->port
)) {
1084 return xasprintf("%s: enqueue to unknown port", port
);
1086 return str_to_u32(queue
, &enqueue
->queue
);
1090 format_ENQUEUE(const struct ofpact_enqueue
*a
,
1091 const struct ofputil_port_map
*port_map
, struct ds
*s
)
1093 ds_put_format(s
, "%senqueue:%s", colors
.param
, colors
.end
);
1094 ofputil_format_port(a
->port
, port_map
, s
);
1095 ds_put_format(s
, ":%"PRIu32
, a
->queue
);
1098 /* Action structure for NXAST_OUTPUT_REG.
1100 * Outputs to the OpenFlow port number written to src[ofs:ofs+nbits].
1102 * The format and semantics of 'src' and 'ofs_nbits' are similar to those for
1103 * the NXAST_REG_LOAD action.
1105 * The acceptable nxm_header values for 'src' are the same as the acceptable
1106 * nxm_header values for the 'src' field of NXAST_REG_MOVE.
1108 * The 'max_len' field indicates the number of bytes to send when the chosen
1109 * port is OFPP_CONTROLLER. Its semantics are equivalent to the 'max_len'
1110 * field of OFPAT_OUTPUT.
1112 * The 'zero' field is required to be zeroed for forward compatibility. */
1113 struct nx_action_output_reg
{
1114 ovs_be16 type
; /* OFPAT_VENDOR. */
1115 ovs_be16 len
; /* 24. */
1116 ovs_be32 vendor
; /* NX_VENDOR_ID. */
1117 ovs_be16 subtype
; /* NXAST_OUTPUT_REG. */
1119 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
1120 ovs_be32 src
; /* Source. */
1122 ovs_be16 max_len
; /* Max length to send to controller. */
1124 uint8_t zero
[6]; /* Reserved, must be zero. */
1126 OFP_ASSERT(sizeof(struct nx_action_output_reg
) == 24);
1128 /* Action structure for NXAST_OUTPUT_REG2.
1130 * Like the NXAST_OUTPUT_REG but organized so that there is room for a 64-bit
1131 * experimenter OXM as 'src'.
1133 struct nx_action_output_reg2
{
1134 ovs_be16 type
; /* OFPAT_VENDOR. */
1135 ovs_be16 len
; /* 24. */
1136 ovs_be32 vendor
; /* NX_VENDOR_ID. */
1137 ovs_be16 subtype
; /* NXAST_OUTPUT_REG2. */
1139 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
1140 ovs_be16 max_len
; /* Max length to send to controller. */
1143 * - 'src', as an OXM/NXM header (either 4 or 8 bytes).
1144 * - Enough 0-bytes to pad the action out to 24 bytes. */
1147 OFP_ASSERT(sizeof(struct nx_action_output_reg2
) == 24);
1150 decode_NXAST_RAW_OUTPUT_REG(const struct nx_action_output_reg
*naor
,
1151 enum ofp_version ofp_version OVS_UNUSED
,
1152 const struct vl_mff_map
*vl_mff_map
,
1153 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
1155 struct ofpact_output_reg
*output_reg
;
1158 if (!is_all_zeros(naor
->zero
, sizeof naor
->zero
)) {
1159 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1162 output_reg
= ofpact_put_OUTPUT_REG(out
);
1163 output_reg
->ofpact
.raw
= NXAST_RAW_OUTPUT_REG
;
1164 output_reg
->src
.ofs
= nxm_decode_ofs(naor
->ofs_nbits
);
1165 output_reg
->src
.n_bits
= nxm_decode_n_bits(naor
->ofs_nbits
);
1166 output_reg
->max_len
= ntohs(naor
->max_len
);
1167 error
= mf_vl_mff_mf_from_nxm_header(ntohl(naor
->src
), vl_mff_map
,
1168 &output_reg
->src
.field
, tlv_bitmap
);
1173 return mf_check_src(&output_reg
->src
, NULL
);
1177 decode_NXAST_RAW_OUTPUT_REG2(const struct nx_action_output_reg2
*naor
,
1178 enum ofp_version ofp_version OVS_UNUSED
,
1179 const struct vl_mff_map
*vl_mff_map
,
1180 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
1182 struct ofpact_output_reg
*output_reg
;
1185 output_reg
= ofpact_put_OUTPUT_REG(out
);
1186 output_reg
->ofpact
.raw
= NXAST_RAW_OUTPUT_REG2
;
1187 output_reg
->src
.ofs
= nxm_decode_ofs(naor
->ofs_nbits
);
1188 output_reg
->src
.n_bits
= nxm_decode_n_bits(naor
->ofs_nbits
);
1189 output_reg
->max_len
= ntohs(naor
->max_len
);
1191 struct ofpbuf b
= ofpbuf_const_initializer(naor
, ntohs(naor
->len
));
1192 ofpbuf_pull(&b
, OBJECT_OFFSETOF(naor
, pad
));
1194 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &output_reg
->src
.field
,
1200 if (!is_all_zeros(b
.data
, b
.size
)) {
1201 return OFPERR_NXBRC_MUST_BE_ZERO
;
1204 return mf_check_src(&output_reg
->src
, NULL
);
1208 encode_OUTPUT_REG(const struct ofpact_output_reg
*output_reg
,
1209 enum ofp_version ofp_version OVS_UNUSED
,
1212 /* If 'output_reg' came in as an NXAST_RAW_OUTPUT_REG2 action, or if it
1213 * cannot be encoded in the older form, encode it as
1214 * NXAST_RAW_OUTPUT_REG2. */
1215 if (output_reg
->ofpact
.raw
== NXAST_RAW_OUTPUT_REG2
1216 || !mf_nxm_header(output_reg
->src
.field
->id
)) {
1217 struct nx_action_output_reg2
*naor
= put_NXAST_OUTPUT_REG2(out
);
1218 size_t size
= out
->size
;
1220 naor
->ofs_nbits
= nxm_encode_ofs_nbits(output_reg
->src
.ofs
,
1221 output_reg
->src
.n_bits
);
1222 naor
->max_len
= htons(output_reg
->max_len
);
1224 out
->size
= size
- sizeof naor
->pad
;
1225 nx_put_mff_header(out
, output_reg
->src
.field
, 0, false);
1228 struct nx_action_output_reg
*naor
= put_NXAST_OUTPUT_REG(out
);
1230 naor
->ofs_nbits
= nxm_encode_ofs_nbits(output_reg
->src
.ofs
,
1231 output_reg
->src
.n_bits
);
1232 naor
->src
= htonl(nxm_header_from_mff(output_reg
->src
.field
));
1233 naor
->max_len
= htons(output_reg
->max_len
);
1237 static char * OVS_WARN_UNUSED_RESULT
1238 parse_OUTPUT_REG(const char *arg
,
1239 const struct ofputil_port_map
*port_map
,
1240 struct ofpbuf
*ofpacts
,
1241 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1243 return parse_OUTPUT(arg
, port_map
, ofpacts
, usable_protocols
);
1247 format_OUTPUT_REG(const struct ofpact_output_reg
*a
,
1248 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1251 ds_put_format(s
, "%soutput:%s", colors
.special
, colors
.end
);
1252 mf_format_subfield(&a
->src
, s
);
1255 /* Action structure for NXAST_BUNDLE and NXAST_BUNDLE_LOAD.
1257 * The bundle actions choose a slave from a supplied list of options.
1258 * NXAST_BUNDLE outputs to its selection. NXAST_BUNDLE_LOAD writes its
1259 * selection to a register.
1261 * The list of possible slaves follows the nx_action_bundle structure. The size
1262 * of each slave is governed by its type as indicated by the 'slave_type'
1263 * parameter. The list of slaves should be padded at its end with zeros to make
1264 * the total length of the action a multiple of 8.
1266 * Switches infer from the 'slave_type' parameter the size of each slave. All
1267 * implementations must support the NXM_OF_IN_PORT 'slave_type' which indicates
1268 * that the slaves are OpenFlow port numbers with NXM_LENGTH(NXM_OF_IN_PORT) ==
1269 * 2 byte width. Switches should reject actions which indicate unknown or
1270 * unsupported slave types.
1272 * Switches use a strategy dictated by the 'algorithm' parameter to choose a
1273 * slave. If the switch does not support the specified 'algorithm' parameter,
1274 * it should reject the action.
1276 * Several algorithms take into account liveness when selecting slaves. The
1277 * liveness of a slave is implementation defined (with one exception), but will
1278 * generally take into account things like its carrier status and the results
1279 * of any link monitoring protocols which happen to be running on it. In order
1280 * to give controllers a place-holder value, the OFPP_NONE port is always
1281 * considered live, that is, NXAST_BUNDLE_LOAD stores OFPP_NONE in the output
1282 * register if no slave is live.
1284 * Some slave selection strategies require the use of a hash function, in which
1285 * case the 'fields' and 'basis' parameters should be populated. The 'fields'
1286 * parameter (one of NX_HASH_FIELDS_*) designates which parts of the flow to
1287 * hash. Refer to the definition of "enum nx_hash_fields" for details. The
1288 * 'basis' parameter is used as a universal hash parameter. Different values
1289 * of 'basis' yield different hash results.
1291 * The 'zero' parameter at the end of the action structure is reserved for
1292 * future use. Switches are required to reject actions which have nonzero
1293 * bytes in the 'zero' field.
1295 * NXAST_BUNDLE actions should have 'ofs_nbits' and 'dst' zeroed. Switches
1296 * should reject actions which have nonzero bytes in either of these fields.
1298 * NXAST_BUNDLE_LOAD stores the OpenFlow port number of the selected slave in
1299 * dst[ofs:ofs+n_bits]. The format and semantics of 'dst' and 'ofs_nbits' are
1300 * similar to those for the NXAST_REG_LOAD action. */
1301 struct nx_action_bundle
{
1302 ovs_be16 type
; /* OFPAT_VENDOR. */
1303 ovs_be16 len
; /* Length including slaves. */
1304 ovs_be32 vendor
; /* NX_VENDOR_ID. */
1305 ovs_be16 subtype
; /* NXAST_BUNDLE or NXAST_BUNDLE_LOAD. */
1307 /* Slave choice algorithm to apply to hash value. */
1308 ovs_be16 algorithm
; /* One of NX_BD_ALG_*. */
1310 /* What fields to hash and how. */
1311 ovs_be16 fields
; /* One of NX_HASH_FIELDS_*. */
1312 ovs_be16 basis
; /* Universal hash parameter. */
1314 ovs_be32 slave_type
; /* NXM_OF_IN_PORT. */
1315 ovs_be16 n_slaves
; /* Number of slaves. */
1317 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
1318 ovs_be32 dst
; /* Destination. */
1320 uint8_t zero
[4]; /* Reserved. Must be zero. */
1322 OFP_ASSERT(sizeof(struct nx_action_bundle
) == 32);
1325 decode_bundle(bool load
, const struct nx_action_bundle
*nab
,
1326 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
1327 struct ofpbuf
*ofpacts
)
1329 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
1330 struct ofpact_bundle
*bundle
;
1331 uint32_t slave_type
;
1332 size_t slaves_size
, i
;
1335 bundle
= ofpact_put_BUNDLE(ofpacts
);
1337 bundle
->n_slaves
= ntohs(nab
->n_slaves
);
1338 bundle
->basis
= ntohs(nab
->basis
);
1339 bundle
->fields
= ntohs(nab
->fields
);
1340 bundle
->algorithm
= ntohs(nab
->algorithm
);
1341 slave_type
= ntohl(nab
->slave_type
);
1342 slaves_size
= ntohs(nab
->len
) - sizeof *nab
;
1344 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1345 if (!flow_hash_fields_valid(bundle
->fields
)) {
1346 VLOG_WARN_RL(&rl
, "unsupported fields %d", (int) bundle
->fields
);
1347 } else if (bundle
->n_slaves
> BUNDLE_MAX_SLAVES
) {
1348 VLOG_WARN_RL(&rl
, "too many slaves");
1349 } else if (bundle
->algorithm
!= NX_BD_ALG_HRW
1350 && bundle
->algorithm
!= NX_BD_ALG_ACTIVE_BACKUP
) {
1351 VLOG_WARN_RL(&rl
, "unsupported algorithm %d", (int) bundle
->algorithm
);
1352 } else if (slave_type
!= mf_nxm_header(MFF_IN_PORT
)) {
1353 VLOG_WARN_RL(&rl
, "unsupported slave type %"PRIu32
, slave_type
);
1358 if (!is_all_zeros(nab
->zero
, sizeof nab
->zero
)) {
1359 VLOG_WARN_RL(&rl
, "reserved field is nonzero");
1360 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1364 bundle
->dst
.ofs
= nxm_decode_ofs(nab
->ofs_nbits
);
1365 bundle
->dst
.n_bits
= nxm_decode_n_bits(nab
->ofs_nbits
);
1366 error
= mf_vl_mff_mf_from_nxm_header(ntohl(nab
->dst
), vl_mff_map
,
1367 &bundle
->dst
.field
, tlv_bitmap
);
1372 if (bundle
->dst
.n_bits
< 16) {
1373 VLOG_WARN_RL(&rl
, "bundle_load action requires at least 16 bit "
1375 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1378 if (nab
->ofs_nbits
|| nab
->dst
) {
1379 VLOG_WARN_RL(&rl
, "bundle action has nonzero reserved fields");
1380 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
1384 if (slaves_size
< bundle
->n_slaves
* sizeof(ovs_be16
)) {
1385 VLOG_WARN_RL(&rl
, "Nicira action %s only has %"PRIuSIZE
" bytes "
1386 "allocated for slaves. %"PRIuSIZE
" bytes are required "
1388 load
? "bundle_load" : "bundle", slaves_size
,
1389 bundle
->n_slaves
* sizeof(ovs_be16
), bundle
->n_slaves
);
1390 error
= OFPERR_OFPBAC_BAD_LEN
;
1393 for (i
= 0; i
< bundle
->n_slaves
; i
++) {
1394 ofp_port_t ofp_port
= u16_to_ofp(ntohs(((ovs_be16
*)(nab
+ 1))[i
]));
1395 ofpbuf_put(ofpacts
, &ofp_port
, sizeof ofp_port
);
1396 bundle
= ofpacts
->header
;
1399 ofpact_finish_BUNDLE(ofpacts
, &bundle
);
1401 error
= bundle_check(bundle
, OFPP_MAX
, NULL
);
1407 decode_NXAST_RAW_BUNDLE(const struct nx_action_bundle
*nab
,
1408 enum ofp_version ofp_version OVS_UNUSED
,
1411 return decode_bundle(false, nab
, NULL
, NULL
, out
);
1415 decode_NXAST_RAW_BUNDLE_LOAD(const struct nx_action_bundle
*nab
,
1416 enum ofp_version ofp_version OVS_UNUSED
,
1417 const struct vl_mff_map
*vl_mff_map
,
1418 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
1420 return decode_bundle(true, nab
, vl_mff_map
, tlv_bitmap
, out
);
1424 encode_BUNDLE(const struct ofpact_bundle
*bundle
,
1425 enum ofp_version ofp_version OVS_UNUSED
,
1428 int slaves_len
= ROUND_UP(2 * bundle
->n_slaves
, OFP_ACTION_ALIGN
);
1429 struct nx_action_bundle
*nab
;
1433 nab
= (bundle
->dst
.field
1434 ? put_NXAST_BUNDLE_LOAD(out
)
1435 : put_NXAST_BUNDLE(out
));
1436 nab
->len
= htons(ntohs(nab
->len
) + slaves_len
);
1437 nab
->algorithm
= htons(bundle
->algorithm
);
1438 nab
->fields
= htons(bundle
->fields
);
1439 nab
->basis
= htons(bundle
->basis
);
1440 nab
->slave_type
= htonl(mf_nxm_header(MFF_IN_PORT
));
1441 nab
->n_slaves
= htons(bundle
->n_slaves
);
1442 if (bundle
->dst
.field
) {
1443 nab
->ofs_nbits
= nxm_encode_ofs_nbits(bundle
->dst
.ofs
,
1444 bundle
->dst
.n_bits
);
1445 nab
->dst
= htonl(nxm_header_from_mff(bundle
->dst
.field
));
1448 slaves
= ofpbuf_put_zeros(out
, slaves_len
);
1449 for (i
= 0; i
< bundle
->n_slaves
; i
++) {
1450 slaves
[i
] = htons(ofp_to_u16(bundle
->slaves
[i
]));
1454 static char * OVS_WARN_UNUSED_RESULT
1455 parse_BUNDLE(const char *arg
, const struct ofputil_port_map
*port_map
,
1456 struct ofpbuf
*ofpacts
,
1457 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1459 return bundle_parse(arg
, port_map
, ofpacts
);
1462 static char * OVS_WARN_UNUSED_RESULT
1463 parse_bundle_load(const char *arg
, const struct ofputil_port_map
*port_map
,
1464 struct ofpbuf
*ofpacts
)
1466 return bundle_parse_load(arg
, port_map
, ofpacts
);
1470 format_BUNDLE(const struct ofpact_bundle
*a
,
1471 const struct ofputil_port_map
*port_map
, struct ds
*s
)
1473 bundle_format(a
, port_map
, s
);
1476 /* Set VLAN actions. */
1479 decode_set_vlan_vid(uint16_t vid
, bool push_vlan_if_needed
, struct ofpbuf
*out
)
1482 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1484 struct ofpact_vlan_vid
*vlan_vid
= ofpact_put_SET_VLAN_VID(out
);
1485 vlan_vid
->vlan_vid
= vid
;
1486 vlan_vid
->push_vlan_if_needed
= push_vlan_if_needed
;
1492 decode_OFPAT_RAW10_SET_VLAN_VID(uint16_t vid
,
1493 enum ofp_version ofp_version OVS_UNUSED
,
1496 return decode_set_vlan_vid(vid
, true, out
);
1500 decode_OFPAT_RAW11_SET_VLAN_VID(uint16_t vid
,
1501 enum ofp_version ofp_version OVS_UNUSED
,
1504 return decode_set_vlan_vid(vid
, false, out
);
1508 encode_SET_VLAN_VID(const struct ofpact_vlan_vid
*vlan_vid
,
1509 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1511 uint16_t vid
= vlan_vid
->vlan_vid
;
1513 /* Push a VLAN tag, if none is present and this form of the action calls
1514 * for such a feature. */
1515 if (ofp_version
> OFP10_VERSION
1516 && vlan_vid
->push_vlan_if_needed
1517 && !vlan_vid
->flow_has_vlan
) {
1518 put_OFPAT11_PUSH_VLAN(out
, htons(ETH_TYPE_VLAN_8021Q
));
1521 if (ofp_version
== OFP10_VERSION
) {
1522 put_OFPAT10_SET_VLAN_VID(out
, vid
);
1523 } else if (ofp_version
== OFP11_VERSION
) {
1524 put_OFPAT11_SET_VLAN_VID(out
, vid
);
1526 put_set_field(out
, ofp_version
, MFF_VLAN_VID
, vid
| OFPVID12_PRESENT
);
1530 static char * OVS_WARN_UNUSED_RESULT
1531 parse_set_vlan_vid(char *arg
,
1532 struct ofpbuf
*ofpacts
, bool push_vlan_if_needed
)
1534 struct ofpact_vlan_vid
*vlan_vid
;
1538 error
= str_to_u16(arg
, "VLAN VID", &vid
);
1543 if (vid
& ~VLAN_VID_MASK
) {
1544 return xasprintf("%s: not a valid VLAN VID", arg
);
1546 vlan_vid
= ofpact_put_SET_VLAN_VID(ofpacts
);
1547 vlan_vid
->vlan_vid
= vid
;
1548 vlan_vid
->push_vlan_if_needed
= push_vlan_if_needed
;
1552 static char * OVS_WARN_UNUSED_RESULT
1553 parse_SET_VLAN_VID(char *arg
,
1554 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1555 struct ofpbuf
*ofpacts
,
1556 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1558 return parse_set_vlan_vid(arg
, ofpacts
, false);
1562 format_SET_VLAN_VID(const struct ofpact_vlan_vid
*a
,
1563 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1566 ds_put_format(s
, "%s%s:%s%"PRIu16
, colors
.param
,
1567 a
->push_vlan_if_needed
? "mod_vlan_vid" : "set_vlan_vid",
1568 colors
.end
, a
->vlan_vid
);
1571 /* Set PCP actions. */
1574 decode_set_vlan_pcp(uint8_t pcp
, bool push_vlan_if_needed
, struct ofpbuf
*out
)
1577 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1579 struct ofpact_vlan_pcp
*vlan_pcp
= ofpact_put_SET_VLAN_PCP(out
);
1580 vlan_pcp
->vlan_pcp
= pcp
;
1581 vlan_pcp
->push_vlan_if_needed
= push_vlan_if_needed
;
1587 decode_OFPAT_RAW10_SET_VLAN_PCP(uint8_t pcp
,
1588 enum ofp_version ofp_version OVS_UNUSED
,
1591 return decode_set_vlan_pcp(pcp
, true, out
);
1595 decode_OFPAT_RAW11_SET_VLAN_PCP(uint8_t pcp
,
1596 enum ofp_version ofp_version OVS_UNUSED
,
1599 return decode_set_vlan_pcp(pcp
, false, out
);
1603 encode_SET_VLAN_PCP(const struct ofpact_vlan_pcp
*vlan_pcp
,
1604 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1606 uint8_t pcp
= vlan_pcp
->vlan_pcp
;
1608 /* Push a VLAN tag, if none is present and this form of the action calls
1609 * for such a feature. */
1610 if (ofp_version
> OFP10_VERSION
1611 && vlan_pcp
->push_vlan_if_needed
1612 && !vlan_pcp
->flow_has_vlan
) {
1613 put_OFPAT11_PUSH_VLAN(out
, htons(ETH_TYPE_VLAN_8021Q
));
1616 if (ofp_version
== OFP10_VERSION
) {
1617 put_OFPAT10_SET_VLAN_PCP(out
, pcp
);
1618 } else if (ofp_version
== OFP11_VERSION
) {
1619 put_OFPAT11_SET_VLAN_PCP(out
, pcp
);
1621 put_set_field(out
, ofp_version
, MFF_VLAN_PCP
, pcp
);
1625 static char * OVS_WARN_UNUSED_RESULT
1626 parse_set_vlan_pcp(char *arg
,
1627 struct ofpbuf
*ofpacts
, bool push_vlan_if_needed
)
1629 struct ofpact_vlan_pcp
*vlan_pcp
;
1633 error
= str_to_u8(arg
, "VLAN PCP", &pcp
);
1639 return xasprintf("%s: not a valid VLAN PCP", arg
);
1641 vlan_pcp
= ofpact_put_SET_VLAN_PCP(ofpacts
);
1642 vlan_pcp
->vlan_pcp
= pcp
;
1643 vlan_pcp
->push_vlan_if_needed
= push_vlan_if_needed
;
1647 static char * OVS_WARN_UNUSED_RESULT
1648 parse_SET_VLAN_PCP(char *arg
,
1649 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1650 struct ofpbuf
*ofpacts
,
1651 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1653 return parse_set_vlan_pcp(arg
, ofpacts
, false);
1657 format_SET_VLAN_PCP(const struct ofpact_vlan_pcp
*a
,
1658 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1661 ds_put_format(s
, "%s%s:%s%"PRIu8
, colors
.param
,
1662 a
->push_vlan_if_needed
? "mod_vlan_pcp" : "set_vlan_pcp",
1663 colors
.end
, a
->vlan_pcp
);
1666 /* Strip VLAN actions. */
1669 decode_OFPAT_RAW10_STRIP_VLAN(struct ofpbuf
*out
)
1671 ofpact_put_STRIP_VLAN(out
)->ofpact
.raw
= OFPAT_RAW10_STRIP_VLAN
;
1676 decode_OFPAT_RAW11_POP_VLAN(struct ofpbuf
*out
)
1678 ofpact_put_STRIP_VLAN(out
)->ofpact
.raw
= OFPAT_RAW11_POP_VLAN
;
1683 encode_STRIP_VLAN(const struct ofpact_null
*null OVS_UNUSED
,
1684 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1686 if (ofp_version
== OFP10_VERSION
) {
1687 put_OFPAT10_STRIP_VLAN(out
);
1689 put_OFPAT11_POP_VLAN(out
);
1693 static char * OVS_WARN_UNUSED_RESULT
1694 parse_STRIP_VLAN(char *arg OVS_UNUSED
,
1695 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1696 struct ofpbuf
*ofpacts
,
1697 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1699 ofpact_put_STRIP_VLAN(ofpacts
)->ofpact
.raw
= OFPAT_RAW10_STRIP_VLAN
;
1703 static char * OVS_WARN_UNUSED_RESULT
1704 parse_pop_vlan(struct ofpbuf
*ofpacts
)
1706 ofpact_put_STRIP_VLAN(ofpacts
)->ofpact
.raw
= OFPAT_RAW11_POP_VLAN
;
1711 format_STRIP_VLAN(const struct ofpact_null
*a
,
1712 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1715 ds_put_format(s
, (a
->ofpact
.raw
== OFPAT_RAW11_POP_VLAN
1717 : "%sstrip_vlan%s"),
1718 colors
.value
, colors
.end
);
1721 /* Push VLAN action. */
1724 decode_OFPAT_RAW11_PUSH_VLAN(ovs_be16 eth_type
,
1725 enum ofp_version ofp_version OVS_UNUSED
,
1728 struct ofpact_push_vlan
*push_vlan
;
1729 if (!eth_type_vlan(eth_type
)) {
1730 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1732 push_vlan
= ofpact_put_PUSH_VLAN(out
);
1733 push_vlan
->ethertype
= eth_type
;
1738 encode_PUSH_VLAN(const struct ofpact_push_vlan
*push_vlan
,
1739 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1741 if (ofp_version
== OFP10_VERSION
) {
1742 /* PUSH is a side effect of a SET_VLAN_VID/PCP, which should
1743 * follow this action. */
1745 put_OFPAT11_PUSH_VLAN(out
, push_vlan
->ethertype
);
1749 static char * OVS_WARN_UNUSED_RESULT
1750 parse_PUSH_VLAN(char *arg
,
1751 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1752 struct ofpbuf
*ofpacts
,
1753 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1755 struct ofpact_push_vlan
*push_vlan
;
1759 *usable_protocols
&= OFPUTIL_P_OF11_UP
;
1760 error
= str_to_u16(arg
, "ethertype", ðertype
);
1765 if (!eth_type_vlan(htons(ethertype
))) {
1766 return xasprintf("%s: not a valid VLAN ethertype", arg
);
1768 push_vlan
= ofpact_put_PUSH_VLAN(ofpacts
);
1769 push_vlan
->ethertype
= htons(ethertype
);
1774 format_PUSH_VLAN(const struct ofpact_push_vlan
*push_vlan
,
1775 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1778 ds_put_format(s
, "%spush_vlan:%s%#"PRIx16
,
1779 colors
.param
, colors
.end
, ntohs(push_vlan
->ethertype
));
1782 /* Action structure for OFPAT10_SET_DL_SRC/DST and OFPAT11_SET_DL_SRC/DST. */
1783 struct ofp_action_dl_addr
{
1784 ovs_be16 type
; /* Type. */
1785 ovs_be16 len
; /* Length is 16. */
1786 struct eth_addr dl_addr
; /* Ethernet address. */
1789 OFP_ASSERT(sizeof(struct ofp_action_dl_addr
) == 16);
1792 decode_OFPAT_RAW_SET_DL_SRC(const struct ofp_action_dl_addr
*a
,
1793 enum ofp_version ofp_version OVS_UNUSED
,
1796 ofpact_put_SET_ETH_SRC(out
)->mac
= a
->dl_addr
;
1801 decode_OFPAT_RAW_SET_DL_DST(const struct ofp_action_dl_addr
*a
,
1802 enum ofp_version ofp_version OVS_UNUSED
,
1805 ofpact_put_SET_ETH_DST(out
)->mac
= a
->dl_addr
;
1810 encode_SET_ETH_addr(const struct ofpact_mac
*mac
, enum ofp_version ofp_version
,
1811 enum ofp_raw_action_type raw
, enum mf_field_id field
,
1814 if (ofp_version
< OFP12_VERSION
) {
1815 struct ofp_action_dl_addr
*oada
;
1817 oada
= ofpact_put_raw(out
, ofp_version
, raw
, 0);
1818 oada
->dl_addr
= mac
->mac
;
1820 put_set_field(out
, ofp_version
, field
, eth_addr_to_uint64(mac
->mac
));
1825 encode_SET_ETH_SRC(const struct ofpact_mac
*mac
, enum ofp_version ofp_version
,
1828 encode_SET_ETH_addr(mac
, ofp_version
, OFPAT_RAW_SET_DL_SRC
, MFF_ETH_SRC
,
1834 encode_SET_ETH_DST(const struct ofpact_mac
*mac
,
1835 enum ofp_version ofp_version
,
1838 encode_SET_ETH_addr(mac
, ofp_version
, OFPAT_RAW_SET_DL_DST
, MFF_ETH_DST
,
1843 static char * OVS_WARN_UNUSED_RESULT
1844 parse_SET_ETH_SRC(char *arg
,
1845 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1846 struct ofpbuf
*ofpacts
,
1847 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1849 return str_to_mac(arg
, &ofpact_put_SET_ETH_SRC(ofpacts
)->mac
);
1852 static char * OVS_WARN_UNUSED_RESULT
1853 parse_SET_ETH_DST(char *arg
,
1854 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1855 struct ofpbuf
*ofpacts
,
1856 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1858 return str_to_mac(arg
, &ofpact_put_SET_ETH_DST(ofpacts
)->mac
);
1862 format_SET_ETH_SRC(const struct ofpact_mac
*a
,
1863 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1866 ds_put_format(s
, "%smod_dl_src:%s"ETH_ADDR_FMT
,
1867 colors
.param
, colors
.end
, ETH_ADDR_ARGS(a
->mac
));
1871 format_SET_ETH_DST(const struct ofpact_mac
*a
,
1872 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1875 ds_put_format(s
, "%smod_dl_dst:%s"ETH_ADDR_FMT
,
1876 colors
.param
, colors
.end
, ETH_ADDR_ARGS(a
->mac
));
1879 /* Set IPv4 address actions. */
1882 decode_OFPAT_RAW_SET_NW_SRC(ovs_be32 ipv4
,
1883 enum ofp_version ofp_version OVS_UNUSED
,
1886 ofpact_put_SET_IPV4_SRC(out
)->ipv4
= ipv4
;
1891 decode_OFPAT_RAW_SET_NW_DST(ovs_be32 ipv4
,
1892 enum ofp_version ofp_version OVS_UNUSED
,
1895 ofpact_put_SET_IPV4_DST(out
)->ipv4
= ipv4
;
1900 encode_SET_IPV4_addr(const struct ofpact_ipv4
*ipv4
,
1901 enum ofp_version ofp_version
,
1902 enum ofp_raw_action_type raw
, enum mf_field_id field
,
1905 ovs_be32 addr
= ipv4
->ipv4
;
1906 if (ofp_version
< OFP12_VERSION
) {
1907 ofpact_put_raw(out
, ofp_version
, raw
, ntohl(addr
));
1909 put_set_field(out
, ofp_version
, field
, ntohl(addr
));
1914 encode_SET_IPV4_SRC(const struct ofpact_ipv4
*ipv4
,
1915 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1917 encode_SET_IPV4_addr(ipv4
, ofp_version
, OFPAT_RAW_SET_NW_SRC
, MFF_IPV4_SRC
,
1922 encode_SET_IPV4_DST(const struct ofpact_ipv4
*ipv4
,
1923 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1925 encode_SET_IPV4_addr(ipv4
, ofp_version
, OFPAT_RAW_SET_NW_DST
, MFF_IPV4_DST
,
1929 static char * OVS_WARN_UNUSED_RESULT
1930 parse_SET_IPV4_SRC(char *arg
,
1931 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1932 struct ofpbuf
*ofpacts
,
1933 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1935 return str_to_ip(arg
, &ofpact_put_SET_IPV4_SRC(ofpacts
)->ipv4
);
1938 static char * OVS_WARN_UNUSED_RESULT
1939 parse_SET_IPV4_DST(char *arg
,
1940 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1941 struct ofpbuf
*ofpacts
,
1942 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
1944 return str_to_ip(arg
, &ofpact_put_SET_IPV4_DST(ofpacts
)->ipv4
);
1948 format_SET_IPV4_SRC(const struct ofpact_ipv4
*a
,
1949 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1952 ds_put_format(s
, "%smod_nw_src:%s"IP_FMT
,
1953 colors
.param
, colors
.end
, IP_ARGS(a
->ipv4
));
1957 format_SET_IPV4_DST(const struct ofpact_ipv4
*a
,
1958 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1961 ds_put_format(s
, "%smod_nw_dst:%s"IP_FMT
,
1962 colors
.param
, colors
.end
, IP_ARGS(a
->ipv4
));
1965 /* Set IPv4/v6 TOS actions. */
1968 decode_OFPAT_RAW_SET_NW_TOS(uint8_t dscp
,
1969 enum ofp_version ofp_version OVS_UNUSED
,
1972 if (dscp
& ~IP_DSCP_MASK
) {
1973 return OFPERR_OFPBAC_BAD_ARGUMENT
;
1975 ofpact_put_SET_IP_DSCP(out
)->dscp
= dscp
;
1981 encode_SET_IP_DSCP(const struct ofpact_dscp
*dscp
,
1982 enum ofp_version ofp_version
, struct ofpbuf
*out
)
1984 if (ofp_version
< OFP12_VERSION
) {
1985 put_OFPAT_SET_NW_TOS(out
, ofp_version
, dscp
->dscp
);
1987 put_set_field(out
, ofp_version
, MFF_IP_DSCP_SHIFTED
, dscp
->dscp
>> 2);
1991 static char * OVS_WARN_UNUSED_RESULT
1992 parse_SET_IP_DSCP(char *arg
,
1993 const struct ofputil_port_map
*port_map OVS_UNUSED
,
1994 struct ofpbuf
*ofpacts
,
1995 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
2000 error
= str_to_u8(arg
, "TOS", &tos
);
2005 if (tos
& ~IP_DSCP_MASK
) {
2006 return xasprintf("%s: not a valid TOS", arg
);
2008 ofpact_put_SET_IP_DSCP(ofpacts
)->dscp
= tos
;
2013 format_SET_IP_DSCP(const struct ofpact_dscp
*a
,
2014 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2017 ds_put_format(s
, "%smod_nw_tos:%s%d", colors
.param
, colors
.end
, a
->dscp
);
2020 /* Set IPv4/v6 ECN actions. */
2023 decode_OFPAT_RAW11_SET_NW_ECN(uint8_t ecn
,
2024 enum ofp_version ofp_version OVS_UNUSED
,
2027 if (ecn
& ~IP_ECN_MASK
) {
2028 return OFPERR_OFPBAC_BAD_ARGUMENT
;
2030 ofpact_put_SET_IP_ECN(out
)->ecn
= ecn
;
2036 encode_SET_IP_ECN(const struct ofpact_ecn
*ip_ecn
,
2037 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2039 uint8_t ecn
= ip_ecn
->ecn
;
2040 if (ofp_version
== OFP10_VERSION
) {
2041 struct mf_subfield dst
= { .field
= mf_from_id(MFF_IP_ECN
),
2042 .ofs
= 0, .n_bits
= 2 };
2043 put_reg_load(out
, &dst
, ecn
);
2044 } else if (ofp_version
== OFP11_VERSION
) {
2045 put_OFPAT11_SET_NW_ECN(out
, ecn
);
2047 put_set_field(out
, ofp_version
, MFF_IP_ECN
, ecn
);
2051 static char * OVS_WARN_UNUSED_RESULT
2052 parse_SET_IP_ECN(char *arg
,
2053 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2054 struct ofpbuf
*ofpacts
,
2055 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
2060 error
= str_to_u8(arg
, "ECN", &ecn
);
2065 if (ecn
& ~IP_ECN_MASK
) {
2066 return xasprintf("%s: not a valid ECN", arg
);
2068 ofpact_put_SET_IP_ECN(ofpacts
)->ecn
= ecn
;
2073 format_SET_IP_ECN(const struct ofpact_ecn
*a
,
2074 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2077 ds_put_format(s
, "%smod_nw_ecn:%s%d",
2078 colors
.param
, colors
.end
, a
->ecn
);
2081 /* Set IPv4/v6 TTL actions. */
2084 decode_OFPAT_RAW11_SET_NW_TTL(uint8_t ttl
,
2085 enum ofp_version ofp_version OVS_UNUSED
,
2088 ofpact_put_SET_IP_TTL(out
)->ttl
= ttl
;
2093 encode_SET_IP_TTL(const struct ofpact_ip_ttl
*ttl
,
2094 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2096 if (ofp_version
>= OFP11_VERSION
) {
2097 put_OFPAT11_SET_NW_TTL(out
, ttl
->ttl
);
2099 struct mf_subfield dst
= { .field
= mf_from_id(MFF_IP_TTL
),
2100 .ofs
= 0, .n_bits
= 8 };
2101 put_reg_load(out
, &dst
, ttl
->ttl
);
2105 static char * OVS_WARN_UNUSED_RESULT
2106 parse_SET_IP_TTL(char *arg
,
2107 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2108 struct ofpbuf
*ofpacts
,
2109 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
2114 error
= str_to_u8(arg
, "TTL", &ttl
);
2119 ofpact_put_SET_IP_TTL(ofpacts
)->ttl
= ttl
;
2124 format_SET_IP_TTL(const struct ofpact_ip_ttl
*a
,
2125 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2128 ds_put_format(s
, "%smod_nw_ttl:%s%d", colors
.param
, colors
.end
, a
->ttl
);
2131 /* Set TCP/UDP/SCTP port actions. */
2134 decode_OFPAT_RAW_SET_TP_SRC(ovs_be16 port
,
2135 enum ofp_version ofp_version OVS_UNUSED
,
2138 ofpact_put_SET_L4_SRC_PORT(out
)->port
= ntohs(port
);
2143 decode_OFPAT_RAW_SET_TP_DST(ovs_be16 port
,
2144 enum ofp_version ofp_version OVS_UNUSED
,
2147 ofpact_put_SET_L4_DST_PORT(out
)->port
= ntohs(port
);
2152 encode_SET_L4_port(const struct ofpact_l4_port
*l4_port
,
2153 enum ofp_version ofp_version
, enum ofp_raw_action_type raw
,
2154 enum mf_field_id field
, struct ofpbuf
*out
)
2156 uint16_t port
= l4_port
->port
;
2158 if (ofp_version
>= OFP12_VERSION
&& field
!= MFF_N_IDS
) {
2159 put_set_field(out
, ofp_version
, field
, port
);
2161 ofpact_put_raw(out
, ofp_version
, raw
, port
);
2166 encode_SET_L4_SRC_PORT(const struct ofpact_l4_port
*l4_port
,
2167 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2169 uint8_t proto
= l4_port
->flow_ip_proto
;
2170 enum mf_field_id field
= (proto
== IPPROTO_TCP
? MFF_TCP_SRC
2171 : proto
== IPPROTO_UDP
? MFF_UDP_SRC
2172 : proto
== IPPROTO_SCTP
? MFF_SCTP_SRC
2175 encode_SET_L4_port(l4_port
, ofp_version
, OFPAT_RAW_SET_TP_SRC
, field
, out
);
2179 encode_SET_L4_DST_PORT(const struct ofpact_l4_port
*l4_port
,
2180 enum ofp_version ofp_version
,
2183 uint8_t proto
= l4_port
->flow_ip_proto
;
2184 enum mf_field_id field
= (proto
== IPPROTO_TCP
? MFF_TCP_DST
2185 : proto
== IPPROTO_UDP
? MFF_UDP_DST
2186 : proto
== IPPROTO_SCTP
? MFF_SCTP_DST
2189 encode_SET_L4_port(l4_port
, ofp_version
, OFPAT_RAW_SET_TP_DST
, field
, out
);
2192 static char * OVS_WARN_UNUSED_RESULT
2193 parse_SET_L4_SRC_PORT(char *arg
,
2194 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2195 struct ofpbuf
*ofpacts
,
2196 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
2198 return str_to_u16(arg
, "source port",
2199 &ofpact_put_SET_L4_SRC_PORT(ofpacts
)->port
);
2202 static char * OVS_WARN_UNUSED_RESULT
2203 parse_SET_L4_DST_PORT(char *arg
,
2204 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2205 struct ofpbuf
*ofpacts
,
2206 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
2208 return str_to_u16(arg
, "destination port",
2209 &ofpact_put_SET_L4_DST_PORT(ofpacts
)->port
);
2213 format_SET_L4_SRC_PORT(const struct ofpact_l4_port
*a
,
2214 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2217 ds_put_format(s
, "%smod_tp_src:%s%d", colors
.param
, colors
.end
, a
->port
);
2221 format_SET_L4_DST_PORT(const struct ofpact_l4_port
*a
,
2222 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2225 ds_put_format(s
, "%smod_tp_dst:%s%d", colors
.param
, colors
.end
, a
->port
);
2228 /* Action structure for OFPAT_COPY_FIELD. */
2229 struct ofp15_action_copy_field
{
2230 ovs_be16 type
; /* OFPAT_COPY_FIELD. */
2231 ovs_be16 len
; /* Length is padded to 64 bits. */
2232 ovs_be16 n_bits
; /* Number of bits to copy. */
2233 ovs_be16 src_offset
; /* Starting bit offset in source. */
2234 ovs_be16 dst_offset
; /* Starting bit offset in destination. */
2237 * - OXM header for source field.
2238 * - OXM header for destination field.
2239 * - Padding with 0-bytes to a multiple of 8 bytes.
2240 * The "pad2" member is the beginning of the above. */
2243 OFP_ASSERT(sizeof(struct ofp15_action_copy_field
) == 16);
2245 /* Action structure for OpenFlow 1.3 extension copy-field action.. */
2246 struct onf_action_copy_field
{
2247 ovs_be16 type
; /* OFPAT_EXPERIMENTER. */
2248 ovs_be16 len
; /* Length is padded to 64 bits. */
2249 ovs_be32 experimenter
; /* ONF_VENDOR_ID. */
2250 ovs_be16 exp_type
; /* 3200. */
2251 uint8_t pad
[2]; /* Not used. */
2252 ovs_be16 n_bits
; /* Number of bits to copy. */
2253 ovs_be16 src_offset
; /* Starting bit offset in source. */
2254 ovs_be16 dst_offset
; /* Starting bit offset in destination. */
2255 uint8_t pad2
[2]; /* Not used. */
2257 * - OXM header for source field.
2258 * - OXM header for destination field.
2259 * - Padding with 0-bytes (either 0 or 4 of them) to a multiple of 8 bytes.
2260 * The "pad3" member is the beginning of the above. */
2261 uint8_t pad3
[4]; /* Not used. */
2263 OFP_ASSERT(sizeof(struct onf_action_copy_field
) == 24);
2265 /* Action structure for NXAST_REG_MOVE.
2267 * Copies src[src_ofs:src_ofs+n_bits] to dst[dst_ofs:dst_ofs+n_bits], where
2268 * a[b:c] denotes the bits within 'a' numbered 'b' through 'c' (not including
2269 * bit 'c'). Bit numbering starts at 0 for the least-significant bit, 1 for
2270 * the next most significant bit, and so on.
2272 * 'src' and 'dst' are nxm_header values with nxm_hasmask=0. (It doesn't make
2273 * sense to use nxm_hasmask=1 because the action does not do any kind of
2274 * matching; it uses the actual value of a field.)
2276 * The following nxm_header values are potentially acceptable as 'src':
2291 * - NXM_OF_ICMP_TYPE
2292 * - NXM_OF_ICMP_CODE
2299 * - NXM_NX_ICMPV6_TYPE
2300 * - NXM_NX_ICMPV6_CODE
2303 * - NXM_NX_REG(idx) for idx in the switch's accepted range.
2305 * - NXM_NX_TUN_IPV4_SRC
2306 * - NXM_NX_TUN_IPV4_DST
2308 * The following nxm_header values are potentially acceptable as 'dst':
2319 * - NXM_OF_ICMP_TYPE
2320 * - NXM_OF_ICMP_CODE
2321 * - NXM_NX_ICMPV6_TYPE
2322 * - NXM_NX_ICMPV6_CODE
2328 * Modifying any of the above fields changes the corresponding packet
2333 * - NXM_NX_REG(idx) for idx in the switch's accepted range.
2337 * - NXM_OF_VLAN_TCI. Modifying this field's value has side effects on the
2338 * packet's 802.1Q header. Setting a value with CFI=0 removes the 802.1Q
2339 * header (if any), ignoring the other bits. Setting a value with CFI=1
2340 * adds or modifies the 802.1Q header appropriately, setting the TCI field
2341 * to the field's new value (with the CFI bit masked out).
2343 * - NXM_NX_TUN_ID, NXM_NX_TUN_IPV4_SRC, NXM_NX_TUN_IPV4_DST. Modifying
2344 * any of these values modifies the corresponding tunnel header field used
2345 * for the packet's next tunnel encapsulation, if allowed by the
2346 * configuration of the output tunnel port.
2348 * A given nxm_header value may be used as 'src' or 'dst' only on a flow whose
2349 * nx_match satisfies its prerequisites. For example, NXM_OF_IP_TOS may be
2350 * used only if the flow's nx_match includes an nxm_entry that specifies
2351 * nxm_type=NXM_OF_ETH_TYPE, nxm_hasmask=0, and nxm_value=0x0800.
2353 * The switch will reject actions for which src_ofs+n_bits is greater than the
2354 * width of 'src' or dst_ofs+n_bits is greater than the width of 'dst' with
2355 * error type OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
2357 * This action behaves properly when 'src' overlaps with 'dst', that is, it
2358 * behaves as if 'src' were copied out to a temporary buffer, then the
2359 * temporary buffer copied to 'dst'.
2361 struct nx_action_reg_move
{
2362 ovs_be16 type
; /* OFPAT_VENDOR. */
2363 ovs_be16 len
; /* Length is 24. */
2364 ovs_be32 vendor
; /* NX_VENDOR_ID. */
2365 ovs_be16 subtype
; /* NXAST_REG_MOVE. */
2366 ovs_be16 n_bits
; /* Number of bits. */
2367 ovs_be16 src_ofs
; /* Starting bit offset in source. */
2368 ovs_be16 dst_ofs
; /* Starting bit offset in destination. */
2370 * - OXM/NXM header for source field (4 or 8 bytes).
2371 * - OXM/NXM header for destination field (4 or 8 bytes).
2372 * - Padding with 0-bytes to a multiple of 8 bytes, if necessary. */
2374 OFP_ASSERT(sizeof(struct nx_action_reg_move
) == 16);
2377 decode_copy_field__(ovs_be16 src_offset
, ovs_be16 dst_offset
, ovs_be16 n_bits
,
2378 const void *action
, ovs_be16 action_len
, size_t oxm_offset
,
2379 const struct vl_mff_map
*vl_mff_map
,
2380 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2382 struct ofpact_reg_move
*move
= ofpact_put_REG_MOVE(ofpacts
);
2385 move
->ofpact
.raw
= ONFACT_RAW13_COPY_FIELD
;
2386 move
->src
.ofs
= ntohs(src_offset
);
2387 move
->src
.n_bits
= ntohs(n_bits
);
2388 move
->dst
.ofs
= ntohs(dst_offset
);
2389 move
->dst
.n_bits
= ntohs(n_bits
);
2391 struct ofpbuf b
= ofpbuf_const_initializer(action
, ntohs(action_len
));
2392 ofpbuf_pull(&b
, oxm_offset
);
2394 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->src
.field
, NULL
,
2399 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->dst
.field
, NULL
,
2405 if (!is_all_zeros(b
.data
, b
.size
)) {
2406 return OFPERR_NXBRC_MUST_BE_ZERO
;
2409 return nxm_reg_move_check(move
, NULL
);
2413 decode_OFPAT_RAW15_COPY_FIELD(const struct ofp15_action_copy_field
*oacf
,
2414 enum ofp_version ofp_version OVS_UNUSED
,
2415 const struct vl_mff_map
*vl_mff_map
,
2416 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2418 return decode_copy_field__(oacf
->src_offset
, oacf
->dst_offset
,
2419 oacf
->n_bits
, oacf
, oacf
->len
,
2420 OBJECT_OFFSETOF(oacf
, pad2
), vl_mff_map
,
2421 tlv_bitmap
, ofpacts
);
2425 decode_ONFACT_RAW13_COPY_FIELD(const struct onf_action_copy_field
*oacf
,
2426 enum ofp_version ofp_version OVS_UNUSED
,
2427 const struct vl_mff_map
*vl_mff_map
,
2428 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2430 return decode_copy_field__(oacf
->src_offset
, oacf
->dst_offset
,
2431 oacf
->n_bits
, oacf
, oacf
->len
,
2432 OBJECT_OFFSETOF(oacf
, pad3
), vl_mff_map
,
2433 tlv_bitmap
, ofpacts
);
2437 decode_NXAST_RAW_REG_MOVE(const struct nx_action_reg_move
*narm
,
2438 enum ofp_version ofp_version OVS_UNUSED
,
2439 const struct vl_mff_map
*vl_mff_map
,
2440 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2442 struct ofpact_reg_move
*move
= ofpact_put_REG_MOVE(ofpacts
);
2445 move
->ofpact
.raw
= NXAST_RAW_REG_MOVE
;
2446 move
->src
.ofs
= ntohs(narm
->src_ofs
);
2447 move
->src
.n_bits
= ntohs(narm
->n_bits
);
2448 move
->dst
.ofs
= ntohs(narm
->dst_ofs
);
2449 move
->dst
.n_bits
= ntohs(narm
->n_bits
);
2451 struct ofpbuf b
= ofpbuf_const_initializer(narm
, ntohs(narm
->len
));
2452 ofpbuf_pull(&b
, sizeof *narm
);
2454 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->src
.field
, NULL
,
2460 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
, &move
->dst
.field
, NULL
,
2466 if (!is_all_zeros(b
.data
, b
.size
)) {
2467 return OFPERR_NXBRC_MUST_BE_ZERO
;
2470 return nxm_reg_move_check(move
, NULL
);
2474 encode_REG_MOVE(const struct ofpact_reg_move
*move
,
2475 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2477 /* For OpenFlow 1.3, the choice of ONFACT_RAW13_COPY_FIELD versus
2478 * NXAST_RAW_REG_MOVE is somewhat difficult. Neither one is guaranteed to
2479 * be supported by every OpenFlow 1.3 implementation. It would be ideal to
2480 * probe for support. Until we have that ability, we currently prefer
2481 * NXAST_RAW_REG_MOVE for backward compatibility with older Open vSwitch
2483 size_t start_ofs
= out
->size
;
2484 if (ofp_version
>= OFP15_VERSION
) {
2485 struct ofp15_action_copy_field
*copy
= put_OFPAT15_COPY_FIELD(out
);
2486 copy
->n_bits
= htons(move
->dst
.n_bits
);
2487 copy
->src_offset
= htons(move
->src
.ofs
);
2488 copy
->dst_offset
= htons(move
->dst
.ofs
);
2489 out
->size
= out
->size
- sizeof copy
->pad2
;
2490 nx_put_mff_header(out
, move
->src
.field
, ofp_version
, false);
2491 nx_put_mff_header(out
, move
->dst
.field
, ofp_version
, false);
2492 } else if (ofp_version
== OFP13_VERSION
2493 && move
->ofpact
.raw
== ONFACT_RAW13_COPY_FIELD
) {
2494 struct onf_action_copy_field
*copy
= put_ONFACT13_COPY_FIELD(out
);
2495 copy
->n_bits
= htons(move
->dst
.n_bits
);
2496 copy
->src_offset
= htons(move
->src
.ofs
);
2497 copy
->dst_offset
= htons(move
->dst
.ofs
);
2498 out
->size
= out
->size
- sizeof copy
->pad3
;
2499 nx_put_mff_header(out
, move
->src
.field
, ofp_version
, false);
2500 nx_put_mff_header(out
, move
->dst
.field
, ofp_version
, false);
2502 struct nx_action_reg_move
*narm
= put_NXAST_REG_MOVE(out
);
2503 narm
->n_bits
= htons(move
->dst
.n_bits
);
2504 narm
->src_ofs
= htons(move
->src
.ofs
);
2505 narm
->dst_ofs
= htons(move
->dst
.ofs
);
2506 nx_put_mff_header(out
, move
->src
.field
, 0, false);
2507 nx_put_mff_header(out
, move
->dst
.field
, 0, false);
2509 pad_ofpat(out
, start_ofs
);
2512 static char * OVS_WARN_UNUSED_RESULT
2513 parse_REG_MOVE(const char *arg
,
2514 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2515 struct ofpbuf
*ofpacts
,
2516 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
2518 struct ofpact_reg_move
*move
= ofpact_put_REG_MOVE(ofpacts
);
2519 return nxm_parse_reg_move(move
, arg
);
2523 format_REG_MOVE(const struct ofpact_reg_move
*a
,
2524 const struct ofputil_port_map
*port_map OVS_UNUSED
,
2527 nxm_format_reg_move(a
, s
);
2530 /* Action structure for OFPAT12_SET_FIELD. */
2531 struct ofp12_action_set_field
{
2532 ovs_be16 type
; /* OFPAT12_SET_FIELD. */
2533 ovs_be16 len
; /* Length is padded to 64 bits. */
2536 * - An OXM header, value, and (in OpenFlow 1.5+) optionally a mask.
2537 * - Enough 0-bytes to pad out to a multiple of 64 bits.
2539 * The "pad" member is the beginning of the above. */
2542 OFP_ASSERT(sizeof(struct ofp12_action_set_field
) == 8);
2544 /* Action structure for NXAST_REG_LOAD.
2546 * Copies value[0:n_bits] to dst[ofs:ofs+n_bits], where a[b:c] denotes the bits
2547 * within 'a' numbered 'b' through 'c' (not including bit 'c'). Bit numbering
2548 * starts at 0 for the least-significant bit, 1 for the next most significant
2551 * 'dst' is an nxm_header with nxm_hasmask=0. See the documentation for
2552 * NXAST_REG_MOVE, above, for the permitted fields and for the side effects of
2555 * The 'ofs' and 'n_bits' fields are combined into a single 'ofs_nbits' field
2556 * to avoid enlarging the structure by another 8 bytes. To allow 'n_bits' to
2557 * take a value between 1 and 64 (inclusive) while taking up only 6 bits, it is
2558 * also stored as one less than its true value:
2561 * +------------------------------+------------------+
2562 * | ofs | n_bits - 1 |
2563 * +------------------------------+------------------+
2565 * The switch will reject actions for which ofs+n_bits is greater than the
2566 * width of 'dst', or in which any bits in 'value' with value 2**n_bits or
2567 * greater are set to 1, with error type OFPET_BAD_ACTION, code
2568 * OFPBAC_BAD_ARGUMENT.
2570 struct nx_action_reg_load
{
2571 ovs_be16 type
; /* OFPAT_VENDOR. */
2572 ovs_be16 len
; /* Length is 24. */
2573 ovs_be32 vendor
; /* NX_VENDOR_ID. */
2574 ovs_be16 subtype
; /* NXAST_REG_LOAD. */
2575 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
2576 ovs_be32 dst
; /* Destination register. */
2577 ovs_be64 value
; /* Immediate value. */
2579 OFP_ASSERT(sizeof(struct nx_action_reg_load
) == 24);
2581 /* The NXAST_REG_LOAD2 action structure is "struct ext_action_header",
2584 * - An NXM/OXM header, value, and optionally a mask.
2585 * - Enough 0-bytes to pad out to a multiple of 64 bits.
2587 * The "pad" member is the beginning of the above. */
2590 decode_ofpat_set_field(const struct ofp12_action_set_field
*oasf
,
2591 bool may_mask
, const struct vl_mff_map
*vl_mff_map
,
2592 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2594 struct ofpbuf b
= ofpbuf_const_initializer(oasf
, ntohs(oasf
->len
));
2595 ofpbuf_pull(&b
, OBJECT_OFFSETOF(oasf
, pad
));
2597 union mf_value value
, mask
;
2598 const struct mf_field
*field
;
2600 error
= mf_vl_mff_nx_pull_entry(&b
, vl_mff_map
, &field
, &value
,
2601 may_mask
? &mask
: NULL
, tlv_bitmap
);
2603 return (error
== OFPERR_OFPBMC_BAD_MASK
2604 ? OFPERR_OFPBAC_BAD_SET_MASK
2609 memset(&mask
, 0xff, field
->n_bytes
);
2612 if (!is_all_zeros(b
.data
, b
.size
)) {
2613 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2616 /* OpenFlow says specifically that one may not set OXM_OF_IN_PORT via
2618 if (field
->id
== MFF_IN_PORT_OXM
) {
2619 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2622 /* oxm_length is now validated to be compatible with mf_value. */
2623 if (!field
->writable
) {
2624 VLOG_WARN_RL(&rl
, "destination field %s is not writable",
2626 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2629 /* The value must be valid for match. OpenFlow 1.5 also says,
2630 * "In an OXM_OF_VLAN_VID set-field action, the OFPVID_PRESENT bit must be
2631 * a 1-bit in oxm_value and in oxm_mask." */
2632 if (!mf_is_value_valid(field
, &value
)
2633 || (field
->id
== MFF_VLAN_VID
2634 && (!(mask
.be16
& htons(OFPVID12_PRESENT
))
2635 || !(value
.be16
& htons(OFPVID12_PRESENT
))))) {
2636 struct ds ds
= DS_EMPTY_INITIALIZER
;
2637 mf_format(field
, &value
, NULL
, NULL
, &ds
);
2638 VLOG_WARN_RL(&rl
, "Invalid value for set field %s: %s",
2639 field
->name
, ds_cstr(&ds
));
2642 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2645 ofpact_put_set_field(ofpacts
, field
, &value
, &mask
);
2650 decode_OFPAT_RAW12_SET_FIELD(const struct ofp12_action_set_field
*oasf
,
2651 enum ofp_version ofp_version OVS_UNUSED
,
2652 const struct vl_mff_map
*vl_mff_map
,
2653 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2655 return decode_ofpat_set_field(oasf
, false, vl_mff_map
, tlv_bitmap
,
2660 decode_OFPAT_RAW15_SET_FIELD(const struct ofp12_action_set_field
*oasf
,
2661 enum ofp_version ofp_version OVS_UNUSED
,
2662 const struct vl_mff_map
*vl_mff_map
,
2663 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
2665 return decode_ofpat_set_field(oasf
, true, vl_mff_map
, tlv_bitmap
, ofpacts
);
2669 decode_NXAST_RAW_REG_LOAD(const struct nx_action_reg_load
*narl
,
2670 enum ofp_version ofp_version OVS_UNUSED
,
2671 const struct vl_mff_map
*vl_mff_map
,
2672 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
2674 struct mf_subfield dst
;
2677 dst
.ofs
= nxm_decode_ofs(narl
->ofs_nbits
);
2678 dst
.n_bits
= nxm_decode_n_bits(narl
->ofs_nbits
);
2679 error
= mf_vl_mff_mf_from_nxm_header(ntohl(narl
->dst
), vl_mff_map
,
2680 &dst
.field
, tlv_bitmap
);
2685 error
= mf_check_dst(&dst
, NULL
);
2690 /* Reject 'narl' if a bit numbered 'n_bits' or higher is set to 1 in
2692 if (dst
.n_bits
< 64 && ntohll(narl
->value
) >> dst
.n_bits
) {
2693 return OFPERR_OFPBAC_BAD_ARGUMENT
;
2696 struct ofpact_set_field
*sf
= ofpact_put_reg_load(out
, dst
.field
, NULL
,
2698 bitwise_put(ntohll(narl
->value
),
2699 sf
->value
, dst
.field
->n_bytes
, dst
.ofs
,
2701 bitwise_put(UINT64_MAX
,
2702 ofpact_set_field_mask(sf
), dst
.field
->n_bytes
, dst
.ofs
,
2708 decode_NXAST_RAW_REG_LOAD2(const struct ext_action_header
*eah
,
2709 enum ofp_version ofp_version OVS_UNUSED
,
2710 const struct vl_mff_map
*vl_mff_map
,
2711 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
2713 struct ofpbuf b
= ofpbuf_const_initializer(eah
, ntohs(eah
->len
));
2714 ofpbuf_pull(&b
, OBJECT_OFFSETOF(eah
, pad
));
2716 union mf_value value
, mask
;
2717 const struct mf_field
*field
;
2719 error
= mf_vl_mff_nx_pull_entry(&b
, vl_mff_map
, &field
, &value
, &mask
,
2725 if (!is_all_zeros(b
.data
, b
.size
)) {
2726 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2729 if (!field
->writable
) {
2730 VLOG_WARN_RL(&rl
, "destination field %s is not writable", field
->name
);
2731 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
2734 /* Put value and mask. */
2735 ofpact_put_reg_load2(out
, field
, &value
, &mask
);
2740 put_set_field(struct ofpbuf
*openflow
, enum ofp_version ofp_version
,
2741 enum mf_field_id field
, uint64_t value_
)
2743 struct ofp12_action_set_field
*oasf OVS_UNUSED
;
2744 int n_bytes
= mf_from_id(field
)->n_bytes
;
2745 size_t start_ofs
= openflow
->size
;
2746 union mf_value value
;
2748 value
.be64
= htonll(value_
<< (8 * (8 - n_bytes
)));
2750 oasf
= put_OFPAT12_SET_FIELD(openflow
);
2751 openflow
->size
= openflow
->size
- sizeof oasf
->pad
;
2752 nx_put_entry(openflow
, mf_from_id(field
), ofp_version
, &value
, NULL
);
2753 pad_ofpat(openflow
, start_ofs
);
2757 put_reg_load(struct ofpbuf
*openflow
,
2758 const struct mf_subfield
*dst
, uint64_t value
)
2760 ovs_assert(dst
->n_bits
<= 64);
2762 struct nx_action_reg_load
*narl
= put_NXAST_REG_LOAD(openflow
);
2763 narl
->ofs_nbits
= nxm_encode_ofs_nbits(dst
->ofs
, dst
->n_bits
);
2764 narl
->dst
= htonl(nxm_header_from_mff(dst
->field
));
2765 narl
->value
= htonll(value
);
2769 next_load_segment(const struct ofpact_set_field
*sf
,
2770 struct mf_subfield
*dst
, uint64_t *value
)
2772 int n_bits
= sf
->field
->n_bits
;
2773 int n_bytes
= sf
->field
->n_bytes
;
2774 int start
= dst
->ofs
+ dst
->n_bits
;
2776 if (start
< n_bits
) {
2777 dst
->field
= sf
->field
;
2778 dst
->ofs
= bitwise_scan(ofpact_set_field_mask(sf
), n_bytes
, 1, start
,
2780 if (dst
->ofs
< n_bits
) {
2781 dst
->n_bits
= bitwise_scan(ofpact_set_field_mask(sf
), n_bytes
, 0,
2783 MIN(dst
->ofs
+ 64, n_bits
)) - dst
->ofs
;
2784 *value
= bitwise_get(sf
->value
, n_bytes
, dst
->ofs
, dst
->n_bits
);
2791 /* Convert 'sf' to a series of REG_LOADs. */
2793 set_field_to_nxast(const struct ofpact_set_field
*sf
, struct ofpbuf
*openflow
)
2795 /* If 'sf' cannot be encoded as NXAST_REG_LOAD because it requires an
2796 * experimenter OXM or is variable length (or if it came in as
2797 * NXAST_REG_LOAD2), encode as NXAST_REG_LOAD2. Otherwise use
2798 * NXAST_REG_LOAD, which is backward compatible. */
2799 if (sf
->ofpact
.raw
== NXAST_RAW_REG_LOAD2
2800 || !mf_nxm_header(sf
->field
->id
) || sf
->field
->variable_len
) {
2801 struct ext_action_header
*eah OVS_UNUSED
;
2802 size_t start_ofs
= openflow
->size
;
2804 eah
= put_NXAST_REG_LOAD2(openflow
);
2805 openflow
->size
= openflow
->size
- sizeof eah
->pad
;
2806 nx_put_entry(openflow
, sf
->field
, 0, sf
->value
,
2807 ofpact_set_field_mask(sf
));
2808 pad_ofpat(openflow
, start_ofs
);
2810 struct mf_subfield dst
;
2813 dst
.ofs
= dst
.n_bits
= 0;
2814 while (next_load_segment(sf
, &dst
, &value
)) {
2815 put_reg_load(openflow
, &dst
, value
);
2820 /* Convert 'sf', which must set an entire field, to standard OpenFlow 1.0/1.1
2821 * actions, if we can, falling back to Nicira extensions if we must.
2823 * We check only meta-flow types that can appear within set field actions and
2824 * that have a mapping to compatible action types. These struct mf_field
2825 * definitions have a defined OXM or NXM header value and specify the field as
2828 set_field_to_legacy_openflow(const struct ofpact_set_field
*sf
,
2829 enum ofp_version ofp_version
,
2832 switch ((int) sf
->field
->id
) {
2833 case MFF_VLAN_TCI
: {
2834 ovs_be16 tci
= sf
->value
->be16
;
2835 bool cfi
= (tci
& htons(VLAN_CFI
)) != 0;
2836 uint16_t vid
= vlan_tci_to_vid(tci
);
2837 uint8_t pcp
= vlan_tci_to_pcp(tci
);
2839 if (ofp_version
< OFP11_VERSION
) {
2840 /* NXM_OF_VLAN_TCI to OpenFlow 1.0 mapping:
2842 * If CFI=1, Add or modify VLAN VID & PCP.
2843 * If CFI=0, strip VLAN header, if any.
2846 put_OFPAT10_SET_VLAN_VID(out
, vid
);
2847 put_OFPAT10_SET_VLAN_PCP(out
, pcp
);
2849 put_OFPAT10_STRIP_VLAN(out
);
2852 /* NXM_OF_VLAN_TCI to OpenFlow 1.1 mapping:
2854 * If CFI=1, Add or modify VLAN VID & PCP.
2855 * OpenFlow 1.1 set actions only apply if the packet
2856 * already has VLAN tags. To be sure that is the case
2857 * we have to push a VLAN header. As we do not support
2858 * multiple layers of VLANs, this is a no-op, if a VLAN
2859 * header already exists. This may backfire, however,
2860 * when we start supporting multiple layers of VLANs.
2861 * If CFI=0, strip VLAN header, if any.
2864 /* Push a VLAN tag, if one was not seen at action validation
2866 if (!sf
->flow_has_vlan
) {
2867 put_OFPAT11_PUSH_VLAN(out
, htons(ETH_TYPE_VLAN_8021Q
));
2869 put_OFPAT11_SET_VLAN_VID(out
, vid
);
2870 put_OFPAT11_SET_VLAN_PCP(out
, pcp
);
2872 /* If the flow did not match on vlan, we have no way of
2873 * knowing if the vlan tag exists, so we must POP just to be
2875 put_OFPAT11_POP_VLAN(out
);
2881 case MFF_VLAN_VID
: {
2882 uint16_t vid
= ntohs(sf
->value
->be16
) & VLAN_VID_MASK
;
2883 if (ofp_version
== OFP10_VERSION
) {
2884 put_OFPAT10_SET_VLAN_VID(out
, vid
);
2886 put_OFPAT11_SET_VLAN_VID(out
, vid
);
2892 if (ofp_version
== OFP10_VERSION
) {
2893 put_OFPAT10_SET_VLAN_PCP(out
, sf
->value
->u8
);
2895 put_OFPAT11_SET_VLAN_PCP(out
, sf
->value
->u8
);
2900 put_OFPAT_SET_DL_SRC(out
, ofp_version
)->dl_addr
= sf
->value
->mac
;
2904 put_OFPAT_SET_DL_DST(out
, ofp_version
)->dl_addr
= sf
->value
->mac
;
2908 put_OFPAT_SET_NW_SRC(out
, ofp_version
, sf
->value
->be32
);
2912 put_OFPAT_SET_NW_DST(out
, ofp_version
, sf
->value
->be32
);
2916 put_OFPAT_SET_NW_TOS(out
, ofp_version
, sf
->value
->u8
);
2919 case MFF_IP_DSCP_SHIFTED
:
2920 put_OFPAT_SET_NW_TOS(out
, ofp_version
, sf
->value
->u8
<< 2);
2924 struct ofpact_ecn ip_ecn
= { .ecn
= sf
->value
->u8
};
2925 encode_SET_IP_ECN(&ip_ecn
, ofp_version
, out
);
2931 put_OFPAT_SET_TP_SRC(out
, sf
->value
->be16
);
2936 put_OFPAT_SET_TP_DST(out
, sf
->value
->be16
);
2940 set_field_to_nxast(sf
, out
);
2946 set_field_to_set_field(const struct ofpact_set_field
*sf
,
2947 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2949 struct ofp12_action_set_field
*oasf OVS_UNUSED
;
2950 size_t start_ofs
= out
->size
;
2952 oasf
= put_OFPAT12_SET_FIELD(out
);
2953 out
->size
= out
->size
- sizeof oasf
->pad
;
2954 nx_put_entry(out
, sf
->field
, ofp_version
, sf
->value
,
2955 ofpact_set_field_mask(sf
));
2956 pad_ofpat(out
, start_ofs
);
2960 encode_SET_FIELD(const struct ofpact_set_field
*sf
,
2961 enum ofp_version ofp_version
, struct ofpbuf
*out
)
2963 if (ofp_version
>= OFP15_VERSION
) {
2964 /* OF1.5+ only has Set-Field (reg_load is redundant so we drop it
2966 set_field_to_set_field(sf
, ofp_version
, out
);
2967 } else if (sf
->ofpact
.raw
== NXAST_RAW_REG_LOAD
||
2968 sf
->ofpact
.raw
== NXAST_RAW_REG_LOAD2
) {
2969 /* It came in as reg_load, send it out the same way. */
2970 set_field_to_nxast(sf
, out
);
2971 } else if (ofp_version
< OFP12_VERSION
) {
2972 /* OpenFlow 1.0 and 1.1 don't have Set-Field. */
2973 set_field_to_legacy_openflow(sf
, ofp_version
, out
);
2974 } else if (is_all_ones(ofpact_set_field_mask(sf
), sf
->field
->n_bytes
)) {
2975 /* We're encoding to OpenFlow 1.2, 1.3, or 1.4. The action sets an
2976 * entire field, so encode it as OFPAT_SET_FIELD. */
2977 set_field_to_set_field(sf
, ofp_version
, out
);
2979 /* We're encoding to OpenFlow 1.2, 1.3, or 1.4. The action cannot be
2980 * encoded as OFPAT_SET_FIELD because it does not set an entire field,
2981 * so encode it as reg_load. */
2982 set_field_to_nxast(sf
, out
);
2986 /* Parses the input argument 'arg' into the key, value, and delimiter
2987 * components that are common across the reg_load and set_field action format.
2989 * With an argument like "1->metadata", sets the following pointers to
2990 * point within 'arg':
2995 * Returns NULL if successful, otherwise a malloc()'d string describing the
2996 * error. The caller is responsible for freeing the returned string. */
2997 static char * OVS_WARN_UNUSED_RESULT
2998 set_field_split_str(char *arg
, char **key
, char **value
, char **delim
)
3003 value_end
= strstr(arg
, "->");
3004 *key
= value_end
+ strlen("->");
3010 return xasprintf("%s: missing `->'", arg
);
3012 if (strlen(value_end
) <= strlen("->")) {
3013 return xasprintf("%s: missing field name following `->'", arg
);
3019 /* Parses a "set_field" action with argument 'arg', appending the parsed
3020 * action to 'ofpacts'.
3022 * Returns NULL if successful, otherwise a malloc()'d string describing the
3023 * error. The caller is responsible for freeing the returned string. */
3024 static char * OVS_WARN_UNUSED_RESULT
3025 set_field_parse__(char *arg
, const struct ofputil_port_map
*port_map
,
3026 struct ofpbuf
*ofpacts
,
3027 enum ofputil_protocol
*usable_protocols
)
3032 const struct mf_field
*mf
;
3033 union mf_value sf_value
, sf_mask
;
3036 error
= set_field_split_str(arg
, &key
, &value
, &delim
);
3041 mf
= mf_from_name(key
);
3043 return xasprintf("%s is not a valid OXM field name", key
);
3045 if (!mf
->writable
) {
3046 return xasprintf("%s is read-only", key
);
3050 error
= mf_parse(mf
, value
, port_map
, &sf_value
, &sf_mask
);
3055 if (!mf_is_value_valid(mf
, &sf_value
)) {
3056 return xasprintf("%s is not a valid value for field %s", value
, key
);
3059 *usable_protocols
&= mf
->usable_protocols_exact
;
3061 ofpact_put_set_field(ofpacts
, mf
, &sf_value
, &sf_mask
);
3065 /* Parses 'arg' as the argument to a "set_field" action, and appends such an
3066 * action to 'ofpacts'.
3068 * Returns NULL if successful, otherwise a malloc()'d string describing the
3069 * error. The caller is responsible for freeing the returned string. */
3070 static char * OVS_WARN_UNUSED_RESULT
3071 parse_SET_FIELD(const char *arg
, const struct ofputil_port_map
*port_map
,
3072 struct ofpbuf
*ofpacts
,
3073 enum ofputil_protocol
*usable_protocols
)
3075 char *copy
= xstrdup(arg
);
3076 char *error
= set_field_parse__(copy
, port_map
, ofpacts
, usable_protocols
);
3081 static char * OVS_WARN_UNUSED_RESULT
3082 parse_reg_load(char *arg
, struct ofpbuf
*ofpacts
)
3084 struct mf_subfield dst
;
3085 char *key
, *value_str
;
3086 union mf_value value
;
3089 error
= set_field_split_str(arg
, &key
, &value_str
, NULL
);
3094 error
= mf_parse_subfield(&dst
, key
);
3099 if (parse_int_string(value_str
, (uint8_t *)&value
, dst
.field
->n_bytes
,
3101 return xasprintf("%s: cannot parse integer value", arg
);
3104 if (!bitwise_is_all_zeros(&value
, dst
.field
->n_bytes
, dst
.n_bits
,
3105 dst
.field
->n_bytes
* 8 - dst
.n_bits
)) {
3109 mf_format(dst
.field
, &value
, NULL
, NULL
, &ds
);
3110 error
= xasprintf("%s: value %s does not fit into %d bits",
3111 arg
, ds_cstr(&ds
), dst
.n_bits
);
3116 struct ofpact_set_field
*sf
= ofpact_put_reg_load(ofpacts
, dst
.field
, NULL
,
3119 bitwise_copy(&value
, dst
.field
->n_bytes
, 0, sf
->value
,
3120 dst
.field
->n_bytes
, dst
.ofs
, dst
.n_bits
);
3121 bitwise_one(ofpact_set_field_mask(sf
), dst
.field
->n_bytes
, dst
.ofs
,
3127 format_SET_FIELD(const struct ofpact_set_field
*a
,
3128 const struct ofputil_port_map
*port_map
,
3131 if (a
->ofpact
.raw
== NXAST_RAW_REG_LOAD
) {
3132 struct mf_subfield dst
;
3135 dst
.ofs
= dst
.n_bits
= 0;
3136 while (next_load_segment(a
, &dst
, &value
)) {
3137 ds_put_format(s
, "%sload:%s%#"PRIx64
"%s->%s",
3138 colors
.special
, colors
.end
, value
,
3139 colors
.special
, colors
.end
);
3140 mf_format_subfield(&dst
, s
);
3141 ds_put_char(s
, ',');
3145 ds_put_format(s
, "%sset_field:%s", colors
.special
, colors
.end
);
3146 mf_format(a
->field
, a
->value
, ofpact_set_field_mask(a
), port_map
, s
);
3147 ds_put_format(s
, "%s->%s%s",
3148 colors
.special
, colors
.end
, a
->field
->name
);
3152 /* Appends an OFPACT_SET_FIELD ofpact with enough space for the value and mask
3153 * for the 'field' to 'ofpacts' and returns it. Fills in the value from
3154 * 'value', if non-NULL, and mask from 'mask' if non-NULL. If 'value' is
3155 * non-NULL and 'mask' is NULL, an all-ones mask will be filled in. */
3156 struct ofpact_set_field
*
3157 ofpact_put_set_field(struct ofpbuf
*ofpacts
, const struct mf_field
*field
,
3158 const void *value
, const void *mask
)
3160 struct ofpact_set_field
*sf
= ofpact_put_SET_FIELD(ofpacts
);
3163 /* Fill in the value and mask if given, otherwise put zeroes so that the
3164 * caller may fill in the value and mask itself. */
3166 ofpbuf_put_uninit(ofpacts
, 2 * field
->n_bytes
);
3167 sf
= ofpacts
->header
;
3168 memcpy(sf
->value
, value
, field
->n_bytes
);
3170 memcpy(ofpact_set_field_mask(sf
), mask
, field
->n_bytes
);
3172 memset(ofpact_set_field_mask(sf
), 0xff, field
->n_bytes
);
3175 ofpbuf_put_zeros(ofpacts
, 2 * field
->n_bytes
);
3176 sf
= ofpacts
->header
;
3178 /* Update length. */
3179 ofpact_finish_SET_FIELD(ofpacts
, &sf
);
3184 /* Appends an OFPACT_SET_FIELD ofpact to 'ofpacts' and returns it. The ofpact
3185 * is marked such that, if possible, it will be translated to OpenFlow as
3186 * NXAST_REG_LOAD extension actions rather than OFPAT_SET_FIELD, either because
3187 * that was the way that the action was expressed when it came into OVS or for
3188 * backward compatibility. */
3189 struct ofpact_set_field
*
3190 ofpact_put_reg_load(struct ofpbuf
*ofpacts
, const struct mf_field
*field
,
3191 const void *value
, const void *mask
)
3193 struct ofpact_set_field
*sf
= ofpact_put_set_field(ofpacts
, field
, value
,
3195 sf
->ofpact
.raw
= NXAST_RAW_REG_LOAD
;
3200 struct ofpact_set_field
*
3201 ofpact_put_reg_load2(struct ofpbuf
*ofpacts
, const struct mf_field
*field
,
3202 const void *value
, const void *mask
)
3204 struct ofpact_set_field
*sf
= ofpact_put_set_field(ofpacts
, field
, value
,
3206 sf
->ofpact
.raw
= NXAST_RAW_REG_LOAD2
;
3212 /* Action structure for NXAST_STACK_PUSH and NXAST_STACK_POP.
3214 * Pushes (or pops) field[offset: offset + n_bits] to (or from)
3217 struct nx_action_stack
{
3218 ovs_be16 type
; /* OFPAT_VENDOR. */
3219 ovs_be16 len
; /* Length is 16. */
3220 ovs_be32 vendor
; /* NX_VENDOR_ID. */
3221 ovs_be16 subtype
; /* NXAST_STACK_PUSH or NXAST_STACK_POP. */
3222 ovs_be16 offset
; /* Bit offset into the field. */
3224 * - OXM/NXM header for field to push or pop (4 or 8 bytes).
3225 * - ovs_be16 'n_bits', the number of bits to extract from the field.
3226 * - Enough 0-bytes to pad out the action to 24 bytes. */
3227 uint8_t pad
[12]; /* See above. */
3229 OFP_ASSERT(sizeof(struct nx_action_stack
) == 24);
3232 decode_stack_action(const struct nx_action_stack
*nasp
,
3233 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
3234 struct ofpact_stack
*stack_action
)
3237 stack_action
->subfield
.ofs
= ntohs(nasp
->offset
);
3239 struct ofpbuf b
= ofpbuf_const_initializer(nasp
, sizeof *nasp
);
3240 ofpbuf_pull(&b
, OBJECT_OFFSETOF(nasp
, pad
));
3241 error
= mf_vl_mff_nx_pull_header(&b
, vl_mff_map
,
3242 &stack_action
->subfield
.field
, NULL
,
3248 stack_action
->subfield
.n_bits
= ntohs(*(const ovs_be16
*) b
.data
);
3250 if (!is_all_zeros(b
.data
, b
.size
)) {
3251 return OFPERR_NXBRC_MUST_BE_ZERO
;
3258 decode_NXAST_RAW_STACK_PUSH(const struct nx_action_stack
*nasp
,
3259 enum ofp_version ofp_version OVS_UNUSED
,
3260 const struct vl_mff_map
*vl_mff_map
,
3261 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
3263 struct ofpact_stack
*push
= ofpact_put_STACK_PUSH(ofpacts
);
3264 enum ofperr error
= decode_stack_action(nasp
, vl_mff_map
, tlv_bitmap
,
3266 return error
? error
: nxm_stack_push_check(push
, NULL
);
3270 decode_NXAST_RAW_STACK_POP(const struct nx_action_stack
*nasp
,
3271 enum ofp_version ofp_version OVS_UNUSED
,
3272 const struct vl_mff_map
*vl_mff_map
,
3273 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
3275 struct ofpact_stack
*pop
= ofpact_put_STACK_POP(ofpacts
);
3276 enum ofperr error
= decode_stack_action(nasp
, vl_mff_map
, tlv_bitmap
,
3278 return error
? error
: nxm_stack_pop_check(pop
, NULL
);
3282 encode_STACK_op(const struct ofpact_stack
*stack_action
,
3283 struct nx_action_stack
*nasp
)
3288 nasp
->offset
= htons(stack_action
->subfield
.ofs
);
3290 ofpbuf_use_stack(&b
, nasp
, ntohs(nasp
->len
));
3291 ofpbuf_put_uninit(&b
, OBJECT_OFFSETOF(nasp
, pad
));
3292 nx_put_mff_header(&b
, stack_action
->subfield
.field
, 0, false);
3293 n_bits
= htons(stack_action
->subfield
.n_bits
);
3294 ofpbuf_put(&b
, &n_bits
, sizeof n_bits
);
3298 encode_STACK_PUSH(const struct ofpact_stack
*stack
,
3299 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
3301 encode_STACK_op(stack
, put_NXAST_STACK_PUSH(out
));
3305 encode_STACK_POP(const struct ofpact_stack
*stack
,
3306 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
3308 encode_STACK_op(stack
, put_NXAST_STACK_POP(out
));
3311 static char * OVS_WARN_UNUSED_RESULT
3312 parse_STACK_PUSH(char *arg
,
3313 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3314 struct ofpbuf
*ofpacts
,
3315 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3317 return nxm_parse_stack_action(ofpact_put_STACK_PUSH(ofpacts
), arg
);
3320 static char * OVS_WARN_UNUSED_RESULT
3321 parse_STACK_POP(char *arg
,
3322 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3323 struct ofpbuf
*ofpacts
,
3324 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3326 return nxm_parse_stack_action(ofpact_put_STACK_POP(ofpacts
), arg
);
3330 format_STACK_PUSH(const struct ofpact_stack
*a
,
3331 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3334 nxm_format_stack_push(a
, s
);
3338 format_STACK_POP(const struct ofpact_stack
*a
,
3339 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3342 nxm_format_stack_pop(a
, s
);
3345 /* Action structure for NXAST_DEC_TTL_CNT_IDS.
3347 * If the packet is not IPv4 or IPv6, does nothing. For IPv4 or IPv6, if the
3348 * TTL or hop limit is at least 2, decrements it by 1. Otherwise, if TTL or
3349 * hop limit is 0 or 1, sends a packet-in to the controllers with each of the
3350 * 'n_controllers' controller IDs specified in 'cnt_ids'.
3352 * (This differs from NXAST_DEC_TTL in that for NXAST_DEC_TTL the packet-in is
3353 * sent only to controllers with id 0.)
3355 struct nx_action_cnt_ids
{
3356 ovs_be16 type
; /* OFPAT_VENDOR. */
3357 ovs_be16 len
; /* Length including slaves. */
3358 ovs_be32 vendor
; /* NX_VENDOR_ID. */
3359 ovs_be16 subtype
; /* NXAST_DEC_TTL_CNT_IDS. */
3361 ovs_be16 n_controllers
; /* Number of controllers. */
3362 uint8_t zeros
[4]; /* Must be zero. */
3364 /* Followed by 1 or more controller ids.
3366 * uint16_t cnt_ids[]; // Controller ids.
3367 * uint8_t pad[]; // Must be 0 to 8-byte align cnt_ids[].
3370 OFP_ASSERT(sizeof(struct nx_action_cnt_ids
) == 16);
3373 decode_OFPAT_RAW_DEC_NW_TTL(struct ofpbuf
*out
)
3376 struct ofpact_cnt_ids
*ids
;
3377 enum ofperr error
= 0;
3379 ids
= ofpact_put_DEC_TTL(out
);
3380 ids
->n_controllers
= 1;
3381 ofpbuf_put(out
, &id
, sizeof id
);
3383 ofpact_finish_DEC_TTL(out
, &ids
);
3388 decode_NXAST_RAW_DEC_TTL_CNT_IDS(const struct nx_action_cnt_ids
*nac_ids
,
3389 enum ofp_version ofp_version OVS_UNUSED
,
3392 struct ofpact_cnt_ids
*ids
;
3396 ids
= ofpact_put_DEC_TTL(out
);
3397 ids
->ofpact
.raw
= NXAST_RAW_DEC_TTL_CNT_IDS
;
3398 ids
->n_controllers
= ntohs(nac_ids
->n_controllers
);
3399 ids_size
= ntohs(nac_ids
->len
) - sizeof *nac_ids
;
3401 if (!is_all_zeros(nac_ids
->zeros
, sizeof nac_ids
->zeros
)) {
3402 return OFPERR_NXBRC_MUST_BE_ZERO
;
3405 if (ids_size
< ids
->n_controllers
* sizeof(ovs_be16
)) {
3406 VLOG_WARN_RL(&rl
, "Nicira action dec_ttl_cnt_ids only has %"PRIuSIZE
" "
3407 "bytes allocated for controller ids. %"PRIuSIZE
" bytes "
3408 "are required for %u controllers.",
3409 ids_size
, ids
->n_controllers
* sizeof(ovs_be16
),
3410 ids
->n_controllers
);
3411 return OFPERR_OFPBAC_BAD_LEN
;
3414 for (i
= 0; i
< ids
->n_controllers
; i
++) {
3415 uint16_t id
= ntohs(((ovs_be16
*)(nac_ids
+ 1))[i
]);
3416 ofpbuf_put(out
, &id
, sizeof id
);
3420 ofpact_finish_DEC_TTL(out
, &ids
);
3426 encode_DEC_TTL(const struct ofpact_cnt_ids
*dec_ttl
,
3427 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3429 if (dec_ttl
->ofpact
.raw
== NXAST_RAW_DEC_TTL_CNT_IDS
3430 || dec_ttl
->n_controllers
!= 1
3431 || dec_ttl
->cnt_ids
[0] != 0) {
3432 struct nx_action_cnt_ids
*nac_ids
= put_NXAST_DEC_TTL_CNT_IDS(out
);
3433 int ids_len
= ROUND_UP(2 * dec_ttl
->n_controllers
, OFP_ACTION_ALIGN
);
3437 nac_ids
->len
= htons(ntohs(nac_ids
->len
) + ids_len
);
3438 nac_ids
->n_controllers
= htons(dec_ttl
->n_controllers
);
3440 ids
= ofpbuf_put_zeros(out
, ids_len
);
3441 for (i
= 0; i
< dec_ttl
->n_controllers
; i
++) {
3442 ids
[i
] = htons(dec_ttl
->cnt_ids
[i
]);
3445 put_OFPAT_DEC_NW_TTL(out
, ofp_version
);
3450 parse_noargs_dec_ttl(struct ofpbuf
*ofpacts
)
3452 struct ofpact_cnt_ids
*ids
;
3455 ofpact_put_DEC_TTL(ofpacts
);
3456 ofpbuf_put(ofpacts
, &id
, sizeof id
);
3457 ids
= ofpacts
->header
;
3458 ids
->n_controllers
++;
3459 ofpact_finish_DEC_TTL(ofpacts
, &ids
);
3462 static char * OVS_WARN_UNUSED_RESULT
3463 parse_DEC_TTL(char *arg
,
3464 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3465 struct ofpbuf
*ofpacts
,
3466 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3469 parse_noargs_dec_ttl(ofpacts
);
3471 struct ofpact_cnt_ids
*ids
;
3474 ids
= ofpact_put_DEC_TTL(ofpacts
);
3475 ids
->ofpact
.raw
= NXAST_RAW_DEC_TTL_CNT_IDS
;
3476 for (cntr
= strtok_r(arg
, ", ", &arg
); cntr
!= NULL
;
3477 cntr
= strtok_r(NULL
, ", ", &arg
)) {
3478 uint16_t id
= atoi(cntr
);
3480 ofpbuf_put(ofpacts
, &id
, sizeof id
);
3481 ids
= ofpacts
->header
;
3482 ids
->n_controllers
++;
3484 if (!ids
->n_controllers
) {
3485 return xstrdup("dec_ttl_cnt_ids: expected at least one controller "
3488 ofpact_finish_DEC_TTL(ofpacts
, &ids
);
3494 format_DEC_TTL(const struct ofpact_cnt_ids
*a
,
3495 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3500 ds_put_format(s
, "%sdec_ttl%s", colors
.paren
, colors
.end
);
3501 if (a
->ofpact
.raw
== NXAST_RAW_DEC_TTL_CNT_IDS
) {
3502 ds_put_format(s
, "%s(%s", colors
.paren
, colors
.end
);
3503 for (i
= 0; i
< a
->n_controllers
; i
++) {
3505 ds_put_cstr(s
, ",");
3507 ds_put_format(s
, "%"PRIu16
, a
->cnt_ids
[i
]);
3509 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
3513 /* Set MPLS label actions. */
3516 decode_OFPAT_RAW_SET_MPLS_LABEL(ovs_be32 label
,
3517 enum ofp_version ofp_version OVS_UNUSED
,
3520 ofpact_put_SET_MPLS_LABEL(out
)->label
= label
;
3525 encode_SET_MPLS_LABEL(const struct ofpact_mpls_label
*label
,
3526 enum ofp_version ofp_version
,
3529 if (ofp_version
< OFP12_VERSION
) {
3530 put_OFPAT_SET_MPLS_LABEL(out
, ofp_version
, label
->label
);
3532 put_set_field(out
, ofp_version
, MFF_MPLS_LABEL
, ntohl(label
->label
));
3536 static char * OVS_WARN_UNUSED_RESULT
3537 parse_SET_MPLS_LABEL(char *arg
,
3538 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3539 struct ofpbuf
*ofpacts
,
3540 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3542 struct ofpact_mpls_label
*mpls_label
= ofpact_put_SET_MPLS_LABEL(ofpacts
);
3544 return xstrdup("set_mpls_label: expected label.");
3547 mpls_label
->label
= htonl(atoi(arg
));
3552 format_SET_MPLS_LABEL(const struct ofpact_mpls_label
*a
,
3553 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3556 ds_put_format(s
, "%sset_mpls_label(%s%"PRIu32
"%s)%s",
3557 colors
.paren
, colors
.end
, ntohl(a
->label
),
3558 colors
.paren
, colors
.end
);
3561 /* Set MPLS TC actions. */
3564 decode_OFPAT_RAW_SET_MPLS_TC(uint8_t tc
,
3565 enum ofp_version ofp_version OVS_UNUSED
,
3568 ofpact_put_SET_MPLS_TC(out
)->tc
= tc
;
3573 encode_SET_MPLS_TC(const struct ofpact_mpls_tc
*tc
,
3574 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3576 if (ofp_version
< OFP12_VERSION
) {
3577 put_OFPAT_SET_MPLS_TC(out
, ofp_version
, tc
->tc
);
3579 put_set_field(out
, ofp_version
, MFF_MPLS_TC
, tc
->tc
);
3583 static char * OVS_WARN_UNUSED_RESULT
3584 parse_SET_MPLS_TC(char *arg
,
3585 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3586 struct ofpbuf
*ofpacts
,
3587 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3589 struct ofpact_mpls_tc
*mpls_tc
= ofpact_put_SET_MPLS_TC(ofpacts
);
3592 return xstrdup("set_mpls_tc: expected tc.");
3595 mpls_tc
->tc
= atoi(arg
);
3600 format_SET_MPLS_TC(const struct ofpact_mpls_tc
*a
,
3601 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3604 ds_put_format(s
, "%sset_mpls_ttl(%s%"PRIu8
"%s)%s",
3605 colors
.paren
, colors
.end
, a
->tc
,
3606 colors
.paren
, colors
.end
);
3609 /* Set MPLS TTL actions. */
3612 decode_OFPAT_RAW_SET_MPLS_TTL(uint8_t ttl
,
3613 enum ofp_version ofp_version OVS_UNUSED
,
3616 ofpact_put_SET_MPLS_TTL(out
)->ttl
= ttl
;
3621 encode_SET_MPLS_TTL(const struct ofpact_mpls_ttl
*ttl
,
3622 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3624 put_OFPAT_SET_MPLS_TTL(out
, ofp_version
, ttl
->ttl
);
3627 /* Parses 'arg' as the argument to a "set_mpls_ttl" action, and appends such an
3628 * action to 'ofpacts'.
3630 * Returns NULL if successful, otherwise a malloc()'d string describing the
3631 * error. The caller is responsible for freeing the returned string. */
3632 static char * OVS_WARN_UNUSED_RESULT
3633 parse_SET_MPLS_TTL(char *arg
,
3634 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3635 struct ofpbuf
*ofpacts
,
3636 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3638 struct ofpact_mpls_ttl
*mpls_ttl
= ofpact_put_SET_MPLS_TTL(ofpacts
);
3641 return xstrdup("set_mpls_ttl: expected ttl.");
3644 mpls_ttl
->ttl
= atoi(arg
);
3649 format_SET_MPLS_TTL(const struct ofpact_mpls_ttl
*a
,
3650 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3653 ds_put_format(s
, "%sset_mpls_ttl(%s%"PRIu8
"%s)%s",
3654 colors
.paren
, colors
.end
, a
->ttl
,
3655 colors
.paren
, colors
.end
);
3658 /* Decrement MPLS TTL actions. */
3661 decode_OFPAT_RAW_DEC_MPLS_TTL(struct ofpbuf
*out
)
3663 ofpact_put_DEC_MPLS_TTL(out
);
3668 encode_DEC_MPLS_TTL(const struct ofpact_null
*null OVS_UNUSED
,
3669 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3671 put_OFPAT_DEC_MPLS_TTL(out
, ofp_version
);
3674 static char * OVS_WARN_UNUSED_RESULT
3675 parse_DEC_MPLS_TTL(char *arg OVS_UNUSED
,
3676 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3677 struct ofpbuf
*ofpacts
,
3678 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3680 ofpact_put_DEC_MPLS_TTL(ofpacts
);
3685 format_DEC_MPLS_TTL(const struct ofpact_null
*a OVS_UNUSED
,
3686 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3689 ds_put_format(s
, "%sdec_mpls_ttl%s", colors
.value
, colors
.end
);
3692 /* Push MPLS label action. */
3695 decode_OFPAT_RAW_PUSH_MPLS(ovs_be16 ethertype
,
3696 enum ofp_version ofp_version OVS_UNUSED
,
3699 struct ofpact_push_mpls
*oam
;
3701 if (!eth_type_mpls(ethertype
)) {
3702 return OFPERR_OFPBAC_BAD_ARGUMENT
;
3704 oam
= ofpact_put_PUSH_MPLS(out
);
3705 oam
->ethertype
= ethertype
;
3711 encode_PUSH_MPLS(const struct ofpact_push_mpls
*push_mpls
,
3712 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3714 put_OFPAT_PUSH_MPLS(out
, ofp_version
, push_mpls
->ethertype
);
3717 static char * OVS_WARN_UNUSED_RESULT
3718 parse_PUSH_MPLS(char *arg
,
3719 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3720 struct ofpbuf
*ofpacts
,
3721 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3726 error
= str_to_u16(arg
, "push_mpls", ðertype
);
3728 ofpact_put_PUSH_MPLS(ofpacts
)->ethertype
= htons(ethertype
);
3734 format_PUSH_MPLS(const struct ofpact_push_mpls
*a
,
3735 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3738 ds_put_format(s
, "%spush_mpls:%s0x%04"PRIx16
,
3739 colors
.param
, colors
.end
, ntohs(a
->ethertype
));
3742 /* Pop MPLS label action. */
3745 decode_OFPAT_RAW_POP_MPLS(ovs_be16 ethertype
,
3746 enum ofp_version ofp_version OVS_UNUSED
,
3749 ofpact_put_POP_MPLS(out
)->ethertype
= ethertype
;
3754 encode_POP_MPLS(const struct ofpact_pop_mpls
*pop_mpls
,
3755 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3757 put_OFPAT_POP_MPLS(out
, ofp_version
, pop_mpls
->ethertype
);
3760 static char * OVS_WARN_UNUSED_RESULT
3761 parse_POP_MPLS(char *arg
,
3762 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3763 struct ofpbuf
*ofpacts
,
3764 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3769 error
= str_to_u16(arg
, "pop_mpls", ðertype
);
3771 ofpact_put_POP_MPLS(ofpacts
)->ethertype
= htons(ethertype
);
3777 format_POP_MPLS(const struct ofpact_pop_mpls
*a
,
3778 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3781 ds_put_format(s
, "%spop_mpls:%s0x%04"PRIx16
,
3782 colors
.param
, colors
.end
, ntohs(a
->ethertype
));
3785 /* Set tunnel ID actions. */
3788 decode_NXAST_RAW_SET_TUNNEL(uint32_t tun_id
,
3789 enum ofp_version ofp_version OVS_UNUSED
,
3792 struct ofpact_tunnel
*tunnel
= ofpact_put_SET_TUNNEL(out
);
3793 tunnel
->ofpact
.raw
= NXAST_RAW_SET_TUNNEL
;
3794 tunnel
->tun_id
= tun_id
;
3799 decode_NXAST_RAW_SET_TUNNEL64(uint64_t tun_id
,
3800 enum ofp_version ofp_version OVS_UNUSED
,
3803 struct ofpact_tunnel
*tunnel
= ofpact_put_SET_TUNNEL(out
);
3804 tunnel
->ofpact
.raw
= NXAST_RAW_SET_TUNNEL64
;
3805 tunnel
->tun_id
= tun_id
;
3810 encode_SET_TUNNEL(const struct ofpact_tunnel
*tunnel
,
3811 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3813 uint64_t tun_id
= tunnel
->tun_id
;
3815 if (ofp_version
< OFP12_VERSION
) {
3816 if (tun_id
<= UINT32_MAX
3817 && tunnel
->ofpact
.raw
!= NXAST_RAW_SET_TUNNEL64
) {
3818 put_NXAST_SET_TUNNEL(out
, tun_id
);
3820 put_NXAST_SET_TUNNEL64(out
, tun_id
);
3823 put_set_field(out
, ofp_version
, MFF_TUN_ID
, tun_id
);
3827 static char * OVS_WARN_UNUSED_RESULT
3828 parse_set_tunnel(char *arg
, struct ofpbuf
*ofpacts
,
3829 enum ofp_raw_action_type raw
)
3831 struct ofpact_tunnel
*tunnel
;
3833 tunnel
= ofpact_put_SET_TUNNEL(ofpacts
);
3834 tunnel
->ofpact
.raw
= raw
;
3835 return str_to_u64(arg
, &tunnel
->tun_id
);
3838 static char * OVS_WARN_UNUSED_RESULT
3839 parse_SET_TUNNEL(char *arg
,
3840 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3841 struct ofpbuf
*ofpacts
,
3842 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3844 return parse_set_tunnel(arg
, ofpacts
, NXAST_RAW_SET_TUNNEL
);
3848 format_SET_TUNNEL(const struct ofpact_tunnel
*a
,
3849 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3852 ds_put_format(s
, "%sset_tunnel%s:%s%#"PRIx64
, colors
.param
,
3853 (a
->tun_id
> UINT32_MAX
3854 || a
->ofpact
.raw
== NXAST_RAW_SET_TUNNEL64
? "64" : ""),
3855 colors
.end
, a
->tun_id
);
3858 /* Set queue action. */
3861 decode_OFPAT_RAW_SET_QUEUE(uint32_t queue_id
,
3862 enum ofp_version ofp_version OVS_UNUSED
,
3865 ofpact_put_SET_QUEUE(out
)->queue_id
= queue_id
;
3870 encode_SET_QUEUE(const struct ofpact_queue
*queue
,
3871 enum ofp_version ofp_version
, struct ofpbuf
*out
)
3873 put_OFPAT_SET_QUEUE(out
, ofp_version
, queue
->queue_id
);
3876 static char * OVS_WARN_UNUSED_RESULT
3877 parse_SET_QUEUE(char *arg
,
3878 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3879 struct ofpbuf
*ofpacts
,
3880 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3882 return str_to_u32(arg
, &ofpact_put_SET_QUEUE(ofpacts
)->queue_id
);
3886 format_SET_QUEUE(const struct ofpact_queue
*a
,
3887 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3890 ds_put_format(s
, "%sset_queue:%s%"PRIu32
,
3891 colors
.param
, colors
.end
, a
->queue_id
);
3894 /* Pop queue action. */
3897 decode_NXAST_RAW_POP_QUEUE(struct ofpbuf
*out
)
3899 ofpact_put_POP_QUEUE(out
);
3904 encode_POP_QUEUE(const struct ofpact_null
*null OVS_UNUSED
,
3905 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
3907 put_NXAST_POP_QUEUE(out
);
3910 static char * OVS_WARN_UNUSED_RESULT
3911 parse_POP_QUEUE(const char *arg OVS_UNUSED
,
3912 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3913 struct ofpbuf
*ofpacts
,
3914 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3916 ofpact_put_POP_QUEUE(ofpacts
);
3921 format_POP_QUEUE(const struct ofpact_null
*a OVS_UNUSED
,
3922 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3925 ds_put_format(s
, "%spop_queue%s", colors
.value
, colors
.end
);
3928 /* Action structure for NXAST_FIN_TIMEOUT.
3930 * This action changes the idle timeout or hard timeout, or both, of this
3931 * OpenFlow rule when the rule matches a TCP packet with the FIN or RST flag.
3932 * When such a packet is observed, the action reduces the rule's idle timeout
3933 * to 'fin_idle_timeout' and its hard timeout to 'fin_hard_timeout'. This
3934 * action has no effect on an existing timeout that is already shorter than the
3935 * one that the action specifies. A 'fin_idle_timeout' or 'fin_hard_timeout'
3936 * of zero has no effect on the respective timeout.
3938 * 'fin_idle_timeout' and 'fin_hard_timeout' are measured in seconds.
3939 * 'fin_hard_timeout' specifies time since the flow's creation, not since the
3940 * receipt of the FIN or RST.
3942 * This is useful for quickly discarding learned TCP flows that otherwise will
3943 * take a long time to expire.
3945 * This action is intended for use with an OpenFlow rule that matches only a
3946 * single TCP flow. If the rule matches multiple TCP flows (e.g. it wildcards
3947 * all TCP traffic, or all TCP traffic to a particular port), then any FIN or
3948 * RST in any of those flows will cause the entire OpenFlow rule to expire
3949 * early, which is not normally desirable.
3951 struct nx_action_fin_timeout
{
3952 ovs_be16 type
; /* OFPAT_VENDOR. */
3953 ovs_be16 len
; /* 16. */
3954 ovs_be32 vendor
; /* NX_VENDOR_ID. */
3955 ovs_be16 subtype
; /* NXAST_FIN_TIMEOUT. */
3956 ovs_be16 fin_idle_timeout
; /* New idle timeout, if nonzero. */
3957 ovs_be16 fin_hard_timeout
; /* New hard timeout, if nonzero. */
3958 ovs_be16 pad
; /* Must be zero. */
3960 OFP_ASSERT(sizeof(struct nx_action_fin_timeout
) == 16);
3963 decode_NXAST_RAW_FIN_TIMEOUT(const struct nx_action_fin_timeout
*naft
,
3964 enum ofp_version ofp_version OVS_UNUSED
,
3967 struct ofpact_fin_timeout
*oft
;
3969 oft
= ofpact_put_FIN_TIMEOUT(out
);
3970 oft
->fin_idle_timeout
= ntohs(naft
->fin_idle_timeout
);
3971 oft
->fin_hard_timeout
= ntohs(naft
->fin_hard_timeout
);
3976 encode_FIN_TIMEOUT(const struct ofpact_fin_timeout
*fin_timeout
,
3977 enum ofp_version ofp_version OVS_UNUSED
,
3980 struct nx_action_fin_timeout
*naft
= put_NXAST_FIN_TIMEOUT(out
);
3981 naft
->fin_idle_timeout
= htons(fin_timeout
->fin_idle_timeout
);
3982 naft
->fin_hard_timeout
= htons(fin_timeout
->fin_hard_timeout
);
3985 static char * OVS_WARN_UNUSED_RESULT
3986 parse_FIN_TIMEOUT(char *arg
,
3987 const struct ofputil_port_map
*port_map OVS_UNUSED
,
3988 struct ofpbuf
*ofpacts
,
3989 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
3991 struct ofpact_fin_timeout
*oft
= ofpact_put_FIN_TIMEOUT(ofpacts
);
3994 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
3997 if (!strcmp(key
, "idle_timeout")) {
3998 error
= str_to_u16(value
, key
, &oft
->fin_idle_timeout
);
3999 } else if (!strcmp(key
, "hard_timeout")) {
4000 error
= str_to_u16(value
, key
, &oft
->fin_hard_timeout
);
4002 error
= xasprintf("invalid key '%s' in 'fin_timeout' argument",
4014 format_FIN_TIMEOUT(const struct ofpact_fin_timeout
*a
,
4015 const struct ofputil_port_map
*port_map OVS_UNUSED
,
4018 ds_put_format(s
, "%sfin_timeout(%s", colors
.paren
, colors
.end
);
4019 if (a
->fin_idle_timeout
) {
4020 ds_put_format(s
, "%sidle_timeout=%s%"PRIu16
",",
4021 colors
.param
, colors
.end
, a
->fin_idle_timeout
);
4023 if (a
->fin_hard_timeout
) {
4024 ds_put_format(s
, "%shard_timeout=%s%"PRIu16
",",
4025 colors
.param
, colors
.end
, a
->fin_hard_timeout
);
4028 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
4031 /* Action structure for NXAST_ENCAP */
4032 struct nx_action_encap
{
4033 ovs_be16 type
; /* OFPAT_VENDOR. */
4034 ovs_be16 len
; /* Total size including any property TLVs. */
4035 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4036 ovs_be16 subtype
; /* NXAST_ENCAP. */
4037 ovs_be16 hdr_size
; /* Header size in bytes, 0 = 'not specified'.*/
4038 ovs_be32 new_pkt_type
; /* Header type to add and PACKET_TYPE of result. */
4039 struct ofp_ed_prop_header props
[]; /* Encap TLV properties. */
4041 OFP_ASSERT(sizeof(struct nx_action_encap
) == 16);
4044 decode_NXAST_RAW_ENCAP(const struct nx_action_encap
*nae
,
4045 enum ofp_version ofp_version OVS_UNUSED
,
4048 struct ofpact_encap
*encap
;
4049 const struct ofp_ed_prop_header
*ofp_prop
;
4051 uint16_t n_props
= 0;
4054 encap
= ofpact_put_ENCAP(out
);
4055 encap
->ofpact
.raw
= NXAST_RAW_ENCAP
;
4056 switch (ntohl(nae
->new_pkt_type
)) {
4059 /* Add supported encap header types here. */
4062 return OFPERR_NXBAC_BAD_HEADER_TYPE
;
4064 encap
->new_pkt_type
= nae
->new_pkt_type
;
4065 encap
->hdr_size
= ntohs(nae
->hdr_size
);
4067 ofp_prop
= nae
->props
;
4068 props_len
= ntohs(nae
->len
) - offsetof(struct nx_action_encap
, props
);
4070 while (props_len
> 0) {
4071 err
= decode_ed_prop(&ofp_prop
, out
, &props_len
);
4077 encap
->n_props
= n_props
;
4078 out
->header
= &encap
->ofpact
;
4079 ofpact_finish_ENCAP(out
, &encap
);
4085 encode_ENCAP(const struct ofpact_encap
*encap
,
4086 enum ofp_version ofp_version OVS_UNUSED
,
4089 size_t start_ofs
= out
->size
;
4090 struct nx_action_encap
*nae
= put_NXAST_ENCAP(out
);
4093 nae
->new_pkt_type
= encap
->new_pkt_type
;
4094 nae
->hdr_size
= htons(encap
->hdr_size
);
4095 const struct ofpact_ed_prop
*prop
= encap
->props
;
4096 for (i
= 0; i
< encap
->n_props
; i
++) {
4097 encode_ed_prop(&prop
, out
);
4099 pad_ofpat(out
, start_ofs
);
4103 parse_encap_header(const char *hdr
, ovs_be32
*packet_type
)
4105 if (strcmp(hdr
, "ethernet") == 0) {
4106 *packet_type
= htonl(PT_ETH
);
4107 } else if (strcmp(hdr
, "nsh") == 0) {
4108 *packet_type
= htonl(PT_NSH
);
4116 parse_ed_props(const uint16_t prop_class
, char **arg
, int *n_props
, struct ofpbuf
*out
)
4118 char *key
, *value
, *err
;
4121 while (ofputil_parse_key_value(arg
, &key
, &value
)) {
4122 if (!parse_ed_prop_type(prop_class
, key
, &prop_type
)) {
4123 return xasprintf("Invalid property: %s", key
);
4125 if (value
== NULL
) {
4126 return xasprintf("Missing the value for property: %s", key
);
4128 err
= parse_ed_prop_value(prop_class
, prop_type
, value
, out
);
4137 /* The string representation of the encap action is
4138 * encap(header_type(prop=<value>,tlv(<class>,<type>,<value>),...))
4141 static char * OVS_WARN_UNUSED_RESULT
4142 parse_ENCAP(char *arg
,
4143 const struct ofputil_port_map
*port_map OVS_UNUSED
,
4145 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
4147 struct ofpact_encap
*encap
;
4148 char *key
, *value
, *str
;
4150 uint16_t prop_class
;
4153 encap
= ofpact_put_ENCAP(out
);
4154 encap
->hdr_size
= 0;
4155 /* Parse encap header type. */
4157 if (!ofputil_parse_key_value(&arg
, &key
, &value
)) {
4158 return xasprintf("Missing encap hdr: %s", str
);
4160 if (!parse_encap_header(key
, &encap
->new_pkt_type
)) {
4161 return xasprintf("Encap hdr not supported: %s", value
);
4163 if (!parse_ed_prop_class(key
, &prop_class
)) {
4164 return xasprintf("Invalid encap prop class: %s", key
);
4166 /* Parse encap properties. */
4167 error
= parse_ed_props(prop_class
, &value
, &n_props
, out
);
4168 if (error
!= NULL
) {
4171 /* ofbuf out may have been re-allocated. */
4172 encap
= out
->header
;
4173 encap
->n_props
= n_props
;
4174 ofpact_finish_ENCAP(out
, &encap
);
4179 format_encap_pkt_type(const ovs_be32 pkt_type
)
4181 switch (ntohl(pkt_type
)) {
4192 format_ed_props(struct ds
*s
, uint16_t n_props
,
4193 const struct ofpact_ed_prop
*prop
)
4195 const uint8_t *p
= (uint8_t *) prop
;
4201 for (i
= 0; i
< n_props
; i
++) {
4202 format_ed_prop(s
, prop
);
4203 ds_put_char(s
, ',');
4204 p
+= ROUND_UP(prop
->len
, 8);
4205 prop
= ALIGNED_CAST(const struct ofpact_ed_prop
*, p
);
4213 format_ENCAP(const struct ofpact_encap
*a
,
4214 const struct ofputil_port_map
*port_map OVS_UNUSED
,
4217 ds_put_format(s
, "%sencap(%s", colors
.paren
, colors
.end
);
4218 ds_put_format(s
, "%s", format_encap_pkt_type(a
->new_pkt_type
));
4219 if (a
->n_props
> 0) {
4220 ds_put_format(s
, "%s(%s", colors
.paren
, colors
.end
);
4221 format_ed_props(s
, a
->n_props
, a
->props
);
4222 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
4224 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
4227 /* Action structure for NXAST_DECAP */
4228 struct nx_action_decap
{
4229 ovs_be16 type
; /* OFPAT_VENDOR. */
4230 ovs_be16 len
; /* Total size including any property TLVs. */
4231 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4232 ovs_be16 subtype
; /* NXAST_DECAP. */
4233 uint8_t pad
[2]; /* 2 bytes padding */
4235 /* Packet type or result.
4237 * The special value (0,0xFFFE) "Use next proto"
4238 * is used to request OVS to automatically set the new packet type based
4239 * on the decap'ed header's next protocol.
4241 ovs_be32 new_pkt_type
;
4243 OFP_ASSERT(sizeof(struct nx_action_decap
) == 16);
4246 decode_NXAST_RAW_DECAP(const struct nx_action_decap
*nad
,
4247 enum ofp_version ofp_version OVS_UNUSED
,
4248 struct ofpbuf
*ofpacts
)
4250 struct ofpact_decap
* decap
;
4252 if (ntohs(nad
->len
) > sizeof *nad
) {
4253 /* No properties supported yet. */
4254 return OFPERR_NXBAC_UNKNOWN_ED_PROP
;
4257 decap
= ofpact_put_DECAP(ofpacts
);
4258 decap
->ofpact
.raw
= NXAST_RAW_DECAP
;
4259 decap
->new_pkt_type
= nad
->new_pkt_type
;
4264 encode_DECAP(const struct ofpact_decap
*decap
,
4265 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
4267 struct nx_action_decap
*nad
= put_NXAST_DECAP(out
);
4269 nad
->len
= htons(sizeof(struct nx_action_decap
));
4270 nad
->new_pkt_type
= decap
->new_pkt_type
;
4273 static char * OVS_WARN_UNUSED_RESULT
4274 parse_DECAP(char *arg
,
4275 const struct ofputil_port_map
*port_map OVS_UNUSED
,
4276 struct ofpbuf
*ofpacts
,
4277 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
4279 struct ofpact_decap
*decap
;
4280 char *key
, *value
, *pos
;
4284 decap
= ofpact_put_DECAP(ofpacts
);
4285 /* Default next packet_type is PT_USE_NEXT_PROTO. */
4286 decap
->new_pkt_type
= htonl(PT_USE_NEXT_PROTO
);
4288 /* Parse decap packet_type if given. */
4289 if (ofputil_parse_key_value(&arg
, &key
, &value
)) {
4290 if (strcmp(key
, "packet_type") == 0) {
4292 if (!ofputil_parse_key_value(&pos
, &key
, &value
)
4293 || strcmp(key
, "ns") != 0) {
4294 return xstrdup("Missing packet_type attribute ns");
4296 error
= str_to_u16(value
, "ns", &ns
);
4300 if (ns
>= OFPHTN_N_TYPES
) {
4301 return xasprintf("Unsupported ns value: %"PRIu16
, ns
);
4303 if (!ofputil_parse_key_value(&pos
, &key
, &value
)
4304 || strcmp(key
, "type") != 0) {
4305 return xstrdup("Missing packet_type attribute type");
4307 error
= str_to_u16(value
, "type", &type
);
4311 decap
->new_pkt_type
= htonl(PACKET_TYPE(ns
, type
));
4313 return xasprintf("Invalid decap argument: %s", key
);
4320 format_DECAP(const struct ofpact_decap
*a
,
4321 const struct ofputil_port_map
*port_map OVS_UNUSED
,
4324 ds_put_format(s
, "%sdecap(%s", colors
.paren
, colors
.end
);
4325 if (a
->new_pkt_type
!= htonl(PT_USE_NEXT_PROTO
)) {
4326 ds_put_format(s
, "packet_type(ns=%"PRIu16
",id=%#"PRIx16
")",
4327 pt_ns(a
->new_pkt_type
),
4328 pt_ns_type(a
->new_pkt_type
));
4330 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
4334 /* Action structures for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE, and
4335 * NXAST_RESUBMIT_TABLE_CT.
4337 * These actions search one of the switch's flow tables:
4339 * - For NXAST_RESUBMIT_TABLE and NXAST_RESUBMIT_TABLE_CT, if the
4340 * 'table' member is not 255, then it specifies the table to search.
4342 * - Otherwise (for NXAST_RESUBMIT_TABLE or NXAST_RESUBMIT_TABLE_CT with a
4343 * 'table' of 255, or for NXAST_RESUBMIT regardless of 'table'), it
4344 * searches the current flow table, that is, the OpenFlow flow table that
4345 * contains the flow from which this action was obtained. If this action
4346 * did not come from a flow table (e.g. it came from an OFPT_PACKET_OUT
4347 * message), then table 0 is the current table.
4349 * The flow table lookup uses a flow that may be slightly modified from the
4352 * - For NXAST_RESUBMIT, the 'in_port' member of struct nx_action_resubmit
4353 * is used as the flow's in_port.
4355 * - For NXAST_RESUBMIT_TABLE and NXAST_RESUBMIT_TABLE_CT, if the 'in_port'
4356 * member is not OFPP_IN_PORT, then its value is used as the flow's
4357 * in_port. Otherwise, the original in_port is used.
4359 * - For NXAST_RESUBMIT_TABLE_CT the Conntrack 5-tuple fields are used as
4360 * the packets IP header fields during the lookup.
4362 * - If actions that modify the flow (e.g. OFPAT_SET_VLAN_VID) precede the
4363 * resubmit action, then the flow is updated with the new values.
4365 * Following the lookup, the original in_port is restored.
4367 * If the modified flow matched in the flow table, then the corresponding
4368 * actions are executed. Afterward, actions following the resubmit in the
4369 * original set of actions, if any, are executed; any changes made to the
4370 * packet (e.g. changes to VLAN) by secondary actions persist when those
4371 * actions are executed, although the original in_port is restored.
4373 * Resubmit actions may be used any number of times within a set of actions.
4375 * Resubmit actions may nest. To prevent infinite loops and excessive resource
4376 * use, the implementation may limit nesting depth and the total number of
4379 * - Open vSwitch 1.0.1 and earlier did not support recursion.
4381 * - Open vSwitch 1.0.2 and 1.0.3 limited recursion to 8 levels.
4383 * - Open vSwitch 1.1 and 1.2 limited recursion to 16 levels.
4385 * - Open vSwitch 1.2 through 1.8 limited recursion to 32 levels.
4387 * - Open vSwitch 1.9 through 2.0 limited recursion to 64 levels.
4389 * - Open vSwitch 2.1 through 2.5 limited recursion to 64 levels and impose
4390 * a total limit of 4,096 resubmits per flow translation (earlier versions
4391 * did not impose any total limit).
4393 * NXAST_RESUBMIT ignores 'table' and 'pad'. NXAST_RESUBMIT_TABLE and
4394 * NXAST_RESUBMIT_TABLE_CT require 'pad' to be all-bits-zero.
4396 * Open vSwitch 1.0.1 and earlier did not support recursion. Open vSwitch
4397 * before 1.2.90 did not support NXAST_RESUBMIT_TABLE. Open vSwitch before
4398 * 2.8.0 did not support NXAST_RESUBMIT_TABLE_CT.
4400 struct nx_action_resubmit
{
4401 ovs_be16 type
; /* OFPAT_VENDOR. */
4402 ovs_be16 len
; /* Length is 16. */
4403 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4404 ovs_be16 subtype
; /* NXAST_RESUBMIT. */
4405 ovs_be16 in_port
; /* New in_port for checking flow table. */
4406 uint8_t table
; /* NXAST_RESUBMIT_TABLE: table to use. */
4409 OFP_ASSERT(sizeof(struct nx_action_resubmit
) == 16);
4412 decode_NXAST_RAW_RESUBMIT(uint16_t port
,
4413 enum ofp_version ofp_version OVS_UNUSED
,
4416 struct ofpact_resubmit
*resubmit
;
4418 resubmit
= ofpact_put_RESUBMIT(out
);
4419 resubmit
->ofpact
.raw
= NXAST_RAW_RESUBMIT
;
4420 resubmit
->in_port
= u16_to_ofp(port
);
4421 resubmit
->table_id
= 0xff;
4426 decode_NXAST_RAW_RESUBMIT_TABLE(const struct nx_action_resubmit
*nar
,
4427 enum ofp_version ofp_version OVS_UNUSED
,
4430 struct ofpact_resubmit
*resubmit
;
4432 if (nar
->pad
[0] || nar
->pad
[1] || nar
->pad
[2]) {
4433 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4436 resubmit
= ofpact_put_RESUBMIT(out
);
4437 resubmit
->ofpact
.raw
= NXAST_RAW_RESUBMIT_TABLE
;
4438 resubmit
->in_port
= u16_to_ofp(ntohs(nar
->in_port
));
4439 resubmit
->table_id
= nar
->table
;
4444 decode_NXAST_RAW_RESUBMIT_TABLE_CT(const struct nx_action_resubmit
*nar
,
4445 enum ofp_version ofp_version OVS_UNUSED
,
4448 enum ofperr error
= decode_NXAST_RAW_RESUBMIT_TABLE(nar
, ofp_version
, out
);
4452 struct ofpact_resubmit
*resubmit
= out
->header
;
4453 resubmit
->ofpact
.raw
= NXAST_RAW_RESUBMIT_TABLE_CT
;
4454 resubmit
->with_ct_orig
= true;
4459 encode_RESUBMIT(const struct ofpact_resubmit
*resubmit
,
4460 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
4462 uint16_t in_port
= ofp_to_u16(resubmit
->in_port
);
4464 if (resubmit
->table_id
== 0xff
4465 && resubmit
->ofpact
.raw
== NXAST_RAW_RESUBMIT
) {
4466 put_NXAST_RESUBMIT(out
, in_port
);
4468 struct nx_action_resubmit
*nar
;
4469 nar
= resubmit
->with_ct_orig
4470 ? put_NXAST_RESUBMIT_TABLE_CT(out
) : put_NXAST_RESUBMIT_TABLE(out
);
4471 nar
->table
= resubmit
->table_id
;
4472 nar
->in_port
= htons(in_port
);
4476 static char * OVS_WARN_UNUSED_RESULT
4477 parse_RESUBMIT(char *arg
,
4478 const struct ofputil_port_map
*port_map
,
4479 struct ofpbuf
*ofpacts
,
4480 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
4482 struct ofpact_resubmit
*resubmit
;
4483 char *in_port_s
, *table_s
, *ct_s
;
4485 resubmit
= ofpact_put_RESUBMIT(ofpacts
);
4487 in_port_s
= strsep(&arg
, ",");
4488 if (in_port_s
&& in_port_s
[0]) {
4489 if (!ofputil_port_from_string(in_port_s
, port_map
,
4490 &resubmit
->in_port
)) {
4491 return xasprintf("%s: resubmit to unknown port", in_port_s
);
4494 resubmit
->in_port
= OFPP_IN_PORT
;
4497 table_s
= strsep(&arg
, ",");
4498 if (table_s
&& table_s
[0]) {
4499 uint32_t table_id
= 0;
4502 error
= str_to_u32(table_s
, &table_id
);
4506 resubmit
->table_id
= table_id
;
4508 resubmit
->table_id
= 255;
4511 ct_s
= strsep(&arg
, ",");
4512 if (ct_s
&& ct_s
[0]) {
4513 if (strcmp(ct_s
, "ct")) {
4514 return xasprintf("%s: unknown parameter", ct_s
);
4516 resubmit
->with_ct_orig
= true;
4518 resubmit
->with_ct_orig
= false;
4521 if (resubmit
->in_port
== OFPP_IN_PORT
&& resubmit
->table_id
== 255) {
4522 return xstrdup("at least one \"in_port\" or \"table\" must be "
4523 "specified on resubmit");
4529 format_RESUBMIT(const struct ofpact_resubmit
*a
,
4530 const struct ofputil_port_map
*port_map
, struct ds
*s
)
4532 if (a
->in_port
!= OFPP_IN_PORT
&& a
->table_id
== 255) {
4533 ds_put_format(s
, "%sresubmit:%s", colors
.special
, colors
.end
);
4534 ofputil_format_port(a
->in_port
, port_map
, s
);
4536 ds_put_format(s
, "%sresubmit(%s", colors
.paren
, colors
.end
);
4537 if (a
->in_port
!= OFPP_IN_PORT
) {
4538 ofputil_format_port(a
->in_port
, port_map
, s
);
4540 ds_put_char(s
, ',');
4541 if (a
->table_id
!= 255) {
4542 ds_put_format(s
, "%"PRIu8
, a
->table_id
);
4544 if (a
->with_ct_orig
) {
4545 ds_put_cstr(s
, ",ct");
4547 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
4551 /* Action structure for NXAST_LEARN and NXAST_LEARN2.
4553 * This action adds or modifies a flow in an OpenFlow table, similar to
4554 * OFPT_FLOW_MOD with OFPFC_MODIFY_STRICT as 'command'. The new flow has the
4555 * specified idle timeout, hard timeout, priority, cookie, and flags. The new
4556 * flow's match criteria and actions are built by applying each of the series
4557 * of flow_mod_spec elements included as part of the action.
4559 * A flow_mod_spec starts with a 16-bit header. A header that is all-bits-0 is
4560 * a no-op used for padding the action as a whole to a multiple of 8 bytes in
4561 * length. Otherwise, the flow_mod_spec can be thought of as copying 'n_bits'
4562 * bits from a source to a destination. In this case, the header contains
4565 * 15 14 13 12 11 10 0
4566 * +------+---+------+---------------------------------+
4567 * | 0 |src| dst | n_bits |
4568 * +------+---+------+---------------------------------+
4570 * The meaning and format of a flow_mod_spec depends on 'src' and 'dst'. The
4571 * following table summarizes the meaning of each possible combination.
4572 * Details follow the table:
4575 * --- --- ----------------------------------------------------------
4576 * 0 0 Add match criteria based on value in a field.
4577 * 1 0 Add match criteria based on an immediate value.
4578 * 0 1 Add NXAST_REG_LOAD action to copy field into a different field.
4579 * 1 1 Add NXAST_REG_LOAD action to load immediate value into a field.
4580 * 0 2 Add OFPAT_OUTPUT action to output to port from specified field.
4581 * All other combinations are undefined and not allowed.
4583 * The flow_mod_spec header is followed by a source specification and a
4584 * destination specification. The format and meaning of the source
4585 * specification depends on 'src':
4587 * - If 'src' is 0, the source bits are taken from a field in the flow to
4588 * which this action is attached. (This should be a wildcarded field. If
4589 * its value is fully specified then the source bits being copied have
4592 * The source specification is an ovs_be32 'field' and an ovs_be16 'ofs'.
4593 * 'field' is an nxm_header with nxm_hasmask=0, and 'ofs' the starting bit
4594 * offset within that field. The source bits are field[ofs:ofs+n_bits-1].
4595 * 'field' and 'ofs' are subject to the same restrictions as the source
4596 * field in NXAST_REG_MOVE.
4598 * - If 'src' is 1, the source bits are a constant value. The source
4599 * specification is (n_bits+15)/16*2 bytes long. Taking those bytes as a
4600 * number in network order, the source bits are the 'n_bits'
4601 * least-significant bits. The switch will report an error if other bits
4602 * in the constant are nonzero.
4604 * The flow_mod_spec destination specification, for 'dst' of 0 or 1, is an
4605 * ovs_be32 'field' and an ovs_be16 'ofs'. 'field' is an nxm_header with
4606 * nxm_hasmask=0 and 'ofs' is a starting bit offset within that field. The
4607 * meaning of the flow_mod_spec depends on 'dst':
4609 * - If 'dst' is 0, the flow_mod_spec specifies match criteria for the new
4610 * flow. The new flow matches only if bits field[ofs:ofs+n_bits-1] in a
4611 * packet equal the source bits. 'field' may be any nxm_header with
4612 * nxm_hasmask=0 that is allowed in NXT_FLOW_MOD.
4614 * Order is significant. Earlier flow_mod_specs must satisfy any
4615 * prerequisites for matching fields specified later, by copying constant
4616 * values into prerequisite fields.
4618 * The switch will reject flow_mod_specs that do not satisfy NXM masking
4621 * - If 'dst' is 1, the flow_mod_spec specifies an NXAST_REG_LOAD action for
4622 * the new flow. The new flow copies the source bits into
4623 * field[ofs:ofs+n_bits-1]. Actions are executed in the same order as the
4626 * A single NXAST_REG_LOAD action writes no more than 64 bits, so n_bits
4627 * greater than 64 yields multiple NXAST_REG_LOAD actions.
4629 * The flow_mod_spec destination spec for 'dst' of 2 (when 'src' is 0) is
4630 * empty. It has the following meaning:
4632 * - The flow_mod_spec specifies an OFPAT_OUTPUT action for the new flow.
4633 * The new flow outputs to the OpenFlow port specified by the source field.
4634 * Of the special output ports with value OFPP_MAX or larger, OFPP_IN_PORT,
4635 * OFPP_FLOOD, OFPP_LOCAL, and OFPP_ALL are supported. Other special ports
4638 * Resource Management
4639 * -------------------
4641 * A switch has a finite amount of flow table space available for learning.
4642 * When this space is exhausted, no new learning table entries will be learned
4643 * until some existing flow table entries expire. The controller should be
4644 * prepared to handle this by flooding (which can be implemented as a
4645 * low-priority flow).
4647 * If a learned flow matches a single TCP stream with a relatively long
4648 * timeout, one may make the best of resource constraints by setting
4649 * 'fin_idle_timeout' or 'fin_hard_timeout' (both measured in seconds), or
4650 * both, to shorter timeouts. When either of these is specified as a nonzero
4651 * value, OVS adds a NXAST_FIN_TIMEOUT action, with the specified timeouts, to
4657 * The following examples give a prose description of the flow_mod_specs along
4658 * with informal notation for how those would be represented and a hex dump of
4659 * the bytes that would be required.
4661 * These examples could work with various nx_action_learn parameters. Typical
4662 * values would be idle_timeout=OFP_FLOW_PERMANENT, hard_timeout=60,
4663 * priority=OFP_DEFAULT_PRIORITY, flags=0, table_id=10.
4665 * 1. Learn input port based on the source MAC, with lookup into
4666 * NXM_NX_REG1[16:31] by resubmit to in_port=99:
4668 * Match on in_port=99:
4669 * ovs_be16(src=1, dst=0, n_bits=16), 20 10
4670 * ovs_be16(99), 00 63
4671 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
4673 * Match Ethernet destination on Ethernet source from packet:
4674 * ovs_be16(src=0, dst=0, n_bits=48), 00 30
4675 * ovs_be32(NXM_OF_ETH_SRC), ovs_be16(0) 00 00 04 06 00 00
4676 * ovs_be32(NXM_OF_ETH_DST), ovs_be16(0) 00 00 02 06 00 00
4678 * Set NXM_NX_REG1[16:31] to the packet's input port:
4679 * ovs_be16(src=0, dst=1, n_bits=16), 08 10
4680 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
4681 * ovs_be32(NXM_NX_REG1), ovs_be16(16) 00 01 02 04 00 10
4683 * Given a packet that arrived on port A with Ethernet source address B,
4684 * this would set up the flow "in_port=99, dl_dst=B,
4685 * actions=load:A->NXM_NX_REG1[16..31]".
4687 * In syntax accepted by ovs-ofctl, this action is: learn(in_port=99,
4688 * NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
4689 * load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
4691 * 2. Output to input port based on the source MAC and VLAN VID, with lookup
4692 * into NXM_NX_REG1[16:31]:
4694 * Match on same VLAN ID as packet:
4695 * ovs_be16(src=0, dst=0, n_bits=12), 00 0c
4696 * ovs_be32(NXM_OF_VLAN_TCI), ovs_be16(0) 00 00 08 02 00 00
4697 * ovs_be32(NXM_OF_VLAN_TCI), ovs_be16(0) 00 00 08 02 00 00
4699 * Match Ethernet destination on Ethernet source from packet:
4700 * ovs_be16(src=0, dst=0, n_bits=48), 00 30
4701 * ovs_be32(NXM_OF_ETH_SRC), ovs_be16(0) 00 00 04 06 00 00
4702 * ovs_be32(NXM_OF_ETH_DST), ovs_be16(0) 00 00 02 06 00 00
4704 * Output to the packet's input port:
4705 * ovs_be16(src=0, dst=2, n_bits=16), 10 10
4706 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
4708 * Given a packet that arrived on port A with Ethernet source address B in
4709 * VLAN C, this would set up the flow "dl_dst=B, vlan_vid=C,
4710 * actions=output:A".
4712 * In syntax accepted by ovs-ofctl, this action is:
4713 * learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
4714 * output:NXM_OF_IN_PORT[])
4716 * 3. Here's a recipe for a very simple-minded MAC learning switch. It uses a
4717 * 10-second MAC expiration time to make it easier to see what's going on
4719 * ovs-vsctl del-controller br0
4720 * ovs-ofctl del-flows br0
4721 * ovs-ofctl add-flow br0 "table=0 actions=learn(table=1, \
4722 hard_timeout=10, NXM_OF_VLAN_TCI[0..11], \
4723 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
4724 output:NXM_OF_IN_PORT[]), resubmit(,1)"
4725 * ovs-ofctl add-flow br0 "table=1 priority=0 actions=flood"
4727 * You can then dump the MAC learning table with:
4729 * ovs-ofctl dump-flows br0 table=1
4734 * For best performance, segregate learned flows into a table that is not used
4735 * for any other flows except possibly for a lowest-priority "catch-all" flow
4736 * (a flow with no match criteria). If different learning actions specify
4737 * different match criteria, use different tables for the learned flows.
4739 * The meaning of 'hard_timeout' and 'idle_timeout' can be counterintuitive.
4740 * These timeouts apply to the flow that is added, which means that a flow with
4741 * an idle timeout will expire when no traffic has been sent *to* the learned
4742 * address. This is not usually the intent in MAC learning; instead, we want
4743 * the MAC learn entry to expire when no traffic has been sent *from* the
4744 * learned address. Use a hard timeout for that.
4747 * Visibility of Changes
4748 * ---------------------
4750 * Prior to Open vSwitch 2.4, any changes made by a "learn" action in a given
4751 * flow translation are visible to flow table lookups made later in the flow
4752 * translation. This means that, in the example above, a MAC learned by the
4753 * learn action in table 0 would be found in table 1 (if the packet being
4754 * processed had the same source and destination MAC address).
4756 * In Open vSwitch 2.4 and later, changes to a flow table (whether to add or
4757 * modify a flow) by a "learn" action are visible only for later flow
4758 * translations, not for later lookups within the same flow translation. In
4759 * the MAC learning example, a MAC learned by the learn action in table 0 would
4760 * not be found in table 1 if the flow translation would resubmit to table 1
4761 * after the processing of the learn action, meaning that if this MAC had not
4762 * been learned before then the packet would be flooded. */
4763 struct nx_action_learn
{
4764 ovs_be16 type
; /* OFPAT_VENDOR. */
4765 ovs_be16 len
; /* At least 24. */
4766 ovs_be32 vendor
; /* NX_VENDOR_ID. */
4767 ovs_be16 subtype
; /* NXAST_LEARN. */
4768 ovs_be16 idle_timeout
; /* Idle time before discarding (seconds). */
4769 ovs_be16 hard_timeout
; /* Max time before discarding (seconds). */
4770 ovs_be16 priority
; /* Priority level of flow entry. */
4771 ovs_be64 cookie
; /* Cookie for new flow. */
4772 ovs_be16 flags
; /* NX_LEARN_F_*. */
4773 uint8_t table_id
; /* Table to insert flow entry. */
4774 uint8_t pad
; /* Must be zero. */
4775 ovs_be16 fin_idle_timeout
; /* Idle timeout after FIN, if nonzero. */
4776 ovs_be16 fin_hard_timeout
; /* Hard timeout after FIN, if nonzero. */
4777 /* Followed by a sequence of flow_mod_spec elements, as described above,
4778 * until the end of the action is reached. */
4780 OFP_ASSERT(sizeof(struct nx_action_learn
) == 32);
4782 struct nx_action_learn2
{
4783 struct nx_action_learn up
; /* The wire format includes nx_action_learn. */
4784 ovs_be32 limit
; /* Maximum number of learned flows.
4785 * 0 indicates unlimited. */
4787 /* Where to store the result. */
4788 ovs_be16 result_dst_ofs
; /* Starting bit offset in destination. */
4790 ovs_be16 pad2
; /* Must be zero. */
4792 * - OXM/NXM header for destination field (4 or 8 bytes),
4793 * if NX_LEARN_F_WRITE_RESULT is set in 'flags'
4794 * - a sequence of flow_mod_spec elements, as described above,
4795 * until the end of the action is reached. */
4797 OFP_ASSERT(sizeof(struct nx_action_learn2
) == 40);
4800 get_be16(const void **pp
)
4802 const ovs_be16
*p
= *pp
;
4803 ovs_be16 value
= *p
;
4809 get_be32(const void **pp
)
4811 const ovs_be32
*p
= *pp
;
4812 ovs_be32 value
= get_unaligned_be32(p
);
4818 get_subfield(int n_bits
, const void **p
, struct mf_subfield
*sf
,
4819 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
)
4823 error
= mf_vl_mff_mf_from_nxm_header(ntohl(get_be32(p
)), vl_mff_map
,
4824 &sf
->field
, tlv_bitmap
);
4825 sf
->ofs
= ntohs(get_be16(p
));
4826 sf
->n_bits
= n_bits
;
4831 learn_min_len(uint16_t header
)
4833 int n_bits
= header
& NX_LEARN_N_BITS_MASK
;
4834 int src_type
= header
& NX_LEARN_SRC_MASK
;
4835 int dst_type
= header
& NX_LEARN_DST_MASK
;
4836 unsigned int min_len
;
4839 if (src_type
== NX_LEARN_SRC_FIELD
) {
4840 min_len
+= sizeof(ovs_be32
); /* src_field */
4841 min_len
+= sizeof(ovs_be16
); /* src_ofs */
4843 min_len
+= DIV_ROUND_UP(n_bits
, 16);
4845 if (dst_type
== NX_LEARN_DST_MATCH
||
4846 dst_type
== NX_LEARN_DST_LOAD
) {
4847 min_len
+= sizeof(ovs_be32
); /* dst_field */
4848 min_len
+= sizeof(ovs_be16
); /* dst_ofs */
4854 decode_LEARN_common(const struct nx_action_learn
*nal
,
4855 enum ofp_raw_action_type raw
,
4856 struct ofpact_learn
*learn
)
4859 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4862 learn
->ofpact
.raw
= raw
;
4863 learn
->idle_timeout
= ntohs(nal
->idle_timeout
);
4864 learn
->hard_timeout
= ntohs(nal
->hard_timeout
);
4865 learn
->priority
= ntohs(nal
->priority
);
4866 learn
->cookie
= nal
->cookie
;
4867 learn
->table_id
= nal
->table_id
;
4868 learn
->fin_idle_timeout
= ntohs(nal
->fin_idle_timeout
);
4869 learn
->fin_hard_timeout
= ntohs(nal
->fin_hard_timeout
);
4870 learn
->flags
= ntohs(nal
->flags
);
4872 if (learn
->table_id
== 0xff) {
4873 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4880 decode_LEARN_specs(const void *p
, const void *end
,
4881 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
4882 struct ofpbuf
*ofpacts
)
4884 struct ofpact_learn
*learn
= ofpacts
->header
;
4887 struct ofpact_learn_spec
*spec
;
4888 uint16_t header
= ntohs(get_be16(&p
));
4894 spec
= ofpbuf_put_zeros(ofpacts
, sizeof *spec
);
4895 learn
= ofpacts
->header
;
4897 spec
->src_type
= header
& NX_LEARN_SRC_MASK
;
4898 spec
->dst_type
= header
& NX_LEARN_DST_MASK
;
4899 spec
->n_bits
= header
& NX_LEARN_N_BITS_MASK
;
4901 /* Check for valid src and dst type combination. */
4902 if (spec
->dst_type
== NX_LEARN_DST_MATCH
||
4903 spec
->dst_type
== NX_LEARN_DST_LOAD
||
4904 (spec
->dst_type
== NX_LEARN_DST_OUTPUT
&&
4905 spec
->src_type
== NX_LEARN_SRC_FIELD
)) {
4908 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4911 /* Check that the arguments don't overrun the end of the action. */
4912 if ((char *) end
- (char *) p
< learn_min_len(header
)) {
4913 return OFPERR_OFPBAC_BAD_LEN
;
4916 /* Get the source. */
4917 const uint8_t *imm
= NULL
;
4918 unsigned int imm_bytes
= 0;
4920 if (spec
->src_type
== NX_LEARN_SRC_FIELD
) {
4921 error
= get_subfield(spec
->n_bits
, &p
, &spec
->src
, vl_mff_map
,
4927 int p_bytes
= 2 * DIV_ROUND_UP(spec
->n_bits
, 16);
4928 p
= (const uint8_t *) p
+ p_bytes
;
4930 imm_bytes
= DIV_ROUND_UP(spec
->n_bits
, 8);
4931 imm
= (const uint8_t *) p
- imm_bytes
;
4934 /* Get the destination. */
4935 if (spec
->dst_type
== NX_LEARN_DST_MATCH
||
4936 spec
->dst_type
== NX_LEARN_DST_LOAD
) {
4937 error
= get_subfield(spec
->n_bits
, &p
, &spec
->dst
, vl_mff_map
,
4945 uint8_t *src_imm
= ofpbuf_put_zeros(ofpacts
,
4946 OFPACT_ALIGN(imm_bytes
));
4947 memcpy(src_imm
, imm
, imm_bytes
);
4949 learn
= ofpacts
->header
;
4952 ofpact_finish_LEARN(ofpacts
, &learn
);
4954 if (!is_all_zeros(p
, (char *) end
- (char *) p
)) {
4955 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4961 /* Converts 'nal' into a "struct ofpact_learn" and appends that struct to
4962 * 'ofpacts'. Returns 0 if successful, otherwise an OFPERR_*. */
4964 decode_NXAST_RAW_LEARN(const struct nx_action_learn
*nal
,
4965 enum ofp_version ofp_version OVS_UNUSED
,
4966 const struct vl_mff_map
*vl_mff_map
,
4967 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
4969 struct ofpact_learn
*learn
;
4972 learn
= ofpact_put_LEARN(ofpacts
);
4974 error
= decode_LEARN_common(nal
, NXAST_RAW_LEARN
, learn
);
4979 if (learn
->flags
& ~(NX_LEARN_F_SEND_FLOW_REM
|
4980 NX_LEARN_F_DELETE_LEARNED
)) {
4981 return OFPERR_OFPBAC_BAD_ARGUMENT
;
4984 return decode_LEARN_specs(nal
+ 1, (char *) nal
+ ntohs(nal
->len
),
4985 vl_mff_map
, tlv_bitmap
, ofpacts
);
4988 /* Converts 'nal' into a "struct ofpact_learn" and appends that struct to
4989 * 'ofpacts'. Returns 0 if successful, otherwise an OFPERR_*. */
4991 decode_NXAST_RAW_LEARN2(const struct nx_action_learn2
*nal
,
4992 enum ofp_version ofp_version OVS_UNUSED
,
4993 const struct vl_mff_map
*vl_mff_map
,
4994 uint64_t *tlv_bitmap
, struct ofpbuf
*ofpacts
)
4996 struct ofpbuf b
= ofpbuf_const_initializer(nal
, ntohs(nal
->up
.len
));
4997 struct ofpact_learn
*learn
;
5001 return OFPERR_NXBAC_MUST_BE_ZERO
;
5004 learn
= ofpact_put_LEARN(ofpacts
);
5005 error
= decode_LEARN_common(&nal
->up
, NXAST_RAW_LEARN2
, learn
);
5010 learn
->limit
= ntohl(nal
->limit
);
5012 if (learn
->flags
& ~(NX_LEARN_F_SEND_FLOW_REM
|
5013 NX_LEARN_F_DELETE_LEARNED
|
5014 NX_LEARN_F_WRITE_RESULT
)) {
5015 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5018 ofpbuf_pull(&b
, sizeof *nal
);
5020 if (learn
->flags
& NX_LEARN_F_WRITE_RESULT
) {
5021 error
= nx_pull_header(&b
, vl_mff_map
, &learn
->result_dst
.field
, NULL
);
5025 if (!learn
->result_dst
.field
->writable
) {
5026 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
5028 learn
->result_dst
.ofs
= ntohs(nal
->result_dst_ofs
);
5029 learn
->result_dst
.n_bits
= 1;
5030 } else if (nal
->result_dst_ofs
) {
5031 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5034 return decode_LEARN_specs(b
.data
, (char *) nal
+ ntohs(nal
->up
.len
),
5035 vl_mff_map
, tlv_bitmap
, ofpacts
);
5039 put_be16(struct ofpbuf
*b
, ovs_be16 x
)
5041 ofpbuf_put(b
, &x
, sizeof x
);
5045 put_be32(struct ofpbuf
*b
, ovs_be32 x
)
5047 ofpbuf_put(b
, &x
, sizeof x
);
5051 put_u16(struct ofpbuf
*b
, uint16_t x
)
5053 put_be16(b
, htons(x
));
5057 put_u32(struct ofpbuf
*b
, uint32_t x
)
5059 put_be32(b
, htonl(x
));
5063 encode_LEARN(const struct ofpact_learn
*learn
,
5064 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5066 const struct ofpact_learn_spec
*spec
;
5067 struct nx_action_learn
*nal
;
5070 start_ofs
= out
->size
;
5072 if (learn
->ofpact
.raw
== NXAST_RAW_LEARN2
5073 || learn
->limit
!= 0
5074 || learn
->flags
& NX_LEARN_F_WRITE_RESULT
) {
5075 struct nx_action_learn2
*nal2
;
5077 nal2
= put_NXAST_LEARN2(out
);
5078 nal2
->limit
= htonl(learn
->limit
);
5079 nal2
->result_dst_ofs
= htons(learn
->result_dst
.ofs
);
5082 nal
= put_NXAST_LEARN(out
);
5084 nal
->idle_timeout
= htons(learn
->idle_timeout
);
5085 nal
->hard_timeout
= htons(learn
->hard_timeout
);
5086 nal
->fin_idle_timeout
= htons(learn
->fin_idle_timeout
);
5087 nal
->fin_hard_timeout
= htons(learn
->fin_hard_timeout
);
5088 nal
->priority
= htons(learn
->priority
);
5089 nal
->cookie
= learn
->cookie
;
5090 nal
->flags
= htons(learn
->flags
);
5091 nal
->table_id
= learn
->table_id
;
5093 if (learn
->flags
& NX_LEARN_F_WRITE_RESULT
) {
5094 nx_put_header(out
, learn
->result_dst
.field
->id
, 0, false);
5097 OFPACT_LEARN_SPEC_FOR_EACH (spec
, learn
) {
5098 put_u16(out
, spec
->n_bits
| spec
->dst_type
| spec
->src_type
);
5100 if (spec
->src_type
== NX_LEARN_SRC_FIELD
) {
5101 put_u32(out
, nxm_header_from_mff(spec
->src
.field
));
5102 put_u16(out
, spec
->src
.ofs
);
5104 size_t n_dst_bytes
= 2 * DIV_ROUND_UP(spec
->n_bits
, 16);
5105 uint8_t *bits
= ofpbuf_put_zeros(out
, n_dst_bytes
);
5106 unsigned int n_bytes
= DIV_ROUND_UP(spec
->n_bits
, 8);
5108 memcpy(bits
+ n_dst_bytes
- n_bytes
, ofpact_learn_spec_imm(spec
),
5112 if (spec
->dst_type
== NX_LEARN_DST_MATCH
||
5113 spec
->dst_type
== NX_LEARN_DST_LOAD
) {
5114 put_u32(out
, nxm_header_from_mff(spec
->dst
.field
));
5115 put_u16(out
, spec
->dst
.ofs
);
5119 pad_ofpat(out
, start_ofs
);
5122 static char * OVS_WARN_UNUSED_RESULT
5123 parse_LEARN(char *arg
, const struct ofputil_port_map
*port_map
,
5124 struct ofpbuf
*ofpacts
,
5125 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5127 return learn_parse(arg
, port_map
, ofpacts
);
5131 format_LEARN(const struct ofpact_learn
*a
,
5132 const struct ofputil_port_map
*port_map
, struct ds
*s
)
5134 learn_format(a
, port_map
, s
);
5137 /* Action structure for NXAST_CONJUNCTION. */
5138 struct nx_action_conjunction
{
5139 ovs_be16 type
; /* OFPAT_VENDOR. */
5140 ovs_be16 len
; /* At least 16. */
5141 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5142 ovs_be16 subtype
; /* See enum ofp_raw_action_type. */
5147 OFP_ASSERT(sizeof(struct nx_action_conjunction
) == 16);
5150 add_conjunction(struct ofpbuf
*out
,
5151 uint32_t id
, uint8_t clause
, uint8_t n_clauses
)
5153 struct ofpact_conjunction
*oc
;
5155 oc
= ofpact_put_CONJUNCTION(out
);
5157 oc
->clause
= clause
;
5158 oc
->n_clauses
= n_clauses
;
5162 decode_NXAST_RAW_CONJUNCTION(const struct nx_action_conjunction
*nac
,
5163 enum ofp_version ofp_version OVS_UNUSED
,
5166 if (nac
->n_clauses
< 2 || nac
->n_clauses
> 64
5167 || nac
->clause
>= nac
->n_clauses
) {
5168 return OFPERR_NXBAC_BAD_CONJUNCTION
;
5170 add_conjunction(out
, ntohl(nac
->id
), nac
->clause
, nac
->n_clauses
);
5176 encode_CONJUNCTION(const struct ofpact_conjunction
*oc
,
5177 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5179 struct nx_action_conjunction
*nac
= put_NXAST_CONJUNCTION(out
);
5180 nac
->clause
= oc
->clause
;
5181 nac
->n_clauses
= oc
->n_clauses
;
5182 nac
->id
= htonl(oc
->id
);
5186 format_CONJUNCTION(const struct ofpact_conjunction
*oc
,
5187 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5190 ds_put_format(s
, "%sconjunction(%s%"PRIu32
",%d/%"PRIu8
"%s)%s",
5191 colors
.paren
, colors
.end
,
5192 oc
->id
, oc
->clause
+ 1, oc
->n_clauses
,
5193 colors
.paren
, colors
.end
);
5196 static char * OVS_WARN_UNUSED_RESULT
5197 parse_CONJUNCTION(const char *arg
,
5198 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5199 struct ofpbuf
*ofpacts
,
5200 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5207 if (!ovs_scan(arg
, "%"SCNi32
" , %"SCNu8
" / %"SCNu8
" %n",
5208 &id
, &clause
, &n_clauses
, &n
) || n
!= strlen(arg
)) {
5209 return xstrdup("\"conjunction\" syntax is \"conjunction(id,i/n)\"");
5212 if (n_clauses
< 2) {
5213 return xstrdup("conjunction must have at least 2 clauses");
5214 } else if (n_clauses
> 64) {
5215 return xstrdup("conjunction must have at most 64 clauses");
5216 } else if (clause
< 1) {
5217 return xstrdup("clause index must be positive");
5218 } else if (clause
> n_clauses
) {
5219 return xstrdup("clause index must be less than or equal to "
5220 "number of clauses");
5223 add_conjunction(ofpacts
, id
, clause
- 1, n_clauses
);
5227 /* Action structure for NXAST_MULTIPATH.
5229 * This action performs the following steps in sequence:
5231 * 1. Hashes the fields designated by 'fields', one of NX_HASH_FIELDS_*.
5232 * Refer to the definition of "enum nx_mp_fields" for details.
5234 * The 'basis' value is used as a universal hash parameter, that is,
5235 * different values of 'basis' yield different hash functions. The
5236 * particular universal hash function used is implementation-defined.
5238 * The hashed fields' values are drawn from the current state of the
5239 * flow, including all modifications that have been made by actions up to
5242 * 2. Applies the multipath link choice algorithm specified by 'algorithm',
5243 * one of NX_MP_ALG_*. Refer to the definition of "enum nx_mp_algorithm"
5246 * The output of the algorithm is 'link', an unsigned integer less than
5247 * or equal to 'max_link'.
5249 * Some algorithms use 'arg' as an additional argument.
5251 * 3. Stores 'link' in dst[ofs:ofs+n_bits]. The format and semantics of
5252 * 'dst' and 'ofs_nbits' are similar to those for the NXAST_REG_LOAD
5255 * The switch will reject actions that have an unknown 'fields', or an unknown
5256 * 'algorithm', or in which ofs+n_bits is greater than the width of 'dst', or
5257 * in which 'max_link' is greater than or equal to 2**n_bits, with error type
5258 * OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
5260 struct nx_action_multipath
{
5261 ovs_be16 type
; /* OFPAT_VENDOR. */
5262 ovs_be16 len
; /* Length is 32. */
5263 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5264 ovs_be16 subtype
; /* NXAST_MULTIPATH. */
5266 /* What fields to hash and how. */
5267 ovs_be16 fields
; /* One of NX_HASH_FIELDS_*. */
5268 ovs_be16 basis
; /* Universal hash parameter. */
5271 /* Multipath link choice algorithm to apply to hash value. */
5272 ovs_be16 algorithm
; /* One of NX_MP_ALG_*. */
5273 ovs_be16 max_link
; /* Number of output links, minus 1. */
5274 ovs_be32 arg
; /* Algorithm-specific argument. */
5277 /* Where to store the result. */
5278 ovs_be16 ofs_nbits
; /* (ofs << 6) | (n_bits - 1). */
5279 ovs_be32 dst
; /* Destination. */
5281 OFP_ASSERT(sizeof(struct nx_action_multipath
) == 32);
5284 decode_NXAST_RAW_MULTIPATH(const struct nx_action_multipath
*nam
,
5285 enum ofp_version ofp_version OVS_UNUSED
,
5286 const struct vl_mff_map
*vl_mff_map
,
5287 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
5289 uint32_t n_links
= ntohs(nam
->max_link
) + 1;
5290 size_t min_n_bits
= log_2_ceil(n_links
);
5291 struct ofpact_multipath
*mp
;
5294 mp
= ofpact_put_MULTIPATH(out
);
5295 mp
->fields
= ntohs(nam
->fields
);
5296 mp
->basis
= ntohs(nam
->basis
);
5297 mp
->algorithm
= ntohs(nam
->algorithm
);
5298 mp
->max_link
= ntohs(nam
->max_link
);
5299 mp
->arg
= ntohl(nam
->arg
);
5300 mp
->dst
.ofs
= nxm_decode_ofs(nam
->ofs_nbits
);
5301 mp
->dst
.n_bits
= nxm_decode_n_bits(nam
->ofs_nbits
);
5302 error
= mf_vl_mff_mf_from_nxm_header(ntohl(nam
->dst
), vl_mff_map
,
5303 &mp
->dst
.field
, tlv_bitmap
);
5308 if (!flow_hash_fields_valid(mp
->fields
)) {
5309 VLOG_WARN_RL(&rl
, "unsupported fields %d", (int) mp
->fields
);
5310 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5311 } else if (mp
->algorithm
!= NX_MP_ALG_MODULO_N
5312 && mp
->algorithm
!= NX_MP_ALG_HASH_THRESHOLD
5313 && mp
->algorithm
!= NX_MP_ALG_HRW
5314 && mp
->algorithm
!= NX_MP_ALG_ITER_HASH
) {
5315 VLOG_WARN_RL(&rl
, "unsupported algorithm %d", (int) mp
->algorithm
);
5316 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5317 } else if (mp
->dst
.n_bits
< min_n_bits
) {
5318 VLOG_WARN_RL(&rl
, "multipath action requires at least %"PRIuSIZE
" bits for "
5319 "%"PRIu32
" links", min_n_bits
, n_links
);
5320 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5323 return multipath_check(mp
, NULL
);
5327 encode_MULTIPATH(const struct ofpact_multipath
*mp
,
5328 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5330 struct nx_action_multipath
*nam
= put_NXAST_MULTIPATH(out
);
5332 nam
->fields
= htons(mp
->fields
);
5333 nam
->basis
= htons(mp
->basis
);
5334 nam
->algorithm
= htons(mp
->algorithm
);
5335 nam
->max_link
= htons(mp
->max_link
);
5336 nam
->arg
= htonl(mp
->arg
);
5337 nam
->ofs_nbits
= nxm_encode_ofs_nbits(mp
->dst
.ofs
, mp
->dst
.n_bits
);
5338 nam
->dst
= htonl(nxm_header_from_mff(mp
->dst
.field
));
5341 static char * OVS_WARN_UNUSED_RESULT
5342 parse_MULTIPATH(const char *arg
,
5343 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5344 struct ofpbuf
*ofpacts
,
5345 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5347 return multipath_parse(ofpact_put_MULTIPATH(ofpacts
), arg
);
5351 format_MULTIPATH(const struct ofpact_multipath
*a
,
5352 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5355 multipath_format(a
, s
);
5358 /* Action structure for NXAST_NOTE.
5360 * This action has no effect. It is variable length. The switch does not
5361 * attempt to interpret the user-defined 'note' data in any way. A controller
5362 * can use this action to attach arbitrary metadata to a flow.
5364 * This action might go away in the future.
5366 struct nx_action_note
{
5367 ovs_be16 type
; /* OFPAT_VENDOR. */
5368 ovs_be16 len
; /* A multiple of 8, but at least 16. */
5369 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5370 ovs_be16 subtype
; /* NXAST_NOTE. */
5371 uint8_t note
[6]; /* Start of user-defined data. */
5372 /* Possibly followed by additional user-defined data. */
5374 OFP_ASSERT(sizeof(struct nx_action_note
) == 16);
5377 decode_NXAST_RAW_NOTE(const struct nx_action_note
*nan
,
5378 enum ofp_version ofp_version OVS_UNUSED
,
5381 struct ofpact_note
*note
;
5382 unsigned int length
;
5384 length
= ntohs(nan
->len
) - offsetof(struct nx_action_note
, note
);
5385 note
= ofpact_put_NOTE(out
);
5386 note
->length
= length
;
5387 ofpbuf_put(out
, nan
->note
, length
);
5389 ofpact_finish_NOTE(out
, ¬e
);
5395 encode_NOTE(const struct ofpact_note
*note
,
5396 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5398 size_t start_ofs
= out
->size
;
5399 struct nx_action_note
*nan
;
5401 put_NXAST_NOTE(out
);
5402 out
->size
= out
->size
- sizeof nan
->note
;
5404 ofpbuf_put(out
, note
->data
, note
->length
);
5405 pad_ofpat(out
, start_ofs
);
5408 static char * OVS_WARN_UNUSED_RESULT
5409 parse_NOTE(const char *arg
,
5410 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5411 struct ofpbuf
*ofpacts
,
5412 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5414 size_t start_ofs
= ofpacts
->size
;
5415 ofpact_put_NOTE(ofpacts
);
5416 arg
= ofpbuf_put_hex(ofpacts
, arg
, NULL
);
5418 return xstrdup("bad hex digit in `note' argument");
5420 struct ofpact_note
*note
= ofpbuf_at_assert(ofpacts
, start_ofs
,
5422 note
->length
= ofpacts
->size
- (start_ofs
+ sizeof *note
);
5423 ofpact_finish_NOTE(ofpacts
, ¬e
);
5428 format_NOTE(const struct ofpact_note
*a
,
5429 const struct ofputil_port_map
*port_map OVS_UNUSED
, struct ds
*s
)
5431 ds_put_format(s
, "%snote:%s", colors
.param
, colors
.end
);
5432 format_hex_arg(s
, a
->data
, a
->length
);
5438 decode_NXAST_RAW_EXIT(struct ofpbuf
*out
)
5440 ofpact_put_EXIT(out
);
5445 encode_EXIT(const struct ofpact_null
*null OVS_UNUSED
,
5446 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5448 put_NXAST_EXIT(out
);
5451 static char * OVS_WARN_UNUSED_RESULT
5452 parse_EXIT(char *arg OVS_UNUSED
,
5453 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5454 struct ofpbuf
*ofpacts
,
5455 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5457 ofpact_put_EXIT(ofpacts
);
5462 format_EXIT(const struct ofpact_null
*a OVS_UNUSED
,
5463 const struct ofputil_port_map
*port_map OVS_UNUSED
, struct ds
*s
)
5465 ds_put_format(s
, "%sexit%s", colors
.special
, colors
.end
);
5468 /* Unroll xlate action. */
5471 encode_UNROLL_XLATE(const struct ofpact_unroll_xlate
*unroll OVS_UNUSED
,
5472 enum ofp_version ofp_version OVS_UNUSED
,
5473 struct ofpbuf
*out OVS_UNUSED
)
5478 static char * OVS_WARN_UNUSED_RESULT
5479 parse_UNROLL_XLATE(char *arg OVS_UNUSED
,
5480 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5481 struct ofpbuf
*ofpacts OVS_UNUSED
,
5482 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5489 format_UNROLL_XLATE(const struct ofpact_unroll_xlate
*a
,
5490 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5493 ds_put_format(s
, "%sunroll_xlate(%s%stable=%s%"PRIu8
5494 ", %scookie=%s%"PRIu64
"%s)%s",
5495 colors
.paren
, colors
.end
,
5496 colors
.special
, colors
.end
, a
->rule_table_id
,
5497 colors
.param
, colors
.end
, ntohll(a
->rule_cookie
),
5498 colors
.paren
, colors
.end
);
5501 /* The NXAST_CLONE action is "struct ext_action_header", followed by zero or
5502 * more embedded OpenFlow actions. */
5505 decode_NXAST_RAW_CLONE(const struct ext_action_header
*eah
,
5506 enum ofp_version ofp_version
,
5507 const struct vl_mff_map
*vl_mff_map
,
5508 uint64_t *tlv_bitmap
, struct ofpbuf
*out
)
5511 struct ofpbuf openflow
;
5512 const size_t clone_offset
= ofpacts_pull(out
);
5513 struct ofpact_nest
*clone
= ofpact_put_CLONE(out
);
5515 /* decode action list */
5516 ofpbuf_pull(out
, sizeof(*clone
));
5517 openflow
= ofpbuf_const_initializer(
5518 eah
+ 1, ntohs(eah
->len
) - sizeof *eah
);
5519 error
= ofpacts_pull_openflow_actions__(&openflow
, openflow
.size
,
5521 1u << OVSINST_OFPIT11_APPLY_ACTIONS
,
5522 out
, 0, vl_mff_map
, tlv_bitmap
);
5523 clone
= ofpbuf_push_uninit(out
, sizeof *clone
);
5524 out
->header
= &clone
->ofpact
;
5525 ofpact_finish_CLONE(out
, &clone
);
5526 ofpbuf_push_uninit(out
, clone_offset
);
5531 encode_CLONE(const struct ofpact_nest
*clone
,
5532 enum ofp_version ofp_version
, struct ofpbuf
*out
)
5535 const size_t ofs
= out
->size
;
5536 struct ext_action_header
*eah
;
5538 eah
= put_NXAST_CLONE(out
);
5539 len
= ofpacts_put_openflow_actions(clone
->actions
,
5540 ofpact_nest_get_action_len(clone
),
5543 eah
= ofpbuf_at(out
, ofs
, sizeof *eah
);
5544 eah
->len
= htons(len
);
5547 static char * OVS_WARN_UNUSED_RESULT
5548 parse_CLONE(char *arg
, const struct ofputil_port_map
*port_map
,
5549 struct ofpbuf
*ofpacts
,
5550 enum ofputil_protocol
*usable_protocols
)
5552 const size_t clone_offset
= ofpacts_pull(ofpacts
);
5553 struct ofpact_nest
*clone
= ofpact_put_CLONE(ofpacts
);
5556 ofpbuf_pull(ofpacts
, sizeof *clone
);
5557 error
= ofpacts_parse_copy(arg
, port_map
, ofpacts
,
5558 usable_protocols
, false, 0);
5559 /* header points to the action list */
5560 ofpacts
->header
= ofpbuf_push_uninit(ofpacts
, sizeof *clone
);
5561 clone
= ofpacts
->header
;
5563 ofpact_finish_CLONE(ofpacts
, &clone
);
5564 ofpbuf_push_uninit(ofpacts
, clone_offset
);
5569 format_CLONE(const struct ofpact_nest
*a
,
5570 const struct ofputil_port_map
*port_map
, struct ds
*s
)
5572 ds_put_format(s
, "%sclone(%s", colors
.paren
, colors
.end
);
5573 ofpacts_format(a
->actions
, ofpact_nest_get_action_len(a
), port_map
, s
);
5574 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
5577 /* Action structure for NXAST_SAMPLE.
5579 * Samples matching packets with the given probability and sends them
5580 * each to the set of collectors identified with the given ID. The
5581 * probability is expressed as a number of packets to be sampled out
5582 * of USHRT_MAX packets, and must be >0.
5584 * When sending packet samples to IPFIX collectors, the IPFIX flow
5585 * record sent for each sampled packet is associated with the given
5586 * observation domain ID and observation point ID. Each IPFIX flow
5587 * record contain the sampled packet's headers when executing this
5588 * rule. If a sampled packet's headers are modified by previous
5589 * actions in the flow, those modified headers are sent. */
5590 struct nx_action_sample
{
5591 ovs_be16 type
; /* OFPAT_VENDOR. */
5592 ovs_be16 len
; /* Length is 24. */
5593 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5594 ovs_be16 subtype
; /* NXAST_SAMPLE. */
5595 ovs_be16 probability
; /* Fraction of packets to sample. */
5596 ovs_be32 collector_set_id
; /* ID of collector set in OVSDB. */
5597 ovs_be32 obs_domain_id
; /* ID of sampling observation domain. */
5598 ovs_be32 obs_point_id
; /* ID of sampling observation point. */
5600 OFP_ASSERT(sizeof(struct nx_action_sample
) == 24);
5602 /* Action structure for NXAST_SAMPLE2 and NXAST_SAMPLE3.
5604 * NXAST_SAMPLE2 was added in Open vSwitch 2.5.90. Compared to NXAST_SAMPLE,
5605 * it adds support for exporting egress tunnel information.
5607 * NXAST_SAMPLE3 was added in Open vSwitch 2.6.90. Compared to NXAST_SAMPLE2,
5608 * it adds support for the 'direction' field. */
5609 struct nx_action_sample2
{
5610 ovs_be16 type
; /* OFPAT_VENDOR. */
5611 ovs_be16 len
; /* Length is 32. */
5612 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5613 ovs_be16 subtype
; /* NXAST_SAMPLE. */
5614 ovs_be16 probability
; /* Fraction of packets to sample. */
5615 ovs_be32 collector_set_id
; /* ID of collector set in OVSDB. */
5616 ovs_be32 obs_domain_id
; /* ID of sampling observation domain. */
5617 ovs_be32 obs_point_id
; /* ID of sampling observation point. */
5618 ovs_be16 sampling_port
; /* Sampling port. */
5619 uint8_t direction
; /* NXAST_SAMPLE3 only. */
5620 uint8_t zeros
[5]; /* Pad to a multiple of 8 bytes */
5622 OFP_ASSERT(sizeof(struct nx_action_sample2
) == 32);
5625 decode_NXAST_RAW_SAMPLE(const struct nx_action_sample
*nas
,
5626 enum ofp_version ofp_version OVS_UNUSED
,
5629 struct ofpact_sample
*sample
;
5631 sample
= ofpact_put_SAMPLE(out
);
5632 sample
->ofpact
.raw
= NXAST_RAW_SAMPLE
;
5633 sample
->probability
= ntohs(nas
->probability
);
5634 sample
->collector_set_id
= ntohl(nas
->collector_set_id
);
5635 sample
->obs_domain_id
= ntohl(nas
->obs_domain_id
);
5636 sample
->obs_point_id
= ntohl(nas
->obs_point_id
);
5637 sample
->sampling_port
= OFPP_NONE
;
5638 sample
->direction
= NX_ACTION_SAMPLE_DEFAULT
;
5640 if (sample
->probability
== 0) {
5641 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5648 decode_SAMPLE2(const struct nx_action_sample2
*nas
,
5649 enum ofp_raw_action_type raw
,
5650 enum nx_action_sample_direction direction
,
5651 struct ofpact_sample
*sample
)
5653 sample
->ofpact
.raw
= raw
;
5654 sample
->probability
= ntohs(nas
->probability
);
5655 sample
->collector_set_id
= ntohl(nas
->collector_set_id
);
5656 sample
->obs_domain_id
= ntohl(nas
->obs_domain_id
);
5657 sample
->obs_point_id
= ntohl(nas
->obs_point_id
);
5658 sample
->sampling_port
= u16_to_ofp(ntohs(nas
->sampling_port
));
5659 sample
->direction
= direction
;
5661 if (sample
->probability
== 0) {
5662 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5669 decode_NXAST_RAW_SAMPLE2(const struct nx_action_sample2
*nas
,
5670 enum ofp_version ofp_version OVS_UNUSED
,
5673 return decode_SAMPLE2(nas
, NXAST_RAW_SAMPLE2
, NX_ACTION_SAMPLE_DEFAULT
,
5674 ofpact_put_SAMPLE(out
));
5678 decode_NXAST_RAW_SAMPLE3(const struct nx_action_sample2
*nas
,
5679 enum ofp_version ofp_version OVS_UNUSED
,
5682 struct ofpact_sample
*sample
= ofpact_put_SAMPLE(out
);
5683 if (!is_all_zeros(nas
->zeros
, sizeof nas
->zeros
)) {
5684 return OFPERR_NXBRC_MUST_BE_ZERO
;
5686 if (nas
->direction
!= NX_ACTION_SAMPLE_DEFAULT
&&
5687 nas
->direction
!= NX_ACTION_SAMPLE_INGRESS
&&
5688 nas
->direction
!= NX_ACTION_SAMPLE_EGRESS
) {
5689 VLOG_WARN_RL(&rl
, "invalid sample direction %"PRIu8
, nas
->direction
);
5690 return OFPERR_OFPBAC_BAD_ARGUMENT
;
5692 return decode_SAMPLE2(nas
, NXAST_RAW_SAMPLE3
, nas
->direction
, sample
);
5696 encode_SAMPLE2(const struct ofpact_sample
*sample
,
5697 struct nx_action_sample2
*nas
)
5699 nas
->probability
= htons(sample
->probability
);
5700 nas
->collector_set_id
= htonl(sample
->collector_set_id
);
5701 nas
->obs_domain_id
= htonl(sample
->obs_domain_id
);
5702 nas
->obs_point_id
= htonl(sample
->obs_point_id
);
5703 nas
->sampling_port
= htons(ofp_to_u16(sample
->sampling_port
));
5704 nas
->direction
= sample
->direction
;
5708 encode_SAMPLE(const struct ofpact_sample
*sample
,
5709 enum ofp_version ofp_version OVS_UNUSED
, struct ofpbuf
*out
)
5711 if (sample
->ofpact
.raw
== NXAST_RAW_SAMPLE3
5712 || sample
->direction
!= NX_ACTION_SAMPLE_DEFAULT
) {
5713 encode_SAMPLE2(sample
, put_NXAST_SAMPLE3(out
));
5714 } else if (sample
->ofpact
.raw
== NXAST_RAW_SAMPLE2
5715 || sample
->sampling_port
!= OFPP_NONE
) {
5716 encode_SAMPLE2(sample
, put_NXAST_SAMPLE2(out
));
5718 struct nx_action_sample
*nas
= put_NXAST_SAMPLE(out
);
5719 nas
->probability
= htons(sample
->probability
);
5720 nas
->collector_set_id
= htonl(sample
->collector_set_id
);
5721 nas
->obs_domain_id
= htonl(sample
->obs_domain_id
);
5722 nas
->obs_point_id
= htonl(sample
->obs_point_id
);
5726 /* Parses 'arg' as the argument to a "sample" action, and appends such an
5727 * action to 'ofpacts'.
5729 * Returns NULL if successful, otherwise a malloc()'d string describing the
5730 * error. The caller is responsible for freeing the returned string. */
5731 static char * OVS_WARN_UNUSED_RESULT
5732 parse_SAMPLE(char *arg
, const struct ofputil_port_map
*port_map
,
5733 struct ofpbuf
*ofpacts
,
5734 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5736 struct ofpact_sample
*os
= ofpact_put_SAMPLE(ofpacts
);
5737 os
->sampling_port
= OFPP_NONE
;
5738 os
->direction
= NX_ACTION_SAMPLE_DEFAULT
;
5741 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
5744 if (!strcmp(key
, "probability")) {
5745 error
= str_to_u16(value
, "probability", &os
->probability
);
5746 if (!error
&& os
->probability
== 0) {
5747 error
= xasprintf("invalid probability value \"%s\"", value
);
5749 } else if (!strcmp(key
, "collector_set_id")) {
5750 error
= str_to_u32(value
, &os
->collector_set_id
);
5751 } else if (!strcmp(key
, "obs_domain_id")) {
5752 error
= str_to_u32(value
, &os
->obs_domain_id
);
5753 } else if (!strcmp(key
, "obs_point_id")) {
5754 error
= str_to_u32(value
, &os
->obs_point_id
);
5755 } else if (!strcmp(key
, "sampling_port")) {
5756 if (!ofputil_port_from_string(value
, port_map
,
5757 &os
->sampling_port
)) {
5758 error
= xasprintf("%s: unknown port", value
);
5760 } else if (!strcmp(key
, "ingress")) {
5761 os
->direction
= NX_ACTION_SAMPLE_INGRESS
;
5762 } else if (!strcmp(key
, "egress")) {
5763 os
->direction
= NX_ACTION_SAMPLE_EGRESS
;
5765 error
= xasprintf("invalid key \"%s\" in \"sample\" argument",
5772 if (os
->probability
== 0) {
5773 return xstrdup("non-zero \"probability\" must be specified on sample");
5780 format_SAMPLE(const struct ofpact_sample
*a
,
5781 const struct ofputil_port_map
*port_map
, struct ds
*s
)
5783 ds_put_format(s
, "%ssample(%s%sprobability=%s%"PRIu16
5784 ",%scollector_set_id=%s%"PRIu32
5785 ",%sobs_domain_id=%s%"PRIu32
5786 ",%sobs_point_id=%s%"PRIu32
,
5787 colors
.paren
, colors
.end
,
5788 colors
.param
, colors
.end
, a
->probability
,
5789 colors
.param
, colors
.end
, a
->collector_set_id
,
5790 colors
.param
, colors
.end
, a
->obs_domain_id
,
5791 colors
.param
, colors
.end
, a
->obs_point_id
);
5792 if (a
->sampling_port
!= OFPP_NONE
) {
5793 ds_put_format(s
, ",%ssampling_port=%s", colors
.param
, colors
.end
);
5794 ofputil_format_port(a
->sampling_port
, port_map
, s
);
5796 if (a
->direction
== NX_ACTION_SAMPLE_INGRESS
) {
5797 ds_put_format(s
, ",%singress%s", colors
.param
, colors
.end
);
5798 } else if (a
->direction
== NX_ACTION_SAMPLE_EGRESS
) {
5799 ds_put_format(s
, ",%segress%s", colors
.param
, colors
.end
);
5801 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
5804 /* debug_recirc instruction. */
5806 static bool enable_debug
;
5809 ofpact_dummy_enable(void)
5811 enable_debug
= true;
5815 decode_NXAST_RAW_DEBUG_RECIRC(struct ofpbuf
*out
)
5817 if (!enable_debug
) {
5818 return OFPERR_OFPBAC_BAD_VENDOR_TYPE
;
5821 ofpact_put_DEBUG_RECIRC(out
);
5826 encode_DEBUG_RECIRC(const struct ofpact_null
*n OVS_UNUSED
,
5827 enum ofp_version ofp_version OVS_UNUSED
,
5830 put_NXAST_DEBUG_RECIRC(out
);
5833 static char * OVS_WARN_UNUSED_RESULT
5834 parse_DEBUG_RECIRC(char *arg OVS_UNUSED
,
5835 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5836 struct ofpbuf
*ofpacts
,
5837 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
5839 ofpact_put_DEBUG_RECIRC(ofpacts
);
5844 format_DEBUG_RECIRC(const struct ofpact_null
*a OVS_UNUSED
,
5845 const struct ofputil_port_map
*port_map OVS_UNUSED
,
5848 ds_put_format(s
, "%sdebug_recirc%s", colors
.value
, colors
.end
);
5851 /* Action structure for NXAST_CT.
5853 * Pass traffic to the connection tracker.
5855 * There are two important concepts to understanding the connection tracking
5856 * interface: Packet state and Connection state. Packets may be "Untracked" or
5857 * "Tracked". Connections may be "Uncommitted" or "Committed".
5861 * Untracked packets have an unknown connection state. In most
5862 * cases, packets entering the OpenFlow pipeline will initially be
5863 * in the untracked state. Untracked packets may become tracked by
5864 * executing NXAST_CT with a "recirc_table" specified. This makes
5865 * various aspects about the connection available, in particular
5866 * the connection state.
5868 * An NXAST_CT action always puts the packet into an untracked
5869 * state for the current processing path. If "recirc_table" is
5870 * set, execution is forked and the packet passes through the
5871 * connection tracker. The specified table's processing path is
5872 * able to match on Connection state until the end of the OpenFlow
5873 * pipeline or NXAST_CT is called again.
5875 * - Connection State:
5877 * Multiple packets may be associated with a single connection. Initially,
5878 * all connections are uncommitted. The connection state corresponding to
5879 * a packet is available in the NXM_NX_CT_STATE field for tracked packets.
5881 * Uncommitted connections have no state stored about them. Uncommitted
5882 * connections may transition into the committed state by executing
5883 * NXAST_CT with the NX_CT_F_COMMIT flag.
5885 * Once a connection becomes committed, information may be gathered about
5886 * the connection by passing subsequent packets through the connection
5887 * tracker, and the state of the connection will be stored beyond the
5888 * lifetime of packet processing.
5890 * A committed connection always has the directionality of the packet that
5891 * caused the connection to be committed in the first place. This is the
5892 * "original direction" of the connection, and the opposite direction is
5893 * the "reply direction". If a connection is already committed, but it is
5894 * then decided that the original direction should be the opposite of the
5895 * existing connection, NX_CT_F_FORCE flag may be used in addition to
5896 * NX_CT_F_COMMIT flag to in effect terminate the existing connection and
5897 * start a new one in the current direction.
5899 * Connections may transition back into the uncommitted state due to
5900 * external timers, or due to the contents of packets that are sent to the
5901 * connection tracker. This behaviour is outside of the scope of the
5902 * OpenFlow interface.
5904 * The "zone" specifies a context within which the tracking is done:
5906 * The connection tracking zone is a 16-bit number. Each zone is an
5907 * independent connection tracking context. The connection state for each
5908 * connection is completely separate for each zone, so if a connection
5909 * is committed to zone A, then it will remain uncommitted in zone B.
5910 * If NXAST_CT is executed with the same zone multiple times, later
5911 * executions have no effect.
5913 * If 'zone_src' is nonzero, this specifies that the zone should be
5914 * sourced from a field zone_src[ofs:ofs+nbits]. The format and semantics
5915 * of 'zone_src' and 'zone_ofs_nbits' are similar to those for the
5916 * NXAST_REG_LOAD action. The acceptable nxm_header values for 'zone_src'
5917 * are the same as the acceptable nxm_header values for the 'src' field of
5920 * If 'zone_src' is zero, then the value of 'zone_imm' will be used as the
5921 * connection tracking zone.
5923 * The "recirc_table" allows NXM_NX_CT_* fields to become available:
5925 * If "recirc_table" has a value other than NX_CT_RECIRC_NONE, then the
5926 * packet will be logically cloned prior to executing this action. One
5927 * copy will be sent to the connection tracker, then will be re-injected
5928 * into the OpenFlow pipeline beginning at the OpenFlow table specified in
5929 * this field. When the packet re-enters the pipeline, the NXM_NX_CT_*
5930 * fields will be populated. The original instance of the packet will
5931 * continue the current actions list. This can be thought of as similar to
5932 * the effect of the "output" action: One copy is sent out (in this case,
5933 * to the connection tracker), but the current copy continues processing.
5935 * It is strongly recommended that this table is later than the current
5936 * table, to prevent loops.
5938 * The "alg" attaches protocol-specific behaviour to this action:
5940 * The ALG is a 16-bit number which specifies that additional
5941 * processing should be applied to this traffic.
5943 * Protocol | Value | Meaning
5944 * --------------------------------------------------------------------
5945 * None | 0 | No protocol-specific behaviour.
5946 * FTP | 21 | Parse FTP control connections and observe the
5947 * | | negotiation of related data connections.
5948 * Other | Other | Unsupported protocols.
5950 * By way of example, if FTP control connections have this action applied
5951 * with the ALG set to FTP (21), then the connection tracker will observe
5952 * the negotiation of data connections. This allows the connection
5953 * tracker to identify subsequent data connections as "related" to this
5954 * existing connection. The "related" flag will be populated in the
5955 * NXM_NX_CT_STATE field for such connections if the 'recirc_table' is
5958 * Zero or more actions may immediately follow this action. These actions will
5959 * be executed within the context of the connection tracker, and they require
5960 * NX_CT_F_COMMIT flag be set.
5962 struct nx_action_conntrack
{
5963 ovs_be16 type
; /* OFPAT_VENDOR. */
5964 ovs_be16 len
; /* At least 24. */
5965 ovs_be32 vendor
; /* NX_VENDOR_ID. */
5966 ovs_be16 subtype
; /* NXAST_CT. */
5967 ovs_be16 flags
; /* Zero or more NX_CT_F_* flags.
5968 * Unspecified flag bits must be zero. */
5969 ovs_be32 zone_src
; /* Connection tracking context. */
5971 ovs_be16 zone_ofs_nbits
;/* Range to use from source field. */
5972 ovs_be16 zone_imm
; /* Immediate value for zone. */
5974 uint8_t recirc_table
; /* Recirculate to a specific table, or
5975 NX_CT_RECIRC_NONE for no recirculation. */
5976 uint8_t pad
[3]; /* Zeroes */
5977 ovs_be16 alg
; /* Well-known port number for the protocol.
5978 * 0 indicates no ALG is required. */
5979 /* Followed by a sequence of zero or more OpenFlow actions. The length of
5980 * these is included in 'len'. */
5982 OFP_ASSERT(sizeof(struct nx_action_conntrack
) == 24);
5985 decode_ct_zone(const struct nx_action_conntrack
*nac
,
5986 struct ofpact_conntrack
*out
,
5987 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
)
5989 if (nac
->zone_src
) {
5992 out
->zone_src
.ofs
= nxm_decode_ofs(nac
->zone_ofs_nbits
);
5993 out
->zone_src
.n_bits
= nxm_decode_n_bits(nac
->zone_ofs_nbits
);
5994 error
= mf_vl_mff_mf_from_nxm_header(ntohl(nac
->zone_src
),
5995 vl_mff_map
, &out
->zone_src
.field
,
6001 error
= mf_check_src(&out
->zone_src
, NULL
);
6006 if (out
->zone_src
.n_bits
!= 16) {
6007 VLOG_WARN_RL(&rl
, "zone n_bits %d not within valid range [16..16]",
6008 out
->zone_src
.n_bits
);
6009 return OFPERR_OFPBAC_BAD_SET_LEN
;
6012 out
->zone_src
.field
= NULL
;
6013 out
->zone_imm
= ntohs(nac
->zone_imm
);
6020 decode_NXAST_RAW_CT(const struct nx_action_conntrack
*nac
,
6021 enum ofp_version ofp_version
,
6022 const struct vl_mff_map
*vl_mff_map
, uint64_t *tlv_bitmap
,
6025 const size_t ct_offset
= ofpacts_pull(out
);
6026 struct ofpact_conntrack
*conntrack
= ofpact_put_CT(out
);
6029 conntrack
->flags
= ntohs(nac
->flags
);
6030 if (conntrack
->flags
& NX_CT_F_FORCE
&&
6031 !(conntrack
->flags
& NX_CT_F_COMMIT
)) {
6032 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
6036 error
= decode_ct_zone(nac
, conntrack
, vl_mff_map
, tlv_bitmap
);
6040 conntrack
->recirc_table
= nac
->recirc_table
;
6041 conntrack
->alg
= ntohs(nac
->alg
);
6043 ofpbuf_pull(out
, sizeof(*conntrack
));
6045 struct ofpbuf openflow
= ofpbuf_const_initializer(
6046 nac
+ 1, ntohs(nac
->len
) - sizeof(*nac
));
6047 error
= ofpacts_pull_openflow_actions__(&openflow
, openflow
.size
,
6049 1u << OVSINST_OFPIT11_APPLY_ACTIONS
,
6050 out
, OFPACT_CT
, vl_mff_map
,
6056 conntrack
= ofpbuf_push_uninit(out
, sizeof(*conntrack
));
6057 out
->header
= &conntrack
->ofpact
;
6058 ofpact_finish_CT(out
, &conntrack
);
6060 if (conntrack
->ofpact
.len
> sizeof(*conntrack
)
6061 && !(conntrack
->flags
& NX_CT_F_COMMIT
)) {
6062 const struct ofpact
*a
;
6063 size_t ofpacts_len
= conntrack
->ofpact
.len
- sizeof(*conntrack
);
6065 OFPACT_FOR_EACH (a
, conntrack
->actions
, ofpacts_len
) {
6066 if (a
->type
!= OFPACT_NAT
|| ofpact_get_NAT(a
)->flags
6067 || ofpact_get_NAT(a
)->range_af
!= AF_UNSPEC
) {
6068 VLOG_WARN_RL(&rl
, "CT action requires commit flag if actions "
6069 "other than NAT without arguments are specified.");
6070 error
= OFPERR_OFPBAC_BAD_ARGUMENT
;
6077 ofpbuf_push_uninit(out
, ct_offset
);
6082 encode_CT(const struct ofpact_conntrack
*conntrack
,
6083 enum ofp_version ofp_version
, struct ofpbuf
*out
)
6085 struct nx_action_conntrack
*nac
;
6086 const size_t ofs
= out
->size
;
6089 nac
= put_NXAST_CT(out
);
6090 nac
->flags
= htons(conntrack
->flags
);
6091 if (conntrack
->zone_src
.field
) {
6092 nac
->zone_src
= htonl(nxm_header_from_mff(conntrack
->zone_src
.field
));
6093 nac
->zone_ofs_nbits
= nxm_encode_ofs_nbits(conntrack
->zone_src
.ofs
,
6094 conntrack
->zone_src
.n_bits
);
6096 nac
->zone_src
= htonl(0);
6097 nac
->zone_imm
= htons(conntrack
->zone_imm
);
6099 nac
->recirc_table
= conntrack
->recirc_table
;
6100 nac
->alg
= htons(conntrack
->alg
);
6102 len
= ofpacts_put_openflow_actions(conntrack
->actions
,
6103 ofpact_ct_get_action_len(conntrack
),
6105 len
+= sizeof(*nac
);
6106 nac
= ofpbuf_at(out
, ofs
, sizeof(*nac
));
6107 nac
->len
= htons(len
);
6110 static char *OVS_WARN_UNUSED_RESULT
6111 parse_NAT(char *arg
, const struct ofputil_port_map
*port_map OVS_UNUSED
,
6112 struct ofpbuf
*, enum ofputil_protocol
* OVS_UNUSED
);
6114 /* Parses 'arg' as the argument to a "ct" action, and appends such an
6115 * action to 'ofpacts'.
6117 * Returns NULL if successful, otherwise a malloc()'d string describing the
6118 * error. The caller is responsible for freeing the returned string. */
6119 static char * OVS_WARN_UNUSED_RESULT
6120 parse_CT(char *arg
, const struct ofputil_port_map
*port_map
,
6121 struct ofpbuf
*ofpacts
,
6122 enum ofputil_protocol
*usable_protocols
)
6124 const size_t ct_offset
= ofpacts_pull(ofpacts
);
6125 struct ofpact_conntrack
*oc
;
6129 oc
= ofpact_put_CT(ofpacts
);
6131 oc
->recirc_table
= NX_CT_RECIRC_NONE
;
6132 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
6133 if (!strcmp(key
, "commit")) {
6134 oc
->flags
|= NX_CT_F_COMMIT
;
6135 } else if (!strcmp(key
, "force")) {
6136 oc
->flags
|= NX_CT_F_FORCE
;
6137 } else if (!strcmp(key
, "table")) {
6138 error
= str_to_u8(value
, "recirc_table", &oc
->recirc_table
);
6139 if (!error
&& oc
->recirc_table
== NX_CT_RECIRC_NONE
) {
6140 error
= xasprintf("invalid table %#"PRIx8
, oc
->recirc_table
);
6142 } else if (!strcmp(key
, "zone")) {
6143 error
= str_to_u16(value
, "zone", &oc
->zone_imm
);
6147 error
= mf_parse_subfield(&oc
->zone_src
, value
);
6152 } else if (!strcmp(key
, "alg")) {
6153 error
= str_to_connhelper(value
, &oc
->alg
);
6154 } else if (!strcmp(key
, "nat")) {
6155 const size_t nat_offset
= ofpacts_pull(ofpacts
);
6157 error
= parse_NAT(value
, port_map
, ofpacts
, usable_protocols
);
6158 /* Update CT action pointer and length. */
6159 ofpacts
->header
= ofpbuf_push_uninit(ofpacts
, nat_offset
);
6160 oc
= ofpacts
->header
;
6161 } else if (!strcmp(key
, "exec")) {
6162 /* Hide existing actions from ofpacts_parse_copy(), so the
6163 * nesting can be handled transparently. */
6164 enum ofputil_protocol usable_protocols2
;
6165 const size_t exec_offset
= ofpacts_pull(ofpacts
);
6167 /* Initializes 'usable_protocol2', fold it back to
6168 * '*usable_protocols' afterwards, so that we do not lose
6169 * restrictions already in there. */
6170 error
= ofpacts_parse_copy(value
, port_map
, ofpacts
,
6171 &usable_protocols2
, false, OFPACT_CT
);
6172 *usable_protocols
&= usable_protocols2
;
6173 ofpacts
->header
= ofpbuf_push_uninit(ofpacts
, exec_offset
);
6174 oc
= ofpacts
->header
;
6176 error
= xasprintf("invalid argument to \"ct\" action: `%s'", key
);
6182 if (!error
&& oc
->flags
& NX_CT_F_FORCE
&& !(oc
->flags
& NX_CT_F_COMMIT
)) {
6183 error
= xasprintf("\"force\" flag requires \"commit\" flag.");
6185 ofpact_finish_CT(ofpacts
, &oc
);
6186 ofpbuf_push_uninit(ofpacts
, ct_offset
);
6191 format_alg(int port
, struct ds
*s
)
6195 ds_put_format(s
, "%salg=%sftp,", colors
.param
, colors
.end
);
6198 ds_put_format(s
, "%salg=%stftp,", colors
.param
, colors
.end
);
6204 ds_put_format(s
, "%salg=%s%d,", colors
.param
, colors
.end
, port
);
6209 static void format_NAT(const struct ofpact_nat
*,
6210 const struct ofputil_port_map
*port_map
,
6214 format_CT(const struct ofpact_conntrack
*a
,
6215 const struct ofputil_port_map
*port_map
,
6218 ds_put_format(s
, "%sct(%s", colors
.paren
, colors
.end
);
6219 if (a
->flags
& NX_CT_F_COMMIT
) {
6220 ds_put_format(s
, "%scommit%s,", colors
.value
, colors
.end
);
6222 if (a
->flags
& NX_CT_F_FORCE
) {
6223 ds_put_format(s
, "%sforce%s,", colors
.value
, colors
.end
);
6225 if (a
->recirc_table
!= NX_CT_RECIRC_NONE
) {
6226 ds_put_format(s
, "%stable=%s%"PRIu8
",",
6227 colors
.special
, colors
.end
, a
->recirc_table
);
6229 if (a
->zone_src
.field
) {
6230 ds_put_format(s
, "%szone=%s", colors
.param
, colors
.end
);
6231 mf_format_subfield(&a
->zone_src
, s
);
6232 ds_put_char(s
, ',');
6233 } else if (a
->zone_imm
) {
6234 ds_put_format(s
, "%szone=%s%"PRIu16
",",
6235 colors
.param
, colors
.end
, a
->zone_imm
);
6237 /* If the first action is a NAT action, format it outside of the 'exec'
6239 const struct ofpact
*action
= a
->actions
;
6240 size_t actions_len
= ofpact_ct_get_action_len(a
);
6241 if (actions_len
&& action
->type
== OFPACT_NAT
) {
6242 format_NAT(ofpact_get_NAT(action
), port_map
, s
);
6243 ds_put_char(s
, ',');
6244 actions_len
-= OFPACT_ALIGN(action
->len
);
6245 action
= ofpact_next(action
);
6248 ds_put_format(s
, "%sexec(%s", colors
.paren
, colors
.end
);
6249 ofpacts_format(action
, actions_len
, port_map
, s
);
6250 ds_put_format(s
, "%s),%s", colors
.paren
, colors
.end
);
6252 format_alg(a
->alg
, s
);
6254 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
6257 /* ct_clear action. */
6260 decode_NXAST_RAW_CT_CLEAR(struct ofpbuf
*out
)
6262 ofpact_put_CT_CLEAR(out
);
6267 encode_CT_CLEAR(const struct ofpact_null
*null OVS_UNUSED
,
6268 enum ofp_version ofp_version OVS_UNUSED
,
6271 put_NXAST_CT_CLEAR(out
);
6274 static char * OVS_WARN_UNUSED_RESULT
6275 parse_CT_CLEAR(char *arg OVS_UNUSED
,
6276 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6277 struct ofpbuf
*ofpacts
,
6278 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
6280 ofpact_put_CT_CLEAR(ofpacts
);
6285 format_CT_CLEAR(const struct ofpact_null
*a OVS_UNUSED
,
6286 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6289 ds_put_format(s
, "%sct_clear%s", colors
.value
, colors
.end
);
6294 /* Which optional fields are present? */
6296 NX_NAT_RANGE_IPV4_MIN
= 1 << 0, /* ovs_be32 */
6297 NX_NAT_RANGE_IPV4_MAX
= 1 << 1, /* ovs_be32 */
6298 NX_NAT_RANGE_IPV6_MIN
= 1 << 2, /* struct in6_addr */
6299 NX_NAT_RANGE_IPV6_MAX
= 1 << 3, /* struct in6_addr */
6300 NX_NAT_RANGE_PROTO_MIN
= 1 << 4, /* ovs_be16 */
6301 NX_NAT_RANGE_PROTO_MAX
= 1 << 5, /* ovs_be16 */
6304 /* Action structure for NXAST_NAT. */
6305 struct nx_action_nat
{
6306 ovs_be16 type
; /* OFPAT_VENDOR. */
6307 ovs_be16 len
; /* At least 16. */
6308 ovs_be32 vendor
; /* NX_VENDOR_ID. */
6309 ovs_be16 subtype
; /* NXAST_NAT. */
6310 uint8_t pad
[2]; /* Must be zero. */
6311 ovs_be16 flags
; /* Zero or more NX_NAT_F_* flags.
6312 * Unspecified flag bits must be zero. */
6313 ovs_be16 range_present
; /* NX_NAT_RANGE_* */
6314 /* Followed by optional parameters as specified by 'range_present' */
6316 OFP_ASSERT(sizeof(struct nx_action_nat
) == 16);
6319 encode_NAT(const struct ofpact_nat
*nat
,
6320 enum ofp_version ofp_version OVS_UNUSED
,
6323 struct nx_action_nat
*nan
;
6324 const size_t ofs
= out
->size
;
6325 uint16_t range_present
= 0;
6327 nan
= put_NXAST_NAT(out
);
6328 nan
->flags
= htons(nat
->flags
);
6329 if (nat
->range_af
== AF_INET
) {
6330 if (nat
->range
.addr
.ipv4
.min
) {
6331 ovs_be32
*min
= ofpbuf_put_uninit(out
, sizeof *min
);
6332 *min
= nat
->range
.addr
.ipv4
.min
;
6333 range_present
|= NX_NAT_RANGE_IPV4_MIN
;
6335 if (nat
->range
.addr
.ipv4
.max
) {
6336 ovs_be32
*max
= ofpbuf_put_uninit(out
, sizeof *max
);
6337 *max
= nat
->range
.addr
.ipv4
.max
;
6338 range_present
|= NX_NAT_RANGE_IPV4_MAX
;
6340 } else if (nat
->range_af
== AF_INET6
) {
6341 if (!ipv6_mask_is_any(&nat
->range
.addr
.ipv6
.min
)) {
6342 struct in6_addr
*min
= ofpbuf_put_uninit(out
, sizeof *min
);
6343 *min
= nat
->range
.addr
.ipv6
.min
;
6344 range_present
|= NX_NAT_RANGE_IPV6_MIN
;
6346 if (!ipv6_mask_is_any(&nat
->range
.addr
.ipv6
.max
)) {
6347 struct in6_addr
*max
= ofpbuf_put_uninit(out
, sizeof *max
);
6348 *max
= nat
->range
.addr
.ipv6
.max
;
6349 range_present
|= NX_NAT_RANGE_IPV6_MAX
;
6352 if (nat
->range_af
!= AF_UNSPEC
) {
6353 if (nat
->range
.proto
.min
) {
6354 ovs_be16
*min
= ofpbuf_put_uninit(out
, sizeof *min
);
6355 *min
= htons(nat
->range
.proto
.min
);
6356 range_present
|= NX_NAT_RANGE_PROTO_MIN
;
6358 if (nat
->range
.proto
.max
) {
6359 ovs_be16
*max
= ofpbuf_put_uninit(out
, sizeof *max
);
6360 *max
= htons(nat
->range
.proto
.max
);
6361 range_present
|= NX_NAT_RANGE_PROTO_MAX
;
6364 pad_ofpat(out
, ofs
);
6365 nan
= ofpbuf_at(out
, ofs
, sizeof *nan
);
6366 nan
->range_present
= htons(range_present
);
6370 decode_NXAST_RAW_NAT(const struct nx_action_nat
*nan
,
6371 enum ofp_version ofp_version OVS_UNUSED
,
6374 struct ofpact_nat
*nat
;
6375 uint16_t range_present
= ntohs(nan
->range_present
);
6376 const char *opts
= (char *)(nan
+ 1);
6377 uint16_t len
= ntohs(nan
->len
) - sizeof *nan
;
6379 nat
= ofpact_put_NAT(out
);
6380 nat
->flags
= ntohs(nan
->flags
);
6382 /* Check for unknown or mutually exclusive flags. */
6383 if ((nat
->flags
& ~NX_NAT_F_MASK
)
6384 || (nat
->flags
& NX_NAT_F_SRC
&& nat
->flags
& NX_NAT_F_DST
)
6385 || (nat
->flags
& NX_NAT_F_PROTO_HASH
6386 && nat
->flags
& NX_NAT_F_PROTO_RANDOM
)) {
6387 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6390 #define NX_NAT_GET_OPT(DST, SRC, LEN, TYPE) \
6391 (LEN >= sizeof(TYPE) \
6392 ? (memcpy(DST, SRC, sizeof(TYPE)), LEN -= sizeof(TYPE), \
6393 SRC += sizeof(TYPE)) \
6396 nat
->range_af
= AF_UNSPEC
;
6397 if (range_present
& NX_NAT_RANGE_IPV4_MIN
) {
6398 if (range_present
& (NX_NAT_RANGE_IPV6_MIN
| NX_NAT_RANGE_IPV6_MAX
)) {
6399 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6402 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv4
.min
, opts
, len
, ovs_be32
)
6403 || !nat
->range
.addr
.ipv4
.min
) {
6404 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6407 nat
->range_af
= AF_INET
;
6409 if (range_present
& NX_NAT_RANGE_IPV4_MAX
) {
6410 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv4
.max
, opts
, len
,
6412 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6414 if (ntohl(nat
->range
.addr
.ipv4
.max
)
6415 < ntohl(nat
->range
.addr
.ipv4
.min
)) {
6416 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6419 } else if (range_present
& NX_NAT_RANGE_IPV4_MAX
) {
6420 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6421 } else if (range_present
& NX_NAT_RANGE_IPV6_MIN
) {
6422 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv6
.min
, opts
, len
,
6424 || ipv6_mask_is_any(&nat
->range
.addr
.ipv6
.min
)) {
6425 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6428 nat
->range_af
= AF_INET6
;
6430 if (range_present
& NX_NAT_RANGE_IPV6_MAX
) {
6431 if (!NX_NAT_GET_OPT(&nat
->range
.addr
.ipv6
.max
, opts
, len
,
6433 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6435 if (memcmp(&nat
->range
.addr
.ipv6
.max
, &nat
->range
.addr
.ipv6
.min
,
6436 sizeof(struct in6_addr
)) < 0) {
6437 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6440 } else if (range_present
& NX_NAT_RANGE_IPV6_MAX
) {
6441 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6444 if (range_present
& NX_NAT_RANGE_PROTO_MIN
) {
6447 if (nat
->range_af
== AF_UNSPEC
) {
6448 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6450 if (!NX_NAT_GET_OPT(&proto
, opts
, len
, ovs_be16
) || proto
== 0) {
6451 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6453 nat
->range
.proto
.min
= ntohs(proto
);
6454 if (range_present
& NX_NAT_RANGE_PROTO_MAX
) {
6455 if (!NX_NAT_GET_OPT(&proto
, opts
, len
, ovs_be16
)) {
6456 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6458 nat
->range
.proto
.max
= ntohs(proto
);
6459 if (nat
->range
.proto
.max
< nat
->range
.proto
.min
) {
6460 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6463 } else if (range_present
& NX_NAT_RANGE_PROTO_MAX
) {
6464 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6471 format_NAT(const struct ofpact_nat
*a
,
6472 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6475 ds_put_format(ds
, "%snat%s", colors
.paren
, colors
.end
);
6477 if (a
->flags
& (NX_NAT_F_SRC
| NX_NAT_F_DST
)) {
6478 ds_put_format(ds
, "%s(%s", colors
.paren
, colors
.end
);
6479 ds_put_format(ds
, a
->flags
& NX_NAT_F_SRC
? "%ssrc%s" : "%sdst%s",
6480 colors
.param
, colors
.end
);
6482 if (a
->range_af
!= AF_UNSPEC
) {
6483 ds_put_format(ds
, "%s=%s", colors
.param
, colors
.end
);
6485 if (a
->range_af
== AF_INET
) {
6486 ds_put_format(ds
, IP_FMT
, IP_ARGS(a
->range
.addr
.ipv4
.min
));
6488 if (a
->range
.addr
.ipv4
.max
6489 && a
->range
.addr
.ipv4
.max
!= a
->range
.addr
.ipv4
.min
) {
6490 ds_put_format(ds
, "-"IP_FMT
,
6491 IP_ARGS(a
->range
.addr
.ipv4
.max
));
6493 } else if (a
->range_af
== AF_INET6
) {
6494 ipv6_format_addr_bracket(&a
->range
.addr
.ipv6
.min
, ds
,
6495 a
->range
.proto
.min
);
6497 if (!ipv6_mask_is_any(&a
->range
.addr
.ipv6
.max
)
6498 && memcmp(&a
->range
.addr
.ipv6
.max
, &a
->range
.addr
.ipv6
.min
,
6499 sizeof(struct in6_addr
)) != 0) {
6500 ds_put_char(ds
, '-');
6501 ipv6_format_addr_bracket(&a
->range
.addr
.ipv6
.max
, ds
,
6502 a
->range
.proto
.min
);
6505 if (a
->range
.proto
.min
) {
6506 ds_put_char(ds
, ':');
6507 ds_put_format(ds
, "%"PRIu16
, a
->range
.proto
.min
);
6509 if (a
->range
.proto
.max
6510 && a
->range
.proto
.max
!= a
->range
.proto
.min
) {
6511 ds_put_format(ds
, "-%"PRIu16
, a
->range
.proto
.max
);
6514 ds_put_char(ds
, ',');
6516 if (a
->flags
& NX_NAT_F_PERSISTENT
) {
6517 ds_put_format(ds
, "%spersistent%s,",
6518 colors
.value
, colors
.end
);
6520 if (a
->flags
& NX_NAT_F_PROTO_HASH
) {
6521 ds_put_format(ds
, "%shash%s,", colors
.value
, colors
.end
);
6523 if (a
->flags
& NX_NAT_F_PROTO_RANDOM
) {
6524 ds_put_format(ds
, "%srandom%s,", colors
.value
, colors
.end
);
6528 ds_put_format(ds
, "%s)%s", colors
.paren
, colors
.end
);
6532 static char * OVS_WARN_UNUSED_RESULT
6533 str_to_nat_range(const char *s
, struct ofpact_nat
*on
)
6535 char ipv6_s
[IPV6_SCAN_LEN
+ 1];
6538 on
->range_af
= AF_UNSPEC
;
6539 if (ovs_scan_len(s
, &n
, IP_SCAN_FMT
,
6540 IP_SCAN_ARGS(&on
->range
.addr
.ipv4
.min
))) {
6541 on
->range_af
= AF_INET
;
6545 if (!ovs_scan_len(s
, &n
, IP_SCAN_FMT
,
6546 IP_SCAN_ARGS(&on
->range
.addr
.ipv4
.max
))
6547 || (ntohl(on
->range
.addr
.ipv4
.max
)
6548 < ntohl(on
->range
.addr
.ipv4
.min
))) {
6552 } else if ((ovs_scan_len(s
, &n
, IPV6_SCAN_FMT
, ipv6_s
)
6553 || ovs_scan_len(s
, &n
, "["IPV6_SCAN_FMT
"]", ipv6_s
))
6554 && inet_pton(AF_INET6
, ipv6_s
, &on
->range
.addr
.ipv6
.min
) == 1) {
6555 on
->range_af
= AF_INET6
;
6559 if (!(ovs_scan_len(s
, &n
, IPV6_SCAN_FMT
, ipv6_s
)
6560 || ovs_scan_len(s
, &n
, "["IPV6_SCAN_FMT
"]", ipv6_s
))
6561 || inet_pton(AF_INET6
, ipv6_s
, &on
->range
.addr
.ipv6
.max
) != 1
6562 || memcmp(&on
->range
.addr
.ipv6
.max
, &on
->range
.addr
.ipv6
.min
,
6563 sizeof on
->range
.addr
.ipv6
.max
) < 0) {
6568 if (on
->range_af
!= AF_UNSPEC
&& s
[n
] == ':') {
6570 if (!ovs_scan_len(s
, &n
, "%"SCNu16
, &on
->range
.proto
.min
)) {
6575 if (!ovs_scan_len(s
, &n
, "%"SCNu16
, &on
->range
.proto
.max
)
6576 || on
->range
.proto
.max
< on
->range
.proto
.min
) {
6581 if (strlen(s
) != n
) {
6582 return xasprintf("garbage (%s) after nat range \"%s\" (pos: %d)",
6587 return xasprintf("invalid nat range \"%s\"", s
);
6591 /* Parses 'arg' as the argument to a "nat" action, and appends such an
6592 * action to 'ofpacts'.
6594 * Returns NULL if successful, otherwise a malloc()'d string describing the
6595 * error. The caller is responsible for freeing the returned string. */
6596 static char * OVS_WARN_UNUSED_RESULT
6597 parse_NAT(char *arg
,
6598 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6599 struct ofpbuf
*ofpacts
,
6600 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
6602 struct ofpact_nat
*on
= ofpact_put_NAT(ofpacts
);
6606 on
->range_af
= AF_UNSPEC
;
6608 while (ofputil_parse_key_value(&arg
, &key
, &value
)) {
6611 if (!strcmp(key
, "src")) {
6612 on
->flags
|= NX_NAT_F_SRC
;
6613 error
= str_to_nat_range(value
, on
);
6614 } else if (!strcmp(key
, "dst")) {
6615 on
->flags
|= NX_NAT_F_DST
;
6616 error
= str_to_nat_range(value
, on
);
6617 } else if (!strcmp(key
, "persistent")) {
6618 on
->flags
|= NX_NAT_F_PERSISTENT
;
6619 } else if (!strcmp(key
, "hash")) {
6620 on
->flags
|= NX_NAT_F_PROTO_HASH
;
6621 } else if (!strcmp(key
, "random")) {
6622 on
->flags
|= NX_NAT_F_PROTO_RANDOM
;
6624 error
= xasprintf("invalid key \"%s\" in \"nat\" argument",
6631 if (on
->flags
& NX_NAT_F_SRC
&& on
->flags
& NX_NAT_F_DST
) {
6632 return xasprintf("May only specify one of \"src\" or \"dst\".");
6634 if (!(on
->flags
& NX_NAT_F_SRC
|| on
->flags
& NX_NAT_F_DST
)) {
6636 return xasprintf("Flags allowed only with \"src\" or \"dst\".");
6638 if (on
->range_af
!= AF_UNSPEC
) {
6639 return xasprintf("Range allowed only with \"src\" or \"dst\".");
6642 if (on
->flags
& NX_NAT_F_PROTO_HASH
&& on
->flags
& NX_NAT_F_PROTO_RANDOM
) {
6643 return xasprintf("Both \"hash\" and \"random\" are not allowed.");
6649 /* Truncate output action. */
6650 struct nx_action_output_trunc
{
6651 ovs_be16 type
; /* OFPAT_VENDOR. */
6652 ovs_be16 len
; /* At least 16. */
6653 ovs_be32 vendor
; /* NX_VENDOR_ID. */
6654 ovs_be16 subtype
; /* NXAST_OUTPUT_TRUNC. */
6655 ovs_be16 port
; /* Output port */
6656 ovs_be32 max_len
; /* Truncate packet to size bytes */
6658 OFP_ASSERT(sizeof(struct nx_action_output_trunc
) == 16);
6661 decode_NXAST_RAW_OUTPUT_TRUNC(const struct nx_action_output_trunc
*natrc
,
6662 enum ofp_version ofp_version OVS_UNUSED
,
6665 struct ofpact_output_trunc
*output_trunc
;
6667 output_trunc
= ofpact_put_OUTPUT_TRUNC(out
);
6668 output_trunc
->max_len
= ntohl(natrc
->max_len
);
6669 output_trunc
->port
= u16_to_ofp(ntohs(natrc
->port
));
6671 if (output_trunc
->max_len
< ETH_HEADER_LEN
) {
6672 return OFPERR_OFPBAC_BAD_ARGUMENT
;
6678 encode_OUTPUT_TRUNC(const struct ofpact_output_trunc
*output_trunc
,
6679 enum ofp_version ofp_version OVS_UNUSED
,
6682 struct nx_action_output_trunc
*natrc
= put_NXAST_OUTPUT_TRUNC(out
);
6684 natrc
->max_len
= htonl(output_trunc
->max_len
);
6685 natrc
->port
= htons(ofp_to_u16(output_trunc
->port
));
6688 static char * OVS_WARN_UNUSED_RESULT
6689 parse_OUTPUT_TRUNC(const char *arg
,
6690 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6691 struct ofpbuf
*ofpacts OVS_UNUSED
,
6692 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
6694 /* Disable output_trunc parsing. Expose as output(port=N,max_len=M) and
6695 * reuse parse_OUTPUT to parse output_trunc action. */
6696 return xasprintf("unknown action %s", arg
);
6700 format_OUTPUT_TRUNC(const struct ofpact_output_trunc
*a
,
6701 const struct ofputil_port_map
*port_map
, struct ds
*s
)
6703 ds_put_format(s
, "%soutput%s(port=", colors
.special
, colors
.end
);
6704 ofputil_format_port(a
->port
, port_map
, s
);
6705 ds_put_format(s
, ",max_len=%"PRIu32
")", a
->max_len
);
6709 /* Meter instruction. */
6712 encode_METER(const struct ofpact_meter
*meter
,
6713 enum ofp_version ofp_version
, struct ofpbuf
*out
)
6715 if (ofp_version
>= OFP13_VERSION
) {
6716 instruction_put_OFPIT13_METER(out
)->meter_id
= htonl(meter
->meter_id
);
6720 static char * OVS_WARN_UNUSED_RESULT
6721 parse_METER(char *arg
,
6722 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6723 struct ofpbuf
*ofpacts
,
6724 enum ofputil_protocol
*usable_protocols
)
6726 *usable_protocols
&= OFPUTIL_P_OF13_UP
;
6727 return str_to_u32(arg
, &ofpact_put_METER(ofpacts
)->meter_id
);
6731 format_METER(const struct ofpact_meter
*a
,
6732 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6735 ds_put_format(s
, "%smeter:%s%"PRIu32
,
6736 colors
.param
, colors
.end
, a
->meter_id
);
6739 /* Clear-Actions instruction. */
6742 encode_CLEAR_ACTIONS(const struct ofpact_null
*null OVS_UNUSED
,
6743 enum ofp_version ofp_version OVS_UNUSED
,
6744 struct ofpbuf
*out OVS_UNUSED
)
6746 if (ofp_version
> OFP10_VERSION
) {
6747 instruction_put_OFPIT11_CLEAR_ACTIONS(out
);
6751 static char * OVS_WARN_UNUSED_RESULT
6752 parse_CLEAR_ACTIONS(char *arg OVS_UNUSED
,
6753 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6754 struct ofpbuf
*ofpacts
,
6755 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
6757 ofpact_put_CLEAR_ACTIONS(ofpacts
);
6762 format_CLEAR_ACTIONS(const struct ofpact_null
*a OVS_UNUSED
,
6763 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6766 ds_put_format(s
, "%sclear_actions%s", colors
.value
, colors
.end
);
6769 /* Write-Actions instruction. */
6772 encode_WRITE_ACTIONS(const struct ofpact_nest
*actions
,
6773 enum ofp_version ofp_version
, struct ofpbuf
*out
)
6775 if (ofp_version
> OFP10_VERSION
) {
6776 const size_t ofs
= out
->size
;
6778 instruction_put_OFPIT11_WRITE_ACTIONS(out
);
6779 ofpacts_put_openflow_actions(actions
->actions
,
6780 ofpact_nest_get_action_len(actions
),
6782 ofpacts_update_instruction_actions(out
, ofs
);
6786 static char * OVS_WARN_UNUSED_RESULT
6787 parse_WRITE_ACTIONS(char *arg
, const struct ofputil_port_map
*port_map
,
6788 struct ofpbuf
*ofpacts
,
6789 enum ofputil_protocol
*usable_protocols
)
6791 size_t ofs
= ofpacts_pull(ofpacts
);
6792 struct ofpact_nest
*on
;
6795 /* Add a Write-Actions instruction and then pull it off. */
6796 ofpact_put(ofpacts
, OFPACT_WRITE_ACTIONS
, sizeof *on
);
6797 ofpbuf_pull(ofpacts
, sizeof *on
);
6799 /* Parse nested actions.
6801 * We pulled off "write-actions" and the previous actions because the
6802 * OFPACT_WRITE_ACTIONS is only partially constructed: its length is such
6803 * that it doesn't actually include the nested actions. That means that
6804 * ofpacts_parse() would reject them as being part of an Apply-Actions that
6805 * follows a Write-Actions, which is an invalid order. */
6806 error
= ofpacts_parse(arg
, port_map
, ofpacts
, usable_protocols
, false,
6807 OFPACT_WRITE_ACTIONS
);
6809 /* Put the Write-Actions back on and update its length. */
6810 on
= ofpbuf_push_uninit(ofpacts
, sizeof *on
);
6811 on
->ofpact
.len
= ofpacts
->size
;
6813 /* Put any previous actions or instructions back on. */
6814 ofpbuf_push_uninit(ofpacts
, ofs
);
6820 format_WRITE_ACTIONS(const struct ofpact_nest
*a
,
6821 const struct ofputil_port_map
*port_map
, struct ds
*s
)
6823 ds_put_format(s
, "%swrite_actions(%s", colors
.paren
, colors
.end
);
6824 ofpacts_format(a
->actions
, ofpact_nest_get_action_len(a
), port_map
, s
);
6825 ds_put_format(s
, "%s)%s", colors
.paren
, colors
.end
);
6828 /* Action structure for NXAST_WRITE_METADATA.
6830 * Modifies the 'mask' bits of the metadata value. */
6831 struct nx_action_write_metadata
{
6832 ovs_be16 type
; /* OFPAT_VENDOR. */
6833 ovs_be16 len
; /* Length is 32. */
6834 ovs_be32 vendor
; /* NX_VENDOR_ID. */
6835 ovs_be16 subtype
; /* NXAST_WRITE_METADATA. */
6836 uint8_t zeros
[6]; /* Must be zero. */
6837 ovs_be64 metadata
; /* Metadata register. */
6838 ovs_be64 mask
; /* Metadata mask. */
6840 OFP_ASSERT(sizeof(struct nx_action_write_metadata
) == 32);
6843 decode_NXAST_RAW_WRITE_METADATA(const struct nx_action_write_metadata
*nawm
,
6844 enum ofp_version ofp_version OVS_UNUSED
,
6847 struct ofpact_metadata
*om
;
6849 if (!is_all_zeros(nawm
->zeros
, sizeof nawm
->zeros
)) {
6850 return OFPERR_NXBRC_MUST_BE_ZERO
;
6853 om
= ofpact_put_WRITE_METADATA(out
);
6854 om
->metadata
= nawm
->metadata
;
6855 om
->mask
= nawm
->mask
;
6861 encode_WRITE_METADATA(const struct ofpact_metadata
*metadata
,
6862 enum ofp_version ofp_version
, struct ofpbuf
*out
)
6864 if (ofp_version
== OFP10_VERSION
) {
6865 struct nx_action_write_metadata
*nawm
;
6867 nawm
= put_NXAST_WRITE_METADATA(out
);
6868 nawm
->metadata
= metadata
->metadata
;
6869 nawm
->mask
= metadata
->mask
;
6871 struct ofp11_instruction_write_metadata
*oiwm
;
6873 oiwm
= instruction_put_OFPIT11_WRITE_METADATA(out
);
6874 oiwm
->metadata
= metadata
->metadata
;
6875 oiwm
->metadata_mask
= metadata
->mask
;
6879 static char * OVS_WARN_UNUSED_RESULT
6880 parse_WRITE_METADATA(char *arg
,
6881 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6882 struct ofpbuf
*ofpacts
,
6883 enum ofputil_protocol
*usable_protocols
)
6885 struct ofpact_metadata
*om
;
6886 char *mask
= strchr(arg
, '/');
6888 *usable_protocols
&= OFPUTIL_P_NXM_OF11_UP
;
6890 om
= ofpact_put_WRITE_METADATA(ofpacts
);
6895 error
= str_to_be64(mask
+ 1, &om
->mask
);
6900 om
->mask
= OVS_BE64_MAX
;
6903 return str_to_be64(arg
, &om
->metadata
);
6907 format_WRITE_METADATA(const struct ofpact_metadata
*a
,
6908 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6911 ds_put_format(s
, "%swrite_metadata:%s%#"PRIx64
,
6912 colors
.param
, colors
.end
, ntohll(a
->metadata
));
6913 if (a
->mask
!= OVS_BE64_MAX
) {
6914 ds_put_format(s
, "/%#"PRIx64
, ntohll(a
->mask
));
6918 /* Goto-Table instruction. */
6921 encode_GOTO_TABLE(const struct ofpact_goto_table
*goto_table
,
6922 enum ofp_version ofp_version
, struct ofpbuf
*out
)
6924 if (ofp_version
== OFP10_VERSION
) {
6925 struct nx_action_resubmit
*nar
;
6927 nar
= put_NXAST_RESUBMIT_TABLE(out
);
6928 nar
->table
= goto_table
->table_id
;
6929 nar
->in_port
= htons(ofp_to_u16(OFPP_IN_PORT
));
6931 struct ofp11_instruction_goto_table
*oigt
;
6933 oigt
= instruction_put_OFPIT11_GOTO_TABLE(out
);
6934 oigt
->table_id
= goto_table
->table_id
;
6935 memset(oigt
->pad
, 0, sizeof oigt
->pad
);
6939 static char * OVS_WARN_UNUSED_RESULT
6940 parse_GOTO_TABLE(char *arg
,
6941 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6942 struct ofpbuf
*ofpacts
,
6943 enum ofputil_protocol
*usable_protocols OVS_UNUSED
)
6945 struct ofpact_goto_table
*ogt
= ofpact_put_GOTO_TABLE(ofpacts
);
6946 char *table_s
= strsep(&arg
, ",");
6947 if (!table_s
|| !table_s
[0]) {
6948 return xstrdup("instruction goto-table needs table id");
6950 return str_to_u8(table_s
, "table", &ogt
->table_id
);
6954 format_GOTO_TABLE(const struct ofpact_goto_table
*a
,
6955 const struct ofputil_port_map
*port_map OVS_UNUSED
,
6958 ds_put_format(s
, "%sgoto_table:%s%"PRIu8
,
6959 colors
.param
, colors
.end
, a
->table_id
);
6963 log_bad_action(const struct ofp_action_header
*actions
, size_t actions_len
,
6964 const struct ofp_action_header
*bad_action
, enum ofperr error
)
6966 if (!VLOG_DROP_WARN(&rl
)) {
6970 ds_put_hex_dump(&s
, actions
, actions_len
, 0, false);
6971 VLOG_WARN("bad action at offset %#"PRIxPTR
" (%s):\n%s",
6972 (char *)bad_action
- (char *)actions
,
6973 ofperr_get_name(error
), ds_cstr(&s
));
6979 ofpacts_decode(const void *actions
, size_t actions_len
,
6980 enum ofp_version ofp_version
,
6981 const struct vl_mff_map
*vl_mff_map
,
6982 uint64_t *ofpacts_tlv_bitmap
, struct ofpbuf
*ofpacts
)
6984 struct ofpbuf openflow
= ofpbuf_const_initializer(actions
, actions_len
);
6985 while (openflow
.size
) {
6986 const struct ofp_action_header
*action
= openflow
.data
;
6987 enum ofp_raw_action_type raw
;
6991 error
= ofpact_pull_raw(&openflow
, ofp_version
, &raw
, &arg
);
6993 error
= ofpact_decode(action
, raw
, ofp_version
, arg
, vl_mff_map
,
6994 ofpacts_tlv_bitmap
, ofpacts
);
6998 log_bad_action(actions
, actions_len
, action
, error
);
7006 ofpacts_pull_openflow_actions__(struct ofpbuf
*openflow
,
7007 unsigned int actions_len
,
7008 enum ofp_version version
,
7009 uint32_t allowed_ovsinsts
,
7010 struct ofpbuf
*ofpacts
,
7011 enum ofpact_type outer_action
,
7012 const struct vl_mff_map
*vl_mff_map
,
7013 uint64_t *ofpacts_tlv_bitmap
)
7015 const struct ofp_action_header
*actions
;
7016 size_t orig_size
= ofpacts
->size
;
7019 if (actions_len
% OFP_ACTION_ALIGN
!= 0) {
7020 VLOG_WARN_RL(&rl
, "OpenFlow message actions length %u is not a "
7021 "multiple of %d", actions_len
, OFP_ACTION_ALIGN
);
7022 return OFPERR_OFPBRC_BAD_LEN
;
7025 actions
= ofpbuf_try_pull(openflow
, actions_len
);
7026 if (actions
== NULL
) {
7027 VLOG_WARN_RL(&rl
, "OpenFlow message actions length %u exceeds "
7028 "remaining message length (%"PRIu32
")",
7029 actions_len
, openflow
->size
);
7030 return OFPERR_OFPBRC_BAD_LEN
;
7033 error
= ofpacts_decode(actions
, actions_len
, version
, vl_mff_map
,
7034 ofpacts_tlv_bitmap
, ofpacts
);
7036 ofpacts
->size
= orig_size
;
7040 error
= ofpacts_verify(ofpacts
->data
, ofpacts
->size
, allowed_ovsinsts
,
7043 ofpacts
->size
= orig_size
;
7048 /* Attempts to convert 'actions_len' bytes of OpenFlow actions from the front
7049 * of 'openflow' into ofpacts. On success, appends the converted actions to
7050 * 'ofpacts'; on failure, 'ofpacts' is unchanged (but might be reallocated) .
7051 * Returns 0 if successful, otherwise an OpenFlow error.
7053 * Actions are processed according to their OpenFlow version which
7054 * is provided in the 'version' parameter.
7056 * In most places in OpenFlow, actions appear encapsulated in instructions, so
7057 * you should call ofpacts_pull_openflow_instructions() instead of this
7060 * 'vl_mff_map' and 'ofpacts_tlv_bitmap' are optional. If 'vl_mff_map' is
7061 * provided, it is used to get variable length mf_fields with configured
7062 * length in the actions. If an action uses a variable length mf_field,
7063 * 'ofpacts_tlv_bitmap' is updated accordingly for ref counting. If
7064 * 'vl_mff_map' is not provided, the default mf_fields with maximum length
7067 * The parsed actions are valid generically, but they may not be valid in a
7068 * specific context. For example, port numbers up to OFPP_MAX are valid
7069 * generically, but specific datapaths may only support port numbers in a
7070 * smaller range. Use ofpacts_check() to additional check whether actions are
7071 * valid in a specific context. */
7073 ofpacts_pull_openflow_actions(struct ofpbuf
*openflow
,
7074 unsigned int actions_len
,
7075 enum ofp_version version
,
7076 const struct vl_mff_map
*vl_mff_map
,
7077 uint64_t *ofpacts_tlv_bitmap
,
7078 struct ofpbuf
*ofpacts
)
7080 return ofpacts_pull_openflow_actions__(openflow
, actions_len
, version
,
7081 1u << OVSINST_OFPIT11_APPLY_ACTIONS
,
7082 ofpacts
, 0, vl_mff_map
,
7083 ofpacts_tlv_bitmap
);
7086 /* OpenFlow 1.1 actions. */
7089 /* True if an action sets the value of a field
7090 * in a way that is compatibile with the action set.
7091 * The field can be set via either a set or a move action.
7092 * False otherwise. */
7094 ofpact_is_set_or_move_action(const struct ofpact
*a
)
7097 case OFPACT_SET_FIELD
:
7098 case OFPACT_REG_MOVE
:
7099 case OFPACT_SET_ETH_DST
:
7100 case OFPACT_SET_ETH_SRC
:
7101 case OFPACT_SET_IP_DSCP
:
7102 case OFPACT_SET_IP_ECN
:
7103 case OFPACT_SET_IP_TTL
:
7104 case OFPACT_SET_IPV4_DST
:
7105 case OFPACT_SET_IPV4_SRC
:
7106 case OFPACT_SET_L4_DST_PORT
:
7107 case OFPACT_SET_L4_SRC_PORT
:
7108 case OFPACT_SET_MPLS_LABEL
:
7109 case OFPACT_SET_MPLS_TC
:
7110 case OFPACT_SET_MPLS_TTL
:
7111 case OFPACT_SET_QUEUE
:
7112 case OFPACT_SET_TUNNEL
:
7113 case OFPACT_SET_VLAN_PCP
:
7114 case OFPACT_SET_VLAN_VID
:
7119 case OFPACT_CLEAR_ACTIONS
:
7121 case OFPACT_CT_CLEAR
:
7124 case OFPACT_CONTROLLER
:
7125 case OFPACT_DEC_MPLS_TTL
:
7126 case OFPACT_DEC_TTL
:
7127 case OFPACT_ENQUEUE
:
7129 case OFPACT_UNROLL_XLATE
:
7130 case OFPACT_FIN_TIMEOUT
:
7131 case OFPACT_GOTO_TABLE
:
7134 case OFPACT_CONJUNCTION
:
7136 case OFPACT_MULTIPATH
:
7139 case OFPACT_OUTPUT_REG
:
7140 case OFPACT_OUTPUT_TRUNC
:
7141 case OFPACT_POP_MPLS
:
7142 case OFPACT_POP_QUEUE
:
7143 case OFPACT_PUSH_MPLS
:
7144 case OFPACT_PUSH_VLAN
:
7145 case OFPACT_RESUBMIT
:
7147 case OFPACT_STACK_POP
:
7148 case OFPACT_STACK_PUSH
:
7149 case OFPACT_STRIP_VLAN
:
7150 case OFPACT_WRITE_ACTIONS
:
7151 case OFPACT_WRITE_METADATA
:
7152 case OFPACT_DEBUG_RECIRC
:
7159 /* True if an action is allowed in the action set.
7160 * False otherwise. */
7162 ofpact_is_allowed_in_actions_set(const struct ofpact
*a
)
7165 case OFPACT_DEC_MPLS_TTL
:
7166 case OFPACT_DEC_TTL
:
7169 case OFPACT_OUTPUT_TRUNC
:
7170 case OFPACT_POP_MPLS
:
7171 case OFPACT_PUSH_MPLS
:
7172 case OFPACT_PUSH_VLAN
:
7173 case OFPACT_REG_MOVE
:
7174 case OFPACT_SET_FIELD
:
7175 case OFPACT_SET_ETH_DST
:
7176 case OFPACT_SET_ETH_SRC
:
7177 case OFPACT_SET_IP_DSCP
:
7178 case OFPACT_SET_IP_ECN
:
7179 case OFPACT_SET_IP_TTL
:
7180 case OFPACT_SET_IPV4_DST
:
7181 case OFPACT_SET_IPV4_SRC
:
7182 case OFPACT_SET_L4_DST_PORT
:
7183 case OFPACT_SET_L4_SRC_PORT
:
7184 case OFPACT_SET_MPLS_LABEL
:
7185 case OFPACT_SET_MPLS_TC
:
7186 case OFPACT_SET_MPLS_TTL
:
7187 case OFPACT_SET_QUEUE
:
7188 case OFPACT_SET_TUNNEL
:
7189 case OFPACT_SET_VLAN_PCP
:
7190 case OFPACT_SET_VLAN_VID
:
7191 case OFPACT_STRIP_VLAN
:
7196 /* In general these actions are excluded because they are not part of
7197 * the OpenFlow specification nor map to actions that are defined in
7198 * the specification. Thus the order in which they should be applied
7199 * in the action set is undefined. */
7202 case OFPACT_CONTROLLER
:
7204 case OFPACT_CT_CLEAR
:
7206 case OFPACT_ENQUEUE
:
7208 case OFPACT_UNROLL_XLATE
:
7209 case OFPACT_FIN_TIMEOUT
:
7211 case OFPACT_CONJUNCTION
:
7212 case OFPACT_MULTIPATH
:
7214 case OFPACT_OUTPUT_REG
:
7215 case OFPACT_POP_QUEUE
:
7216 case OFPACT_RESUBMIT
:
7218 case OFPACT_STACK_POP
:
7219 case OFPACT_STACK_PUSH
:
7220 case OFPACT_DEBUG_RECIRC
:
7222 /* The action set may only include actions and thus
7223 * may not include any instructions */
7224 case OFPACT_CLEAR_ACTIONS
:
7225 case OFPACT_GOTO_TABLE
:
7227 case OFPACT_WRITE_ACTIONS
:
7228 case OFPACT_WRITE_METADATA
:
7235 /* Append ofpact 'a' onto the tail of 'out' */
7237 ofpact_copy(struct ofpbuf
*out
, const struct ofpact
*a
)
7239 ofpbuf_put(out
, a
, OFPACT_ALIGN(a
->len
));
7242 /* Copies the last ofpact whose type is 'filter' from 'in' to 'out'. */
7244 ofpacts_copy_last(struct ofpbuf
*out
, const struct ofpbuf
*in
,
7245 enum ofpact_type filter
)
7247 const struct ofpact
*target
;
7248 const struct ofpact
*a
;
7251 OFPACT_FOR_EACH (a
, in
->data
, in
->size
) {
7252 if (a
->type
== filter
) {
7257 ofpact_copy(out
, target
);
7259 return target
!= NULL
;
7262 /* Append all ofpacts, for which 'filter' returns true, from 'in' to 'out'.
7263 * The order of appended ofpacts is preserved between 'in' and 'out' */
7265 ofpacts_copy_all(struct ofpbuf
*out
, const struct ofpbuf
*in
,
7266 bool (*filter
)(const struct ofpact
*))
7268 const struct ofpact
*a
;
7270 OFPACT_FOR_EACH (a
, in
->data
, in
->size
) {
7272 ofpact_copy(out
, a
);
7277 /* Reads 'action_set', which contains ofpacts accumulated by
7278 * OFPACT_WRITE_ACTIONS instructions, and writes equivalent actions to be
7279 * executed directly into 'action_list'. (These names correspond to the
7280 * "Action Set" and "Action List" terms used in OpenFlow 1.1+.)
7282 * In general this involves appending the last instance of each action that is
7283 * admissible in the action set in the order described in the OpenFlow
7287 * + output action is only appended if no group action was present in 'in'.
7288 * + As a simplification all set actions are copied in the order the are
7289 * provided in 'in' as many set actions applied to a field has the same
7290 * affect as only applying the last action that sets a field and
7291 * duplicates are removed by do_xlate_actions().
7292 * This has an unwanted side-effect of compsoting multiple
7293 * LOAD_REG actions that touch different regions of the same field. */
7295 ofpacts_execute_action_set(struct ofpbuf
*action_list
,
7296 const struct ofpbuf
*action_set
)
7298 /* The OpenFlow spec "Action Set" section specifies this order. */
7299 ofpacts_copy_last(action_list
, action_set
, OFPACT_STRIP_VLAN
);
7300 ofpacts_copy_last(action_list
, action_set
, OFPACT_POP_MPLS
);
7301 ofpacts_copy_last(action_list
, action_set
, OFPACT_DECAP
);
7302 ofpacts_copy_last(action_list
, action_set
, OFPACT_ENCAP
);
7303 ofpacts_copy_last(action_list
, action_set
, OFPACT_PUSH_MPLS
);
7304 ofpacts_copy_last(action_list
, action_set
, OFPACT_PUSH_VLAN
);
7305 ofpacts_copy_last(action_list
, action_set
, OFPACT_DEC_TTL
);
7306 ofpacts_copy_last(action_list
, action_set
, OFPACT_DEC_MPLS_TTL
);
7307 ofpacts_copy_all(action_list
, action_set
, ofpact_is_set_or_move_action
);
7308 ofpacts_copy_last(action_list
, action_set
, OFPACT_SET_QUEUE
);
7310 /* If both OFPACT_GROUP and OFPACT_OUTPUT are present, OpenFlow says that
7311 * we should execute only OFPACT_GROUP.
7313 * If neither OFPACT_GROUP nor OFPACT_OUTPUT is present, then we can drop
7314 * all the actions because there's no point in modifying a packet that will
7315 * not be sent anywhere. */
7316 if (!ofpacts_copy_last(action_list
, action_set
, OFPACT_GROUP
) &&
7317 !ofpacts_copy_last(action_list
, action_set
, OFPACT_OUTPUT
) &&
7318 !ofpacts_copy_last(action_list
, action_set
, OFPACT_RESUBMIT
) &&
7319 !ofpacts_copy_last(action_list
, action_set
, OFPACT_CT
)) {
7320 ofpbuf_clear(action_list
);
7326 ofpacts_decode_for_action_set(const struct ofp_action_header
*in
,
7327 size_t n_in
, enum ofp_version version
,
7328 const struct vl_mff_map
*vl_mff_map
,
7329 uint64_t *ofpacts_tlv_bitmap
,
7334 size_t start
= out
->size
;
7336 error
= ofpacts_decode(in
, n_in
, version
, vl_mff_map
, ofpacts_tlv_bitmap
,
7343 OFPACT_FOR_EACH (a
, ofpact_end(out
->data
, start
), out
->size
- start
) {
7344 if (!ofpact_is_allowed_in_actions_set(a
)) {
7345 VLOG_WARN_RL(&rl
, "disallowed action in action set");
7346 return OFPERR_OFPBAC_BAD_TYPE
;
7353 /* OpenFlow 1.1 instructions. */
7355 struct instruction_type_info
{
7356 enum ovs_instruction_type type
;
7360 static const struct instruction_type_info inst_info
[] = {
7361 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) {OVSINST_##ENUM, NAME},
7367 ovs_instruction_name_from_type(enum ovs_instruction_type type
)
7369 return type
< ARRAY_SIZE(inst_info
) ? inst_info
[type
].name
: NULL
;
7373 ovs_instruction_type_from_name(const char *name
)
7375 const struct instruction_type_info
*p
;
7376 for (p
= inst_info
; p
< &inst_info
[ARRAY_SIZE(inst_info
)]; p
++) {
7377 if (!strcasecmp(name
, p
->name
)) {
7384 enum ovs_instruction_type
7385 ovs_instruction_type_from_ofpact_type(enum ofpact_type type
)
7389 return OVSINST_OFPIT13_METER
;
7390 case OFPACT_CLEAR_ACTIONS
:
7391 return OVSINST_OFPIT11_CLEAR_ACTIONS
;
7392 case OFPACT_WRITE_ACTIONS
:
7393 return OVSINST_OFPIT11_WRITE_ACTIONS
;
7394 case OFPACT_WRITE_METADATA
:
7395 return OVSINST_OFPIT11_WRITE_METADATA
;
7396 case OFPACT_GOTO_TABLE
:
7397 return OVSINST_OFPIT11_GOTO_TABLE
;
7401 case OFPACT_CONTROLLER
:
7402 case OFPACT_ENQUEUE
:
7403 case OFPACT_OUTPUT_REG
:
7404 case OFPACT_OUTPUT_TRUNC
:
7406 case OFPACT_SET_VLAN_VID
:
7407 case OFPACT_SET_VLAN_PCP
:
7408 case OFPACT_STRIP_VLAN
:
7409 case OFPACT_PUSH_VLAN
:
7410 case OFPACT_SET_ETH_SRC
:
7411 case OFPACT_SET_ETH_DST
:
7412 case OFPACT_SET_IPV4_SRC
:
7413 case OFPACT_SET_IPV4_DST
:
7414 case OFPACT_SET_IP_DSCP
:
7415 case OFPACT_SET_IP_ECN
:
7416 case OFPACT_SET_IP_TTL
:
7417 case OFPACT_SET_L4_SRC_PORT
:
7418 case OFPACT_SET_L4_DST_PORT
:
7419 case OFPACT_REG_MOVE
:
7420 case OFPACT_SET_FIELD
:
7421 case OFPACT_STACK_PUSH
:
7422 case OFPACT_STACK_POP
:
7423 case OFPACT_DEC_TTL
:
7424 case OFPACT_SET_MPLS_LABEL
:
7425 case OFPACT_SET_MPLS_TC
:
7426 case OFPACT_SET_MPLS_TTL
:
7427 case OFPACT_DEC_MPLS_TTL
:
7428 case OFPACT_PUSH_MPLS
:
7429 case OFPACT_POP_MPLS
:
7430 case OFPACT_SET_TUNNEL
:
7431 case OFPACT_SET_QUEUE
:
7432 case OFPACT_POP_QUEUE
:
7433 case OFPACT_FIN_TIMEOUT
:
7434 case OFPACT_RESUBMIT
:
7436 case OFPACT_CONJUNCTION
:
7437 case OFPACT_MULTIPATH
:
7440 case OFPACT_UNROLL_XLATE
:
7442 case OFPACT_DEBUG_RECIRC
:
7444 case OFPACT_CT_CLEAR
:
7449 return OVSINST_OFPIT11_APPLY_ACTIONS
;
7454 ovs_instruction_type_from_inst_type(enum ovs_instruction_type
*instruction_type
,
7455 const uint16_t inst_type
)
7457 switch (inst_type
) {
7459 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
7461 *instruction_type = OVSINST_##ENUM; \
7467 return OFPERR_OFPBIC_UNKNOWN_INST
;
7471 /* Two-way translation between OVS's internal "OVSINST_*" representation of
7472 * instructions and the "OFPIT_*" representation used in OpenFlow. */
7473 struct ovsinst_map
{
7474 enum ovs_instruction_type ovsinst
; /* Internal name for instruction. */
7475 int ofpit
; /* OFPIT_* number from OpenFlow spec. */
7478 static const struct ovsinst_map
*
7479 get_ovsinst_map(enum ofp_version version
)
7481 /* OpenFlow 1.1 and 1.2 instructions. */
7482 static const struct ovsinst_map of11
[] = {
7483 { OVSINST_OFPIT11_GOTO_TABLE
, 1 },
7484 { OVSINST_OFPIT11_WRITE_METADATA
, 2 },
7485 { OVSINST_OFPIT11_WRITE_ACTIONS
, 3 },
7486 { OVSINST_OFPIT11_APPLY_ACTIONS
, 4 },
7487 { OVSINST_OFPIT11_CLEAR_ACTIONS
, 5 },
7491 /* OpenFlow 1.3+ instructions. */
7492 static const struct ovsinst_map of13
[] = {
7493 { OVSINST_OFPIT11_GOTO_TABLE
, 1 },
7494 { OVSINST_OFPIT11_WRITE_METADATA
, 2 },
7495 { OVSINST_OFPIT11_WRITE_ACTIONS
, 3 },
7496 { OVSINST_OFPIT11_APPLY_ACTIONS
, 4 },
7497 { OVSINST_OFPIT11_CLEAR_ACTIONS
, 5 },
7498 { OVSINST_OFPIT13_METER
, 6 },
7502 return version
< OFP13_VERSION
? of11
: of13
;
7505 /* Converts 'ovsinst_bitmap', a bitmap whose bits correspond to OVSINST_*
7506 * values, into a bitmap of instructions suitable for OpenFlow 'version'
7507 * (OFP11_VERSION or later), and returns the result. */
7509 ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap
, enum ofp_version version
)
7511 uint32_t ofpit_bitmap
= 0;
7512 const struct ovsinst_map
*x
;
7514 for (x
= get_ovsinst_map(version
); x
->ofpit
>= 0; x
++) {
7515 if (ovsinst_bitmap
& (1u << x
->ovsinst
)) {
7516 ofpit_bitmap
|= 1u << x
->ofpit
;
7519 return htonl(ofpit_bitmap
);
7522 /* Converts 'ofpit_bitmap', a bitmap of instructions from an OpenFlow message
7523 * with the given 'version' (OFP11_VERSION or later) into a bitmap whose bits
7524 * correspond to OVSINST_* values, and returns the result. */
7526 ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap
, enum ofp_version version
)
7528 uint32_t ovsinst_bitmap
= 0;
7529 const struct ovsinst_map
*x
;
7531 for (x
= get_ovsinst_map(version
); x
->ofpit
>= 0; x
++) {
7532 if (ofpit_bitmap
& htonl(1u << x
->ofpit
)) {
7533 ovsinst_bitmap
|= 1u << x
->ovsinst
;
7536 return ovsinst_bitmap
;
7539 static inline struct ofp11_instruction
*
7540 instruction_next(const struct ofp11_instruction
*inst
)
7542 return ((struct ofp11_instruction
*) (void *)
7543 ((uint8_t *) inst
+ ntohs(inst
->len
)));
7547 instruction_is_valid(const struct ofp11_instruction
*inst
,
7548 size_t n_instructions
)
7550 uint16_t len
= ntohs(inst
->len
);
7551 return (!(len
% OFP11_INSTRUCTION_ALIGN
)
7552 && len
>= sizeof *inst
7553 && len
/ sizeof *inst
<= n_instructions
);
7556 /* This macro is careful to check for instructions with bad lengths. */
7557 #define INSTRUCTION_FOR_EACH(ITER, LEFT, INSTRUCTIONS, N_INSTRUCTIONS) \
7558 for ((ITER) = (INSTRUCTIONS), (LEFT) = (N_INSTRUCTIONS); \
7559 (LEFT) > 0 && instruction_is_valid(ITER, LEFT); \
7560 ((LEFT) -= (ntohs((ITER)->len) \
7561 / sizeof(struct ofp11_instruction)), \
7562 (ITER) = instruction_next(ITER)))
7565 decode_openflow11_instruction(const struct ofp11_instruction
*inst
,
7566 enum ovs_instruction_type
*type
)
7568 uint16_t len
= ntohs(inst
->len
);
7570 switch (inst
->type
) {
7571 case CONSTANT_HTONS(OFPIT11_EXPERIMENTER
):
7572 return OFPERR_OFPBIC_BAD_EXPERIMENTER
;
7574 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
7575 case CONSTANT_HTONS(ENUM): \
7577 ? len >= sizeof(struct STRUCT) \
7578 : len == sizeof(struct STRUCT)) { \
7579 *type = OVSINST_##ENUM; \
7582 return OFPERR_OFPBIC_BAD_LEN; \
7588 return OFPERR_OFPBIC_UNKNOWN_INST
;
7593 decode_openflow11_instructions(const struct ofp11_instruction insts
[],
7595 const struct ofp11_instruction
*out
[])
7597 const struct ofp11_instruction
*inst
;
7600 memset(out
, 0, N_OVS_INSTRUCTIONS
* sizeof *out
);
7601 INSTRUCTION_FOR_EACH (inst
, left
, insts
, n_insts
) {
7602 enum ovs_instruction_type type
;
7605 error
= decode_openflow11_instruction(inst
, &type
);
7611 return OFPERR_OFPBIC_DUP_INST
;
7617 VLOG_WARN_RL(&rl
, "bad instruction format at offset %"PRIuSIZE
,
7618 (n_insts
- left
) * sizeof *inst
);
7619 return OFPERR_OFPBIC_BAD_LEN
;
7625 get_actions_from_instruction(const struct ofp11_instruction
*inst
,
7626 const struct ofp_action_header
**actions
,
7627 size_t *actions_len
)
7629 *actions
= ALIGNED_CAST(const struct ofp_action_header
*, inst
+ 1);
7630 *actions_len
= ntohs(inst
->len
) - sizeof *inst
;
7634 ofpacts_pull_openflow_instructions(struct ofpbuf
*openflow
,
7635 unsigned int instructions_len
,
7636 enum ofp_version version
,
7637 const struct vl_mff_map
*vl_mff_map
,
7638 uint64_t *ofpacts_tlv_bitmap
,
7639 struct ofpbuf
*ofpacts
)
7641 const struct ofp11_instruction
*instructions
;
7642 const struct ofp11_instruction
*insts
[N_OVS_INSTRUCTIONS
];
7645 ofpbuf_clear(ofpacts
);
7646 if (version
== OFP10_VERSION
) {
7647 return ofpacts_pull_openflow_actions__(openflow
, instructions_len
,
7649 (1u << N_OVS_INSTRUCTIONS
) - 1,
7650 ofpacts
, 0, vl_mff_map
,
7651 ofpacts_tlv_bitmap
);
7654 if (instructions_len
% OFP11_INSTRUCTION_ALIGN
!= 0) {
7655 VLOG_WARN_RL(&rl
, "OpenFlow message instructions length %u is not a "
7657 instructions_len
, OFP11_INSTRUCTION_ALIGN
);
7658 error
= OFPERR_OFPBIC_BAD_LEN
;
7662 instructions
= ofpbuf_try_pull(openflow
, instructions_len
);
7663 if (instructions
== NULL
) {
7664 VLOG_WARN_RL(&rl
, "OpenFlow message instructions length %u exceeds "
7665 "remaining message length (%"PRIu32
")",
7666 instructions_len
, openflow
->size
);
7667 error
= OFPERR_OFPBIC_BAD_LEN
;
7671 error
= decode_openflow11_instructions(
7672 instructions
, instructions_len
/ OFP11_INSTRUCTION_ALIGN
,
7678 if (insts
[OVSINST_OFPIT13_METER
]) {
7679 const struct ofp13_instruction_meter
*oim
;
7680 struct ofpact_meter
*om
;
7682 oim
= ALIGNED_CAST(const struct ofp13_instruction_meter
*,
7683 insts
[OVSINST_OFPIT13_METER
]);
7685 om
= ofpact_put_METER(ofpacts
);
7686 om
->meter_id
= ntohl(oim
->meter_id
);
7687 om
->provider_meter_id
= UINT32_MAX
; /* No provider meter ID. */
7689 if (insts
[OVSINST_OFPIT11_APPLY_ACTIONS
]) {
7690 const struct ofp_action_header
*actions
;
7693 get_actions_from_instruction(insts
[OVSINST_OFPIT11_APPLY_ACTIONS
],
7694 &actions
, &actions_len
);
7695 error
= ofpacts_decode(actions
, actions_len
, version
, vl_mff_map
,
7696 ofpacts_tlv_bitmap
, ofpacts
);
7701 if (insts
[OVSINST_OFPIT11_CLEAR_ACTIONS
]) {
7702 instruction_get_OFPIT11_CLEAR_ACTIONS(
7703 insts
[OVSINST_OFPIT11_CLEAR_ACTIONS
]);
7704 ofpact_put_CLEAR_ACTIONS(ofpacts
);
7706 if (insts
[OVSINST_OFPIT11_WRITE_ACTIONS
]) {
7707 struct ofpact_nest
*on
;
7708 const struct ofp_action_header
*actions
;
7710 size_t start
= ofpacts
->size
;
7711 ofpact_put(ofpacts
, OFPACT_WRITE_ACTIONS
,
7712 offsetof(struct ofpact_nest
, actions
));
7713 get_actions_from_instruction(insts
[OVSINST_OFPIT11_WRITE_ACTIONS
],
7714 &actions
, &actions_len
);
7715 error
= ofpacts_decode_for_action_set(actions
, actions_len
,
7716 version
, vl_mff_map
,
7717 ofpacts_tlv_bitmap
, ofpacts
);
7721 on
= ofpbuf_at_assert(ofpacts
, start
, sizeof *on
);
7722 on
->ofpact
.len
= ofpacts
->size
- start
;
7724 if (insts
[OVSINST_OFPIT11_WRITE_METADATA
]) {
7725 const struct ofp11_instruction_write_metadata
*oiwm
;
7726 struct ofpact_metadata
*om
;
7728 oiwm
= ALIGNED_CAST(const struct ofp11_instruction_write_metadata
*,
7729 insts
[OVSINST_OFPIT11_WRITE_METADATA
]);
7731 om
= ofpact_put_WRITE_METADATA(ofpacts
);
7732 om
->metadata
= oiwm
->metadata
;
7733 om
->mask
= oiwm
->metadata_mask
;
7735 if (insts
[OVSINST_OFPIT11_GOTO_TABLE
]) {
7736 const struct ofp11_instruction_goto_table
*oigt
;
7737 struct ofpact_goto_table
*ogt
;
7739 oigt
= instruction_get_OFPIT11_GOTO_TABLE(
7740 insts
[OVSINST_OFPIT11_GOTO_TABLE
]);
7741 ogt
= ofpact_put_GOTO_TABLE(ofpacts
);
7742 ogt
->table_id
= oigt
->table_id
;
7745 error
= ofpacts_verify(ofpacts
->data
, ofpacts
->size
,
7746 (1u << N_OVS_INSTRUCTIONS
) - 1, 0);
7749 ofpbuf_clear(ofpacts
);
7754 /* Update the length of the instruction that begins at offset 'ofs' within
7755 * 'openflow' and contains nested actions that extend to the end of 'openflow'.
7756 * If the instruction contains no nested actions, deletes it entirely. */
7758 ofpacts_update_instruction_actions(struct ofpbuf
*openflow
, size_t ofs
)
7760 struct ofp11_instruction_actions
*oia
;
7762 oia
= ofpbuf_at_assert(openflow
, ofs
, sizeof *oia
);
7763 if (openflow
->size
> ofs
+ sizeof *oia
) {
7764 oia
->len
= htons(openflow
->size
- ofs
);
7766 openflow
->size
= ofs
;
7770 /* Checks that 'port' is a valid output port for OFPACT_OUTPUT, given that the
7771 * switch will never have more than 'max_ports' ports. Returns 0 if 'port' is
7772 * valid, otherwise an OpenFlow error code. */
7774 ofpact_check_output_port(ofp_port_t port
, ofp_port_t max_ports
)
7782 case OFPP_CONTROLLER
:
7787 return OFPERR_OFPBAC_BAD_OUT_PORT
;
7790 if (ofp_to_u16(port
) < ofp_to_u16(max_ports
)) {
7793 return OFPERR_OFPBAC_BAD_OUT_PORT
;
7797 /* Removes the protocols that require consistency between match and actions
7798 * (that's everything but OpenFlow 1.0) from '*usable_protocols'.
7800 * (An example of an inconsistency between match and actions is a flow that
7801 * does not match on an MPLS Ethertype but has an action that pops an MPLS
7804 inconsistent_match(enum ofputil_protocol
*usable_protocols
)
7806 *usable_protocols
&= OFPUTIL_P_OF10_ANY
;
7809 /* May modify flow->packet_type, flow->dl_type, flow->nw_proto and
7810 * flow->vlan_tci, caller must restore them.
7812 * Modifies some actions, filling in fields that could not be properly set
7813 * without context. */
7815 ofpact_check__(enum ofputil_protocol
*usable_protocols
, struct ofpact
*a
,
7816 struct match
*match
, ofp_port_t max_ports
,
7817 uint8_t table_id
, uint8_t n_tables
)
7819 struct flow
*flow
= &match
->flow
;
7820 const struct ofpact_enqueue
*enqueue
;
7821 const struct mf_field
*mf
;
7822 ovs_be16 dl_type
= get_dl_type(flow
);
7826 return ofpact_check_output_port(ofpact_get_OUTPUT(a
)->port
,
7829 case OFPACT_CONTROLLER
:
7832 case OFPACT_ENQUEUE
:
7833 enqueue
= ofpact_get_ENQUEUE(a
);
7834 if (ofp_to_u16(enqueue
->port
) >= ofp_to_u16(max_ports
)
7835 && enqueue
->port
!= OFPP_IN_PORT
7836 && enqueue
->port
!= OFPP_LOCAL
) {
7837 return OFPERR_OFPBAC_BAD_OUT_PORT
;
7841 case OFPACT_OUTPUT_REG
:
7842 return mf_check_src(&ofpact_get_OUTPUT_REG(a
)->src
, match
);
7844 case OFPACT_OUTPUT_TRUNC
:
7845 return ofpact_check_output_port(ofpact_get_OUTPUT_TRUNC(a
)->port
,
7849 return bundle_check(ofpact_get_BUNDLE(a
), max_ports
, match
);
7851 case OFPACT_SET_VLAN_VID
:
7852 /* Remember if we saw a vlan tag in the flow to aid translating to
7853 * OpenFlow 1.1+ if need be. */
7854 ofpact_get_SET_VLAN_VID(a
)->flow_has_vlan
=
7855 (flow
->vlans
[0].tci
& htons(VLAN_CFI
)) == htons(VLAN_CFI
);
7856 if (!(flow
->vlans
[0].tci
& htons(VLAN_CFI
)) &&
7857 !ofpact_get_SET_VLAN_VID(a
)->push_vlan_if_needed
) {
7858 inconsistent_match(usable_protocols
);
7860 /* Temporary mark that we have a vlan tag. */
7861 flow
->vlans
[0].tci
|= htons(VLAN_CFI
);
7864 case OFPACT_SET_VLAN_PCP
:
7865 /* Remember if we saw a vlan tag in the flow to aid translating to
7866 * OpenFlow 1.1+ if need be. */
7867 ofpact_get_SET_VLAN_PCP(a
)->flow_has_vlan
=
7868 (flow
->vlans
[0].tci
& htons(VLAN_CFI
)) == htons(VLAN_CFI
);
7869 if (!(flow
->vlans
[0].tci
& htons(VLAN_CFI
)) &&
7870 !ofpact_get_SET_VLAN_PCP(a
)->push_vlan_if_needed
) {
7871 inconsistent_match(usable_protocols
);
7873 /* Temporary mark that we have a vlan tag. */
7874 flow
->vlans
[0].tci
|= htons(VLAN_CFI
);
7877 case OFPACT_STRIP_VLAN
:
7878 if (!(flow
->vlans
[0].tci
& htons(VLAN_CFI
))) {
7879 inconsistent_match(usable_protocols
);
7881 flow_pop_vlan(flow
, NULL
);
7884 case OFPACT_PUSH_VLAN
:
7885 if (flow
->vlans
[FLOW_MAX_VLAN_HEADERS
- 1].tci
& htons(VLAN_CFI
)) {
7886 /* Support maximum (FLOW_MAX_VLAN_HEADERS) VLAN headers. */
7887 return OFPERR_OFPBAC_BAD_TAG
;
7889 /* Temporary mark that we have a vlan tag. */
7890 flow_push_vlan_uninit(flow
, NULL
);
7891 flow
->vlans
[0].tci
|= htons(VLAN_CFI
);
7894 case OFPACT_SET_ETH_SRC
:
7895 case OFPACT_SET_ETH_DST
:
7898 case OFPACT_SET_IPV4_SRC
:
7899 case OFPACT_SET_IPV4_DST
:
7900 if (dl_type
!= htons(ETH_TYPE_IP
)) {
7901 inconsistent_match(usable_protocols
);
7905 case OFPACT_SET_IP_DSCP
:
7906 case OFPACT_SET_IP_ECN
:
7907 case OFPACT_SET_IP_TTL
:
7908 case OFPACT_DEC_TTL
:
7909 if (!is_ip_any(flow
)) {
7910 inconsistent_match(usable_protocols
);
7914 case OFPACT_SET_L4_SRC_PORT
:
7915 case OFPACT_SET_L4_DST_PORT
:
7916 if (!is_ip_any(flow
) || (flow
->nw_frag
& FLOW_NW_FRAG_LATER
) ||
7917 (flow
->nw_proto
!= IPPROTO_TCP
&& flow
->nw_proto
!= IPPROTO_UDP
7918 && flow
->nw_proto
!= IPPROTO_SCTP
)) {
7919 inconsistent_match(usable_protocols
);
7921 /* Note on which transport protocol the port numbers are set.
7922 * This allows this set action to be converted to an OF1.2 set field
7924 if (a
->type
== OFPACT_SET_L4_SRC_PORT
) {
7925 ofpact_get_SET_L4_SRC_PORT(a
)->flow_ip_proto
= flow
->nw_proto
;
7927 ofpact_get_SET_L4_DST_PORT(a
)->flow_ip_proto
= flow
->nw_proto
;
7931 case OFPACT_REG_MOVE
:
7932 return nxm_reg_move_check(ofpact_get_REG_MOVE(a
), match
);
7934 case OFPACT_SET_FIELD
:
7935 mf
= ofpact_get_SET_FIELD(a
)->field
;
7936 /* Require OXM_OF_VLAN_VID to have an existing VLAN header. */
7937 if (!mf_are_prereqs_ok(mf
, flow
, NULL
) ||
7938 (mf
->id
== MFF_VLAN_VID
&&
7939 !(flow
->vlans
[0].tci
& htons(VLAN_CFI
)))) {
7940 VLOG_WARN_RL(&rl
, "set_field %s lacks correct prerequisites",
7942 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
7944 /* Remember if we saw a vlan tag in the flow to aid translating to
7945 * OpenFlow 1.1 if need be. */
7946 ofpact_get_SET_FIELD(a
)->flow_has_vlan
=
7947 (flow
->vlans
[0].tci
& htons(VLAN_CFI
)) == htons(VLAN_CFI
);
7948 if (mf
->id
== MFF_VLAN_TCI
) {
7949 /* The set field may add or remove the vlan tag,
7950 * Mark the status temporarily. */
7951 flow
->vlans
[0].tci
= ofpact_get_SET_FIELD(a
)->value
->be16
;
7955 case OFPACT_STACK_PUSH
:
7956 return nxm_stack_push_check(ofpact_get_STACK_PUSH(a
), match
);
7958 case OFPACT_STACK_POP
:
7959 return nxm_stack_pop_check(ofpact_get_STACK_POP(a
), match
);
7961 case OFPACT_SET_MPLS_LABEL
:
7962 case OFPACT_SET_MPLS_TC
:
7963 case OFPACT_SET_MPLS_TTL
:
7964 case OFPACT_DEC_MPLS_TTL
:
7965 if (!eth_type_mpls(dl_type
)) {
7966 inconsistent_match(usable_protocols
);
7970 case OFPACT_SET_TUNNEL
:
7971 case OFPACT_SET_QUEUE
:
7972 case OFPACT_POP_QUEUE
:
7975 case OFPACT_RESUBMIT
: {
7976 struct ofpact_resubmit
*resubmit
= ofpact_get_RESUBMIT(a
);
7978 if (resubmit
->with_ct_orig
&& !is_ct_valid(flow
, &match
->wc
, NULL
)) {
7979 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
7983 case OFPACT_FIN_TIMEOUT
:
7984 if (flow
->nw_proto
!= IPPROTO_TCP
) {
7985 inconsistent_match(usable_protocols
);
7990 return learn_check(ofpact_get_LEARN(a
), match
);
7992 case OFPACT_CONJUNCTION
:
7995 case OFPACT_MULTIPATH
:
7996 return multipath_check(ofpact_get_MULTIPATH(a
), match
);
8002 case OFPACT_PUSH_MPLS
:
8003 if (flow
->packet_type
!= htonl(PT_ETH
)) {
8004 inconsistent_match(usable_protocols
);
8006 flow
->dl_type
= ofpact_get_PUSH_MPLS(a
)->ethertype
;
8007 /* The packet is now MPLS and the MPLS payload is opaque.
8008 * Thus nothing can be assumed about the network protocol.
8009 * Temporarily mark that we have no nw_proto. */
8013 case OFPACT_POP_MPLS
:
8014 if (flow
->packet_type
!= htonl(PT_ETH
)
8015 || !eth_type_mpls(dl_type
)) {
8016 inconsistent_match(usable_protocols
);
8018 flow
->dl_type
= ofpact_get_POP_MPLS(a
)->ethertype
;
8024 case OFPACT_CLONE
: {
8025 struct ofpact_nest
*on
= ofpact_get_CLONE(a
);
8026 return ofpacts_check(on
->actions
, ofpact_nest_get_action_len(on
),
8027 match
, max_ports
, table_id
, n_tables
,
8032 struct ofpact_conntrack
*oc
= ofpact_get_CT(a
);
8034 if (!dl_type_is_ip_any(dl_type
)
8035 || (flow
->ct_state
& CS_INVALID
&& oc
->flags
& NX_CT_F_COMMIT
)
8036 || (oc
->alg
== IPPORT_FTP
&& flow
->nw_proto
!= IPPROTO_TCP
)
8037 || (oc
->alg
== IPPORT_TFTP
&& flow
->nw_proto
!= IPPROTO_UDP
)) {
8038 /* We can't downgrade to OF1.0 and expect inconsistent CT actions
8039 * be silently discarded. Instead, datapath flow install fails, so
8040 * it is better to flag inconsistent CT actions as hard errors. */
8041 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
8044 if (oc
->zone_src
.field
) {
8045 return mf_check_src(&oc
->zone_src
, match
);
8048 return ofpacts_check(oc
->actions
, ofpact_ct_get_action_len(oc
),
8049 match
, max_ports
, table_id
, n_tables
,
8053 case OFPACT_CT_CLEAR
:
8057 struct ofpact_nat
*on
= ofpact_get_NAT(a
);
8059 if (!dl_type_is_ip_any(dl_type
) ||
8060 (on
->range_af
== AF_INET
&& dl_type
!= htons(ETH_TYPE_IP
)) ||
8061 (on
->range_af
== AF_INET6
8062 && dl_type
!= htons(ETH_TYPE_IPV6
))) {
8063 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
8068 case OFPACT_CLEAR_ACTIONS
:
8071 case OFPACT_WRITE_ACTIONS
: {
8072 /* Use a temporary copy of 'usable_protocols' because we can't check
8073 * consistency of an action set. */
8074 struct ofpact_nest
*on
= ofpact_get_WRITE_ACTIONS(a
);
8075 enum ofputil_protocol p
= *usable_protocols
;
8076 return ofpacts_check(on
->actions
, ofpact_nest_get_action_len(on
),
8077 match
, max_ports
, table_id
, n_tables
, &p
);
8080 case OFPACT_WRITE_METADATA
:
8083 case OFPACT_METER
: {
8084 uint32_t mid
= ofpact_get_METER(a
)->meter_id
;
8085 if (mid
== 0 || mid
> OFPM13_MAX
) {
8086 return OFPERR_OFPMMFC_INVALID_METER
;
8091 case OFPACT_GOTO_TABLE
: {
8092 uint8_t goto_table
= ofpact_get_GOTO_TABLE(a
)->table_id
;
8093 if ((table_id
!= 255 && goto_table
<= table_id
)
8094 || (n_tables
!= 255 && goto_table
>= n_tables
)) {
8095 return OFPERR_OFPBIC_BAD_TABLE_ID
;
8103 case OFPACT_UNROLL_XLATE
:
8104 /* UNROLL is an internal action that should never be seen via
8106 return OFPERR_OFPBAC_BAD_TYPE
;
8108 case OFPACT_DEBUG_RECIRC
:
8112 flow
->packet_type
= ofpact_get_ENCAP(a
)->new_pkt_type
;
8113 if (pt_ns(flow
->packet_type
) == OFPHTN_ETHERTYPE
) {
8114 flow
->dl_type
= htons(pt_ns_type(flow
->packet_type
));
8116 if (!is_ip_any(flow
)) {
8122 if (flow
->packet_type
== htonl(PT_ETH
)) {
8123 /* Adjust the packet_type to allow subsequent actions. */
8124 flow
->packet_type
= PACKET_TYPE_BE(OFPHTN_ETHERTYPE
,
8125 ntohs(flow
->dl_type
));
8127 /* The actual packet_type is only known after decapsulation.
8128 * Do not allow subsequent actions that depend on packet headers. */
8129 flow
->packet_type
= htonl(PT_UNKNOWN
);
8130 flow
->dl_type
= OVS_BE16_MAX
;
8139 /* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are
8140 * appropriate for a packet with the prerequisites satisfied by 'flow' in a
8141 * switch with no more than 'max_ports' ports.
8143 * If 'ofpacts' and 'flow' are inconsistent with one another, un-sets in
8144 * '*usable_protocols' the protocols that forbid the inconsistency. (An
8145 * example of an inconsistency between match and actions is a flow that does
8146 * not match on an MPLS Ethertype but has an action that pops an MPLS label.)
8148 * May annotate ofpacts with information gathered from the 'match'.
8150 * May temporarily modify 'match', but restores the changes before
8153 ofpacts_check(struct ofpact ofpacts
[], size_t ofpacts_len
,
8154 struct match
*match
, ofp_port_t max_ports
,
8155 uint8_t table_id
, uint8_t n_tables
,
8156 enum ofputil_protocol
*usable_protocols
)
8159 ovs_be32 packet_type
= match
->flow
.packet_type
;
8160 ovs_be16 dl_type
= match
->flow
.dl_type
;
8161 uint8_t nw_proto
= match
->flow
.nw_proto
;
8162 enum ofperr error
= 0;
8163 union flow_vlan_hdr vlans
[FLOW_MAX_VLAN_HEADERS
];
8165 memcpy(&vlans
, &match
->flow
.vlans
, sizeof(vlans
));
8167 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8168 error
= ofpact_check__(usable_protocols
, a
, match
,
8169 max_ports
, table_id
, n_tables
);
8174 /* Restore fields that may have been modified. */
8175 match
->flow
.packet_type
= packet_type
;
8176 match
->flow
.dl_type
= dl_type
;
8177 memcpy(&match
->flow
.vlans
, &vlans
, sizeof(vlans
));
8178 match
->flow
.nw_proto
= nw_proto
;
8182 /* Like ofpacts_check(), but reports inconsistencies as
8183 * OFPERR_OFPBAC_MATCH_INCONSISTENT rather than clearing bits. */
8185 ofpacts_check_consistency(struct ofpact ofpacts
[], size_t ofpacts_len
,
8186 struct match
*match
, ofp_port_t max_ports
,
8187 uint8_t table_id
, uint8_t n_tables
,
8188 enum ofputil_protocol usable_protocols
)
8190 enum ofputil_protocol p
= usable_protocols
;
8193 error
= ofpacts_check(ofpacts
, ofpacts_len
, match
, max_ports
,
8194 table_id
, n_tables
, &p
);
8195 return (error
? error
8196 : p
!= usable_protocols
? OFPERR_OFPBAC_MATCH_INCONSISTENT
8200 /* Returns the destination field that 'ofpact' would write to, or NULL
8201 * if the action would not write to an mf_field. */
8202 const struct mf_field
*
8203 ofpact_get_mf_dst(const struct ofpact
*ofpact
)
8205 if (ofpact
->type
== OFPACT_SET_FIELD
) {
8206 const struct ofpact_set_field
*orl
;
8208 orl
= CONTAINER_OF(ofpact
, struct ofpact_set_field
, ofpact
);
8210 } else if (ofpact
->type
== OFPACT_REG_MOVE
) {
8211 const struct ofpact_reg_move
*orm
;
8213 orm
= CONTAINER_OF(ofpact
, struct ofpact_reg_move
, ofpact
);
8214 return orm
->dst
.field
;
8221 unsupported_nesting(enum ofpact_type action
, enum ofpact_type outer_action
)
8223 VLOG_WARN("%s action doesn't support nested action %s",
8224 ofpact_name(outer_action
), ofpact_name(action
));
8225 return OFPERR_OFPBAC_BAD_ARGUMENT
;
8229 field_requires_ct(enum mf_field_id field
)
8231 return field
== MFF_CT_MARK
|| field
== MFF_CT_LABEL
;
8234 /* Apply nesting constraints for actions */
8236 ofpacts_verify_nested(const struct ofpact
*a
, enum ofpact_type outer_action
)
8238 const struct mf_field
*field
= ofpact_get_mf_dst(a
);
8240 if (field
&& field_requires_ct(field
->id
) && outer_action
!= OFPACT_CT
) {
8241 VLOG_WARN("cannot set CT fields outside of ct action");
8242 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
8244 if (a
->type
== OFPACT_NAT
) {
8245 if (outer_action
!= OFPACT_CT
) {
8246 VLOG_WARN("Cannot have NAT action outside of \"ct\" action");
8247 return OFPERR_OFPBAC_BAD_SET_ARGUMENT
;
8253 ovs_assert(outer_action
== OFPACT_WRITE_ACTIONS
8254 || outer_action
== OFPACT_CT
);
8256 if (outer_action
== OFPACT_CT
) {
8258 return unsupported_nesting(a
->type
, outer_action
);
8259 } else if (!field_requires_ct(field
->id
)) {
8260 VLOG_WARN("%s action doesn't support nested modification "
8261 "of %s", ofpact_name(outer_action
), field
->name
);
8262 return OFPERR_OFPBAC_BAD_ARGUMENT
;
8270 /* Verifies that the 'ofpacts_len' bytes of actions in 'ofpacts' are in the
8271 * appropriate order as defined by the OpenFlow spec and as required by Open
8274 * 'allowed_ovsinsts' is a bitmap of OVSINST_* values, in which 1-bits indicate
8275 * instructions that are allowed within 'ofpacts[]'.
8277 * If 'outer_action' is not zero, it specifies that the actions are nested
8278 * within another action of type 'outer_action'. */
8280 ofpacts_verify(const struct ofpact ofpacts
[], size_t ofpacts_len
,
8281 uint32_t allowed_ovsinsts
, enum ofpact_type outer_action
)
8283 const struct ofpact
*a
;
8284 enum ovs_instruction_type inst
;
8286 inst
= OVSINST_OFPIT13_METER
;
8287 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8288 enum ovs_instruction_type next
;
8291 if (a
->type
== OFPACT_CONJUNCTION
) {
8292 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8293 if (a
->type
!= OFPACT_CONJUNCTION
&& a
->type
!= OFPACT_NOTE
) {
8294 VLOG_WARN("\"conjunction\" actions may be used along with "
8295 "\"note\" but not any other kind of action "
8296 "(such as the \"%s\" action used here)",
8297 ofpact_name(a
->type
));
8298 return OFPERR_NXBAC_BAD_CONJUNCTION
;
8304 error
= ofpacts_verify_nested(a
, outer_action
);
8309 next
= ovs_instruction_type_from_ofpact_type(a
->type
);
8311 && (inst
== OVSINST_OFPIT11_APPLY_ACTIONS
8314 const char *name
= ovs_instruction_name_from_type(inst
);
8315 const char *next_name
= ovs_instruction_name_from_type(next
);
8318 VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
8319 "1.1+ compatibility", name
);
8321 VLOG_WARN("invalid instruction ordering: %s must appear "
8322 "before %s, for OpenFlow 1.1+ compatibility",
8325 return OFPERR_OFPBAC_UNSUPPORTED_ORDER
;
8327 if (!((1u << next
) & allowed_ovsinsts
)) {
8328 const char *name
= ovs_instruction_name_from_type(next
);
8330 VLOG_WARN("%s instruction not allowed here", name
);
8331 return OFPERR_OFPBIC_UNSUP_INST
;
8340 /* Converting ofpacts to OpenFlow. */
8343 encode_ofpact(const struct ofpact
*a
, enum ofp_version ofp_version
,
8347 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8348 case OFPACT_##ENUM: \
8349 encode_##ENUM(ofpact_get_##ENUM(a), ofp_version, out); \
8358 /* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow
8359 * actions in 'openflow', appending the actions to any existing data in
8362 ofpacts_put_openflow_actions(const struct ofpact ofpacts
[], size_t ofpacts_len
,
8363 struct ofpbuf
*openflow
,
8364 enum ofp_version ofp_version
)
8366 const struct ofpact
*a
;
8367 size_t start_size
= openflow
->size
;
8369 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8370 encode_ofpact(a
, ofp_version
, openflow
);
8372 return openflow
->size
- start_size
;
8375 static enum ovs_instruction_type
8376 ofpact_is_apply_actions(const struct ofpact
*a
)
8378 return (ovs_instruction_type_from_ofpact_type(a
->type
)
8379 == OVSINST_OFPIT11_APPLY_ACTIONS
);
8383 ofpacts_put_openflow_instructions(const struct ofpact ofpacts
[],
8385 struct ofpbuf
*openflow
,
8386 enum ofp_version ofp_version
)
8388 const struct ofpact
*end
= ofpact_end(ofpacts
, ofpacts_len
);
8389 const struct ofpact
*a
;
8391 if (ofp_version
== OFP10_VERSION
) {
8392 ofpacts_put_openflow_actions(ofpacts
, ofpacts_len
, openflow
,
8399 if (ofpact_is_apply_actions(a
)) {
8400 size_t ofs
= openflow
->size
;
8402 instruction_put_OFPIT11_APPLY_ACTIONS(openflow
);
8404 encode_ofpact(a
, ofp_version
, openflow
);
8406 } while (a
< end
&& ofpact_is_apply_actions(a
));
8407 ofpacts_update_instruction_actions(openflow
, ofs
);
8409 encode_ofpact(a
, ofp_version
, openflow
);
8415 /* Sets of supported actions. */
8417 /* Two-way translation between OVS's internal "OFPACT_*" representation of
8418 * actions and the "OFPAT_*" representation used in some OpenFlow version.
8419 * (OFPAT_* numbering varies from one OpenFlow version to another, so a given
8420 * instance is specific to one OpenFlow version.) */
8422 enum ofpact_type ofpact
; /* Internal name for action type. */
8423 int ofpat
; /* OFPAT_* number from OpenFlow spec. */
8426 static const struct ofpact_map
*
8427 get_ofpact_map(enum ofp_version version
)
8429 /* OpenFlow 1.0 actions. */
8430 static const struct ofpact_map of10
[] = {
8431 { OFPACT_OUTPUT
, 0 },
8432 { OFPACT_SET_VLAN_VID
, 1 },
8433 { OFPACT_SET_VLAN_PCP
, 2 },
8434 { OFPACT_STRIP_VLAN
, 3 },
8435 { OFPACT_SET_ETH_SRC
, 4 },
8436 { OFPACT_SET_ETH_DST
, 5 },
8437 { OFPACT_SET_IPV4_SRC
, 6 },
8438 { OFPACT_SET_IPV4_DST
, 7 },
8439 { OFPACT_SET_IP_DSCP
, 8 },
8440 { OFPACT_SET_L4_SRC_PORT
, 9 },
8441 { OFPACT_SET_L4_DST_PORT
, 10 },
8442 { OFPACT_ENQUEUE
, 11 },
8446 /* OpenFlow 1.1 actions. */
8447 static const struct ofpact_map of11
[] = {
8448 { OFPACT_OUTPUT
, 0 },
8449 { OFPACT_SET_VLAN_VID
, 1 },
8450 { OFPACT_SET_VLAN_PCP
, 2 },
8451 { OFPACT_SET_ETH_SRC
, 3 },
8452 { OFPACT_SET_ETH_DST
, 4 },
8453 { OFPACT_SET_IPV4_SRC
, 5 },
8454 { OFPACT_SET_IPV4_DST
, 6 },
8455 { OFPACT_SET_IP_DSCP
, 7 },
8456 { OFPACT_SET_IP_ECN
, 8 },
8457 { OFPACT_SET_L4_SRC_PORT
, 9 },
8458 { OFPACT_SET_L4_DST_PORT
, 10 },
8459 /* OFPAT_COPY_TTL_OUT (11) not supported. */
8460 /* OFPAT_COPY_TTL_IN (12) not supported. */
8461 { OFPACT_SET_MPLS_LABEL
, 13 },
8462 { OFPACT_SET_MPLS_TC
, 14 },
8463 { OFPACT_SET_MPLS_TTL
, 15 },
8464 { OFPACT_DEC_MPLS_TTL
, 16 },
8465 { OFPACT_PUSH_VLAN
, 17 },
8466 { OFPACT_STRIP_VLAN
, 18 },
8467 { OFPACT_PUSH_MPLS
, 19 },
8468 { OFPACT_POP_MPLS
, 20 },
8469 { OFPACT_SET_QUEUE
, 21 },
8470 { OFPACT_GROUP
, 22 },
8471 { OFPACT_SET_IP_TTL
, 23 },
8472 { OFPACT_DEC_TTL
, 24 },
8476 /* OpenFlow 1.2, 1.3, and 1.4 actions. */
8477 static const struct ofpact_map of12
[] = {
8478 { OFPACT_OUTPUT
, 0 },
8479 /* OFPAT_COPY_TTL_OUT (11) not supported. */
8480 /* OFPAT_COPY_TTL_IN (12) not supported. */
8481 { OFPACT_SET_MPLS_TTL
, 15 },
8482 { OFPACT_DEC_MPLS_TTL
, 16 },
8483 { OFPACT_PUSH_VLAN
, 17 },
8484 { OFPACT_STRIP_VLAN
, 18 },
8485 { OFPACT_PUSH_MPLS
, 19 },
8486 { OFPACT_POP_MPLS
, 20 },
8487 { OFPACT_SET_QUEUE
, 21 },
8488 { OFPACT_GROUP
, 22 },
8489 { OFPACT_SET_IP_TTL
, 23 },
8490 { OFPACT_DEC_TTL
, 24 },
8491 { OFPACT_SET_FIELD
, 25 },
8492 /* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
8493 /* OF1.3+ OFPAT_POP_PBB (27) not supported. */
8514 /* Converts 'ofpacts_bitmap', a bitmap whose bits correspond to OFPACT_*
8515 * values, into a bitmap of actions suitable for OpenFlow 'version', and
8516 * returns the result. */
8518 ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap
, enum ofp_version version
)
8520 uint32_t openflow_bitmap
= 0;
8521 const struct ofpact_map
*x
;
8523 for (x
= get_ofpact_map(version
); x
->ofpat
>= 0; x
++) {
8524 if (ofpacts_bitmap
& (UINT64_C(1) << x
->ofpact
)) {
8525 openflow_bitmap
|= 1u << x
->ofpat
;
8528 return htonl(openflow_bitmap
);
8531 /* Converts 'ofpat_bitmap', a bitmap of actions from an OpenFlow message with
8532 * the given 'version' into a bitmap whose bits correspond to OFPACT_* values,
8533 * and returns the result. */
8535 ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap
, enum ofp_version version
)
8537 uint64_t ofpact_bitmap
= 0;
8538 const struct ofpact_map
*x
;
8540 for (x
= get_ofpact_map(version
); x
->ofpat
>= 0; x
++) {
8541 if (ofpat_bitmap
& htonl(1u << x
->ofpat
)) {
8542 ofpact_bitmap
|= UINT64_C(1) << x
->ofpact
;
8545 return ofpact_bitmap
;
8548 /* Appends to 's' a string representation of the set of OFPACT_* represented
8549 * by 'ofpacts_bitmap'. */
8551 ofpact_bitmap_format(uint64_t ofpacts_bitmap
, struct ds
*s
)
8553 if (!ofpacts_bitmap
) {
8554 ds_put_cstr(s
, "<none>");
8556 while (ofpacts_bitmap
) {
8557 ds_put_format(s
, "%s ",
8558 ofpact_name(rightmost_1bit_idx(ofpacts_bitmap
)));
8559 ofpacts_bitmap
= zero_rightmost_1bit(ofpacts_bitmap
);
8565 /* Returns true if 'action' outputs to 'port', false otherwise. */
8567 ofpact_outputs_to_port(const struct ofpact
*ofpact
, ofp_port_t port
)
8569 switch (ofpact
->type
) {
8571 return ofpact_get_OUTPUT(ofpact
)->port
== port
;
8572 case OFPACT_ENQUEUE
:
8573 return ofpact_get_ENQUEUE(ofpact
)->port
== port
;
8574 case OFPACT_CONTROLLER
:
8575 return port
== OFPP_CONTROLLER
;
8577 case OFPACT_OUTPUT_REG
:
8578 case OFPACT_OUTPUT_TRUNC
:
8580 case OFPACT_SET_VLAN_VID
:
8581 case OFPACT_SET_VLAN_PCP
:
8582 case OFPACT_STRIP_VLAN
:
8583 case OFPACT_PUSH_VLAN
:
8584 case OFPACT_SET_ETH_SRC
:
8585 case OFPACT_SET_ETH_DST
:
8586 case OFPACT_SET_IPV4_SRC
:
8587 case OFPACT_SET_IPV4_DST
:
8588 case OFPACT_SET_IP_DSCP
:
8589 case OFPACT_SET_IP_ECN
:
8590 case OFPACT_SET_IP_TTL
:
8591 case OFPACT_SET_L4_SRC_PORT
:
8592 case OFPACT_SET_L4_DST_PORT
:
8593 case OFPACT_REG_MOVE
:
8594 case OFPACT_SET_FIELD
:
8595 case OFPACT_STACK_PUSH
:
8596 case OFPACT_STACK_POP
:
8597 case OFPACT_DEC_TTL
:
8598 case OFPACT_SET_MPLS_LABEL
:
8599 case OFPACT_SET_MPLS_TC
:
8600 case OFPACT_SET_MPLS_TTL
:
8601 case OFPACT_DEC_MPLS_TTL
:
8602 case OFPACT_SET_TUNNEL
:
8603 case OFPACT_WRITE_METADATA
:
8604 case OFPACT_SET_QUEUE
:
8605 case OFPACT_POP_QUEUE
:
8606 case OFPACT_FIN_TIMEOUT
:
8607 case OFPACT_RESUBMIT
:
8609 case OFPACT_CONJUNCTION
:
8610 case OFPACT_MULTIPATH
:
8613 case OFPACT_UNROLL_XLATE
:
8614 case OFPACT_PUSH_MPLS
:
8615 case OFPACT_POP_MPLS
:
8617 case OFPACT_CLEAR_ACTIONS
:
8619 case OFPACT_WRITE_ACTIONS
:
8620 case OFPACT_GOTO_TABLE
:
8623 case OFPACT_DEBUG_RECIRC
:
8625 case OFPACT_CT_CLEAR
:
8634 /* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
8635 * to 'port', false otherwise. */
8637 ofpacts_output_to_port(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
8640 const struct ofpact
*a
;
8642 OFPACT_FOR_EACH_FLATTENED (a
, ofpacts
, ofpacts_len
) {
8643 if (ofpact_outputs_to_port(a
, port
)) {
8651 /* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
8652 * to 'group', false otherwise. */
8654 ofpacts_output_to_group(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
8657 const struct ofpact
*a
;
8659 OFPACT_FOR_EACH_FLATTENED (a
, ofpacts
, ofpacts_len
) {
8660 if (a
->type
== OFPACT_GROUP
8661 && ofpact_get_GROUP(a
)->group_id
== group_id
) {
8669 /* Returns true if the 'a_len' bytes of actions in 'a' and the 'b_len' bytes of
8670 * actions in 'b' are bytewise identical. */
8672 ofpacts_equal(const struct ofpact
*a
, size_t a_len
,
8673 const struct ofpact
*b
, size_t b_len
)
8675 return a_len
== b_len
&& !memcmp(a
, b
, a_len
);
8678 /* Returns true if the 'a_len' bytes of actions in 'a' and the 'b_len' bytes of
8679 * actions in 'b' are identical when formatted as strings. (Converting actions
8680 * to string form suppresses some rarely meaningful differences, such as the
8681 * 'compat' member of actions.) */
8683 ofpacts_equal_stringwise(const struct ofpact
*a
, size_t a_len
,
8684 const struct ofpact
*b
, size_t b_len
)
8686 struct ds a_s
= DS_EMPTY_INITIALIZER
;
8687 struct ds b_s
= DS_EMPTY_INITIALIZER
;
8689 ofpacts_format(a
, a_len
, NULL
, &a_s
);
8690 ofpacts_format(b
, b_len
, NULL
, &b_s
);
8692 bool equal
= !strcmp(ds_cstr(&a_s
), ds_cstr(&b_s
));
8700 /* Finds the OFPACT_METER action, if any, in the 'ofpacts_len' bytes of
8701 * 'ofpacts'. If found, returns its meter ID; if not, returns 0.
8703 * This function relies on the order of 'ofpacts' being correct (as checked by
8704 * ofpacts_verify()). */
8706 ofpacts_get_meter(const struct ofpact ofpacts
[], size_t ofpacts_len
)
8708 const struct ofpact
*a
;
8710 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8711 enum ovs_instruction_type inst
;
8713 inst
= ovs_instruction_type_from_ofpact_type(a
->type
);
8714 if (a
->type
== OFPACT_METER
) {
8715 return ofpact_get_METER(a
)->meter_id
;
8716 } else if (inst
> OVSINST_OFPIT13_METER
) {
8724 /* Formatting ofpacts. */
8727 ofpact_format(const struct ofpact
*a
,
8728 const struct ofputil_port_map
*port_map
, struct ds
*s
)
8731 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8732 case OFPACT_##ENUM: \
8733 format_##ENUM(ALIGNED_CAST(const struct STRUCT *, a), \
8743 /* Appends a string representing the 'ofpacts_len' bytes of ofpacts in
8744 * 'ofpacts' to 'string'. If 'port_map' is nonnull, uses it to translate
8745 * port numbers to names in output. */
8747 ofpacts_format(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
8748 const struct ofputil_port_map
*port_map
, struct ds
*string
)
8751 ds_put_format(string
, "%sdrop%s", colors
.drop
, colors
.end
);
8753 const struct ofpact
*a
;
8755 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
8757 ds_put_char(string
, ',');
8760 ofpact_format(a
, port_map
, string
);
8765 /* Internal use by helpers. */
8767 /* Implementation of ofpact_put_<ENUM>(). */
8769 ofpact_put(struct ofpbuf
*ofpacts
, enum ofpact_type type
, size_t len
)
8771 struct ofpact
*ofpact
;
8773 ofpacts
->header
= ofpbuf_put_uninit(ofpacts
, len
);
8774 ofpact
= ofpacts
->header
;
8775 ofpact_init(ofpact
, type
, len
);
8779 /* Implementation of ofpact_init_<ENUM>(). */
8781 ofpact_init(struct ofpact
*ofpact
, enum ofpact_type type
, size_t len
)
8783 memset(ofpact
, 0, len
);
8784 ofpact
->type
= type
;
8789 /* Implementation of ofpact_finish_<ENUM>().
8791 * Finishes composing a variable-length action (begun using
8792 * ofpact_put_<NAME>()), by padding the action to a multiple of OFPACT_ALIGNTO
8793 * bytes and updating its embedded length field. See the large comment near
8794 * the end of ofp-actions.h for more information.
8796 * May reallocate 'ofpacts'. Callers should consider updating their 'ofpact'
8797 * pointer to the return value of this function. */
8799 ofpact_finish(struct ofpbuf
*ofpacts
, struct ofpact
*ofpact
)
8803 ovs_assert(ofpact
== ofpacts
->header
);
8804 len
= (char *) ofpbuf_tail(ofpacts
) - (char *) ofpact
;
8805 ovs_assert(len
> 0 && len
<= UINT16_MAX
);
8807 ofpbuf_padto(ofpacts
, OFPACT_ALIGN(ofpacts
->size
));
8809 return ofpacts
->header
;
8812 static char * OVS_WARN_UNUSED_RESULT
8813 ofpact_parse(enum ofpact_type type
, char *value
,
8814 const struct ofputil_port_map
*port_map
, struct ofpbuf
*ofpacts
,
8815 enum ofputil_protocol
*usable_protocols
)
8818 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8819 case OFPACT_##ENUM: \
8820 return parse_##ENUM(value, port_map, ofpacts, usable_protocols);
8829 ofpact_type_from_name(const char *name
, enum ofpact_type
*type
)
8831 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8832 if (!strcasecmp(name, NAME)) { \
8833 *type = OFPACT_##ENUM; \
8842 /* Parses 'str' as a series of instructions, and appends them to 'ofpacts'.
8844 * Returns NULL if successful, otherwise a malloc()'d string describing the
8845 * error. The caller is responsible for freeing the returned string.
8847 * If 'outer_action' is specified, indicates that the actions being parsed
8848 * are nested within another action of the type specified in 'outer_action'. */
8849 static char * OVS_WARN_UNUSED_RESULT
8850 ofpacts_parse__(char *str
, const struct ofputil_port_map
*port_map
,
8851 struct ofpbuf
*ofpacts
,
8852 enum ofputil_protocol
*usable_protocols
,
8853 bool allow_instructions
, enum ofpact_type outer_action
)
8862 while (ofputil_parse_key_value(&pos
, &key
, &value
)) {
8863 enum ovs_instruction_type inst
= OVSINST_OFPIT11_APPLY_ACTIONS
;
8864 enum ofpact_type type
;
8868 if (ofpact_type_from_name(key
, &type
)) {
8869 error
= ofpact_parse(type
, value
, port_map
,
8870 ofpacts
, usable_protocols
);
8871 inst
= ovs_instruction_type_from_ofpact_type(type
);
8872 } else if (!strcasecmp(key
, "mod_vlan_vid")) {
8873 error
= parse_set_vlan_vid(value
, ofpacts
, true);
8874 } else if (!strcasecmp(key
, "mod_vlan_pcp")) {
8875 error
= parse_set_vlan_pcp(value
, ofpacts
, true);
8876 } else if (!strcasecmp(key
, "set_nw_ttl")) {
8877 error
= parse_SET_IP_TTL(value
, port_map
,
8878 ofpacts
, usable_protocols
);
8879 } else if (!strcasecmp(key
, "pop_vlan")) {
8880 error
= parse_pop_vlan(ofpacts
);
8881 } else if (!strcasecmp(key
, "set_tunnel64")) {
8882 error
= parse_set_tunnel(value
, ofpacts
,
8883 NXAST_RAW_SET_TUNNEL64
);
8884 } else if (!strcasecmp(key
, "load")) {
8885 error
= parse_reg_load(value
, ofpacts
);
8886 } else if (!strcasecmp(key
, "bundle_load")) {
8887 error
= parse_bundle_load(value
, port_map
, ofpacts
);
8888 } else if (!strcasecmp(key
, "drop")) {
8890 } else if (!strcasecmp(key
, "apply_actions")) {
8891 return xstrdup("apply_actions is the default instruction");
8892 } else if (ofputil_port_from_string(key
, port_map
, &port
)) {
8893 ofpact_put_OUTPUT(ofpacts
)->port
= port
;
8895 return xasprintf("unknown action %s", key
);
8901 if (inst
!= OVSINST_OFPIT11_APPLY_ACTIONS
) {
8902 if (!allow_instructions
) {
8903 return xasprintf("only actions are allowed here (not "
8905 ovs_instruction_name_from_type(inst
));
8907 if (inst
== prev_inst
) {
8908 return xasprintf("instruction %s may be specified only once",
8909 ovs_instruction_name_from_type(inst
));
8912 if (prev_inst
!= -1 && inst
< prev_inst
) {
8913 return xasprintf("instruction %s must be specified before %s",
8914 ovs_instruction_name_from_type(inst
),
8915 ovs_instruction_name_from_type(prev_inst
));
8920 if (drop
&& ofpacts
->size
) {
8921 return xstrdup("\"drop\" must not be accompanied by any other action "
8925 retval
= ofpacts_verify(ofpacts
->data
, ofpacts
->size
,
8927 ? (1u << N_OVS_INSTRUCTIONS
) - 1
8928 : 1u << OVSINST_OFPIT11_APPLY_ACTIONS
),
8931 return xstrdup("Incorrect instruction ordering");
8937 static char * OVS_WARN_UNUSED_RESULT
8938 ofpacts_parse(char *str
, const struct ofputil_port_map
*port_map
,
8939 struct ofpbuf
*ofpacts
, enum ofputil_protocol
*usable_protocols
,
8940 bool allow_instructions
, enum ofpact_type outer_action
)
8942 uint32_t orig_size
= ofpacts
->size
;
8943 char *error
= ofpacts_parse__(str
, port_map
, ofpacts
, usable_protocols
,
8944 allow_instructions
, outer_action
);
8946 ofpacts
->size
= orig_size
;
8951 static char * OVS_WARN_UNUSED_RESULT
8952 ofpacts_parse_copy(const char *s_
, const struct ofputil_port_map
*port_map
,
8953 struct ofpbuf
*ofpacts
,
8954 enum ofputil_protocol
*usable_protocols
,
8955 bool allow_instructions
, enum ofpact_type outer_action
)
8959 *usable_protocols
= OFPUTIL_P_ANY
;
8962 error
= ofpacts_parse(s
, port_map
, ofpacts
, usable_protocols
,
8963 allow_instructions
, outer_action
);
8969 /* Parses 's' as a set of OpenFlow actions and appends the actions to
8970 * 'ofpacts'. 'outer_action', if nonzero, specifies that 's' contains actions
8971 * that are nested within the action of type 'outer_action'.
8973 * Returns NULL if successful, otherwise a malloc()'d string describing the
8974 * error. The caller is responsible for freeing the returned string. */
8975 char * OVS_WARN_UNUSED_RESULT
8976 ofpacts_parse_actions(const char *s
, const struct ofputil_port_map
*port_map
,
8977 struct ofpbuf
*ofpacts
,
8978 enum ofputil_protocol
*usable_protocols
)
8980 return ofpacts_parse_copy(s
, port_map
, ofpacts
, usable_protocols
,
8984 /* Parses 's' as a set of OpenFlow instructions and appends the instructions to
8987 * Returns NULL if successful, otherwise a malloc()'d string describing the
8988 * error. The caller is responsible for freeing the returned string. */
8989 char * OVS_WARN_UNUSED_RESULT
8990 ofpacts_parse_instructions(const char *s
,
8991 const struct ofputil_port_map
*port_map
,
8992 struct ofpbuf
*ofpacts
,
8993 enum ofputil_protocol
*usable_protocols
)
8995 return ofpacts_parse_copy(s
, port_map
, ofpacts
, usable_protocols
, true, 0);
8999 ofpact_name(enum ofpact_type type
)
9002 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) case OFPACT_##ENUM: return NAME;
9009 /* Low-level action decoding and encoding functions. */
9011 /* Everything needed to identify a particular OpenFlow action. */
9012 struct ofpact_hdrs
{
9013 uint32_t vendor
; /* 0 if standard, otherwise a vendor code. */
9014 uint16_t type
; /* Type if standard, otherwise subtype. */
9015 uint8_t ofp_version
; /* From ofp_header. */
9018 /* Information about a particular OpenFlow action. */
9019 struct ofpact_raw_instance
{
9020 /* The action's identity. */
9021 struct ofpact_hdrs hdrs
;
9022 enum ofp_raw_action_type raw
;
9024 /* Looking up the action. */
9025 struct hmap_node decode_node
; /* Based on 'hdrs'. */
9026 struct hmap_node encode_node
; /* Based on 'raw' + 'hdrs.ofp_version'. */
9028 /* The action's encoded size.
9030 * If this action is fixed-length, 'min_length' == 'max_length'.
9031 * If it is variable length, then 'max_length' is ROUND_DOWN(UINT16_MAX,
9032 * OFP_ACTION_ALIGN) == 65528. */
9033 unsigned short int min_length
;
9034 unsigned short int max_length
;
9036 /* For actions with a simple integer numeric argument, 'arg_ofs' is the
9037 * offset of that argument from the beginning of the action and 'arg_len'
9038 * its length, both in bytes.
9040 * For actions that take other forms, these are both zero. */
9041 unsigned short int arg_ofs
;
9042 unsigned short int arg_len
;
9044 /* The name of the action, e.g. "OFPAT_OUTPUT" or "NXAST_RESUBMIT". */
9047 /* If this action is deprecated, a human-readable string with a brief
9049 const char *deprecation
;
9052 /* Action header. */
9053 struct ofp_action_header
{
9054 /* The meaning of other values of 'type' generally depends on the OpenFlow
9055 * version (see enum ofp_raw_action_type).
9057 * Across all OpenFlow versions, OFPAT_VENDOR indicates that 'vendor'
9058 * designates an OpenFlow vendor ID and that the remainder of the action
9059 * structure has a vendor-defined meaning.
9061 #define OFPAT_VENDOR 0xffff
9064 /* Always a multiple of 8. */
9067 /* For type == OFPAT_VENDOR only, this is a vendor ID, e.g. NX_VENDOR_ID or
9068 * ONF_VENDOR_ID. Other 'type's use this space for some other purpose. */
9071 OFP_ASSERT(sizeof(struct ofp_action_header
) == 8);
9074 ofpact_hdrs_equal(const struct ofpact_hdrs
*a
,
9075 const struct ofpact_hdrs
*b
)
9077 return (a
->vendor
== b
->vendor
9078 && a
->type
== b
->type
9079 && a
->ofp_version
== b
->ofp_version
);
9083 ofpact_hdrs_hash(const struct ofpact_hdrs
*hdrs
)
9085 return hash_2words(hdrs
->vendor
, (hdrs
->type
<< 16) | hdrs
->ofp_version
);
9088 #include "ofp-actions.inc2"
9090 static struct hmap
*
9091 ofpact_decode_hmap(void)
9093 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
9094 static struct hmap hmap
;
9096 if (ovsthread_once_start(&once
)) {
9097 struct ofpact_raw_instance
*inst
;
9100 for (inst
= all_raw_instances
;
9101 inst
< &all_raw_instances
[ARRAY_SIZE(all_raw_instances
)];
9103 hmap_insert(&hmap
, &inst
->decode_node
,
9104 ofpact_hdrs_hash(&inst
->hdrs
));
9106 ovsthread_once_done(&once
);
9111 static struct hmap
*
9112 ofpact_encode_hmap(void)
9114 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
9115 static struct hmap hmap
;
9117 if (ovsthread_once_start(&once
)) {
9118 struct ofpact_raw_instance
*inst
;
9121 for (inst
= all_raw_instances
;
9122 inst
< &all_raw_instances
[ARRAY_SIZE(all_raw_instances
)];
9124 hmap_insert(&hmap
, &inst
->encode_node
,
9125 hash_2words(inst
->raw
, inst
->hdrs
.ofp_version
));
9127 ovsthread_once_done(&once
);
9133 ofpact_decode_raw(enum ofp_version ofp_version
,
9134 const struct ofp_action_header
*oah
, size_t length
,
9135 const struct ofpact_raw_instance
**instp
)
9137 const struct ofpact_raw_instance
*inst
;
9138 struct ofpact_hdrs hdrs
;
9141 if (length
< sizeof *oah
) {
9142 return OFPERR_OFPBAC_BAD_LEN
;
9145 /* Get base action type. */
9146 if (oah
->type
== htons(OFPAT_VENDOR
)) {
9148 hdrs
.vendor
= ntohl(oah
->vendor
);
9149 if (hdrs
.vendor
== NX_VENDOR_ID
|| hdrs
.vendor
== ONF_VENDOR_ID
) {
9150 /* Get extension subtype. */
9151 const struct ext_action_header
*nah
;
9153 nah
= ALIGNED_CAST(const struct ext_action_header
*, oah
);
9154 if (length
< sizeof *nah
) {
9155 return OFPERR_OFPBAC_BAD_LEN
;
9157 hdrs
.type
= ntohs(nah
->subtype
);
9159 VLOG_WARN_RL(&rl
, "OpenFlow action has unknown vendor %#"PRIx32
,
9161 return OFPERR_OFPBAC_BAD_VENDOR
;
9165 hdrs
.type
= ntohs(oah
->type
);
9168 hdrs
.ofp_version
= ofp_version
;
9169 HMAP_FOR_EACH_WITH_HASH (inst
, decode_node
, ofpact_hdrs_hash(&hdrs
),
9170 ofpact_decode_hmap()) {
9171 if (ofpact_hdrs_equal(&hdrs
, &inst
->hdrs
)) {
9178 ? OFPERR_OFPBAC_BAD_VENDOR_TYPE
9179 : OFPERR_OFPBAC_BAD_TYPE
);
9183 ofpact_pull_raw(struct ofpbuf
*buf
, enum ofp_version ofp_version
,
9184 enum ofp_raw_action_type
*raw
, uint64_t *arg
)
9186 const struct ofp_action_header
*oah
= buf
->data
;
9187 const struct ofpact_raw_instance
*action
;
9188 unsigned int length
;
9192 error
= ofpact_decode_raw(ofp_version
, oah
, buf
->size
, &action
);
9197 if (action
->deprecation
) {
9198 VLOG_INFO_RL(&rl
, "%s is deprecated in %s (%s)",
9199 action
->name
, ofputil_version_to_string(ofp_version
),
9200 action
->deprecation
);
9203 length
= ntohs(oah
->len
);
9204 if (length
> buf
->size
) {
9205 VLOG_WARN_RL(&rl
, "OpenFlow action %s length %u exceeds action buffer "
9206 "length %"PRIu32
, action
->name
, length
, buf
->size
);
9207 return OFPERR_OFPBAC_BAD_LEN
;
9209 if (length
< action
->min_length
|| length
> action
->max_length
) {
9210 VLOG_WARN_RL(&rl
, "OpenFlow action %s length %u not in valid range "
9211 "[%hu,%hu]", action
->name
, length
,
9212 action
->min_length
, action
->max_length
);
9213 return OFPERR_OFPBAC_BAD_LEN
;
9216 VLOG_WARN_RL(&rl
, "OpenFlow action %s length %u is not a multiple "
9217 "of 8", action
->name
, length
);
9218 return OFPERR_OFPBAC_BAD_LEN
;
9223 if (action
->arg_len
) {
9227 p
= ofpbuf_at_assert(buf
, action
->arg_ofs
, action
->arg_len
);
9228 for (i
= 0; i
< action
->arg_len
; i
++) {
9229 *arg
= (*arg
<< 8) | p
[i
];
9233 ofpbuf_pull(buf
, length
);
9238 static const struct ofpact_raw_instance
*
9239 ofpact_raw_lookup(enum ofp_version ofp_version
, enum ofp_raw_action_type raw
)
9241 const struct ofpact_raw_instance
*inst
;
9243 HMAP_FOR_EACH_WITH_HASH (inst
, encode_node
, hash_2words(raw
, ofp_version
),
9244 ofpact_encode_hmap()) {
9245 if (inst
->raw
== raw
&& inst
->hdrs
.ofp_version
== ofp_version
) {
9253 ofpact_put_raw(struct ofpbuf
*buf
, enum ofp_version ofp_version
,
9254 enum ofp_raw_action_type raw
, uint64_t arg
)
9256 const struct ofpact_raw_instance
*inst
;
9257 struct ofp_action_header
*oah
;
9258 const struct ofpact_hdrs
*hdrs
;
9260 inst
= ofpact_raw_lookup(ofp_version
, raw
);
9263 oah
= ofpbuf_put_zeros(buf
, inst
->min_length
);
9264 oah
->type
= htons(hdrs
->vendor
? OFPAT_VENDOR
: hdrs
->type
);
9265 oah
->len
= htons(inst
->min_length
);
9266 oah
->vendor
= htonl(hdrs
->vendor
);
9268 switch (hdrs
->vendor
) {
9273 case ONF_VENDOR_ID
: {
9274 struct ext_action_header
*nah
= (struct ext_action_header
*) oah
;
9275 nah
->subtype
= htons(hdrs
->type
);
9283 if (inst
->arg_len
) {
9284 uint8_t *p
= (uint8_t *) oah
+ inst
->arg_ofs
+ inst
->arg_len
;
9287 for (i
= 0; i
< inst
->arg_len
; i
++) {
9299 pad_ofpat(struct ofpbuf
*openflow
, size_t start_ofs
)
9301 struct ofp_action_header
*oah
;
9303 ofpbuf_put_zeros(openflow
, PAD_SIZE(openflow
->size
- start_ofs
,
9306 oah
= ofpbuf_at_assert(openflow
, start_ofs
, sizeof *oah
);
9307 oah
->len
= htons(openflow
->size
- start_ofs
);