2 * Copyright (c) 2012, 2013, 2014, 2015, 2016, 2017, 2019 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.
17 #ifndef OPENVSWITCH_OFP_ACTIONS_H
18 #define OPENVSWITCH_OFP_ACTIONS_H 1
22 #include "openflow/openflow.h"
23 #include "openflow/nicira-ext.h"
24 #include "openvswitch/meta-flow.h"
25 #include "openvswitch/ofp-errors.h"
26 #include "openvswitch/ofp-protocol.h"
27 #include "openvswitch/types.h"
28 #include "openvswitch/ofp-ed-props.h"
36 /* List of OVS abstracted actions.
38 * This macro is used directly only internally by this header, but the list is
39 * still of interest to developers.
41 * Each OFPACT invocation has the following parameters:
43 * 1. <ENUM>, used below in the enum definition of OFPACT_<ENUM>, and
46 * 2. <STRUCT> corresponding to a structure "struct <STRUCT>", that must be
47 * defined below. This structure must be an abstract definition of the
48 * action. Its first member must have type "struct ofpact" and name
49 * "ofpact". It may be fixed length or end with a flexible array member
50 * (e.g. "int member[];").
52 * 3. <MEMBER>, which has one of two possible values:
54 * - If "struct <STRUCT>" is fixed-length, it must be "ofpact".
56 * - If "struct <STRUCT>" is variable-length, it must be the name of the
57 * flexible array member.
59 * 4. <NAME>, a quoted string that gives the name of the action, for use in
60 * parsing actions from text.
64 OFPACT(OUTPUT, ofpact_output, ofpact, "output") \
65 OFPACT(GROUP, ofpact_group, ofpact, "group") \
66 OFPACT(CONTROLLER, ofpact_controller, userdata, "controller") \
67 OFPACT(ENQUEUE, ofpact_enqueue, ofpact, "enqueue") \
68 OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact, "output_reg") \
69 OFPACT(BUNDLE, ofpact_bundle, slaves, "bundle") \
71 /* Header changes. */ \
72 OFPACT(SET_FIELD, ofpact_set_field, ofpact, "set_field") \
73 OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact, "set_vlan_vid") \
74 OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact, "set_vlan_pcp") \
75 OFPACT(STRIP_VLAN, ofpact_null, ofpact, "strip_vlan") \
76 OFPACT(PUSH_VLAN, ofpact_push_vlan, ofpact, "push_vlan") \
77 OFPACT(SET_ETH_SRC, ofpact_mac, ofpact, "mod_dl_src") \
78 OFPACT(SET_ETH_DST, ofpact_mac, ofpact, "mod_dl_dst") \
79 OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact, "mod_nw_src") \
80 OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact, "mod_nw_dst") \
81 OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact, "mod_nw_tos") \
82 OFPACT(SET_IP_ECN, ofpact_ecn, ofpact, "mod_nw_ecn") \
83 OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact, "mod_nw_ttl") \
84 OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact, "mod_tp_src") \
85 OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact, "mod_tp_dst") \
86 OFPACT(REG_MOVE, ofpact_reg_move, ofpact, "move") \
87 OFPACT(STACK_PUSH, ofpact_stack, ofpact, "push") \
88 OFPACT(STACK_POP, ofpact_stack, ofpact, "pop") \
89 OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids, "dec_ttl") \
90 OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact, "set_mpls_label") \
91 OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact, "set_mpls_tc") \
92 OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact, "set_mpls_ttl") \
93 OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \
94 OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \
95 OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \
96 OFPACT(DEC_NSH_TTL, ofpact_null, ofpact, "dec_nsh_ttl") \
98 /* Generic encap & decap */ \
99 OFPACT(ENCAP, ofpact_encap, props, "encap") \
100 OFPACT(DECAP, ofpact_decap, ofpact, "decap") \
103 OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact, "set_tunnel") \
104 OFPACT(SET_QUEUE, ofpact_queue, ofpact, "set_queue") \
105 OFPACT(POP_QUEUE, ofpact_null, ofpact, "pop_queue") \
106 OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact, "fin_timeout") \
108 /* Flow table interaction. */ \
109 OFPACT(RESUBMIT, ofpact_resubmit, ofpact, "resubmit") \
110 OFPACT(LEARN, ofpact_learn, specs, "learn") \
111 OFPACT(CONJUNCTION, ofpact_conjunction, ofpact, "conjunction") \
114 OFPACT(MULTIPATH, ofpact_multipath, ofpact, "multipath") \
117 OFPACT(NOTE, ofpact_note, data, "note") \
118 OFPACT(EXIT, ofpact_null, ofpact, "exit") \
119 OFPACT(SAMPLE, ofpact_sample, ofpact, "sample") \
120 OFPACT(UNROLL_XLATE, ofpact_unroll_xlate, ofpact, "unroll_xlate") \
121 OFPACT(CT, ofpact_conntrack, ofpact, "ct") \
122 OFPACT(CT_CLEAR, ofpact_null, ofpact, "ct_clear") \
123 OFPACT(NAT, ofpact_nat, ofpact, "nat") \
124 OFPACT(OUTPUT_TRUNC, ofpact_output_trunc,ofpact, "output_trunc") \
125 OFPACT(CLONE, ofpact_nest, actions, "clone") \
126 OFPACT(CHECK_PKT_LARGER, ofpact_check_pkt_larger, ofpact, \
127 "check_pkt_larger") \
129 /* Debugging actions. \
131 * These are intentionally undocumented, subject to change, and \
132 * only accepted if ovs-vswitchd is started with --enable-dummy. */ \
133 OFPACT(DEBUG_RECIRC, ofpact_null, ofpact, "debug_recirc") \
134 OFPACT(DEBUG_SLOW, ofpact_null, ofpact, "debug_slow") \
136 /* Instructions ("meter" is an action in OF1.5+). */ \
137 OFPACT(METER, ofpact_meter, ofpact, "meter") \
138 OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact, "clear_actions") \
139 OFPACT(WRITE_ACTIONS, ofpact_nest, actions, "write_actions") \
140 OFPACT(WRITE_METADATA, ofpact_metadata, ofpact, "write_metadata") \
141 OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact, "goto_table")
143 /* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
144 enum OVS_PACKED_ENUM ofpact_type
{
145 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) OFPACT_##ENUM,
150 /* Define N_OFPACTS to the number of types of ofpacts. */
152 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) + 1
157 /* Header for an action.
159 * Each action is a structure "struct ofpact_*" that begins with "struct
160 * ofpact", usually followed by other data that describes the action. Actions
161 * are padded out to a multiple of OFPACT_ALIGNTO bytes in length.
163 * The 'raw' member is special:
165 * - Most "struct ofpact"s correspond to one particular kind of OpenFlow
166 * action, at least in a given OpenFlow version. For example,
167 * OFPACT_SET_VLAN_VID corresponds to OFPAT10_SET_VLAN_VID in OpenFlow
170 * For such actions, the 'raw' member is not meaningful and generally
173 * - A few "struct ofpact"s correspond to multiple OpenFlow actions. For
174 * example, OFPACT_SET_TUNNEL can be NXAST_SET_TUNNEL or
175 * NXAST_SET_TUNNEL64. In these cases, if the "struct ofpact" originated
176 * from OpenFlow, then we want to make sure that, if it gets translated
177 * back to OpenFlow later, it is translated back to the same action type.
178 * (Otherwise, we'd violate the promise made in the topics/design doc, in
179 * the "Action Reproduction" section.)
181 * For such actions, the 'raw' member should be the "enum ofp_raw_action"
182 * originally extracted from the OpenFlow action. (If the action didn't
183 * originate from OpenFlow, then setting 'raw' to zero should be fine:
184 * code to translate the ofpact to OpenFlow must tolerate this case.)
187 /* We want the space advantage of an 8-bit type here on every
188 * implementation, without giving up the advantage of having a useful type
189 * on implementations that support packed enums. */
190 #ifdef HAVE_PACKED_ENUM
191 enum ofpact_type type
; /* OFPACT_*. */
193 uint8_t type
; /* OFPACT_* */
196 uint8_t raw
; /* Original type when added, if any. */
197 uint16_t len
; /* Length of the action, in bytes, including
198 * struct ofpact, excluding padding. */
200 BUILD_ASSERT_DECL(sizeof(struct ofpact
) == 4);
203 #define OFPACT_ALIGNTO 8
204 #define OFPACT_ALIGN(SIZE) ROUND_UP(SIZE, OFPACT_ALIGNTO)
205 #define OFPACT_PADDED_MEMBERS(MEMBERS) PADDED_MEMBERS(OFPACT_ALIGNTO, MEMBERS)
207 /* Returns the ofpact following 'ofpact'. */
208 static inline struct ofpact
*
209 ofpact_next(const struct ofpact
*ofpact
)
211 return ALIGNED_CAST(struct ofpact
*,
212 (uint8_t *) ofpact
+ OFPACT_ALIGN(ofpact
->len
));
215 struct ofpact
*ofpact_next_flattened(const struct ofpact
*);
217 static inline struct ofpact
*
218 ofpact_end(const struct ofpact
*ofpacts
, size_t ofpacts_len
)
220 return ALIGNED_CAST(struct ofpact
*, (uint8_t *) ofpacts
+ ofpacts_len
);
224 ofpact_last(const struct ofpact
*a
, const struct ofpact
*ofpacts
,
227 return ofpact_next(a
) == ofpact_end(ofpacts
, ofpact_len
);
231 ofpact_remaining_len(const struct ofpact
*a
, const struct ofpact
*ofpacts
,
234 return ofpact_len
- ((uint8_t *)a
- (uint8_t *)ofpacts
);
237 static inline const struct ofpact
*
238 ofpact_find_type_flattened(const struct ofpact
*a
, enum ofpact_type type
,
239 const struct ofpact
* const end
)
242 if (a
->type
== type
) {
245 a
= ofpact_next_flattened(a
);
250 #define OFPACT_FIND_TYPE_FLATTENED(A, TYPE, END) \
251 ofpact_get_##TYPE##_nullable( \
252 ofpact_find_type_flattened(A, OFPACT_##TYPE, END))
254 /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts
255 * starting at OFPACTS. */
256 #define OFPACT_FOR_EACH(POS, OFPACTS, OFPACTS_LEN) \
257 for ((POS) = (OFPACTS); (POS) < ofpact_end(OFPACTS, OFPACTS_LEN); \
258 (POS) = ofpact_next(POS))
260 /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts
261 * starting at OFPACTS.
263 * For ofpacts that contain nested ofpacts, this visits each of the inner
264 * ofpacts as well. */
265 #define OFPACT_FOR_EACH_FLATTENED(POS, OFPACTS, OFPACTS_LEN) \
266 for ((POS) = (OFPACTS); (POS) < ofpact_end(OFPACTS, OFPACTS_LEN); \
267 (POS) = ofpact_next_flattened(POS))
269 #define OFPACT_FOR_EACH_TYPE_FLATTENED(POS, TYPE, OFPACTS, OFPACTS_LEN) \
270 for ((POS) = OFPACT_FIND_TYPE_FLATTENED(OFPACTS, TYPE, \
271 ofpact_end(OFPACTS, OFPACTS_LEN)); \
273 (POS) = OFPACT_FIND_TYPE_FLATTENED( \
274 ofpact_next_flattened(&(POS)->ofpact), TYPE, \
275 ofpact_end(OFPACTS, OFPACTS_LEN)))
277 /* Action structure for each OFPACT_*. */
279 /* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS.
281 * Used for OFPAT10_STRIP_VLAN, NXAST_POP_QUEUE, NXAST_EXIT,
282 * OFPAT11_POP_VLAN, OFPIT11_CLEAR_ACTIONS.
284 * Action structure for actions that do not have any extra data beyond the
287 OFPACT_PADDED_MEMBERS(
288 struct ofpact ofpact
;
294 * Used for OFPAT10_OUTPUT. */
295 struct ofpact_output
{
296 OFPACT_PADDED_MEMBERS(
297 struct ofpact ofpact
;
298 ofp_port_t port
; /* Output port. */
299 uint16_t max_len
; /* Max send len, for port OFPP_CONTROLLER. */
303 #define NX_CTLR_NO_METER 0
305 /* OFPACT_CONTROLLER.
307 * Used for NXAST_CONTROLLER. */
308 struct ofpact_controller
{
309 OFPACT_PADDED_MEMBERS(
310 struct ofpact ofpact
;
311 uint16_t max_len
; /* Max length to send to controller. */
312 uint16_t controller_id
; /* Controller ID to send packet-in. */
313 enum ofp_packet_in_reason reason
; /* Reason to put in packet-in. */
315 /* If true, this action freezes packet traversal of the OpenFlow
316 * tables and adds a continuation to the packet-in message, that
317 * a controller can use to resume that traversal. */
320 /* Arbitrary data to include in the packet-in message (currently,
321 * only in NXT_PACKET_IN2). */
322 uint16_t userdata_len
;
324 /* Meter to which this controller action should be associated.
325 * If requested, this will override a "controller" virtual meter.
326 * A value of NX_CTLR_NO_METER means no meter is requested. */
328 uint32_t provider_meter_id
;
335 * Used for OFPAT10_ENQUEUE. */
336 struct ofpact_enqueue
{
337 OFPACT_PADDED_MEMBERS(
338 struct ofpact ofpact
;
344 /* OFPACT_OUTPUT_REG.
346 * Used for NXAST_OUTPUT_REG. */
347 struct ofpact_output_reg
{
348 OFPACT_PADDED_MEMBERS(
349 struct ofpact ofpact
;
351 struct mf_subfield src
;
355 /* OFPACT_OUTPUT_TRUNC.
357 * Used for NXAST_OUTPUT_TRUNC. */
358 struct ofpact_output_trunc
{
359 OFPACT_PADDED_MEMBERS(
360 struct ofpact ofpact
;
361 ofp_port_t port
; /* Output port. */
362 uint32_t max_len
; /* Max send len. */
366 /* Bundle slave choice algorithm to apply.
368 * In the descriptions below, 'slaves' is the list of possible slaves in the
369 * order they appear in the OpenFlow action. */
370 enum nx_bd_algorithm
{
371 /* Chooses the first live slave listed in the bundle.
373 * O(n_slaves) performance. */
374 NX_BD_ALG_ACTIVE_BACKUP
= 0,
376 /* Highest Random Weight.
378 * for i in [0,n_slaves):
379 * weights[i] = hash(flow, i)
380 * slave = { slaves[i] such that weights[i] >= weights[j] for all j != i }
382 * Redistributes 1/n_slaves of traffic when a slave's liveness changes.
383 * O(n_slaves) performance.
385 * Uses the 'fields' and 'basis' parameters. */
391 * Used for NXAST_BUNDLE. */
392 struct ofpact_bundle
{
393 OFPACT_PADDED_MEMBERS(
394 struct ofpact ofpact
;
396 /* Slave choice algorithm to apply to hash value. */
397 enum nx_bd_algorithm algorithm
;
399 /* What fields to hash and how. */
400 enum nx_hash_fields fields
;
401 uint16_t basis
; /* Universal hash parameter. */
403 struct mf_subfield dst
;
405 /* Slaves for output. */
406 unsigned int n_slaves
;
411 /* OFPACT_SET_VLAN_VID.
413 * We keep track if vlan was present at action validation time to avoid a
414 * PUSH_VLAN when translating to OpenFlow 1.1+.
416 * We also keep the originating OFPUTIL action code in ofpact.compat.
418 * Used for OFPAT10_SET_VLAN_VID and OFPAT11_SET_VLAN_VID. */
419 struct ofpact_vlan_vid
{
420 OFPACT_PADDED_MEMBERS(
421 struct ofpact ofpact
;
422 uint16_t vlan_vid
; /* VLAN VID in low 12 bits, other bits 0. */
423 bool push_vlan_if_needed
; /* OF 1.0 semantics if true. */
424 bool flow_has_vlan
; /* VLAN present at action validation time? */
428 /* OFPACT_SET_VLAN_PCP.
430 * We keep track if vlan was present at action validation time to avoid a
431 * PUSH_VLAN when translating to OpenFlow 1.1+.
433 * We also keep the originating OFPUTIL action code in ofpact.compat.
435 * Used for OFPAT10_SET_VLAN_PCP and OFPAT11_SET_VLAN_PCP. */
436 struct ofpact_vlan_pcp
{
437 OFPACT_PADDED_MEMBERS(
438 struct ofpact ofpact
;
439 uint8_t vlan_pcp
; /* VLAN PCP in low 3 bits, other bits 0. */
440 bool push_vlan_if_needed
; /* OF 1.0 semantics if true. */
441 bool flow_has_vlan
; /* VLAN present at action validation? */
447 * Used for OFPAT11_PUSH_VLAN. */
448 struct ofpact_push_vlan
{
449 OFPACT_PADDED_MEMBERS(
450 struct ofpact ofpact
;
455 /* OFPACT_SET_ETH_SRC, OFPACT_SET_ETH_DST.
457 * Used for OFPAT10_SET_DL_SRC, OFPAT10_SET_DL_DST. */
459 OFPACT_PADDED_MEMBERS(
460 struct ofpact ofpact
;
465 /* OFPACT_SET_IPV4_SRC, OFPACT_SET_IPV4_DST.
467 * Used for OFPAT10_SET_NW_SRC, OFPAT10_SET_NW_DST. */
469 OFPACT_PADDED_MEMBERS(
470 struct ofpact ofpact
;
475 /* OFPACT_SET_IP_DSCP.
477 * Used for OFPAT10_SET_NW_TOS. */
479 OFPACT_PADDED_MEMBERS(
480 struct ofpact ofpact
;
481 uint8_t dscp
; /* DSCP in high 6 bits, rest ignored. */
485 /* OFPACT_SET_IP_ECN.
487 * Used for OFPAT11_SET_NW_ECN. */
489 OFPACT_PADDED_MEMBERS(
490 struct ofpact ofpact
;
491 uint8_t ecn
; /* ECN in low 2 bits, rest ignored. */
495 /* OFPACT_SET_IP_TTL.
497 * Used for OFPAT11_SET_NW_TTL. */
498 struct ofpact_ip_ttl
{
499 OFPACT_PADDED_MEMBERS(
500 struct ofpact ofpact
;
505 /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT.
507 * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */
508 struct ofpact_l4_port
{
509 OFPACT_PADDED_MEMBERS(
510 struct ofpact ofpact
;
511 uint16_t port
; /* TCP, UDP or SCTP port number. */
512 uint8_t flow_ip_proto
; /* IP proto from corresponding match, or 0 */
518 * Used for NXAST_REG_MOVE. */
519 struct ofpact_reg_move
{
520 OFPACT_PADDED_MEMBERS(
521 struct ofpact ofpact
;
522 struct mf_subfield src
;
523 struct mf_subfield dst
;
527 /* OFPACT_STACK_PUSH, OFPACT_STACK_POP.
529 * Used for NXAST_STACK_PUSH and NXAST_STACK_POP. */
530 struct ofpact_stack
{
531 OFPACT_PADDED_MEMBERS(
532 struct ofpact ofpact
;
533 struct mf_subfield subfield
;
539 * Used for NXAST_REG_LOAD and OFPAT12_SET_FIELD. */
540 struct ofpact_set_field
{
541 OFPACT_PADDED_MEMBERS(
542 struct ofpact ofpact
;
543 bool flow_has_vlan
; /* VLAN present at action validation time. */
544 const struct mf_field
*field
;
546 union mf_value value
[]; /* Significant value bytes followed by
547 * significant mask bytes. */
549 BUILD_ASSERT_DECL(offsetof(struct ofpact_set_field
, value
)
550 % OFPACT_ALIGNTO
== 0);
551 BUILD_ASSERT_DECL(offsetof(struct ofpact_set_field
, value
)
552 == sizeof(struct ofpact_set_field
));
554 /* Use macro to not have to deal with constness. */
555 #define ofpact_set_field_mask(SF) \
556 ALIGNED_CAST(union mf_value *, \
557 (uint8_t *)(SF)->value + (SF)->field->n_bytes)
559 /* OFPACT_PUSH_VLAN/MPLS/PBB
561 * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
562 struct ofpact_push_mpls
{
563 OFPACT_PADDED_MEMBERS(
564 struct ofpact ofpact
;
571 * Used for NXAST_POP_MPLS, OFPAT11_POP_MPLS.. */
572 struct ofpact_pop_mpls
{
573 OFPACT_PADDED_MEMBERS(
574 struct ofpact ofpact
;
579 /* OFPACT_SET_TUNNEL.
581 * Used for NXAST_SET_TUNNEL, NXAST_SET_TUNNEL64. */
582 struct ofpact_tunnel
{
583 OFPACT_PADDED_MEMBERS(
584 struct ofpact ofpact
;
591 * Used for NXAST_SET_QUEUE. */
592 struct ofpact_queue
{
593 OFPACT_PADDED_MEMBERS(
594 struct ofpact ofpact
;
599 /* OFPACT_FIN_TIMEOUT.
601 * Used for NXAST_FIN_TIMEOUT. */
602 struct ofpact_fin_timeout
{
603 OFPACT_PADDED_MEMBERS(
604 struct ofpact ofpact
;
605 uint16_t fin_idle_timeout
;
606 uint16_t fin_hard_timeout
;
610 /* OFPACT_WRITE_METADATA.
612 * Used for NXAST_WRITE_METADATA. */
613 struct ofpact_metadata
{
614 OFPACT_PADDED_MEMBERS(
615 struct ofpact ofpact
;
623 * Used for OFPIT13_METER. */
624 struct ofpact_meter
{
625 OFPACT_PADDED_MEMBERS(
626 struct ofpact ofpact
;
628 uint32_t provider_meter_id
;
632 /* OFPACT_CHECK_PKT_LARGER.
634 * Used for NXAST_CHECK_PKT_LARGER. */
635 struct ofpact_check_pkt_larger
{
636 OFPACT_PADDED_MEMBERS(
637 struct ofpact ofpact
;
638 struct mf_subfield dst
;
642 /* OFPACT_WRITE_ACTIONS, OFPACT_CLONE.
644 * Used for OFPIT11_WRITE_ACTIONS, NXAST_CLONE. */
646 OFPACT_PADDED_MEMBERS(struct ofpact ofpact
;);
647 struct ofpact actions
[];
649 BUILD_ASSERT_DECL(offsetof(struct ofpact_nest
, actions
) % OFPACT_ALIGNTO
== 0);
650 BUILD_ASSERT_DECL(offsetof(struct ofpact_nest
, actions
)
651 == sizeof(struct ofpact_nest
));
654 ofpact_nest_get_action_len(const struct ofpact_nest
*on
)
656 return on
->ofpact
.len
- offsetof(struct ofpact_nest
, actions
);
659 /* Bits for 'flags' in struct nx_action_conntrack.
661 * If NX_CT_F_COMMIT is set, then the connection entry is moved from the
662 * unconfirmed to confirmed list in the tracker.
663 * If NX_CT_F_FORCE is set, in addition to NX_CT_F_COMMIT, then the conntrack
664 * entry is replaced with a new one in case the original direction of the
665 * existing entry is opposite of the current packet direction.
667 enum nx_conntrack_flags
{
668 NX_CT_F_COMMIT
= 1 << 0,
669 NX_CT_F_FORCE
= 1 << 1,
672 /* Magic value for struct nx_action_conntrack 'recirc_table' field, to specify
673 * that the packet should not be recirculated. */
674 #define NX_CT_RECIRC_NONE OFPTT_ALL
676 #if !defined(IPPORT_FTP)
677 #define IPPORT_FTP 21
680 #if !defined(IPPORT_TFTP)
681 #define IPPORT_TFTP 69
686 * Used for NXAST_CT. */
687 struct ofpact_conntrack
{
688 OFPACT_PADDED_MEMBERS(
689 struct ofpact ofpact
;
692 struct mf_subfield zone_src
;
694 uint8_t recirc_table
;
696 struct ofpact actions
[0];
698 BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack
, actions
)
699 % OFPACT_ALIGNTO
== 0);
700 BUILD_ASSERT_DECL(offsetof(struct ofpact_conntrack
, actions
)
701 == sizeof(struct ofpact_conntrack
));
704 ofpact_ct_get_action_len(const struct ofpact_conntrack
*oc
)
706 return oc
->ofpact
.len
- offsetof(struct ofpact_conntrack
, actions
);
709 void ofpacts_execute_action_set(struct ofpbuf
*action_list
,
710 const struct ofpbuf
*action_set
);
712 /* Bits for 'flags' in struct nx_action_nat.
715 NX_NAT_F_SRC
= 1 << 0, /* Mutually exclusive with NX_NAT_F_DST. */
716 NX_NAT_F_DST
= 1 << 1,
717 NX_NAT_F_PERSISTENT
= 1 << 2,
718 NX_NAT_F_PROTO_HASH
= 1 << 3, /* Mutually exclusive with PROTO_RANDOM. */
719 NX_NAT_F_PROTO_RANDOM
= 1 << 4,
720 NX_NAT_F_MASK
= (NX_NAT_F_SRC
| NX_NAT_F_DST
| NX_NAT_F_PERSISTENT
| NX_NAT_F_PROTO_HASH
| NX_NAT_F_PROTO_RANDOM
)
725 * Used for NXAST_NAT. */
727 OFPACT_PADDED_MEMBERS(
728 struct ofpact ofpact
;
729 uint8_t range_af
; /* AF_UNSPEC, AF_INET, or AF_INET6 */
730 uint16_t flags
; /* NX_NAT_F_* */
753 * Used for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE, NXAST_RESUBMIT_TABLE_CT. */
754 struct ofpact_resubmit
{
755 OFPACT_PADDED_MEMBERS(
756 struct ofpact ofpact
;
759 bool with_ct_orig
; /* Resubmit with Conntrack original direction tuple
760 * fields in place of IP header fields. */
764 /* Bits for 'flags' in struct nx_action_learn.
766 * If NX_LEARN_F_SEND_FLOW_REM is set, then the learned flows will have their
767 * OFPFF_SEND_FLOW_REM flag set.
769 * If NX_LEARN_F_WRITE_RESULT is set, then the actions will write whether the
770 * learn operation succeded on a bit. If the learn is successful the bit will
771 * be set, otherwise (e.g. if the limit is hit) the bit will be unset.
773 * If NX_LEARN_F_DELETE_LEARNED is set, then removing this action will delete
774 * all the flows from the learn action's 'table_id' that have the learn
775 * action's 'cookie'. Important points:
777 * - The deleted flows include those created by this action, those created
778 * by other learn actions with the same 'table_id' and 'cookie', those
779 * created by flow_mod requests by a controller in the specified table
780 * with the specified cookie, and those created through any other
783 * - If multiple flows specify "learn" actions with
784 * NX_LEARN_F_DELETE_LEARNED with the same 'table_id' and 'cookie', then
785 * no deletion occurs until all of those "learn" actions are deleted.
787 * - Deleting a flow that contains a learn action is the most obvious way
788 * to delete a learn action. Modifying a flow's actions, or replacing it
789 * by a new flow, can also delete a learn action. Finally, replacing a
790 * learn action with NX_LEARN_F_DELETE_LEARNED with a learn action
791 * without that flag also effectively deletes the learn action and can
792 * trigger flow deletion.
794 * NX_LEARN_F_DELETE_LEARNED was added in Open vSwitch 2.4. */
795 enum nx_learn_flags
{
796 NX_LEARN_F_SEND_FLOW_REM
= 1 << 0,
797 NX_LEARN_F_DELETE_LEARNED
= 1 << 1,
798 NX_LEARN_F_WRITE_RESULT
= 1 << 2,
801 #define NX_LEARN_N_BITS_MASK 0x3ff
803 #define NX_LEARN_SRC_FIELD (0 << 13) /* Copy from field. */
804 #define NX_LEARN_SRC_IMMEDIATE (1 << 13) /* Copy from immediate value. */
805 #define NX_LEARN_SRC_MASK (1 << 13)
807 #define NX_LEARN_DST_MATCH (0 << 11) /* Add match criterion. */
808 #define NX_LEARN_DST_LOAD (1 << 11) /* Add NXAST_REG_LOAD action. */
809 #define NX_LEARN_DST_OUTPUT (2 << 11) /* Add OFPAT_OUTPUT action. */
810 #define NX_LEARN_DST_RESERVED (3 << 11) /* Not yet defined. */
811 #define NX_LEARN_DST_MASK (3 << 11)
813 /* Part of struct ofpact_learn, below. */
814 struct ofpact_learn_spec
{
815 OFPACT_PADDED_MEMBERS(
816 struct mf_subfield src
; /* NX_LEARN_SRC_FIELD only. */
817 struct mf_subfield dst
; /* NX_LEARN_DST_MATCH,
818 * NX_LEARN_DST_LOAD only. */
819 uint16_t src_type
; /* One of NX_LEARN_SRC_*. */
820 uint16_t dst_type
; /* One of NX_LEARN_DST_*. */
821 uint32_t n_bits
; /* Number of bits in source and dest. */
823 /* Followed by 'DIV_ROUND_UP(n_bits, 8)' bytes of immediate data for
824 * match 'dst_type's NX_LEARN_DST_MATCH and NX_LEARN_DST_LOAD when
825 * NX_LEARN_SRC_IMMEDIATE is set in 'src_type', followed by zeroes to align
826 * to OFPACT_ALIGNTO. */
828 BUILD_ASSERT_DECL(sizeof(struct ofpact_learn_spec
) % OFPACT_ALIGNTO
== 0);
830 static inline const void *
831 ofpact_learn_spec_imm(const struct ofpact_learn_spec
*spec
)
836 static inline const struct ofpact_learn_spec
*
837 ofpact_learn_spec_next(const struct ofpact_learn_spec
*spec
)
839 if (spec
->src_type
== NX_LEARN_SRC_IMMEDIATE
) {
840 unsigned int n_bytes
= OFPACT_ALIGN(DIV_ROUND_UP(spec
->n_bits
, 8));
841 return ALIGNED_CAST(const struct ofpact_learn_spec
*,
842 (const uint8_t *)(spec
+ 1) + n_bytes
);
849 * Used for NXAST_LEARN. */
850 struct ofpact_learn
{
851 OFPACT_PADDED_MEMBERS(
852 struct ofpact ofpact
;
854 uint16_t idle_timeout
; /* Idle time before discarding (seconds). */
855 uint16_t hard_timeout
; /* Max time before discarding (seconds). */
856 uint16_t priority
; /* Priority level of flow entry. */
857 uint8_t table_id
; /* Table to insert flow entry. */
858 enum nx_learn_flags flags
; /* NX_LEARN_F_*. */
859 ovs_be64 cookie
; /* Cookie for new flow. */
860 uint16_t fin_idle_timeout
; /* Idle timeout after FIN, if nonzero. */
861 uint16_t fin_hard_timeout
; /* Hard timeout after FIN, if nonzero. */
862 /* If the number of flows on 'table_id' with 'cookie' exceeds this,
863 * the action will not add a new flow. 0 indicates unlimited. */
865 /* Used only if 'flags' has NX_LEARN_F_WRITE_RESULT. If the execution
866 * failed to install a new flow because 'limit' is exceeded,
867 * result_dst will be set to 0, otherwise to 1. */
868 struct mf_subfield result_dst
;
871 struct ofpact_learn_spec specs
[];
874 static inline const struct ofpact_learn_spec
*
875 ofpact_learn_spec_end(const struct ofpact_learn
*learn
)
877 return ALIGNED_CAST(const struct ofpact_learn_spec
*,
878 ofpact_next(&learn
->ofpact
));
881 #define OFPACT_LEARN_SPEC_FOR_EACH(SPEC, LEARN) \
882 for ((SPEC) = (LEARN)->specs; \
883 (SPEC) < ofpact_learn_spec_end(LEARN); \
884 (SPEC) = ofpact_learn_spec_next(SPEC))
886 /* Multipath link choice algorithm to apply.
888 * In the descriptions below, 'n_links' is max_link + 1. */
889 enum nx_mp_algorithm
{
890 /* link = hash(flow) % n_links.
892 * Redistributes all traffic when n_links changes. O(1) performance. See
895 * Use UINT16_MAX for max_link to get a raw hash value. */
896 NX_MP_ALG_MODULO_N
= 0,
898 /* link = hash(flow) / (MAX_HASH / n_links).
900 * Redistributes between one-quarter and one-half of traffic when n_links
901 * changes. O(1) performance. See RFC 2992.
903 NX_MP_ALG_HASH_THRESHOLD
= 1,
905 /* Highest Random Weight.
907 * for i in [0,n_links):
908 * weights[i] = hash(flow, i)
909 * link = { i such that weights[i] >= weights[j] for all j != i }
911 * Redistributes 1/n_links of traffic when n_links changes. O(n_links)
912 * performance. If n_links is greater than a threshold (currently 64, but
913 * subject to change), Open vSwitch will substitute another algorithm
914 * automatically. See RFC 2992. */
922 * link = hash(flow, i) % arg
923 * while link > max_link
925 * Redistributes 1/n_links of traffic when n_links changes. O(1)
926 * performance when arg/max_link is bounded by a constant.
928 * Redistributes all traffic when arg changes.
930 * arg must be greater than max_link and for best performance should be no
931 * more than approximately max_link * 2. If arg is outside the acceptable
932 * range, Open vSwitch will automatically substitute the least power of 2
933 * greater than max_link.
935 * This algorithm is specific to Open vSwitch.
937 NX_MP_ALG_ITER_HASH
= 3,
940 /* OFPACT_CONJUNCTION.
942 * Used for NXAST_CONJUNCTION. */
943 struct ofpact_conjunction
{
944 OFPACT_PADDED_MEMBERS(
945 struct ofpact ofpact
;
954 * Used for NXAST_MULTIPATH. */
955 struct ofpact_multipath
{
956 OFPACT_PADDED_MEMBERS(
957 struct ofpact ofpact
;
959 /* What fields to hash and how. */
960 enum nx_hash_fields fields
;
961 uint16_t basis
; /* Universal hash parameter. */
963 /* Multipath link choice algorithm to apply to hash value. */
964 enum nx_mp_algorithm algorithm
;
965 uint16_t max_link
; /* Number of output links, minus 1. */
966 uint32_t arg
; /* Algorithm-specific argument. */
968 /* Where to store the result. */
969 struct mf_subfield dst
;
975 * Used for NXAST_NOTE. */
977 OFPACT_PADDED_MEMBERS(
978 struct ofpact ofpact
;
984 /* Direction of sampled packets. */
985 enum nx_action_sample_direction
{
986 /* OVS will attempt to infer the sample's direction based on whether
987 * 'sampling_port' is the packet's output port. This is generally
988 * effective except when sampling happens as part of an output to a patch
989 * port, which doesn't involve a datapath output action. */
990 NX_ACTION_SAMPLE_DEFAULT
,
992 /* Explicit direction. This is useful for sampling packets coming in from
993 * or going out of a patch port, where the direction cannot be inferred. */
994 NX_ACTION_SAMPLE_INGRESS
,
995 NX_ACTION_SAMPLE_EGRESS
1000 * Used for NXAST_SAMPLE, NXAST_SAMPLE2, and NXAST_SAMPLE3. */
1001 struct ofpact_sample
{
1002 OFPACT_PADDED_MEMBERS(
1003 struct ofpact ofpact
;
1004 uint16_t probability
; /* Always positive. */
1005 uint32_t collector_set_id
;
1006 uint32_t obs_domain_id
;
1007 uint32_t obs_point_id
;
1008 ofp_port_t sampling_port
;
1009 enum nx_action_sample_direction direction
;
1015 * Used for OFPAT11_DEC_NW_TTL, NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */
1016 struct ofpact_cnt_ids
{
1017 OFPACT_PADDED_MEMBERS(
1018 struct ofpact ofpact
;
1019 unsigned int n_controllers
;
1024 /* OFPACT_SET_MPLS_LABEL.
1026 * Used for OFPAT11_SET_MPLS_LABEL and NXAST_SET_MPLS_LABEL */
1027 struct ofpact_mpls_label
{
1028 OFPACT_PADDED_MEMBERS(
1029 struct ofpact ofpact
;
1034 /* OFPACT_SET_MPLS_TC.
1036 * Used for OFPAT11_SET_MPLS_TC and NXAST_SET_MPLS_TC */
1037 struct ofpact_mpls_tc
{
1038 OFPACT_PADDED_MEMBERS(
1039 struct ofpact ofpact
;
1044 /* OFPACT_SET_MPLS_TTL.
1046 * Used for OFPAT11_SET_MPLS_TTL and NXAST_SET_MPLS_TTL */
1047 struct ofpact_mpls_ttl
{
1048 OFPACT_PADDED_MEMBERS(
1049 struct ofpact ofpact
;
1054 /* OFPACT_GOTO_TABLE
1056 * Used for OFPIT11_GOTO_TABLE */
1057 struct ofpact_goto_table
{
1058 OFPACT_PADDED_MEMBERS(
1059 struct ofpact ofpact
;
1066 * Used for OFPAT11_GROUP. */
1067 struct ofpact_group
{
1068 OFPACT_PADDED_MEMBERS(
1069 struct ofpact ofpact
;
1074 /* OFPACT_UNROLL_XLATE.
1076 * Used only internally. */
1077 struct ofpact_unroll_xlate
{
1078 OFPACT_PADDED_MEMBERS(
1079 struct ofpact ofpact
;
1081 /* Metadata in xlate context, visible to controller via PACKET_INs. */
1082 uint8_t rule_table_id
; /* 0xFF if none. */
1083 ovs_be64 rule_cookie
; /* OVS_BE64_MAX if none. */
1089 * Used for NXAST_ENCAP. */
1091 struct ofpact_encap
{
1092 OFPACT_PADDED_MEMBERS(
1093 struct ofpact ofpact
;
1094 ovs_be32 new_pkt_type
; /* Packet type of the header to add. */
1095 uint16_t hdr_size
; /* New header size in bytes. */
1096 uint16_t n_props
; /* Number of encap properties. */
1098 struct ofpact_ed_prop props
[]; /* Properties in internal format. */
1103 * Used for NXAST_DECAP. */
1104 struct ofpact_decap
{
1105 OFPACT_PADDED_MEMBERS(
1106 struct ofpact ofpact
;
1110 * The special value (0,0xFFFE) "Use next proto" is used to request OVS
1111 * to automatically set the new packet type based on the decap'ed
1112 * header's next protocol.
1114 ovs_be32 new_pkt_type
;
1118 /* Converting OpenFlow to ofpacts. */
1119 enum ofperr
ofpacts_pull_openflow_actions(struct ofpbuf
*openflow
,
1120 unsigned int actions_len
,
1121 enum ofp_version version
,
1122 const struct vl_mff_map
*,
1123 uint64_t *ofpacts_tlv_bitmap
,
1124 struct ofpbuf
*ofpacts
);
1126 ofpacts_pull_openflow_instructions(struct ofpbuf
*openflow
,
1127 unsigned int instructions_len
,
1128 enum ofp_version version
,
1129 const struct vl_mff_map
*vl_mff_map
,
1130 uint64_t *ofpacts_tlv_bitmap
,
1131 struct ofpbuf
*ofpacts
);
1133 struct ofpact_check_params
{
1135 struct match
*match
;
1136 ofp_port_t max_ports
;
1141 enum ofputil_protocol usable_protocols
;
1143 enum ofperr
ofpacts_check(struct ofpact
[], size_t ofpacts_len
,
1144 struct ofpact_check_params
*);
1145 enum ofperr
ofpacts_check_consistency(struct ofpact
[], size_t ofpacts_len
,
1146 enum ofputil_protocol needed_protocols
,
1147 struct ofpact_check_params
*);
1148 enum ofperr
ofpact_check_output_port(ofp_port_t port
, ofp_port_t max_ports
);
1150 /* Converting ofpacts to OpenFlow. */
1151 size_t ofpacts_put_openflow_actions(const struct ofpact
[], size_t ofpacts_len
,
1152 struct ofpbuf
*openflow
, enum ofp_version
);
1153 void ofpacts_put_openflow_instructions(const struct ofpact
[],
1155 struct ofpbuf
*openflow
,
1156 enum ofp_version ofp_version
);
1158 /* Sets of supported actions. */
1159 ovs_be32
ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap
, enum ofp_version
);
1160 uint64_t ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap
, enum ofp_version
);
1161 void ofpact_bitmap_format(uint64_t ofpacts_bitmap
, struct ds
*);
1163 /* Working with ofpacts. */
1164 bool ofpacts_output_to_port(const struct ofpact
[], size_t ofpacts_len
,
1166 bool ofpacts_output_to_group(const struct ofpact
[], size_t ofpacts_len
,
1168 bool ofpacts_equal(const struct ofpact a
[], size_t a_len
,
1169 const struct ofpact b
[], size_t b_len
);
1170 bool ofpacts_equal_stringwise(const struct ofpact a
[], size_t a_len
,
1171 const struct ofpact b
[], size_t b_len
);
1172 const struct mf_field
*ofpact_get_mf_dst(const struct ofpact
*ofpact
);
1173 uint32_t ofpacts_get_meter(const struct ofpact
[], size_t ofpacts_len
);
1175 /* Formatting ofpacts. */
1176 struct ofpact_format_params
{
1178 const struct ofputil_port_map
*port_map
;
1179 const struct ofputil_table_map
*table_map
;
1184 void ofpacts_format(const struct ofpact
[], size_t ofpacts_len
,
1185 const struct ofpact_format_params
*);
1186 const char *ofpact_name(enum ofpact_type
);
1188 /* Parsing ofpacts. */
1189 struct ofpact_parse_params
{
1191 const struct ofputil_port_map
*port_map
;
1192 const struct ofputil_table_map
*table_map
;
1195 struct ofpbuf
*ofpacts
;
1196 enum ofputil_protocol
*usable_protocols
;
1198 /* Parse context. */
1201 #define MAX_OFPACT_PARSE_DEPTH 100
1202 char *ofpacts_parse_actions(const char *, const struct ofpact_parse_params
*)
1203 OVS_WARN_UNUSED_RESULT
;
1204 char *ofpacts_parse_instructions(const char *,
1205 const struct ofpact_parse_params
*)
1206 OVS_WARN_UNUSED_RESULT
;
1208 /* Internal use by the helpers below. */
1209 void ofpact_init(struct ofpact
*, enum ofpact_type
, size_t len
);
1210 void *ofpact_put(struct ofpbuf
*, enum ofpact_type
, size_t len
);
1211 void *ofpact_finish(struct ofpbuf
*, struct ofpact
*);
1213 /* For each OFPACT_<ENUM> with a corresponding struct <STRUCT>, this defines
1214 * the following commonly useful functions:
1216 * struct <STRUCT> *ofpact_put_<ENUM>(struct ofpbuf *ofpacts);
1218 * Appends a new 'ofpact', of length OFPACT_<ENUM>_SIZE, to 'ofpacts',
1219 * initializes it with ofpact_init_<ENUM>(), and returns it. Also sets
1220 * 'ofpacts->header' to the returned action.
1222 * After using this function to add a variable-length action, add the
1223 * elements of the flexible array (e.g. with ofpbuf_put()), then use
1224 * ofpact_finish() to pad the action to a multiple of OFPACT_ALIGNTO bytes
1225 * and update its embedded length field. (Keep in mind the need to refresh
1226 * the structure from 'ofpacts->header' after adding data to 'ofpacts'.)
1228 * struct <STRUCT> *ofpact_get_<ENUM>(const struct ofpact *ofpact);
1230 * Returns 'ofpact' cast to "struct <STRUCT> *". 'ofpact->type' must be
1233 * void ofpact_finish_<ENUM>(struct ofpbuf *ofpacts, struct <STRUCT> **ap);
1235 * Finishes composing variable-length action '*ap' (begun using
1236 * ofpact_put_<NAME>() on 'ofpacts'), by padding the action to a multiple
1237 * of OFPACT_ALIGNTO bytes and updating its embedded length field.
1239 * May reallocate 'ofpacts', and so as a convenience automatically updates
1240 * '*ap' to point to the new location. If the caller has other pointers
1241 * within 'ap' or 'ofpacts', it needs to update them manually.
1243 * as well as the following more rarely useful definitions:
1245 * void ofpact_init_<ENUM>(struct <STRUCT> *ofpact);
1247 * Initializes the parts of 'ofpact' that identify it as having type
1248 * OFPACT_<ENUM> and length OFPACT_<ENUM>_SIZE and zeros the rest.
1250 #define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
1251 BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \
1253 /* Action structures must be a multiple of OFPACT_ALIGNTO bytes. */ \
1254 BUILD_ASSERT_DECL(sizeof(struct STRUCT) % OFPACT_ALIGNTO == 0); \
1256 /* Variable-length data must start at a multiple of OFPACT_ALIGNTO \
1258 BUILD_ASSERT_DECL(offsetof(struct STRUCT, MEMBER) \
1259 % OFPACT_ALIGNTO == 0); \
1261 /* If there is variable-length data, it starts at the end of the \
1263 BUILD_ASSERT_DECL(!offsetof(struct STRUCT, MEMBER) \
1264 || (offsetof(struct STRUCT, MEMBER) \
1265 == sizeof(struct STRUCT))); \
1267 static inline struct STRUCT * \
1268 ofpact_get_##ENUM(const struct ofpact *ofpact) \
1270 ovs_assert(ofpact->type == OFPACT_##ENUM); \
1271 return ALIGNED_CAST(struct STRUCT *, ofpact); \
1274 static inline struct STRUCT * \
1275 ofpact_get_##ENUM##_nullable(const struct ofpact *ofpact) \
1277 ovs_assert(!ofpact || ofpact->type == OFPACT_##ENUM); \
1278 return ALIGNED_CAST(struct STRUCT *, ofpact); \
1281 static inline struct STRUCT * \
1282 ofpact_put_##ENUM(struct ofpbuf *ofpacts) \
1284 return (struct STRUCT *) ofpact_put(ofpacts, OFPACT_##ENUM, \
1285 sizeof(struct STRUCT)); \
1288 static inline void \
1289 ofpact_init_##ENUM(struct STRUCT *ofpact) \
1291 ofpact_init(&ofpact->ofpact, OFPACT_##ENUM, \
1292 sizeof(struct STRUCT)); \
1295 static inline void \
1296 ofpact_finish_##ENUM(struct ofpbuf *ofpbuf, struct STRUCT **ofpactp) \
1298 struct ofpact *ofpact = &(*ofpactp)->ofpact; \
1299 ovs_assert(ofpact->type == OFPACT_##ENUM); \
1300 *ofpactp = (struct STRUCT *) ofpact_finish(ofpbuf, ofpact); \
1305 /* Additional functions for composing ofpacts. */
1306 struct ofpact_set_field
*ofpact_put_set_field(struct ofpbuf
*ofpacts
,
1307 const struct mf_field
*,
1310 struct ofpact_set_field
*ofpact_put_reg_load(struct ofpbuf
*ofpacts
,
1311 const struct mf_field
*,
1314 struct ofpact_set_field
*ofpact_put_reg_load2(struct ofpbuf
*ofpacts
,
1315 const struct mf_field
*,
1319 /* OpenFlow 1.1 instructions.
1320 * The order is sorted in execution order. Not in the value of OFPIT11_xxx.
1321 * It is enforced on parser from text string.
1323 #define OVS_INSTRUCTIONS \
1324 DEFINE_INST(OFPIT13_METER, \
1325 ofp13_instruction_meter, false, \
1328 DEFINE_INST(OFPIT11_APPLY_ACTIONS, \
1329 ofp11_instruction_actions, true, \
1332 DEFINE_INST(OFPIT11_CLEAR_ACTIONS, \
1333 ofp11_instruction, false, \
1336 DEFINE_INST(OFPIT11_WRITE_ACTIONS, \
1337 ofp11_instruction_actions, true, \
1340 DEFINE_INST(OFPIT11_WRITE_METADATA, \
1341 ofp11_instruction_write_metadata, false, \
1344 DEFINE_INST(OFPIT11_GOTO_TABLE, \
1345 ofp11_instruction_goto_table, false, \
1348 enum ovs_instruction_type
{
1349 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) OVSINST_##ENUM,
1355 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
1356 N_OVS_INSTRUCTIONS
= OVS_INSTRUCTIONS
1360 const char *ovs_instruction_name_from_type(enum ovs_instruction_type type
);
1361 int ovs_instruction_type_from_name(const char *name
);
1362 enum ovs_instruction_type
ovs_instruction_type_from_ofpact_type(
1363 enum ofpact_type
, enum ofp_version
);
1364 enum ofperr
ovs_instruction_type_from_inst_type(
1365 enum ovs_instruction_type
*instruction_type
, const uint16_t inst_type
);
1367 ovs_be32
ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap
, enum ofp_version
);
1368 uint32_t ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap
,
1375 #endif /* ofp-actions.h */