2 * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
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 "ofp-actions.h"
21 #include "byte-order.h"
23 #include "dynamic-string.h"
25 #include "meta-flow.h"
26 #include "multipath.h"
32 VLOG_DEFINE_THIS_MODULE(ofp_actions
);
34 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
36 /* Converting OpenFlow 1.0 to ofpacts. */
39 output_from_openflow10(const struct ofp10_action_output
*oao
,
42 struct ofpact_output
*output
;
44 output
= ofpact_put_OUTPUT(out
);
45 output
->port
= ntohs(oao
->port
);
46 output
->max_len
= ntohs(oao
->max_len
);
48 return ofputil_check_output_port(output
->port
, OFPP_MAX
);
52 enqueue_from_openflow10(const struct ofp_action_enqueue
*oae
,
55 struct ofpact_enqueue
*enqueue
;
57 enqueue
= ofpact_put_ENQUEUE(out
);
58 enqueue
->port
= ntohs(oae
->port
);
59 enqueue
->queue
= ntohl(oae
->queue_id
);
60 if (enqueue
->port
>= OFPP_MAX
&& enqueue
->port
!= OFPP_IN_PORT
61 && enqueue
->port
!= OFPP_LOCAL
) {
62 return OFPERR_OFPBAC_BAD_OUT_PORT
;
68 resubmit_from_openflow(const struct nx_action_resubmit
*nar
,
71 struct ofpact_resubmit
*resubmit
;
73 resubmit
= ofpact_put_RESUBMIT(out
);
74 resubmit
->ofpact
.compat
= OFPUTIL_NXAST_RESUBMIT
;
75 resubmit
->in_port
= ntohs(nar
->in_port
);
76 resubmit
->table_id
= 0xff;
80 resubmit_table_from_openflow(const struct nx_action_resubmit
*nar
,
83 struct ofpact_resubmit
*resubmit
;
85 if (nar
->pad
[0] || nar
->pad
[1] || nar
->pad
[2]) {
86 return OFPERR_OFPBAC_BAD_ARGUMENT
;
89 resubmit
= ofpact_put_RESUBMIT(out
);
90 resubmit
->ofpact
.compat
= OFPUTIL_NXAST_RESUBMIT_TABLE
;
91 resubmit
->in_port
= ntohs(nar
->in_port
);
92 resubmit
->table_id
= nar
->table
;
97 output_reg_from_openflow(const struct nx_action_output_reg
*naor
,
100 struct ofpact_output_reg
*output_reg
;
102 if (!is_all_zeros(naor
->zero
, sizeof naor
->zero
)) {
103 return OFPERR_OFPBAC_BAD_ARGUMENT
;
106 output_reg
= ofpact_put_OUTPUT_REG(out
);
107 output_reg
->src
.field
= mf_from_nxm_header(ntohl(naor
->src
));
108 output_reg
->src
.ofs
= nxm_decode_ofs(naor
->ofs_nbits
);
109 output_reg
->src
.n_bits
= nxm_decode_n_bits(naor
->ofs_nbits
);
110 output_reg
->max_len
= ntohs(naor
->max_len
);
112 return mf_check_src(&output_reg
->src
, NULL
);
116 fin_timeout_from_openflow(const struct nx_action_fin_timeout
*naft
,
119 struct ofpact_fin_timeout
*oft
;
121 oft
= ofpact_put_FIN_TIMEOUT(out
);
122 oft
->fin_idle_timeout
= ntohs(naft
->fin_idle_timeout
);
123 oft
->fin_hard_timeout
= ntohs(naft
->fin_hard_timeout
);
127 controller_from_openflow(const struct nx_action_controller
*nac
,
130 struct ofpact_controller
*oc
;
132 oc
= ofpact_put_CONTROLLER(out
);
133 oc
->max_len
= ntohs(nac
->max_len
);
134 oc
->controller_id
= ntohs(nac
->controller_id
);
135 oc
->reason
= nac
->reason
;
139 note_from_openflow(const struct nx_action_note
*nan
, struct ofpbuf
*out
)
141 struct ofpact_note
*note
;
144 length
= ntohs(nan
->len
) - offsetof(struct nx_action_note
, note
);
145 note
= ofpact_put(out
, OFPACT_NOTE
,
146 offsetof(struct ofpact_note
, data
) + length
);
147 note
->length
= length
;
148 memcpy(note
->data
, nan
->note
, length
);
152 decode_nxast_action(const union ofp_action
*a
, enum ofputil_action_code
*code
)
154 const struct nx_action_header
*nah
= (const struct nx_action_header
*) a
;
155 uint16_t len
= ntohs(a
->header
.len
);
157 if (len
< sizeof(struct nx_action_header
)) {
158 return OFPERR_OFPBAC_BAD_LEN
;
159 } else if (a
->vendor
.vendor
!= CONSTANT_HTONL(NX_VENDOR_ID
)) {
160 return OFPERR_OFPBAC_BAD_VENDOR
;
163 switch (nah
->subtype
) {
164 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
165 case CONSTANT_HTONS(ENUM): \
167 ? len >= sizeof(struct STRUCT) \
168 : len == sizeof(struct STRUCT)) { \
169 *code = OFPUTIL_##ENUM; \
172 return OFPERR_OFPBAC_BAD_LEN; \
175 #include "ofp-util.def"
177 case CONSTANT_HTONS(NXAST_SNAT__OBSOLETE
):
178 case CONSTANT_HTONS(NXAST_DROP_SPOOFED_ARP__OBSOLETE
):
180 return OFPERR_OFPBAC_BAD_TYPE
;
184 /* Parses 'a' to determine its type. On success stores the correct type into
185 * '*code' and returns 0. On failure returns an OFPERR_* error code and
186 * '*code' is indeterminate.
188 * The caller must have already verified that 'a''s length is potentially
189 * correct (that is, a->header.len is nonzero and a multiple of sizeof(union
190 * ofp_action) and no longer than the amount of space allocated to 'a').
192 * This function verifies that 'a''s length is correct for the type of action
193 * that it represents. */
195 decode_openflow10_action(const union ofp_action
*a
,
196 enum ofputil_action_code
*code
)
199 case CONSTANT_HTONS(OFPAT10_VENDOR
):
200 return decode_nxast_action(a
, code
);
202 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
203 case CONSTANT_HTONS(ENUM): \
204 if (a->header.len == htons(sizeof(struct STRUCT))) { \
205 *code = OFPUTIL_##ENUM; \
208 return OFPERR_OFPBAC_BAD_LEN; \
211 #include "ofp-util.def"
214 return OFPERR_OFPBAC_BAD_TYPE
;
219 ofpact_from_nxast(const union ofp_action
*a
, enum ofputil_action_code code
,
222 const struct nx_action_resubmit
*nar
;
223 const struct nx_action_set_tunnel
*nast
;
224 const struct nx_action_set_queue
*nasq
;
225 const struct nx_action_note
*nan
;
226 const struct nx_action_set_tunnel64
*nast64
;
227 struct ofpact_tunnel
*tunnel
;
228 enum ofperr error
= 0;
231 case OFPUTIL_ACTION_INVALID
:
232 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
233 #define OFPAT11_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
234 #include "ofp-util.def"
237 case OFPUTIL_NXAST_RESUBMIT
:
238 resubmit_from_openflow((const struct nx_action_resubmit
*) a
, out
);
241 case OFPUTIL_NXAST_SET_TUNNEL
:
242 nast
= (const struct nx_action_set_tunnel
*) a
;
243 tunnel
= ofpact_put_SET_TUNNEL(out
);
244 tunnel
->ofpact
.compat
= code
;
245 tunnel
->tun_id
= ntohl(nast
->tun_id
);
248 case OFPUTIL_NXAST_SET_QUEUE
:
249 nasq
= (const struct nx_action_set_queue
*) a
;
250 ofpact_put_SET_QUEUE(out
)->queue_id
= ntohl(nasq
->queue_id
);
253 case OFPUTIL_NXAST_POP_QUEUE
:
254 ofpact_put_POP_QUEUE(out
);
257 case OFPUTIL_NXAST_REG_MOVE
:
258 error
= nxm_reg_move_from_openflow(
259 (const struct nx_action_reg_move
*) a
, out
);
262 case OFPUTIL_NXAST_REG_LOAD
:
263 error
= nxm_reg_load_from_openflow(
264 (const struct nx_action_reg_load
*) a
, out
);
267 case OFPUTIL_NXAST_NOTE
:
268 nan
= (const struct nx_action_note
*) a
;
269 note_from_openflow(nan
, out
);
272 case OFPUTIL_NXAST_SET_TUNNEL64
:
273 nast64
= (const struct nx_action_set_tunnel64
*) a
;
274 tunnel
= ofpact_put_SET_TUNNEL(out
);
275 tunnel
->ofpact
.compat
= code
;
276 tunnel
->tun_id
= ntohll(nast64
->tun_id
);
279 case OFPUTIL_NXAST_MULTIPATH
:
280 error
= multipath_from_openflow((const struct nx_action_multipath
*) a
,
281 ofpact_put_MULTIPATH(out
));
284 case OFPUTIL_NXAST_AUTOPATH
:
285 error
= autopath_from_openflow((const struct nx_action_autopath
*) a
,
286 ofpact_put_AUTOPATH(out
));
289 case OFPUTIL_NXAST_BUNDLE
:
290 case OFPUTIL_NXAST_BUNDLE_LOAD
:
291 error
= bundle_from_openflow((const struct nx_action_bundle
*) a
, out
);
294 case OFPUTIL_NXAST_OUTPUT_REG
:
295 error
= output_reg_from_openflow(
296 (const struct nx_action_output_reg
*) a
, out
);
299 case OFPUTIL_NXAST_RESUBMIT_TABLE
:
300 nar
= (const struct nx_action_resubmit
*) a
;
301 error
= resubmit_table_from_openflow(nar
, out
);
304 case OFPUTIL_NXAST_LEARN
:
305 error
= learn_from_openflow((const struct nx_action_learn
*) a
, out
);
308 case OFPUTIL_NXAST_EXIT
:
309 ofpact_put_EXIT(out
);
312 case OFPUTIL_NXAST_DEC_TTL
:
313 ofpact_put_DEC_TTL(out
);
316 case OFPUTIL_NXAST_FIN_TIMEOUT
:
317 fin_timeout_from_openflow(
318 (const struct nx_action_fin_timeout
*) a
, out
);
321 case OFPUTIL_NXAST_CONTROLLER
:
322 controller_from_openflow((const struct nx_action_controller
*) a
, out
);
330 ofpact_from_openflow10(const union ofp_action
*a
, struct ofpbuf
*out
)
332 enum ofputil_action_code code
;
335 error
= decode_openflow10_action(a
, &code
);
341 case OFPUTIL_ACTION_INVALID
:
342 #define OFPAT11_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
343 #include "ofp-util.def"
346 case OFPUTIL_OFPAT10_OUTPUT
:
347 return output_from_openflow10(&a
->output10
, out
);
349 case OFPUTIL_OFPAT10_SET_VLAN_VID
:
350 if (a
->vlan_vid
.vlan_vid
& ~htons(0xfff)) {
351 return OFPERR_OFPBAC_BAD_ARGUMENT
;
353 ofpact_put_SET_VLAN_VID(out
)->vlan_vid
= ntohs(a
->vlan_vid
.vlan_vid
);
356 case OFPUTIL_OFPAT10_SET_VLAN_PCP
:
357 if (a
->vlan_pcp
.vlan_pcp
& ~7) {
358 return OFPERR_OFPBAC_BAD_ARGUMENT
;
360 ofpact_put_SET_VLAN_PCP(out
)->vlan_pcp
= a
->vlan_pcp
.vlan_pcp
;
363 case OFPUTIL_OFPAT10_STRIP_VLAN
:
364 ofpact_put_STRIP_VLAN(out
);
367 case OFPUTIL_OFPAT10_SET_DL_SRC
:
368 memcpy(ofpact_put_SET_ETH_SRC(out
)->mac
,
369 ((const struct ofp_action_dl_addr
*) a
)->dl_addr
, ETH_ADDR_LEN
);
372 case OFPUTIL_OFPAT10_SET_DL_DST
:
373 memcpy(ofpact_put_SET_ETH_DST(out
)->mac
,
374 ((const struct ofp_action_dl_addr
*) a
)->dl_addr
, ETH_ADDR_LEN
);
377 case OFPUTIL_OFPAT10_SET_NW_SRC
:
378 ofpact_put_SET_IPV4_SRC(out
)->ipv4
= a
->nw_addr
.nw_addr
;
381 case OFPUTIL_OFPAT10_SET_NW_DST
:
382 ofpact_put_SET_IPV4_DST(out
)->ipv4
= a
->nw_addr
.nw_addr
;
385 case OFPUTIL_OFPAT10_SET_NW_TOS
:
386 if (a
->nw_tos
.nw_tos
& ~IP_DSCP_MASK
) {
387 return OFPERR_OFPBAC_BAD_ARGUMENT
;
389 ofpact_put_SET_IPV4_DSCP(out
)->dscp
= a
->nw_tos
.nw_tos
;
392 case OFPUTIL_OFPAT10_SET_TP_SRC
:
393 ofpact_put_SET_L4_SRC_PORT(out
)->port
= ntohs(a
->tp_port
.tp_port
);
396 case OFPUTIL_OFPAT10_SET_TP_DST
:
397 ofpact_put_SET_L4_DST_PORT(out
)->port
= ntohs(a
->tp_port
.tp_port
);
401 case OFPUTIL_OFPAT10_ENQUEUE
:
402 error
= enqueue_from_openflow10((const struct ofp_action_enqueue
*) a
,
406 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
407 #include "ofp-util.def"
408 return ofpact_from_nxast(a
, code
, out
);
414 static inline union ofp_action
*
415 action_next(const union ofp_action
*a
)
417 return ((union ofp_action
*) (void *)
418 ((uint8_t *) a
+ ntohs(a
->header
.len
)));
422 action_is_valid(const union ofp_action
*a
, size_t n_actions
)
424 uint16_t len
= ntohs(a
->header
.len
);
425 return (!(len
% OFP_ACTION_ALIGN
)
427 && len
/ sizeof *a
<= n_actions
);
430 /* This macro is careful to check for actions with bad lengths. */
431 #define ACTION_FOR_EACH(ITER, LEFT, ACTIONS, N_ACTIONS) \
432 for ((ITER) = (ACTIONS), (LEFT) = (N_ACTIONS); \
433 (LEFT) > 0 && action_is_valid(ITER, LEFT); \
434 ((LEFT) -= ntohs((ITER)->header.len) / sizeof(union ofp_action), \
435 (ITER) = action_next(ITER)))
438 ofpacts_from_openflow10(const union ofp_action
*in
, size_t n_in
,
441 const union ofp_action
*a
;
444 ACTION_FOR_EACH (a
, left
, in
, n_in
) {
445 enum ofperr error
= ofpact_from_openflow10(a
, out
);
447 VLOG_WARN_RL(&rl
, "bad action at offset %td (%s)",
448 (a
- in
) * sizeof *a
, ofperr_get_name(error
));
453 if (!VLOG_DROP_WARN(&rl
)) {
457 ds_put_hex_dump(&s
, in
, n_in
* sizeof *a
, 0, false);
458 VLOG_WARN("bad action format at offset %#x:\n%s",
459 (n_in
- left
) * sizeof *a
, ds_cstr(&s
));
462 return OFPERR_OFPBAC_BAD_LEN
;
470 ofpacts_pull_actions(struct ofpbuf
*openflow
, unsigned int actions_len
,
471 struct ofpbuf
*ofpacts
,
472 enum ofperr (*translate
)(const union ofp_action
*actions
,
474 struct ofpbuf
*ofpacts
))
476 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
477 const union ofp_action
*actions
;
480 ofpbuf_clear(ofpacts
);
482 if (actions_len
% OFP_ACTION_ALIGN
!= 0) {
483 VLOG_WARN_RL(&rl
, "OpenFlow message actions length %u is not a "
484 "multiple of %d", actions_len
, OFP_ACTION_ALIGN
);
485 return OFPERR_OFPBRC_BAD_LEN
;
488 actions
= ofpbuf_try_pull(openflow
, actions_len
);
489 if (actions
== NULL
) {
490 VLOG_WARN_RL(&rl
, "OpenFlow message actions length %u exceeds "
491 "remaining message length (%zu)",
492 actions_len
, openflow
->size
);
493 return OFPERR_OFPBRC_BAD_LEN
;
496 error
= translate(actions
, actions_len
/ OFP_ACTION_ALIGN
, ofpacts
);
498 ofpbuf_clear(ofpacts
);
503 /* Attempts to convert 'actions_len' bytes of OpenFlow 1.0 actions from the
504 * front of 'openflow' into ofpacts. On success, replaces any existing content
505 * in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'.
506 * Returns 0 if successful, otherwise an OpenFlow error.
508 * This function does not check that the actions are valid in a given context.
509 * The caller should do so, with ofpacts_check(). */
511 ofpacts_pull_openflow10(struct ofpbuf
*openflow
, unsigned int actions_len
,
512 struct ofpbuf
*ofpacts
)
514 return ofpacts_pull_actions(openflow
, actions_len
, ofpacts
,
515 ofpacts_from_openflow10
);
518 /* OpenFlow 1.1 actions. */
520 /* Parses 'a' to determine its type. On success stores the correct type into
521 * '*code' and returns 0. On failure returns an OFPERR_* error code and
522 * '*code' is indeterminate.
524 * The caller must have already verified that 'a''s length is potentially
525 * correct (that is, a->header.len is nonzero and a multiple of sizeof(union
526 * ofp_action) and no longer than the amount of space allocated to 'a').
528 * This function verifies that 'a''s length is correct for the type of action
529 * that it represents. */
531 decode_openflow11_action(const union ofp_action
*a
,
532 enum ofputil_action_code
*code
)
535 case CONSTANT_HTONS(OFPAT11_EXPERIMENTER
):
536 return decode_nxast_action(a
, code
);
538 #define OFPAT11_ACTION(ENUM, STRUCT, NAME) \
539 case CONSTANT_HTONS(ENUM): \
540 if (a->header.len == htons(sizeof(struct STRUCT))) { \
541 *code = OFPUTIL_##ENUM; \
544 return OFPERR_OFPBAC_BAD_LEN; \
547 #include "ofp-util.def"
550 return OFPERR_OFPBAC_BAD_TYPE
;
555 output_from_openflow11(const struct ofp11_action_output
*oao
,
558 struct ofpact_output
*output
;
561 output
= ofpact_put_OUTPUT(out
);
562 output
->max_len
= ntohs(oao
->max_len
);
564 error
= ofputil_port_from_ofp11(oao
->port
, &output
->port
);
569 return ofputil_check_output_port(output
->port
, OFPP_MAX
);
573 ofpact_from_openflow11(const union ofp_action
*a
, struct ofpbuf
*out
)
575 enum ofputil_action_code code
;
578 error
= decode_openflow11_action(a
, &code
);
584 case OFPUTIL_ACTION_INVALID
:
585 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
586 #include "ofp-util.def"
589 case OFPUTIL_OFPAT11_OUTPUT
:
590 return output_from_openflow11((const struct ofp11_action_output
*) a
,
593 case OFPUTIL_OFPAT11_SET_VLAN_VID
:
594 if (a
->vlan_vid
.vlan_vid
& ~htons(0xfff)) {
595 return OFPERR_OFPBAC_BAD_ARGUMENT
;
597 ofpact_put_SET_VLAN_VID(out
)->vlan_vid
= ntohs(a
->vlan_vid
.vlan_vid
);
600 case OFPUTIL_OFPAT11_SET_VLAN_PCP
:
601 if (a
->vlan_pcp
.vlan_pcp
& ~7) {
602 return OFPERR_OFPBAC_BAD_ARGUMENT
;
604 ofpact_put_SET_VLAN_PCP(out
)->vlan_pcp
= a
->vlan_pcp
.vlan_pcp
;
607 case OFPUTIL_OFPAT11_SET_DL_SRC
:
608 memcpy(ofpact_put_SET_ETH_SRC(out
)->mac
,
609 ((const struct ofp_action_dl_addr
*) a
)->dl_addr
, ETH_ADDR_LEN
);
612 case OFPUTIL_OFPAT11_SET_DL_DST
:
613 memcpy(ofpact_put_SET_ETH_DST(out
)->mac
,
614 ((const struct ofp_action_dl_addr
*) a
)->dl_addr
, ETH_ADDR_LEN
);
617 case OFPUTIL_OFPAT11_SET_NW_SRC
:
618 ofpact_put_SET_IPV4_SRC(out
)->ipv4
= a
->nw_addr
.nw_addr
;
621 case OFPUTIL_OFPAT11_SET_NW_DST
:
622 ofpact_put_SET_IPV4_DST(out
)->ipv4
= a
->nw_addr
.nw_addr
;
625 case OFPUTIL_OFPAT11_SET_NW_TOS
:
626 if (a
->nw_tos
.nw_tos
& ~IP_DSCP_MASK
) {
627 return OFPERR_OFPBAC_BAD_ARGUMENT
;
629 ofpact_put_SET_IPV4_DSCP(out
)->dscp
= a
->nw_tos
.nw_tos
;
632 case OFPUTIL_OFPAT11_SET_TP_SRC
:
633 ofpact_put_SET_L4_SRC_PORT(out
)->port
= ntohs(a
->tp_port
.tp_port
);
636 case OFPUTIL_OFPAT11_SET_TP_DST
:
637 ofpact_put_SET_L4_DST_PORT(out
)->port
= ntohs(a
->tp_port
.tp_port
);
640 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
641 #include "ofp-util.def"
642 return ofpact_from_nxast(a
, code
, out
);
649 ofpacts_from_openflow11(const union ofp_action
*in
, size_t n_in
,
652 const union ofp_action
*a
;
655 ACTION_FOR_EACH (a
, left
, in
, n_in
) {
656 enum ofperr error
= ofpact_from_openflow11(a
, out
);
658 VLOG_WARN_RL(&rl
, "bad action at offset %td (%s)",
659 (a
- in
) * sizeof *a
, ofperr_get_name(error
));
664 VLOG_WARN_RL(&rl
, "bad action format at offset %zu",
665 (n_in
- left
) * sizeof *a
);
666 return OFPERR_OFPBAC_BAD_LEN
;
672 /* OpenFlow 1.1 instructions. */
674 #define OVS_INSTRUCTIONS \
675 DEFINE_INST(OFPIT11_GOTO_TABLE, \
676 ofp11_instruction_goto_table, false, \
679 DEFINE_INST(OFPIT11_WRITE_METADATA, \
680 ofp11_instruction_write_metadata, false, \
683 DEFINE_INST(OFPIT11_WRITE_ACTIONS, \
684 ofp11_instruction_actions, true, \
687 DEFINE_INST(OFPIT11_APPLY_ACTIONS, \
688 ofp11_instruction_actions, true, \
691 DEFINE_INST(OFPIT11_CLEAR_ACTIONS, \
692 ofp11_instruction, false, \
695 enum ovs_instruction_type
{
696 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) OVSINST_##ENUM,
702 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
703 N_OVS_INSTRUCTIONS
= OVS_INSTRUCTIONS
707 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
709 instruction_init_##ENUM(struct STRUCT *s) \
711 memset(s, 0, sizeof *s); \
712 s->type = htons(ENUM); \
713 s->len = htons(sizeof *s); \
716 static inline struct STRUCT * \
717 instruction_put_##ENUM(struct ofpbuf *buf) \
719 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
720 instruction_init_##ENUM(s); \
726 static inline struct ofp11_instruction
*
727 instruction_next(const struct ofp11_instruction
*inst
)
729 return ((struct ofp11_instruction
*) (void *)
730 ((uint8_t *) inst
+ ntohs(inst
->len
)));
734 instruction_is_valid(const struct ofp11_instruction
*inst
,
735 size_t n_instructions
)
737 uint16_t len
= ntohs(inst
->len
);
738 return (!(len
% OFP11_INSTRUCTION_ALIGN
)
739 && len
>= sizeof *inst
740 && len
/ sizeof *inst
<= n_instructions
);
743 /* This macro is careful to check for instructions with bad lengths. */
744 #define INSTRUCTION_FOR_EACH(ITER, LEFT, INSTRUCTIONS, N_INSTRUCTIONS) \
745 for ((ITER) = (INSTRUCTIONS), (LEFT) = (N_INSTRUCTIONS); \
746 (LEFT) > 0 && instruction_is_valid(ITER, LEFT); \
747 ((LEFT) -= (ntohs((ITER)->len) \
748 / sizeof(struct ofp11_instruction)), \
749 (ITER) = instruction_next(ITER)))
752 decode_openflow11_instruction(const struct ofp11_instruction
*inst
,
753 enum ovs_instruction_type
*type
)
755 uint16_t len
= ntohs(inst
->len
);
757 switch (inst
->type
) {
758 case CONSTANT_HTONS(OFPIT11_EXPERIMENTER
):
759 return OFPERR_OFPBIC_BAD_EXPERIMENTER
;
761 #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
762 case CONSTANT_HTONS(ENUM): \
764 ? len >= sizeof(struct STRUCT) \
765 : len == sizeof(struct STRUCT)) { \
766 *type = OVSINST_##ENUM; \
769 return OFPERR_OFPBIC_BAD_LEN; \
775 return OFPERR_OFPBIC_UNKNOWN_INST
;
780 decode_openflow11_instructions(const struct ofp11_instruction insts
[],
782 const struct ofp11_instruction
*out
[])
784 const struct ofp11_instruction
*inst
;
787 memset(out
, 0, N_OVS_INSTRUCTIONS
* sizeof *out
);
788 INSTRUCTION_FOR_EACH (inst
, left
, insts
, n_insts
) {
789 enum ovs_instruction_type type
;
792 error
= decode_openflow11_instruction(inst
, &type
);
798 return OFPERR_NXBIC_DUP_TYPE
;
804 VLOG_WARN_RL(&rl
, "bad instruction format at offset %zu",
805 (n_insts
- left
) * sizeof *inst
);
806 return OFPERR_OFPBIC_BAD_LEN
;
812 get_actions_from_instruction(const struct ofp11_instruction
*inst
,
813 const union ofp_action
**actions
,
816 *actions
= (const union ofp_action
*) (inst
+ 1);
817 *n_actions
= (ntohs(inst
->len
) - sizeof *inst
) / OFP11_INSTRUCTION_ALIGN
;
820 /* Attempts to convert 'actions_len' bytes of OpenFlow 1.1 actions from the
821 * front of 'openflow' into ofpacts. On success, replaces any existing content
822 * in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'.
823 * Returns 0 if successful, otherwise an OpenFlow error.
825 * In most places in OpenFlow 1.1 and 1.2, actions appear encapsulated in
826 * instructions, so you should call ofpacts_pull_openflow11_instructions()
827 * instead of this function.
829 * This function does not check that the actions are valid in a given context.
830 * The caller should do so, with ofpacts_check(). */
832 ofpacts_pull_openflow11_actions(struct ofpbuf
*openflow
,
833 unsigned int actions_len
,
834 struct ofpbuf
*ofpacts
)
838 error
= ofpacts_pull_actions(openflow
, actions_len
, ofpacts
,
839 ofpacts_from_openflow11
);
847 ofpacts_pull_openflow11_instructions(struct ofpbuf
*openflow
,
848 unsigned int instructions_len
,
849 struct ofpbuf
*ofpacts
)
851 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
852 const struct ofp11_instruction
*instructions
;
853 const struct ofp11_instruction
*insts
[N_OVS_INSTRUCTIONS
];
856 ofpbuf_clear(ofpacts
);
858 if (instructions_len
% OFP11_INSTRUCTION_ALIGN
!= 0) {
859 VLOG_WARN_RL(&rl
, "OpenFlow message instructions length %u is not a "
861 instructions_len
, OFP11_INSTRUCTION_ALIGN
);
862 error
= OFPERR_OFPBIC_BAD_LEN
;
866 instructions
= ofpbuf_try_pull(openflow
, instructions_len
);
867 if (instructions
== NULL
) {
868 VLOG_WARN_RL(&rl
, "OpenFlow message instructions length %u exceeds "
869 "remaining message length (%zu)",
870 instructions_len
, openflow
->size
);
871 error
= OFPERR_OFPBIC_BAD_LEN
;
875 error
= decode_openflow11_instructions(
876 instructions
, instructions_len
/ OFP11_INSTRUCTION_ALIGN
,
882 if (insts
[OVSINST_OFPIT11_APPLY_ACTIONS
]) {
883 const union ofp_action
*actions
;
886 get_actions_from_instruction(insts
[OVSINST_OFPIT11_APPLY_ACTIONS
],
887 &actions
, &n_actions
);
888 error
= ofpacts_from_openflow11(actions
, n_actions
, ofpacts
);
896 if (insts
[OVSINST_OFPIT11_GOTO_TABLE
] ||
897 insts
[OVSINST_OFPIT11_WRITE_METADATA
] ||
898 insts
[OVSINST_OFPIT11_WRITE_ACTIONS
] ||
899 insts
[OVSINST_OFPIT11_CLEAR_ACTIONS
]) {
900 error
= OFPERR_OFPBIC_UNSUP_INST
;
906 ofpbuf_clear(ofpacts
);
912 ofpact_check__(const struct ofpact
*a
, const struct flow
*flow
, int max_ports
)
914 const struct ofpact_enqueue
*enqueue
;
918 return ofputil_check_output_port(ofpact_get_OUTPUT(a
)->port
,
921 case OFPACT_CONTROLLER
:
925 enqueue
= ofpact_get_ENQUEUE(a
);
926 if (enqueue
->port
>= max_ports
&& enqueue
->port
!= OFPP_IN_PORT
927 && enqueue
->port
!= OFPP_LOCAL
) {
928 return OFPERR_OFPBAC_BAD_OUT_PORT
;
932 case OFPACT_OUTPUT_REG
:
933 return mf_check_src(&ofpact_get_OUTPUT_REG(a
)->src
, flow
);
936 return bundle_check(ofpact_get_BUNDLE(a
), max_ports
, flow
);
938 case OFPACT_SET_VLAN_VID
:
939 case OFPACT_SET_VLAN_PCP
:
940 case OFPACT_STRIP_VLAN
:
941 case OFPACT_SET_ETH_SRC
:
942 case OFPACT_SET_ETH_DST
:
943 case OFPACT_SET_IPV4_SRC
:
944 case OFPACT_SET_IPV4_DST
:
945 case OFPACT_SET_IPV4_DSCP
:
946 case OFPACT_SET_L4_SRC_PORT
:
947 case OFPACT_SET_L4_DST_PORT
:
950 case OFPACT_REG_MOVE
:
951 return nxm_reg_move_check(ofpact_get_REG_MOVE(a
), flow
);
953 case OFPACT_REG_LOAD
:
954 return nxm_reg_load_check(ofpact_get_REG_LOAD(a
), flow
);
957 case OFPACT_SET_TUNNEL
:
958 case OFPACT_SET_QUEUE
:
959 case OFPACT_POP_QUEUE
:
960 case OFPACT_FIN_TIMEOUT
:
961 case OFPACT_RESUBMIT
:
965 return learn_check(ofpact_get_LEARN(a
), flow
);
967 case OFPACT_MULTIPATH
:
968 return multipath_check(ofpact_get_MULTIPATH(a
), flow
);
970 case OFPACT_AUTOPATH
:
971 return autopath_check(ofpact_get_AUTOPATH(a
), flow
);
982 /* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are
983 * appropriate for a packet with the prerequisites satisfied by 'flow' in a
984 * switch with no more than 'max_ports' ports. */
986 ofpacts_check(const struct ofpact ofpacts
[], size_t ofpacts_len
,
987 const struct flow
*flow
, int max_ports
)
989 const struct ofpact
*a
;
991 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
992 enum ofperr error
= ofpact_check__(a
, flow
, max_ports
);
1001 /* Converting ofpacts to Nicira OpenFlow extensions. */
1004 ofpact_output_reg_to_nxast(const struct ofpact_output_reg
*output_reg
,
1007 struct nx_action_output_reg
*naor
= ofputil_put_NXAST_OUTPUT_REG(out
);
1009 naor
->ofs_nbits
= nxm_encode_ofs_nbits(output_reg
->src
.ofs
,
1010 output_reg
->src
.n_bits
);
1011 naor
->src
= htonl(output_reg
->src
.field
->nxm_header
);
1012 naor
->max_len
= htons(output_reg
->max_len
);
1016 ofpact_resubmit_to_nxast(const struct ofpact_resubmit
*resubmit
,
1019 struct nx_action_resubmit
*nar
;
1021 if (resubmit
->table_id
== 0xff
1022 && resubmit
->ofpact
.compat
!= OFPUTIL_NXAST_RESUBMIT_TABLE
) {
1023 nar
= ofputil_put_NXAST_RESUBMIT(out
);
1025 nar
= ofputil_put_NXAST_RESUBMIT_TABLE(out
);
1026 nar
->table
= resubmit
->table_id
;
1028 nar
->in_port
= htons(resubmit
->in_port
);
1032 ofpact_set_tunnel_to_nxast(const struct ofpact_tunnel
*tunnel
,
1035 uint64_t tun_id
= tunnel
->tun_id
;
1037 if (tun_id
<= UINT32_MAX
1038 && tunnel
->ofpact
.compat
!= OFPUTIL_NXAST_SET_TUNNEL64
) {
1039 ofputil_put_NXAST_SET_TUNNEL(out
)->tun_id
= htonl(tun_id
);
1041 ofputil_put_NXAST_SET_TUNNEL64(out
)->tun_id
= htonll(tun_id
);
1046 ofpact_note_to_nxast(const struct ofpact_note
*note
, struct ofpbuf
*out
)
1048 size_t start_ofs
= out
->size
;
1049 struct nx_action_note
*nan
;
1050 unsigned int remainder
;
1053 nan
= ofputil_put_NXAST_NOTE(out
);
1054 out
->size
-= sizeof nan
->note
;
1056 ofpbuf_put(out
, note
->data
, note
->length
);
1058 len
= out
->size
- start_ofs
;
1059 remainder
= len
% OFP_ACTION_ALIGN
;
1061 ofpbuf_put_zeros(out
, OFP_ACTION_ALIGN
- remainder
);
1063 nan
= (struct nx_action_note
*)((char *)out
->data
+ start_ofs
);
1064 nan
->len
= htons(out
->size
- start_ofs
);
1068 ofpact_controller_to_nxast(const struct ofpact_controller
*oc
,
1071 struct nx_action_controller
*nac
;
1073 nac
= ofputil_put_NXAST_CONTROLLER(out
);
1074 nac
->max_len
= htons(oc
->max_len
);
1075 nac
->controller_id
= htons(oc
->controller_id
);
1076 nac
->reason
= oc
->reason
;
1080 ofpact_fin_timeout_to_nxast(const struct ofpact_fin_timeout
*fin_timeout
,
1083 struct nx_action_fin_timeout
*naft
= ofputil_put_NXAST_FIN_TIMEOUT(out
);
1084 naft
->fin_idle_timeout
= htons(fin_timeout
->fin_idle_timeout
);
1085 naft
->fin_hard_timeout
= htons(fin_timeout
->fin_hard_timeout
);
1089 ofpact_to_nxast(const struct ofpact
*a
, struct ofpbuf
*out
)
1092 case OFPACT_CONTROLLER
:
1093 ofpact_controller_to_nxast(ofpact_get_CONTROLLER(a
), out
);
1096 case OFPACT_OUTPUT_REG
:
1097 ofpact_output_reg_to_nxast(ofpact_get_OUTPUT_REG(a
), out
);
1101 bundle_to_nxast(ofpact_get_BUNDLE(a
), out
);
1104 case OFPACT_REG_MOVE
:
1105 nxm_reg_move_to_nxast(ofpact_get_REG_MOVE(a
), out
);
1108 case OFPACT_REG_LOAD
:
1109 nxm_reg_load_to_nxast(ofpact_get_REG_LOAD(a
), out
);
1112 case OFPACT_DEC_TTL
:
1113 ofputil_put_NXAST_DEC_TTL(out
);
1116 case OFPACT_SET_TUNNEL
:
1117 ofpact_set_tunnel_to_nxast(ofpact_get_SET_TUNNEL(a
), out
);
1120 case OFPACT_SET_QUEUE
:
1121 ofputil_put_NXAST_SET_QUEUE(out
)->queue_id
1122 = htonl(ofpact_get_SET_QUEUE(a
)->queue_id
);
1125 case OFPACT_POP_QUEUE
:
1126 ofputil_put_NXAST_POP_QUEUE(out
);
1129 case OFPACT_FIN_TIMEOUT
:
1130 ofpact_fin_timeout_to_nxast(ofpact_get_FIN_TIMEOUT(a
), out
);
1133 case OFPACT_RESUBMIT
:
1134 ofpact_resubmit_to_nxast(ofpact_get_RESUBMIT(a
), out
);
1138 learn_to_nxast(ofpact_get_LEARN(a
), out
);
1141 case OFPACT_MULTIPATH
:
1142 multipath_to_nxast(ofpact_get_MULTIPATH(a
), out
);
1145 case OFPACT_AUTOPATH
:
1146 autopath_to_nxast(ofpact_get_AUTOPATH(a
), out
);
1150 ofpact_note_to_nxast(ofpact_get_NOTE(a
), out
);
1154 ofputil_put_NXAST_EXIT(out
);
1158 case OFPACT_ENQUEUE
:
1159 case OFPACT_SET_VLAN_VID
:
1160 case OFPACT_SET_VLAN_PCP
:
1161 case OFPACT_STRIP_VLAN
:
1162 case OFPACT_SET_ETH_SRC
:
1163 case OFPACT_SET_ETH_DST
:
1164 case OFPACT_SET_IPV4_SRC
:
1165 case OFPACT_SET_IPV4_DST
:
1166 case OFPACT_SET_IPV4_DSCP
:
1167 case OFPACT_SET_L4_SRC_PORT
:
1168 case OFPACT_SET_L4_DST_PORT
:
1173 /* Converting ofpacts to OpenFlow 1.0. */
1176 ofpact_output_to_openflow10(const struct ofpact_output
*output
,
1179 struct ofp10_action_output
*oao
;
1181 oao
= ofputil_put_OFPAT10_OUTPUT(out
);
1182 oao
->port
= htons(output
->port
);
1183 oao
->max_len
= htons(output
->max_len
);
1187 ofpact_enqueue_to_openflow10(const struct ofpact_enqueue
*enqueue
,
1190 struct ofp_action_enqueue
*oae
;
1192 oae
= ofputil_put_OFPAT10_ENQUEUE(out
);
1193 oae
->port
= htons(enqueue
->port
);
1194 oae
->queue_id
= htonl(enqueue
->queue
);
1198 ofpact_to_openflow10(const struct ofpact
*a
, struct ofpbuf
*out
)
1202 ofpact_output_to_openflow10(ofpact_get_OUTPUT(a
), out
);
1205 case OFPACT_ENQUEUE
:
1206 ofpact_enqueue_to_openflow10(ofpact_get_ENQUEUE(a
), out
);
1209 case OFPACT_SET_VLAN_VID
:
1210 ofputil_put_OFPAT10_SET_VLAN_VID(out
)->vlan_vid
1211 = htons(ofpact_get_SET_VLAN_VID(a
)->vlan_vid
);
1214 case OFPACT_SET_VLAN_PCP
:
1215 ofputil_put_OFPAT10_SET_VLAN_PCP(out
)->vlan_pcp
1216 = ofpact_get_SET_VLAN_PCP(a
)->vlan_pcp
;
1219 case OFPACT_STRIP_VLAN
:
1220 ofputil_put_OFPAT10_STRIP_VLAN(out
);
1223 case OFPACT_SET_ETH_SRC
:
1224 memcpy(ofputil_put_OFPAT10_SET_DL_SRC(out
)->dl_addr
,
1225 ofpact_get_SET_ETH_SRC(a
)->mac
, ETH_ADDR_LEN
);
1228 case OFPACT_SET_ETH_DST
:
1229 memcpy(ofputil_put_OFPAT10_SET_DL_DST(out
)->dl_addr
,
1230 ofpact_get_SET_ETH_DST(a
)->mac
, ETH_ADDR_LEN
);
1233 case OFPACT_SET_IPV4_SRC
:
1234 ofputil_put_OFPAT10_SET_NW_SRC(out
)->nw_addr
1235 = ofpact_get_SET_IPV4_SRC(a
)->ipv4
;
1238 case OFPACT_SET_IPV4_DST
:
1239 ofputil_put_OFPAT10_SET_NW_DST(out
)->nw_addr
1240 = ofpact_get_SET_IPV4_DST(a
)->ipv4
;
1243 case OFPACT_SET_IPV4_DSCP
:
1244 ofputil_put_OFPAT10_SET_NW_TOS(out
)->nw_tos
1245 = ofpact_get_SET_IPV4_DSCP(a
)->dscp
;
1248 case OFPACT_SET_L4_SRC_PORT
:
1249 ofputil_put_OFPAT10_SET_TP_SRC(out
)->tp_port
1250 = htons(ofpact_get_SET_L4_SRC_PORT(a
)->port
);
1253 case OFPACT_SET_L4_DST_PORT
:
1254 ofputil_put_OFPAT10_SET_TP_DST(out
)->tp_port
1255 = htons(ofpact_get_SET_L4_DST_PORT(a
)->port
);
1258 case OFPACT_CONTROLLER
:
1259 case OFPACT_OUTPUT_REG
:
1261 case OFPACT_REG_MOVE
:
1262 case OFPACT_REG_LOAD
:
1263 case OFPACT_DEC_TTL
:
1264 case OFPACT_SET_TUNNEL
:
1265 case OFPACT_SET_QUEUE
:
1266 case OFPACT_POP_QUEUE
:
1267 case OFPACT_FIN_TIMEOUT
:
1268 case OFPACT_RESUBMIT
:
1270 case OFPACT_MULTIPATH
:
1271 case OFPACT_AUTOPATH
:
1274 ofpact_to_nxast(a
, out
);
1279 /* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow 1.0
1280 * actions in 'openflow', appending the actions to any existing data in
1283 ofpacts_put_openflow10(const struct ofpact ofpacts
[], size_t ofpacts_len
,
1284 struct ofpbuf
*openflow
)
1286 const struct ofpact
*a
;
1288 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
1289 ofpact_to_openflow10(a
, openflow
);
1293 /* Converting ofpacts to OpenFlow 1.1. */
1296 ofpact_output_to_openflow11(const struct ofpact_output
*output
,
1299 struct ofp11_action_output
*oao
;
1301 oao
= ofputil_put_OFPAT11_OUTPUT(out
);
1302 oao
->port
= ofputil_port_to_ofp11(output
->port
);
1303 oao
->max_len
= htons(output
->max_len
);
1307 ofpact_to_openflow11(const struct ofpact
*a
, struct ofpbuf
*out
)
1311 return ofpact_output_to_openflow11(ofpact_get_OUTPUT(a
), out
);
1313 case OFPACT_ENQUEUE
:
1317 case OFPACT_SET_VLAN_VID
:
1318 ofputil_put_OFPAT11_SET_VLAN_VID(out
)->vlan_vid
1319 = htons(ofpact_get_SET_VLAN_VID(a
)->vlan_vid
);
1322 case OFPACT_SET_VLAN_PCP
:
1323 ofputil_put_OFPAT11_SET_VLAN_PCP(out
)->vlan_pcp
1324 = ofpact_get_SET_VLAN_PCP(a
)->vlan_pcp
;
1327 case OFPACT_STRIP_VLAN
:
1331 case OFPACT_SET_ETH_SRC
:
1332 memcpy(ofputil_put_OFPAT11_SET_DL_SRC(out
)->dl_addr
,
1333 ofpact_get_SET_ETH_SRC(a
)->mac
, ETH_ADDR_LEN
);
1336 case OFPACT_SET_ETH_DST
:
1337 memcpy(ofputil_put_OFPAT11_SET_DL_DST(out
)->dl_addr
,
1338 ofpact_get_SET_ETH_DST(a
)->mac
, ETH_ADDR_LEN
);
1341 case OFPACT_SET_IPV4_SRC
:
1342 ofputil_put_OFPAT11_SET_NW_SRC(out
)->nw_addr
1343 = ofpact_get_SET_IPV4_SRC(a
)->ipv4
;
1346 case OFPACT_SET_IPV4_DST
:
1347 ofputil_put_OFPAT11_SET_NW_DST(out
)->nw_addr
1348 = ofpact_get_SET_IPV4_DST(a
)->ipv4
;
1351 case OFPACT_SET_IPV4_DSCP
:
1352 ofputil_put_OFPAT11_SET_NW_TOS(out
)->nw_tos
1353 = ofpact_get_SET_IPV4_DSCP(a
)->dscp
;
1356 case OFPACT_SET_L4_SRC_PORT
:
1357 ofputil_put_OFPAT11_SET_TP_SRC(out
)->tp_port
1358 = htons(ofpact_get_SET_L4_SRC_PORT(a
)->port
);
1361 case OFPACT_SET_L4_DST_PORT
:
1362 ofputil_put_OFPAT11_SET_TP_DST(out
)->tp_port
1363 = htons(ofpact_get_SET_L4_DST_PORT(a
)->port
);
1366 case OFPACT_CONTROLLER
:
1367 case OFPACT_OUTPUT_REG
:
1369 case OFPACT_REG_MOVE
:
1370 case OFPACT_REG_LOAD
:
1371 case OFPACT_DEC_TTL
:
1372 case OFPACT_SET_TUNNEL
:
1373 case OFPACT_SET_QUEUE
:
1374 case OFPACT_POP_QUEUE
:
1375 case OFPACT_FIN_TIMEOUT
:
1376 case OFPACT_RESUBMIT
:
1378 case OFPACT_MULTIPATH
:
1379 case OFPACT_AUTOPATH
:
1382 ofpact_to_nxast(a
, out
);
1387 /* Converts the ofpacts in 'ofpacts' (terminated by OFPACT_END) into OpenFlow
1388 * 1.1 actions in 'openflow', appending the actions to any existing data in
1391 ofpacts_put_openflow11_actions(const struct ofpact ofpacts
[],
1392 size_t ofpacts_len
, struct ofpbuf
*openflow
)
1394 const struct ofpact
*a
;
1396 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
1397 ofpact_to_openflow11(a
, openflow
);
1402 ofpacts_put_openflow11_instructions(const struct ofpact ofpacts
[],
1404 struct ofpbuf
*openflow
)
1406 struct ofp11_instruction_actions
*oia
;
1409 /* Put an OFPIT11_APPLY_ACTIONS instruction and fill it in. */
1410 ofs
= openflow
->size
;
1411 instruction_put_OFPIT11_APPLY_ACTIONS(openflow
);
1412 ofpacts_put_openflow11_actions(ofpacts
, ofpacts_len
, openflow
);
1414 /* Update the instruction's length (or, if it's empty, delete it). */
1415 oia
= ofpbuf_at_assert(openflow
, ofs
, sizeof *oia
);
1416 if (openflow
->size
> ofs
+ sizeof *oia
) {
1417 oia
->len
= htons(openflow
->size
- ofs
);
1419 openflow
->size
= ofs
;
1423 /* Returns true if 'action' outputs to 'port', false otherwise. */
1425 ofpact_outputs_to_port(const struct ofpact
*ofpact
, uint16_t port
)
1427 switch (ofpact
->type
) {
1429 return ofpact_get_OUTPUT(ofpact
)->port
== port
;
1430 case OFPACT_ENQUEUE
:
1431 return ofpact_get_ENQUEUE(ofpact
)->port
== port
;
1432 case OFPACT_CONTROLLER
:
1433 return port
== OFPP_CONTROLLER
;
1435 case OFPACT_OUTPUT_REG
:
1437 case OFPACT_SET_VLAN_VID
:
1438 case OFPACT_SET_VLAN_PCP
:
1439 case OFPACT_STRIP_VLAN
:
1440 case OFPACT_SET_ETH_SRC
:
1441 case OFPACT_SET_ETH_DST
:
1442 case OFPACT_SET_IPV4_SRC
:
1443 case OFPACT_SET_IPV4_DST
:
1444 case OFPACT_SET_IPV4_DSCP
:
1445 case OFPACT_SET_L4_SRC_PORT
:
1446 case OFPACT_SET_L4_DST_PORT
:
1447 case OFPACT_REG_MOVE
:
1448 case OFPACT_REG_LOAD
:
1449 case OFPACT_DEC_TTL
:
1450 case OFPACT_SET_TUNNEL
:
1451 case OFPACT_SET_QUEUE
:
1452 case OFPACT_POP_QUEUE
:
1453 case OFPACT_FIN_TIMEOUT
:
1454 case OFPACT_RESUBMIT
:
1456 case OFPACT_MULTIPATH
:
1457 case OFPACT_AUTOPATH
:
1465 /* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
1466 * to 'port', false otherwise. */
1468 ofpacts_output_to_port(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
1471 const struct ofpact
*a
;
1473 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
1474 if (ofpact_outputs_to_port(a
, port
)) {
1483 ofpacts_equal(const struct ofpact
*a
, size_t a_len
,
1484 const struct ofpact
*b
, size_t b_len
)
1486 return a_len
== b_len
&& !memcmp(a
, b
, a_len
);
1489 /* Formatting ofpacts. */
1492 print_note(const struct ofpact_note
*note
, struct ds
*string
)
1496 ds_put_cstr(string
, "note:");
1497 for (i
= 0; i
< note
->length
; i
++) {
1499 ds_put_char(string
, '.');
1501 ds_put_format(string
, "%02"PRIx8
, note
->data
[i
]);
1506 print_fin_timeout(const struct ofpact_fin_timeout
*fin_timeout
,
1509 ds_put_cstr(s
, "fin_timeout(");
1510 if (fin_timeout
->fin_idle_timeout
) {
1511 ds_put_format(s
, "idle_timeout=%"PRIu16
",",
1512 fin_timeout
->fin_idle_timeout
);
1514 if (fin_timeout
->fin_hard_timeout
) {
1515 ds_put_format(s
, "hard_timeout=%"PRIu16
",",
1516 fin_timeout
->fin_hard_timeout
);
1519 ds_put_char(s
, ')');
1523 ofpact_format(const struct ofpact
*a
, struct ds
*s
)
1525 const struct ofpact_enqueue
*enqueue
;
1526 const struct ofpact_resubmit
*resubmit
;
1527 const struct ofpact_autopath
*autopath
;
1528 const struct ofpact_controller
*controller
;
1529 const struct ofpact_tunnel
*tunnel
;
1534 port
= ofpact_get_OUTPUT(a
)->port
;
1535 if (port
< OFPP_MAX
) {
1536 ds_put_format(s
, "output:%"PRIu16
, port
);
1538 ofputil_format_port(port
, s
);
1539 if (port
== OFPP_CONTROLLER
) {
1540 ds_put_format(s
, ":%"PRIu16
, ofpact_get_OUTPUT(a
)->max_len
);
1545 case OFPACT_CONTROLLER
:
1546 controller
= ofpact_get_CONTROLLER(a
);
1547 if (controller
->reason
== OFPR_ACTION
&&
1548 controller
->controller_id
== 0) {
1549 ds_put_format(s
, "CONTROLLER:%"PRIu16
,
1550 ofpact_get_CONTROLLER(a
)->max_len
);
1552 enum ofp_packet_in_reason reason
= controller
->reason
;
1554 ds_put_cstr(s
, "controller(");
1555 if (reason
!= OFPR_ACTION
) {
1556 ds_put_format(s
, "reason=%s,",
1557 ofputil_packet_in_reason_to_string(reason
));
1559 if (controller
->max_len
!= UINT16_MAX
) {
1560 ds_put_format(s
, "max_len=%"PRIu16
",", controller
->max_len
);
1562 if (controller
->controller_id
!= 0) {
1563 ds_put_format(s
, "id=%"PRIu16
",", controller
->controller_id
);
1566 ds_put_char(s
, ')');
1570 case OFPACT_ENQUEUE
:
1571 enqueue
= ofpact_get_ENQUEUE(a
);
1572 ds_put_format(s
, "enqueue:");
1573 ofputil_format_port(enqueue
->port
, s
);
1574 ds_put_format(s
, "q%"PRIu32
, enqueue
->queue
);
1577 case OFPACT_OUTPUT_REG
:
1578 ds_put_cstr(s
, "output:");
1579 mf_format_subfield(&ofpact_get_OUTPUT_REG(a
)->src
, s
);
1583 bundle_format(ofpact_get_BUNDLE(a
), s
);
1586 case OFPACT_SET_VLAN_VID
:
1587 ds_put_format(s
, "mod_vlan_vid:%"PRIu16
,
1588 ofpact_get_SET_VLAN_VID(a
)->vlan_vid
);
1591 case OFPACT_SET_VLAN_PCP
:
1592 ds_put_format(s
, "mod_vlan_pcp:%"PRIu8
,
1593 ofpact_get_SET_VLAN_PCP(a
)->vlan_pcp
);
1596 case OFPACT_STRIP_VLAN
:
1597 ds_put_cstr(s
, "strip_vlan");
1600 case OFPACT_SET_ETH_SRC
:
1601 ds_put_format(s
, "mod_dl_src:"ETH_ADDR_FMT
,
1602 ETH_ADDR_ARGS(ofpact_get_SET_ETH_SRC(a
)->mac
));
1605 case OFPACT_SET_ETH_DST
:
1606 ds_put_format(s
, "mod_dl_dst:"ETH_ADDR_FMT
,
1607 ETH_ADDR_ARGS(ofpact_get_SET_ETH_DST(a
)->mac
));
1610 case OFPACT_SET_IPV4_SRC
:
1611 ds_put_format(s
, "mod_nw_src:"IP_FMT
,
1612 IP_ARGS(&ofpact_get_SET_IPV4_SRC(a
)->ipv4
));
1615 case OFPACT_SET_IPV4_DST
:
1616 ds_put_format(s
, "mod_nw_dst:"IP_FMT
,
1617 IP_ARGS(&ofpact_get_SET_IPV4_DST(a
)->ipv4
));
1620 case OFPACT_SET_IPV4_DSCP
:
1621 ds_put_format(s
, "mod_nw_tos:%d", ofpact_get_SET_IPV4_DSCP(a
)->dscp
);
1624 case OFPACT_SET_L4_SRC_PORT
:
1625 ds_put_format(s
, "mod_tp_src:%d", ofpact_get_SET_L4_SRC_PORT(a
)->port
);
1628 case OFPACT_SET_L4_DST_PORT
:
1629 ds_put_format(s
, "mod_tp_dst:%d", ofpact_get_SET_L4_DST_PORT(a
)->port
);
1632 case OFPACT_REG_MOVE
:
1633 nxm_format_reg_move(ofpact_get_REG_MOVE(a
), s
);
1636 case OFPACT_REG_LOAD
:
1637 nxm_format_reg_load(ofpact_get_REG_LOAD(a
), s
);
1640 case OFPACT_DEC_TTL
:
1641 ds_put_cstr(s
, "dec_ttl");
1644 case OFPACT_SET_TUNNEL
:
1645 tunnel
= ofpact_get_SET_TUNNEL(a
);
1646 ds_put_format(s
, "set_tunnel%s:%#"PRIx64
,
1647 (tunnel
->tun_id
> UINT32_MAX
1648 || a
->compat
== OFPUTIL_NXAST_SET_TUNNEL64
? "64" : ""),
1652 case OFPACT_SET_QUEUE
:
1653 ds_put_format(s
, "set_queue:%"PRIu32
,
1654 ofpact_get_SET_QUEUE(a
)->queue_id
);
1657 case OFPACT_POP_QUEUE
:
1658 ds_put_cstr(s
, "pop_queue");
1661 case OFPACT_FIN_TIMEOUT
:
1662 print_fin_timeout(ofpact_get_FIN_TIMEOUT(a
), s
);
1665 case OFPACT_RESUBMIT
:
1666 resubmit
= ofpact_get_RESUBMIT(a
);
1667 if (resubmit
->in_port
!= OFPP_IN_PORT
&& resubmit
->table_id
== 255) {
1668 ds_put_format(s
, "resubmit:%"PRIu16
, resubmit
->in_port
);
1670 ds_put_format(s
, "resubmit(");
1671 if (resubmit
->in_port
!= OFPP_IN_PORT
) {
1672 ofputil_format_port(resubmit
->in_port
, s
);
1674 ds_put_char(s
, ',');
1675 if (resubmit
->table_id
!= 255) {
1676 ds_put_format(s
, "%"PRIu8
, resubmit
->table_id
);
1678 ds_put_char(s
, ')');
1683 learn_format(ofpact_get_LEARN(a
), s
);
1686 case OFPACT_MULTIPATH
:
1687 multipath_format(ofpact_get_MULTIPATH(a
), s
);
1690 case OFPACT_AUTOPATH
:
1691 autopath
= ofpact_get_AUTOPATH(a
);
1692 ds_put_format(s
, "autopath(%u,", autopath
->port
);
1693 mf_format_subfield(&autopath
->dst
, s
);
1694 ds_put_char(s
, ')');
1698 print_note(ofpact_get_NOTE(a
), s
);
1702 ds_put_cstr(s
, "exit");
1707 /* Appends a string representing the 'ofpacts_len' bytes of ofpacts in
1708 * 'ofpacts' to 'string'. */
1710 ofpacts_format(const struct ofpact
*ofpacts
, size_t ofpacts_len
,
1713 ds_put_cstr(string
, "actions=");
1715 ds_put_cstr(string
, "drop");
1717 const struct ofpact
*a
;
1719 OFPACT_FOR_EACH (a
, ofpacts
, ofpacts_len
) {
1721 ds_put_cstr(string
, ",");
1723 ofpact_format(a
, string
);
1728 /* Internal use by helpers. */
1731 ofpact_put(struct ofpbuf
*ofpacts
, enum ofpact_type type
, size_t len
)
1733 struct ofpact
*ofpact
;
1735 ofpact_pad(ofpacts
);
1736 ofpact
= ofpacts
->l2
= ofpbuf_put_uninit(ofpacts
, len
);
1737 ofpact_init(ofpact
, type
, len
);
1742 ofpact_init(struct ofpact
*ofpact
, enum ofpact_type type
, size_t len
)
1744 memset(ofpact
, 0, len
);
1745 ofpact
->type
= type
;
1746 ofpact
->compat
= OFPUTIL_ACTION_INVALID
;
1750 /* Updates 'ofpact->len' to the number of bytes in the tail of 'ofpacts'
1751 * starting at 'ofpact'.
1753 * This is the correct way to update a variable-length ofpact's length after
1754 * adding the variable-length part of the payload. (See the large comment
1755 * near the end of ofp-actions.h for more information.) */
1757 ofpact_update_len(struct ofpbuf
*ofpacts
, struct ofpact
*ofpact
)
1759 assert(ofpact
== ofpacts
->l2
);
1760 ofpact
->len
= (char *) ofpbuf_tail(ofpacts
) - (char *) ofpact
;
1763 /* Pads out 'ofpacts' to a multiple of OFPACT_ALIGNTO bytes in length. Each
1764 * ofpact_put_<ENUM>() calls this function automatically beforehand, but the
1765 * client must call this itself after adding the final ofpact to an array of
1768 * (The consequences of failing to call this function are probably not dire.
1769 * OFPACT_FOR_EACH will calculate a pointer beyond the end of the ofpacts, but
1770 * not dereference it. That's undefined behavior, technically, but it will not
1771 * cause a real problem on common systems. Still, it seems better to call
1774 ofpact_pad(struct ofpbuf
*ofpacts
)
1776 unsigned int rem
= ofpacts
->size
% OFPACT_ALIGNTO
;
1778 ofpbuf_put_zeros(ofpacts
, OFPACT_ALIGNTO
- rem
);