]> git.proxmox.com Git - mirror_ovs.git/blame - lib/ofp-actions.c
Restore all flow changes by compose_output_action__().
[mirror_ovs.git] / lib / ofp-actions.c
CommitLineData
f25d0cf3 1/*
6813ee7c 2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
f25d0cf3
BP
3 *
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:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#include <config.h>
18#include "ofp-actions.h"
f25d0cf3
BP
19#include "bundle.h"
20#include "byte-order.h"
21#include "compiler.h"
22#include "dynamic-string.h"
23#include "learn.h"
24#include "meta-flow.h"
25#include "multipath.h"
26#include "nx-match.h"
27#include "ofp-util.h"
28#include "ofpbuf.h"
cb22974d 29#include "util.h"
f25d0cf3
BP
30#include "vlog.h"
31
32VLOG_DEFINE_THIS_MODULE(ofp_actions);
33
34static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
35\f
36/* Converting OpenFlow 1.0 to ofpacts. */
37
38static enum ofperr
d01c980f 39output_from_openflow10(const struct ofp10_action_output *oao,
f25d0cf3
BP
40 struct ofpbuf *out)
41{
42 struct ofpact_output *output;
43
44 output = ofpact_put_OUTPUT(out);
45 output->port = ntohs(oao->port);
46 output->max_len = ntohs(oao->max_len);
47
48 return ofputil_check_output_port(output->port, OFPP_MAX);
49}
50
51static enum ofperr
31a9e63f 52enqueue_from_openflow10(const struct ofp10_action_enqueue *oae,
f25d0cf3
BP
53 struct ofpbuf *out)
54{
55 struct ofpact_enqueue *enqueue;
56
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;
63 }
64 return 0;
65}
66
67static void
68resubmit_from_openflow(const struct nx_action_resubmit *nar,
69 struct ofpbuf *out)
70{
71 struct ofpact_resubmit *resubmit;
72
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;
77}
78
79static enum ofperr
80resubmit_table_from_openflow(const struct nx_action_resubmit *nar,
81 struct ofpbuf *out)
82{
83 struct ofpact_resubmit *resubmit;
84
85 if (nar->pad[0] || nar->pad[1] || nar->pad[2]) {
86 return OFPERR_OFPBAC_BAD_ARGUMENT;
87 }
88
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;
93 return 0;
94}
95
96static enum ofperr
97output_reg_from_openflow(const struct nx_action_output_reg *naor,
98 struct ofpbuf *out)
99{
100 struct ofpact_output_reg *output_reg;
101
102 if (!is_all_zeros(naor->zero, sizeof naor->zero)) {
103 return OFPERR_OFPBAC_BAD_ARGUMENT;
104 }
105
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);
111
112 return mf_check_src(&output_reg->src, NULL);
113}
114
115static void
116fin_timeout_from_openflow(const struct nx_action_fin_timeout *naft,
117 struct ofpbuf *out)
118{
119 struct ofpact_fin_timeout *oft;
120
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);
124}
125
126static void
127controller_from_openflow(const struct nx_action_controller *nac,
128 struct ofpbuf *out)
129{
130 struct ofpact_controller *oc;
131
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;
136}
137
4cceacb9
JS
138static enum ofperr
139metadata_from_nxast(const struct nx_action_write_metadata *nawm,
140 struct ofpbuf *out)
141{
142 struct ofpact_metadata *om;
143
144 if (!is_all_zeros(nawm->zeros, sizeof nawm->zeros)) {
145 return OFPERR_NXBRC_MUST_BE_ZERO;
146 }
147
148 om = ofpact_put_WRITE_METADATA(out);
149 om->metadata = nawm->metadata;
150 om->mask = nawm->mask;
151
152 return 0;
153}
154
f25d0cf3
BP
155static void
156note_from_openflow(const struct nx_action_note *nan, struct ofpbuf *out)
157{
158 struct ofpact_note *note;
159 unsigned int length;
160
161 length = ntohs(nan->len) - offsetof(struct nx_action_note, note);
162 note = ofpact_put(out, OFPACT_NOTE,
163 offsetof(struct ofpact_note, data) + length);
164 note->length = length;
165 memcpy(note->data, nan->note, length);
166}
167
c2d967a5 168static enum ofperr
7bcb1506 169dec_ttl_from_openflow(struct ofpbuf *out, enum ofputil_action_code compat)
c2d967a5
MM
170{
171 uint16_t id = 0;
172 struct ofpact_cnt_ids *ids;
173 enum ofperr error = 0;
174
175 ids = ofpact_put_DEC_TTL(out);
7bcb1506 176 ids->ofpact.compat = compat;
c2d967a5
MM
177 ids->n_controllers = 1;
178 ofpbuf_put(out, &id, sizeof id);
179 ids = out->l2;
180 ofpact_update_len(out, &ids->ofpact);
181 return error;
182}
183
184static enum ofperr
185dec_ttl_cnt_ids_from_openflow(const struct nx_action_cnt_ids *nac_ids,
186 struct ofpbuf *out)
187{
188 struct ofpact_cnt_ids *ids;
189 size_t ids_size;
190 int i;
191
192 ids = ofpact_put_DEC_TTL(out);
193 ids->ofpact.compat = OFPUTIL_NXAST_DEC_TTL_CNT_IDS;
194 ids->n_controllers = ntohs(nac_ids->n_controllers);
195 ids_size = ntohs(nac_ids->len) - sizeof *nac_ids;
196
197 if (!is_all_zeros(nac_ids->zeros, sizeof nac_ids->zeros)) {
198 return OFPERR_NXBRC_MUST_BE_ZERO;
199 }
200
201 if (ids_size < ids->n_controllers * sizeof(ovs_be16)) {
202 VLOG_WARN_RL(&rl, "Nicira action dec_ttl_cnt_ids only has %zu bytes "
203 "allocated for controller ids. %zu bytes are required for "
204 "%"PRIu16" controllers.", ids_size,
205 ids->n_controllers * sizeof(ovs_be16), ids->n_controllers);
206 return OFPERR_OFPBAC_BAD_LEN;
207 }
208
209 for (i = 0; i < ids->n_controllers; i++) {
210 uint16_t id = ntohs(((ovs_be16 *)(nac_ids + 1))[i]);
211 ofpbuf_put(out, &id, sizeof id);
212 }
213
214 ids = out->l2;
215 ofpact_update_len(out, &ids->ofpact);
216
217 return 0;
218}
219
f25d0cf3
BP
220static enum ofperr
221decode_nxast_action(const union ofp_action *a, enum ofputil_action_code *code)
222{
223 const struct nx_action_header *nah = (const struct nx_action_header *) a;
224 uint16_t len = ntohs(a->header.len);
225
226 if (len < sizeof(struct nx_action_header)) {
227 return OFPERR_OFPBAC_BAD_LEN;
228 } else if (a->vendor.vendor != CONSTANT_HTONL(NX_VENDOR_ID)) {
229 return OFPERR_OFPBAC_BAD_VENDOR;
230 }
231
232 switch (nah->subtype) {
233#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
234 case CONSTANT_HTONS(ENUM): \
235 if (EXTENSIBLE \
236 ? len >= sizeof(struct STRUCT) \
237 : len == sizeof(struct STRUCT)) { \
238 *code = OFPUTIL_##ENUM; \
239 return 0; \
240 } else { \
241 return OFPERR_OFPBAC_BAD_LEN; \
242 } \
243 NOT_REACHED();
244#include "ofp-util.def"
245
246 case CONSTANT_HTONS(NXAST_SNAT__OBSOLETE):
247 case CONSTANT_HTONS(NXAST_DROP_SPOOFED_ARP__OBSOLETE):
248 default:
249 return OFPERR_OFPBAC_BAD_TYPE;
250 }
251}
252
253/* Parses 'a' to determine its type. On success stores the correct type into
254 * '*code' and returns 0. On failure returns an OFPERR_* error code and
255 * '*code' is indeterminate.
256 *
257 * The caller must have already verified that 'a''s length is potentially
258 * correct (that is, a->header.len is nonzero and a multiple of sizeof(union
259 * ofp_action) and no longer than the amount of space allocated to 'a').
260 *
261 * This function verifies that 'a''s length is correct for the type of action
262 * that it represents. */
263static enum ofperr
264decode_openflow10_action(const union ofp_action *a,
265 enum ofputil_action_code *code)
266{
267 switch (a->type) {
268 case CONSTANT_HTONS(OFPAT10_VENDOR):
269 return decode_nxast_action(a, code);
270
271#define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
272 case CONSTANT_HTONS(ENUM): \
273 if (a->header.len == htons(sizeof(struct STRUCT))) { \
274 *code = OFPUTIL_##ENUM; \
275 return 0; \
276 } else { \
277 return OFPERR_OFPBAC_BAD_LEN; \
278 } \
279 break;
280#include "ofp-util.def"
281
282 default:
283 return OFPERR_OFPBAC_BAD_TYPE;
284 }
285}
286
287static enum ofperr
d01c980f
BP
288ofpact_from_nxast(const union ofp_action *a, enum ofputil_action_code code,
289 struct ofpbuf *out)
f25d0cf3
BP
290{
291 const struct nx_action_resubmit *nar;
292 const struct nx_action_set_tunnel *nast;
293 const struct nx_action_set_queue *nasq;
294 const struct nx_action_note *nan;
295 const struct nx_action_set_tunnel64 *nast64;
4cceacb9 296 const struct nx_action_write_metadata *nawm;
f25d0cf3 297 struct ofpact_tunnel *tunnel;
d01c980f 298 enum ofperr error = 0;
f25d0cf3
BP
299
300 switch (code) {
301 case OFPUTIL_ACTION_INVALID:
d01c980f 302#define OFPAT10_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
3ddcaf2d 303#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
d01c980f 304#include "ofp-util.def"
f25d0cf3
BP
305 NOT_REACHED();
306
f25d0cf3
BP
307 case OFPUTIL_NXAST_RESUBMIT:
308 resubmit_from_openflow((const struct nx_action_resubmit *) a, out);
309 break;
310
311 case OFPUTIL_NXAST_SET_TUNNEL:
312 nast = (const struct nx_action_set_tunnel *) a;
313 tunnel = ofpact_put_SET_TUNNEL(out);
314 tunnel->ofpact.compat = code;
315 tunnel->tun_id = ntohl(nast->tun_id);
316 break;
317
4cceacb9
JS
318 case OFPUTIL_NXAST_WRITE_METADATA:
319 nawm = (const struct nx_action_write_metadata *) a;
320 error = metadata_from_nxast(nawm, out);
321 break;
322
f25d0cf3
BP
323 case OFPUTIL_NXAST_SET_QUEUE:
324 nasq = (const struct nx_action_set_queue *) a;
325 ofpact_put_SET_QUEUE(out)->queue_id = ntohl(nasq->queue_id);
326 break;
327
328 case OFPUTIL_NXAST_POP_QUEUE:
329 ofpact_put_POP_QUEUE(out);
330 break;
331
332 case OFPUTIL_NXAST_REG_MOVE:
333 error = nxm_reg_move_from_openflow(
334 (const struct nx_action_reg_move *) a, out);
335 break;
336
337 case OFPUTIL_NXAST_REG_LOAD:
338 error = nxm_reg_load_from_openflow(
339 (const struct nx_action_reg_load *) a, out);
340 break;
341
bd85dac1
AZ
342 case OFPUTIL_NXAST_STACK_PUSH:
343 error = nxm_stack_push_from_openflow(
344 (const struct nx_action_stack *) a, out);
345 break;
346
347 case OFPUTIL_NXAST_STACK_POP:
348 error = nxm_stack_pop_from_openflow(
349 (const struct nx_action_stack *) a, out);
350 break;
351
f25d0cf3
BP
352 case OFPUTIL_NXAST_NOTE:
353 nan = (const struct nx_action_note *) a;
354 note_from_openflow(nan, out);
355 break;
356
357 case OFPUTIL_NXAST_SET_TUNNEL64:
358 nast64 = (const struct nx_action_set_tunnel64 *) a;
359 tunnel = ofpact_put_SET_TUNNEL(out);
360 tunnel->ofpact.compat = code;
361 tunnel->tun_id = ntohll(nast64->tun_id);
362 break;
363
364 case OFPUTIL_NXAST_MULTIPATH:
365 error = multipath_from_openflow((const struct nx_action_multipath *) a,
366 ofpact_put_MULTIPATH(out));
367 break;
368
f25d0cf3
BP
369 case OFPUTIL_NXAST_BUNDLE:
370 case OFPUTIL_NXAST_BUNDLE_LOAD:
371 error = bundle_from_openflow((const struct nx_action_bundle *) a, out);
372 break;
373
374 case OFPUTIL_NXAST_OUTPUT_REG:
375 error = output_reg_from_openflow(
376 (const struct nx_action_output_reg *) a, out);
377 break;
378
379 case OFPUTIL_NXAST_RESUBMIT_TABLE:
380 nar = (const struct nx_action_resubmit *) a;
381 error = resubmit_table_from_openflow(nar, out);
382 break;
383
384 case OFPUTIL_NXAST_LEARN:
385 error = learn_from_openflow((const struct nx_action_learn *) a, out);
386 break;
387
388 case OFPUTIL_NXAST_EXIT:
389 ofpact_put_EXIT(out);
390 break;
391
392 case OFPUTIL_NXAST_DEC_TTL:
7bcb1506 393 error = dec_ttl_from_openflow(out, code);
c2d967a5
MM
394 break;
395
396 case OFPUTIL_NXAST_DEC_TTL_CNT_IDS:
397 error = dec_ttl_cnt_ids_from_openflow(
398 (const struct nx_action_cnt_ids *) a, out);
f25d0cf3
BP
399 break;
400
401 case OFPUTIL_NXAST_FIN_TIMEOUT:
402 fin_timeout_from_openflow(
403 (const struct nx_action_fin_timeout *) a, out);
404 break;
405
406 case OFPUTIL_NXAST_CONTROLLER:
407 controller_from_openflow((const struct nx_action_controller *) a, out);
408 break;
b02475c5
SH
409
410 case OFPUTIL_NXAST_PUSH_MPLS: {
411 struct nx_action_push_mpls *nxapm = (struct nx_action_push_mpls *)a;
412 if (!eth_type_mpls(nxapm->ethertype)) {
413 return OFPERR_OFPBAC_BAD_ARGUMENT;
414 }
415 ofpact_put_PUSH_MPLS(out)->ethertype = nxapm->ethertype;
416 break;
417 }
418
0f3f3c3d
SH
419 case OFPUTIL_NXAST_SET_MPLS_TTL: {
420 struct nx_action_mpls_ttl *nxamt = (struct nx_action_mpls_ttl *)a;
421 ofpact_put_SET_MPLS_TTL(out)->ttl = nxamt->ttl;
422 break;
423 }
424
b676167a
SH
425 case OFPUTIL_NXAST_DEC_MPLS_TTL:
426 ofpact_put_DEC_MPLS_TTL(out);
427 break;
428
b02475c5
SH
429 case OFPUTIL_NXAST_POP_MPLS: {
430 struct nx_action_pop_mpls *nxapm = (struct nx_action_pop_mpls *)a;
431 if (eth_type_mpls(nxapm->ethertype)) {
432 return OFPERR_OFPBAC_BAD_ARGUMENT;
433 }
434 ofpact_put_POP_MPLS(out)->ethertype = nxapm->ethertype;
435 break;
436 }
f25d0cf3
BP
437 }
438
439 return error;
440}
441
d01c980f
BP
442static enum ofperr
443ofpact_from_openflow10(const union ofp_action *a, struct ofpbuf *out)
444{
445 enum ofputil_action_code code;
446 enum ofperr error;
447
448 error = decode_openflow10_action(a, &code);
449 if (error) {
450 return error;
451 }
452
453 switch (code) {
454 case OFPUTIL_ACTION_INVALID:
3ddcaf2d 455#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
d01c980f
BP
456#include "ofp-util.def"
457 NOT_REACHED();
458
459 case OFPUTIL_OFPAT10_OUTPUT:
460 return output_from_openflow10(&a->output10, out);
461
462 case OFPUTIL_OFPAT10_SET_VLAN_VID:
463 if (a->vlan_vid.vlan_vid & ~htons(0xfff)) {
464 return OFPERR_OFPBAC_BAD_ARGUMENT;
465 }
466 ofpact_put_SET_VLAN_VID(out)->vlan_vid = ntohs(a->vlan_vid.vlan_vid);
467 break;
468
469 case OFPUTIL_OFPAT10_SET_VLAN_PCP:
470 if (a->vlan_pcp.vlan_pcp & ~7) {
471 return OFPERR_OFPBAC_BAD_ARGUMENT;
472 }
473 ofpact_put_SET_VLAN_PCP(out)->vlan_pcp = a->vlan_pcp.vlan_pcp;
474 break;
475
476 case OFPUTIL_OFPAT10_STRIP_VLAN:
477 ofpact_put_STRIP_VLAN(out);
478 break;
479
480 case OFPUTIL_OFPAT10_SET_DL_SRC:
481 memcpy(ofpact_put_SET_ETH_SRC(out)->mac,
482 ((const struct ofp_action_dl_addr *) a)->dl_addr, ETH_ADDR_LEN);
483 break;
484
485 case OFPUTIL_OFPAT10_SET_DL_DST:
486 memcpy(ofpact_put_SET_ETH_DST(out)->mac,
487 ((const struct ofp_action_dl_addr *) a)->dl_addr, ETH_ADDR_LEN);
488 break;
489
490 case OFPUTIL_OFPAT10_SET_NW_SRC:
491 ofpact_put_SET_IPV4_SRC(out)->ipv4 = a->nw_addr.nw_addr;
492 break;
493
494 case OFPUTIL_OFPAT10_SET_NW_DST:
495 ofpact_put_SET_IPV4_DST(out)->ipv4 = a->nw_addr.nw_addr;
496 break;
497
498 case OFPUTIL_OFPAT10_SET_NW_TOS:
499 if (a->nw_tos.nw_tos & ~IP_DSCP_MASK) {
500 return OFPERR_OFPBAC_BAD_ARGUMENT;
501 }
502 ofpact_put_SET_IPV4_DSCP(out)->dscp = a->nw_tos.nw_tos;
503 break;
504
505 case OFPUTIL_OFPAT10_SET_TP_SRC:
506 ofpact_put_SET_L4_SRC_PORT(out)->port = ntohs(a->tp_port.tp_port);
507 break;
508
509 case OFPUTIL_OFPAT10_SET_TP_DST:
510 ofpact_put_SET_L4_DST_PORT(out)->port = ntohs(a->tp_port.tp_port);
511
512 break;
513
514 case OFPUTIL_OFPAT10_ENQUEUE:
31a9e63f 515 error = enqueue_from_openflow10((const struct ofp10_action_enqueue *) a,
d01c980f
BP
516 out);
517 break;
518
519#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
520#include "ofp-util.def"
521 return ofpact_from_nxast(a, code, out);
522 }
523
524 return error;
525}
526
f25d0cf3
BP
527static inline union ofp_action *
528action_next(const union ofp_action *a)
529{
530 return ((union ofp_action *) (void *)
531 ((uint8_t *) a + ntohs(a->header.len)));
532}
533
534static inline bool
535action_is_valid(const union ofp_action *a, size_t n_actions)
536{
537 uint16_t len = ntohs(a->header.len);
538 return (!(len % OFP_ACTION_ALIGN)
539 && len >= sizeof *a
540 && len / sizeof *a <= n_actions);
541}
542
543/* This macro is careful to check for actions with bad lengths. */
544#define ACTION_FOR_EACH(ITER, LEFT, ACTIONS, N_ACTIONS) \
545 for ((ITER) = (ACTIONS), (LEFT) = (N_ACTIONS); \
546 (LEFT) > 0 && action_is_valid(ITER, LEFT); \
547 ((LEFT) -= ntohs((ITER)->header.len) / sizeof(union ofp_action), \
548 (ITER) = action_next(ITER)))
549
699dddf1
BP
550static void
551log_bad_action(const union ofp_action *actions, size_t n_actions, size_t ofs,
552 enum ofperr error)
553{
554 if (!VLOG_DROP_WARN(&rl)) {
555 struct ds s;
556
557 ds_init(&s);
558 ds_put_hex_dump(&s, actions, n_actions * sizeof *actions, 0, false);
559 VLOG_WARN("bad action at offset %#zx (%s):\n%s",
560 ofs * sizeof *actions, ofperr_get_name(error), ds_cstr(&s));
561 ds_destroy(&s);
562 }
563}
564
f25d0cf3 565static enum ofperr
0300caaf
IY
566ofpacts_from_openflow(const union ofp_action *in, size_t n_in,
567 struct ofpbuf *out,
568 enum ofperr (*ofpact_from_openflow)(
569 const union ofp_action *a, struct ofpbuf *out))
f25d0cf3
BP
570{
571 const union ofp_action *a;
572 size_t left;
573
574 ACTION_FOR_EACH (a, left, in, n_in) {
0300caaf 575 enum ofperr error = ofpact_from_openflow(a, out);
f25d0cf3 576 if (error) {
699dddf1 577 log_bad_action(in, n_in, a - in, error);
f25d0cf3
BP
578 return error;
579 }
580 }
581 if (left) {
699dddf1
BP
582 enum ofperr error = OFPERR_OFPBAC_BAD_LEN;
583 log_bad_action(in, n_in, n_in - left, error);
584 return error;
f25d0cf3
BP
585 }
586
587 ofpact_pad(out);
588 return 0;
589}
590
0300caaf
IY
591static enum ofperr
592ofpacts_from_openflow10(const union ofp_action *in, size_t n_in,
593 struct ofpbuf *out)
594{
595 return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow10);
596}
597
d01c980f
BP
598static enum ofperr
599ofpacts_pull_actions(struct ofpbuf *openflow, unsigned int actions_len,
600 struct ofpbuf *ofpacts,
601 enum ofperr (*translate)(const union ofp_action *actions,
602 size_t n_actions,
603 struct ofpbuf *ofpacts))
f25d0cf3
BP
604{
605 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
606 const union ofp_action *actions;
607 enum ofperr error;
608
609 ofpbuf_clear(ofpacts);
610
611 if (actions_len % OFP_ACTION_ALIGN != 0) {
612 VLOG_WARN_RL(&rl, "OpenFlow message actions length %u is not a "
613 "multiple of %d", actions_len, OFP_ACTION_ALIGN);
614 return OFPERR_OFPBRC_BAD_LEN;
615 }
616
617 actions = ofpbuf_try_pull(openflow, actions_len);
618 if (actions == NULL) {
619 VLOG_WARN_RL(&rl, "OpenFlow message actions length %u exceeds "
620 "remaining message length (%zu)",
621 actions_len, openflow->size);
622 return OFPERR_OFPBRC_BAD_LEN;
623 }
624
d01c980f 625 error = translate(actions, actions_len / OFP_ACTION_ALIGN, ofpacts);
4cceacb9
JS
626 if (error) {
627 ofpbuf_clear(ofpacts);
628 return error;
629 }
630
631 error = ofpacts_verify(ofpacts->data, ofpacts->size);
f25d0cf3
BP
632 if (error) {
633 ofpbuf_clear(ofpacts);
634 }
d01c980f
BP
635 return error;
636}
637
638/* Attempts to convert 'actions_len' bytes of OpenFlow 1.0 actions from the
639 * front of 'openflow' into ofpacts. On success, replaces any existing content
640 * in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'.
641 * Returns 0 if successful, otherwise an OpenFlow error.
642 *
13f894b1
BP
643 * The parsed actions are valid generically, but they may not be valid in a
644 * specific context. For example, port numbers up to OFPP_MAX are valid
645 * generically, but specific datapaths may only support port numbers in a
646 * smaller range. Use ofpacts_check() to additional check whether actions are
647 * valid in a specific context. */
d01c980f
BP
648enum ofperr
649ofpacts_pull_openflow10(struct ofpbuf *openflow, unsigned int actions_len,
650 struct ofpbuf *ofpacts)
651{
652 return ofpacts_pull_actions(openflow, actions_len, ofpacts,
653 ofpacts_from_openflow10);
654}
655\f
656/* OpenFlow 1.1 actions. */
657
658/* Parses 'a' to determine its type. On success stores the correct type into
659 * '*code' and returns 0. On failure returns an OFPERR_* error code and
660 * '*code' is indeterminate.
661 *
662 * The caller must have already verified that 'a''s length is potentially
663 * correct (that is, a->header.len is nonzero and a multiple of sizeof(union
664 * ofp_action) and no longer than the amount of space allocated to 'a').
665 *
666 * This function verifies that 'a''s length is correct for the type of action
667 * that it represents. */
668static enum ofperr
669decode_openflow11_action(const union ofp_action *a,
670 enum ofputil_action_code *code)
671{
3ddcaf2d
BP
672 uint16_t len;
673
d01c980f
BP
674 switch (a->type) {
675 case CONSTANT_HTONS(OFPAT11_EXPERIMENTER):
676 return decode_nxast_action(a, code);
677
3ddcaf2d
BP
678#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
679 case CONSTANT_HTONS(ENUM): \
680 len = ntohs(a->header.len); \
681 if (EXTENSIBLE \
682 ? len >= sizeof(struct STRUCT) \
683 : len == sizeof(struct STRUCT)) { \
684 *code = OFPUTIL_##ENUM; \
685 return 0; \
686 } else { \
687 return OFPERR_OFPBAC_BAD_LEN; \
688 } \
689 NOT_REACHED();
d01c980f
BP
690#include "ofp-util.def"
691
692 default:
693 return OFPERR_OFPBAC_BAD_TYPE;
694 }
695}
696
697static enum ofperr
698output_from_openflow11(const struct ofp11_action_output *oao,
699 struct ofpbuf *out)
700{
701 struct ofpact_output *output;
702 enum ofperr error;
703
704 output = ofpact_put_OUTPUT(out);
705 output->max_len = ntohs(oao->max_len);
706
707 error = ofputil_port_from_ofp11(oao->port, &output->port);
708 if (error) {
709 return error;
710 }
711
712 return ofputil_check_output_port(output->port, OFPP_MAX);
713}
714
715static enum ofperr
716ofpact_from_openflow11(const union ofp_action *a, struct ofpbuf *out)
717{
718 enum ofputil_action_code code;
719 enum ofperr error;
720
721 error = decode_openflow11_action(a, &code);
722 if (error) {
723 return error;
724 }
725
726 switch (code) {
727 case OFPUTIL_ACTION_INVALID:
728#define OFPAT10_ACTION(ENUM, STRUCT, NAME) case OFPUTIL_##ENUM:
729#include "ofp-util.def"
730 NOT_REACHED();
731
732 case OFPUTIL_OFPAT11_OUTPUT:
733 return output_from_openflow11((const struct ofp11_action_output *) a,
734 out);
735
736 case OFPUTIL_OFPAT11_SET_VLAN_VID:
737 if (a->vlan_vid.vlan_vid & ~htons(0xfff)) {
738 return OFPERR_OFPBAC_BAD_ARGUMENT;
739 }
740 ofpact_put_SET_VLAN_VID(out)->vlan_vid = ntohs(a->vlan_vid.vlan_vid);
741 break;
742
743 case OFPUTIL_OFPAT11_SET_VLAN_PCP:
744 if (a->vlan_pcp.vlan_pcp & ~7) {
745 return OFPERR_OFPBAC_BAD_ARGUMENT;
746 }
747 ofpact_put_SET_VLAN_PCP(out)->vlan_pcp = a->vlan_pcp.vlan_pcp;
748 break;
749
3e34fbdd
IY
750 case OFPUTIL_OFPAT11_PUSH_VLAN:
751 if (((const struct ofp11_action_push *)a)->ethertype !=
752 htons(ETH_TYPE_VLAN_8021Q)) {
5dca28b5 753 /* XXX 802.1AD(QinQ) isn't supported at the moment */
15549878 754 return OFPERR_OFPBAC_BAD_ARGUMENT;
3e34fbdd
IY
755 }
756 ofpact_put_PUSH_VLAN(out);
757 break;
758
8e61c110
IY
759 case OFPUTIL_OFPAT11_POP_VLAN:
760 ofpact_put_STRIP_VLAN(out);
761 break;
762
276c4e7a
SH
763 case OFPUTIL_OFPAT11_SET_QUEUE:
764 ofpact_put_SET_QUEUE(out)->queue_id =
765 ntohl(((const struct ofp11_action_set_queue *)a)->queue_id);
766 break;
767
d01c980f
BP
768 case OFPUTIL_OFPAT11_SET_DL_SRC:
769 memcpy(ofpact_put_SET_ETH_SRC(out)->mac,
770 ((const struct ofp_action_dl_addr *) a)->dl_addr, ETH_ADDR_LEN);
771 break;
772
773 case OFPUTIL_OFPAT11_SET_DL_DST:
774 memcpy(ofpact_put_SET_ETH_DST(out)->mac,
775 ((const struct ofp_action_dl_addr *) a)->dl_addr, ETH_ADDR_LEN);
776 break;
777
7bcb1506
IY
778 case OFPUTIL_OFPAT11_DEC_NW_TTL:
779 dec_ttl_from_openflow(out, code);
780 break;
781
d01c980f
BP
782 case OFPUTIL_OFPAT11_SET_NW_SRC:
783 ofpact_put_SET_IPV4_SRC(out)->ipv4 = a->nw_addr.nw_addr;
784 break;
785
786 case OFPUTIL_OFPAT11_SET_NW_DST:
787 ofpact_put_SET_IPV4_DST(out)->ipv4 = a->nw_addr.nw_addr;
788 break;
789
790 case OFPUTIL_OFPAT11_SET_NW_TOS:
791 if (a->nw_tos.nw_tos & ~IP_DSCP_MASK) {
792 return OFPERR_OFPBAC_BAD_ARGUMENT;
793 }
794 ofpact_put_SET_IPV4_DSCP(out)->dscp = a->nw_tos.nw_tos;
795 break;
796
797 case OFPUTIL_OFPAT11_SET_TP_SRC:
798 ofpact_put_SET_L4_SRC_PORT(out)->port = ntohs(a->tp_port.tp_port);
799 break;
800
801 case OFPUTIL_OFPAT11_SET_TP_DST:
802 ofpact_put_SET_L4_DST_PORT(out)->port = ntohs(a->tp_port.tp_port);
803 break;
804
e9536ecb 805 case OFPUTIL_OFPAT12_SET_FIELD:
d55b18c8
IY
806 return nxm_reg_load_from_openflow12_set_field(
807 (const struct ofp12_action_set_field *)a, out);
e9536ecb 808
0f3f3c3d
SH
809 case OFPUTIL_OFPAT11_SET_MPLS_TTL: {
810 struct ofp11_action_mpls_ttl *oamt = (struct ofp11_action_mpls_ttl *)a;
811 ofpact_put_SET_MPLS_TTL(out)->ttl = oamt->mpls_ttl;
812 break;
813 }
814
b676167a
SH
815 case OFPUTIL_OFPAT11_DEC_MPLS_TTL:
816 ofpact_put_DEC_MPLS_TTL(out);
817 break;
818
b02475c5
SH
819 case OFPUTIL_OFPAT11_PUSH_MPLS: {
820 struct ofp11_action_push *oap = (struct ofp11_action_push *)a;
821 if (!eth_type_mpls(oap->ethertype)) {
822 return OFPERR_OFPBAC_BAD_ARGUMENT;
823 }
824 ofpact_put_PUSH_MPLS(out)->ethertype = oap->ethertype;
825 break;
826 }
827
828 case OFPUTIL_OFPAT11_POP_MPLS: {
829 struct ofp11_action_pop_mpls *oapm = (struct ofp11_action_pop_mpls *)a;
830 if (eth_type_mpls(oapm->ethertype)) {
831 return OFPERR_OFPBAC_BAD_ARGUMENT;
832 }
833 ofpact_put_POP_MPLS(out)->ethertype = oapm->ethertype;
834 break;
835 }
836
d01c980f
BP
837#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM:
838#include "ofp-util.def"
839 return ofpact_from_nxast(a, code, out);
840 }
841
842 return error;
843}
844
845static enum ofperr
846ofpacts_from_openflow11(const union ofp_action *in, size_t n_in,
847 struct ofpbuf *out)
848{
0300caaf 849 return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow11);
f25d0cf3
BP
850}
851\f
d01c980f
BP
852/* OpenFlow 1.1 instructions. */
853
d01c980f 854#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
a359d5ad
IY
855 static inline const struct STRUCT * \
856 instruction_get_##ENUM(const struct ofp11_instruction *inst)\
857 { \
cb22974d 858 ovs_assert(inst->type == htons(ENUM)); \
a359d5ad
IY
859 return (struct STRUCT *)inst; \
860 } \
861 \
d01c980f
BP
862 static inline void \
863 instruction_init_##ENUM(struct STRUCT *s) \
864 { \
865 memset(s, 0, sizeof *s); \
866 s->type = htons(ENUM); \
867 s->len = htons(sizeof *s); \
868 } \
869 \
870 static inline struct STRUCT * \
871 instruction_put_##ENUM(struct ofpbuf *buf) \
872 { \
873 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
874 instruction_init_##ENUM(s); \
875 return s; \
876 }
877OVS_INSTRUCTIONS
878#undef DEFINE_INST
879
a359d5ad
IY
880struct instruction_type_info {
881 enum ovs_instruction_type type;
882 const char *name;
883};
884
885static const struct instruction_type_info inst_info[] = {
886#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) {OVSINST_##ENUM, NAME},
887OVS_INSTRUCTIONS
888#undef DEFINE_INST
889};
890
891const char *
892ofpact_instruction_name_from_type(enum ovs_instruction_type type)
893{
6ae0fd54 894 return inst_info[type].name;
a359d5ad
IY
895}
896
897int
898ofpact_instruction_type_from_name(const char *name)
899{
900 const struct instruction_type_info *p;
901 for (p = inst_info; p < &inst_info[ARRAY_SIZE(inst_info)]; p++) {
902 if (!strcasecmp(name, p->name)) {
903 return p->type;
904 }
905 }
906 return -1;
907}
908
d01c980f
BP
909static inline struct ofp11_instruction *
910instruction_next(const struct ofp11_instruction *inst)
911{
912 return ((struct ofp11_instruction *) (void *)
913 ((uint8_t *) inst + ntohs(inst->len)));
914}
915
916static inline bool
917instruction_is_valid(const struct ofp11_instruction *inst,
918 size_t n_instructions)
919{
920 uint16_t len = ntohs(inst->len);
921 return (!(len % OFP11_INSTRUCTION_ALIGN)
922 && len >= sizeof *inst
923 && len / sizeof *inst <= n_instructions);
924}
925
926/* This macro is careful to check for instructions with bad lengths. */
927#define INSTRUCTION_FOR_EACH(ITER, LEFT, INSTRUCTIONS, N_INSTRUCTIONS) \
928 for ((ITER) = (INSTRUCTIONS), (LEFT) = (N_INSTRUCTIONS); \
929 (LEFT) > 0 && instruction_is_valid(ITER, LEFT); \
930 ((LEFT) -= (ntohs((ITER)->len) \
931 / sizeof(struct ofp11_instruction)), \
932 (ITER) = instruction_next(ITER)))
933
934static enum ofperr
935decode_openflow11_instruction(const struct ofp11_instruction *inst,
936 enum ovs_instruction_type *type)
937{
938 uint16_t len = ntohs(inst->len);
939
940 switch (inst->type) {
941 case CONSTANT_HTONS(OFPIT11_EXPERIMENTER):
942 return OFPERR_OFPBIC_BAD_EXPERIMENTER;
943
944#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
945 case CONSTANT_HTONS(ENUM): \
946 if (EXTENSIBLE \
947 ? len >= sizeof(struct STRUCT) \
948 : len == sizeof(struct STRUCT)) { \
949 *type = OVSINST_##ENUM; \
950 return 0; \
951 } else { \
952 return OFPERR_OFPBIC_BAD_LEN; \
953 }
954OVS_INSTRUCTIONS
955#undef DEFINE_INST
956
957 default:
958 return OFPERR_OFPBIC_UNKNOWN_INST;
959 }
960}
961
962static enum ofperr
963decode_openflow11_instructions(const struct ofp11_instruction insts[],
964 size_t n_insts,
965 const struct ofp11_instruction *out[])
966{
967 const struct ofp11_instruction *inst;
968 size_t left;
969
970 memset(out, 0, N_OVS_INSTRUCTIONS * sizeof *out);
971 INSTRUCTION_FOR_EACH (inst, left, insts, n_insts) {
972 enum ovs_instruction_type type;
973 enum ofperr error;
974
975 error = decode_openflow11_instruction(inst, &type);
976 if (error) {
977 return error;
978 }
979
980 if (out[type]) {
15549878
JR
981 return OFPERR_OFPBAC_UNSUPPORTED_ORDER; /* No specific code for
982 * a duplicate instruction
983 * exist */
d01c980f
BP
984 }
985 out[type] = inst;
986 }
987
988 if (left) {
989 VLOG_WARN_RL(&rl, "bad instruction format at offset %zu",
990 (n_insts - left) * sizeof *inst);
991 return OFPERR_OFPBIC_BAD_LEN;
992 }
993 return 0;
994}
995
996static void
997get_actions_from_instruction(const struct ofp11_instruction *inst,
998 const union ofp_action **actions,
999 size_t *n_actions)
1000{
1001 *actions = (const union ofp_action *) (inst + 1);
1002 *n_actions = (ntohs(inst->len) - sizeof *inst) / OFP11_INSTRUCTION_ALIGN;
1003}
1004
1005/* Attempts to convert 'actions_len' bytes of OpenFlow 1.1 actions from the
1006 * front of 'openflow' into ofpacts. On success, replaces any existing content
1007 * in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'.
1008 * Returns 0 if successful, otherwise an OpenFlow error.
1009 *
1010 * In most places in OpenFlow 1.1 and 1.2, actions appear encapsulated in
1011 * instructions, so you should call ofpacts_pull_openflow11_instructions()
1012 * instead of this function.
1013 *
13f894b1
BP
1014 * The parsed actions are valid generically, but they may not be valid in a
1015 * specific context. For example, port numbers up to OFPP_MAX are valid
1016 * generically, but specific datapaths may only support port numbers in a
1017 * smaller range. Use ofpacts_check() to additional check whether actions are
1018 * valid in a specific context. */
d01c980f
BP
1019enum ofperr
1020ofpacts_pull_openflow11_actions(struct ofpbuf *openflow,
1021 unsigned int actions_len,
1022 struct ofpbuf *ofpacts)
1023{
0300caaf
IY
1024 return ofpacts_pull_actions(openflow, actions_len, ofpacts,
1025 ofpacts_from_openflow11);
d01c980f
BP
1026}
1027
1028enum ofperr
1029ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
1030 unsigned int instructions_len,
1031 struct ofpbuf *ofpacts)
1032{
1033 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
1034 const struct ofp11_instruction *instructions;
1035 const struct ofp11_instruction *insts[N_OVS_INSTRUCTIONS];
1036 enum ofperr error;
1037
1038 ofpbuf_clear(ofpacts);
1039
1040 if (instructions_len % OFP11_INSTRUCTION_ALIGN != 0) {
1041 VLOG_WARN_RL(&rl, "OpenFlow message instructions length %u is not a "
1042 "multiple of %d",
1043 instructions_len, OFP11_INSTRUCTION_ALIGN);
1044 error = OFPERR_OFPBIC_BAD_LEN;
1045 goto exit;
1046 }
1047
1048 instructions = ofpbuf_try_pull(openflow, instructions_len);
1049 if (instructions == NULL) {
1050 VLOG_WARN_RL(&rl, "OpenFlow message instructions length %u exceeds "
1051 "remaining message length (%zu)",
1052 instructions_len, openflow->size);
1053 error = OFPERR_OFPBIC_BAD_LEN;
1054 goto exit;
1055 }
1056
1057 error = decode_openflow11_instructions(
1058 instructions, instructions_len / OFP11_INSTRUCTION_ALIGN,
1059 insts);
1060 if (error) {
1061 goto exit;
1062 }
1063
1064 if (insts[OVSINST_OFPIT11_APPLY_ACTIONS]) {
1065 const union ofp_action *actions;
1066 size_t n_actions;
1067
1068 get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS],
1069 &actions, &n_actions);
1070 error = ofpacts_from_openflow11(actions, n_actions, ofpacts);
1071 if (error) {
1072 goto exit;
1073 }
1074 }
b19e8793
IY
1075 if (insts[OVSINST_OFPIT11_CLEAR_ACTIONS]) {
1076 instruction_get_OFPIT11_CLEAR_ACTIONS(
1077 insts[OVSINST_OFPIT11_CLEAR_ACTIONS]);
1078 ofpact_put_CLEAR_ACTIONS(ofpacts);
1079 }
5dca28b5 1080 /* XXX Write-Actions */
4cceacb9
JS
1081 if (insts[OVSINST_OFPIT11_WRITE_METADATA]) {
1082 const struct ofp11_instruction_write_metadata *oiwm;
1083 struct ofpact_metadata *om;
1084
1085 oiwm = (const struct ofp11_instruction_write_metadata *)
1086 insts[OVSINST_OFPIT11_WRITE_METADATA];
1087
1088 om = ofpact_put_WRITE_METADATA(ofpacts);
1089 om->metadata = oiwm->metadata;
1090 om->mask = oiwm->metadata_mask;
1091 }
8dd54666
IY
1092 if (insts[OVSINST_OFPIT11_GOTO_TABLE]) {
1093 const struct ofp11_instruction_goto_table *oigt;
1094 struct ofpact_goto_table *ogt;
1095
1096 oigt = instruction_get_OFPIT11_GOTO_TABLE(
1097 insts[OVSINST_OFPIT11_GOTO_TABLE]);
1098 ogt = ofpact_put_GOTO_TABLE(ofpacts);
1099 ogt->table_id = oigt->table_id;
1100 }
d01c980f 1101
4cceacb9 1102 if (insts[OVSINST_OFPIT11_WRITE_ACTIONS]) {
d01c980f
BP
1103 error = OFPERR_OFPBIC_UNSUP_INST;
1104 goto exit;
1105 }
1106
4cceacb9 1107 error = ofpacts_verify(ofpacts->data, ofpacts->size);
d01c980f
BP
1108exit:
1109 if (error) {
1110 ofpbuf_clear(ofpacts);
1111 }
1112 return error;
1113}
1114\f
f25d0cf3 1115static enum ofperr
b02475c5
SH
1116ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports,
1117 ovs_be16 *dl_type)
f25d0cf3
BP
1118{
1119 const struct ofpact_enqueue *enqueue;
1120
1121 switch (a->type) {
1122 case OFPACT_OUTPUT:
1123 return ofputil_check_output_port(ofpact_get_OUTPUT(a)->port,
1124 max_ports);
1125
1126 case OFPACT_CONTROLLER:
1127 return 0;
1128
1129 case OFPACT_ENQUEUE:
1130 enqueue = ofpact_get_ENQUEUE(a);
1131 if (enqueue->port >= max_ports && enqueue->port != OFPP_IN_PORT
1132 && enqueue->port != OFPP_LOCAL) {
1133 return OFPERR_OFPBAC_BAD_OUT_PORT;
1134 }
1135 return 0;
1136
1137 case OFPACT_OUTPUT_REG:
1138 return mf_check_src(&ofpact_get_OUTPUT_REG(a)->src, flow);
1139
1140 case OFPACT_BUNDLE:
1141 return bundle_check(ofpact_get_BUNDLE(a), max_ports, flow);
1142
1143 case OFPACT_SET_VLAN_VID:
1144 case OFPACT_SET_VLAN_PCP:
1145 case OFPACT_STRIP_VLAN:
3e34fbdd 1146 case OFPACT_PUSH_VLAN:
f25d0cf3
BP
1147 case OFPACT_SET_ETH_SRC:
1148 case OFPACT_SET_ETH_DST:
1149 case OFPACT_SET_IPV4_SRC:
1150 case OFPACT_SET_IPV4_DST:
1151 case OFPACT_SET_IPV4_DSCP:
1152 case OFPACT_SET_L4_SRC_PORT:
1153 case OFPACT_SET_L4_DST_PORT:
1154 return 0;
1155
1156 case OFPACT_REG_MOVE:
1157 return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow);
1158
1159 case OFPACT_REG_LOAD:
b02475c5
SH
1160 if (*dl_type != flow->dl_type) {
1161 struct flow updated_flow = *flow;
1162 updated_flow.dl_type = *dl_type;
1163 return nxm_reg_load_check(ofpact_get_REG_LOAD(a), &updated_flow);
1164 } else {
1165 return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow);
1166 }
f25d0cf3 1167
bd85dac1
AZ
1168 case OFPACT_STACK_PUSH:
1169 return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow);
1170
1171 case OFPACT_STACK_POP:
1172 return nxm_stack_pop_check(ofpact_get_STACK_POP(a), flow);
1173
f25d0cf3 1174 case OFPACT_DEC_TTL:
0f3f3c3d 1175 case OFPACT_SET_MPLS_TTL:
b676167a 1176 case OFPACT_DEC_MPLS_TTL:
f25d0cf3
BP
1177 case OFPACT_SET_TUNNEL:
1178 case OFPACT_SET_QUEUE:
1179 case OFPACT_POP_QUEUE:
1180 case OFPACT_FIN_TIMEOUT:
1181 case OFPACT_RESUBMIT:
1182 return 0;
1183
1184 case OFPACT_LEARN:
1185 return learn_check(ofpact_get_LEARN(a), flow);
1186
1187 case OFPACT_MULTIPATH:
1188 return multipath_check(ofpact_get_MULTIPATH(a), flow);
1189
f25d0cf3
BP
1190 case OFPACT_NOTE:
1191 case OFPACT_EXIT:
1192 return 0;
1193
b02475c5
SH
1194 case OFPACT_PUSH_MPLS:
1195 *dl_type = ofpact_get_PUSH_MPLS(a)->ethertype;
1196 return 0;
1197
1198 case OFPACT_POP_MPLS:
1199 *dl_type = ofpact_get_POP_MPLS(a)->ethertype;
1200 return 0;
1201
b19e8793 1202 case OFPACT_CLEAR_ACTIONS:
4cceacb9 1203 case OFPACT_WRITE_METADATA:
8dd54666
IY
1204 case OFPACT_GOTO_TABLE:
1205 return 0;
1206
f25d0cf3
BP
1207 default:
1208 NOT_REACHED();
1209 }
1210}
1211
1212/* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are
1213 * appropriate for a packet with the prerequisites satisfied by 'flow' in a
1214 * switch with no more than 'max_ports' ports. */
1215enum ofperr
1216ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len,
1217 const struct flow *flow, int max_ports)
1218{
1219 const struct ofpact *a;
b02475c5 1220 ovs_be16 dl_type = flow->dl_type;
f25d0cf3
BP
1221
1222 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
b02475c5 1223 enum ofperr error = ofpact_check__(a, flow, max_ports, &dl_type);
f25d0cf3
BP
1224 if (error) {
1225 return error;
1226 }
1227 }
1228
1229 return 0;
1230}
4cceacb9
JS
1231
1232/* Verifies that the 'ofpacts_len' bytes of actions in 'ofpacts' are
1233 * in the appropriate order as defined by the OpenFlow spec. */
1234enum ofperr
1235ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len)
1236{
1237 const struct ofpact *a;
6813ee7c 1238 enum ovs_instruction_type inst;
4cceacb9 1239
6813ee7c 1240 inst = OVSINST_OFPIT11_APPLY_ACTIONS;
4cceacb9 1241 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
6813ee7c
BP
1242 enum ovs_instruction_type next;
1243
1244 if (a->type == OFPACT_CLEAR_ACTIONS) {
1245 next = OVSINST_OFPIT11_CLEAR_ACTIONS;
1246 } else if (a->type == OFPACT_WRITE_METADATA) {
1247 next = OVSINST_OFPIT11_WRITE_METADATA;
1248 } else if (a->type == OFPACT_GOTO_TABLE) {
1249 next = OVSINST_OFPIT11_GOTO_TABLE;
1250 } else {
1251 next = OVSINST_OFPIT11_APPLY_ACTIONS;
1252 }
1253
1254 if (inst != OVSINST_OFPIT11_APPLY_ACTIONS && next <= inst) {
1255 const char *name = ofpact_instruction_name_from_type(inst);
1256 const char *next_name = ofpact_instruction_name_from_type(next);
1257
1258 if (next == inst) {
1259 VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
1260 "1.1+ compatibility", name);
4cceacb9 1261 } else {
6813ee7c
BP
1262 VLOG_WARN("invalid instruction ordering: %s must appear "
1263 "before %s, for OpenFlow 1.1+ compatibility",
1264 next_name, name);
4cceacb9 1265 }
6813ee7c 1266 return OFPERR_OFPBAC_UNSUPPORTED_ORDER;
4cceacb9
JS
1267 }
1268
6813ee7c 1269 inst = next;
4cceacb9
JS
1270 }
1271
1272 return 0;
1273}
f25d0cf3
BP
1274\f
1275/* Converting ofpacts to Nicira OpenFlow extensions. */
1276
1277static void
1278ofpact_output_reg_to_nxast(const struct ofpact_output_reg *output_reg,
1279 struct ofpbuf *out)
1280{
1281 struct nx_action_output_reg *naor = ofputil_put_NXAST_OUTPUT_REG(out);
1282
1283 naor->ofs_nbits = nxm_encode_ofs_nbits(output_reg->src.ofs,
1284 output_reg->src.n_bits);
1285 naor->src = htonl(output_reg->src.field->nxm_header);
1286 naor->max_len = htons(output_reg->max_len);
1287}
1288
1289static void
1290ofpact_resubmit_to_nxast(const struct ofpact_resubmit *resubmit,
1291 struct ofpbuf *out)
1292{
1293 struct nx_action_resubmit *nar;
1294
1295 if (resubmit->table_id == 0xff
1296 && resubmit->ofpact.compat != OFPUTIL_NXAST_RESUBMIT_TABLE) {
1297 nar = ofputil_put_NXAST_RESUBMIT(out);
1298 } else {
1299 nar = ofputil_put_NXAST_RESUBMIT_TABLE(out);
1300 nar->table = resubmit->table_id;
1301 }
1302 nar->in_port = htons(resubmit->in_port);
1303}
1304
1305static void
1306ofpact_set_tunnel_to_nxast(const struct ofpact_tunnel *tunnel,
1307 struct ofpbuf *out)
1308{
1309 uint64_t tun_id = tunnel->tun_id;
1310
1311 if (tun_id <= UINT32_MAX
1312 && tunnel->ofpact.compat != OFPUTIL_NXAST_SET_TUNNEL64) {
1313 ofputil_put_NXAST_SET_TUNNEL(out)->tun_id = htonl(tun_id);
1314 } else {
1315 ofputil_put_NXAST_SET_TUNNEL64(out)->tun_id = htonll(tun_id);
1316 }
1317}
1318
4cceacb9
JS
1319static void
1320ofpact_write_metadata_to_nxast(const struct ofpact_metadata *om,
1321 struct ofpbuf *out)
1322{
1323 struct nx_action_write_metadata *nawm;
1324
1325 nawm = ofputil_put_NXAST_WRITE_METADATA(out);
1326 nawm->metadata = om->metadata;
1327 nawm->mask = om->mask;
1328}
1329
f25d0cf3
BP
1330static void
1331ofpact_note_to_nxast(const struct ofpact_note *note, struct ofpbuf *out)
1332{
1333 size_t start_ofs = out->size;
1334 struct nx_action_note *nan;
1335 unsigned int remainder;
1336 unsigned int len;
1337
1338 nan = ofputil_put_NXAST_NOTE(out);
1339 out->size -= sizeof nan->note;
1340
1341 ofpbuf_put(out, note->data, note->length);
1342
1343 len = out->size - start_ofs;
1344 remainder = len % OFP_ACTION_ALIGN;
1345 if (remainder) {
1346 ofpbuf_put_zeros(out, OFP_ACTION_ALIGN - remainder);
1347 }
1348 nan = (struct nx_action_note *)((char *)out->data + start_ofs);
1349 nan->len = htons(out->size - start_ofs);
1350}
1351
1352static void
1353ofpact_controller_to_nxast(const struct ofpact_controller *oc,
1354 struct ofpbuf *out)
1355{
1356 struct nx_action_controller *nac;
1357
1358 nac = ofputil_put_NXAST_CONTROLLER(out);
1359 nac->max_len = htons(oc->max_len);
1360 nac->controller_id = htons(oc->controller_id);
1361 nac->reason = oc->reason;
1362}
1363
c2d967a5
MM
1364static void
1365ofpact_dec_ttl_to_nxast(const struct ofpact_cnt_ids *oc_ids,
1366 struct ofpbuf *out)
1367{
1368 if (oc_ids->ofpact.compat == OFPUTIL_NXAST_DEC_TTL) {
1369 ofputil_put_NXAST_DEC_TTL(out);
1370 } else {
1371 struct nx_action_cnt_ids *nac_ids =
1372 ofputil_put_NXAST_DEC_TTL_CNT_IDS(out);
1373 int ids_len = ROUND_UP(2 * oc_ids->n_controllers, OFP_ACTION_ALIGN);
1374 ovs_be16 *ids;
1375 size_t i;
1376
1377 nac_ids->len = htons(ntohs(nac_ids->len) + ids_len);
1378 nac_ids->n_controllers = htons(oc_ids->n_controllers);
1379
1380 ids = ofpbuf_put_zeros(out, ids_len);
1381 for (i = 0; i < oc_ids->n_controllers; i++) {
1382 ids[i] = htons(oc_ids->cnt_ids[i]);
1383 }
1384 }
1385}
1386
f25d0cf3
BP
1387static void
1388ofpact_fin_timeout_to_nxast(const struct ofpact_fin_timeout *fin_timeout,
1389 struct ofpbuf *out)
1390{
1391 struct nx_action_fin_timeout *naft = ofputil_put_NXAST_FIN_TIMEOUT(out);
1392 naft->fin_idle_timeout = htons(fin_timeout->fin_idle_timeout);
1393 naft->fin_hard_timeout = htons(fin_timeout->fin_hard_timeout);
1394}
1395
1396static void
1397ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
1398{
1399 switch (a->type) {
1400 case OFPACT_CONTROLLER:
1401 ofpact_controller_to_nxast(ofpact_get_CONTROLLER(a), out);
1402 break;
1403
1404 case OFPACT_OUTPUT_REG:
1405 ofpact_output_reg_to_nxast(ofpact_get_OUTPUT_REG(a), out);
1406 break;
1407
1408 case OFPACT_BUNDLE:
1409 bundle_to_nxast(ofpact_get_BUNDLE(a), out);
1410 break;
1411
1412 case OFPACT_REG_MOVE:
1413 nxm_reg_move_to_nxast(ofpact_get_REG_MOVE(a), out);
1414 break;
1415
1416 case OFPACT_REG_LOAD:
1417 nxm_reg_load_to_nxast(ofpact_get_REG_LOAD(a), out);
1418 break;
1419
bd85dac1
AZ
1420 case OFPACT_STACK_PUSH:
1421 nxm_stack_push_to_nxast(ofpact_get_STACK_PUSH(a), out);
1422 break;
1423
1424 case OFPACT_STACK_POP:
1425 nxm_stack_pop_to_nxast(ofpact_get_STACK_POP(a), out);
1426 break;
1427
f25d0cf3 1428 case OFPACT_DEC_TTL:
c2d967a5 1429 ofpact_dec_ttl_to_nxast(ofpact_get_DEC_TTL(a), out);
f25d0cf3
BP
1430 break;
1431
0f3f3c3d
SH
1432 case OFPACT_SET_MPLS_TTL:
1433 ofputil_put_NXAST_SET_MPLS_TTL(out)->ttl
1434 = ofpact_get_SET_MPLS_TTL(a)->ttl;
1435 break;
1436
b676167a
SH
1437 case OFPACT_DEC_MPLS_TTL:
1438 ofputil_put_NXAST_DEC_MPLS_TTL(out);
1439 break;
1440
f25d0cf3
BP
1441 case OFPACT_SET_TUNNEL:
1442 ofpact_set_tunnel_to_nxast(ofpact_get_SET_TUNNEL(a), out);
1443 break;
1444
4cceacb9
JS
1445 case OFPACT_WRITE_METADATA:
1446 ofpact_write_metadata_to_nxast(ofpact_get_WRITE_METADATA(a), out);
1447 break;
1448
f25d0cf3
BP
1449 case OFPACT_SET_QUEUE:
1450 ofputil_put_NXAST_SET_QUEUE(out)->queue_id
1451 = htonl(ofpact_get_SET_QUEUE(a)->queue_id);
1452 break;
1453
1454 case OFPACT_POP_QUEUE:
1455 ofputil_put_NXAST_POP_QUEUE(out);
1456 break;
1457
1458 case OFPACT_FIN_TIMEOUT:
1459 ofpact_fin_timeout_to_nxast(ofpact_get_FIN_TIMEOUT(a), out);
1460 break;
1461
1462 case OFPACT_RESUBMIT:
1463 ofpact_resubmit_to_nxast(ofpact_get_RESUBMIT(a), out);
1464 break;
1465
1466 case OFPACT_LEARN:
1467 learn_to_nxast(ofpact_get_LEARN(a), out);
1468 break;
1469
1470 case OFPACT_MULTIPATH:
1471 multipath_to_nxast(ofpact_get_MULTIPATH(a), out);
1472 break;
1473
f25d0cf3
BP
1474 case OFPACT_NOTE:
1475 ofpact_note_to_nxast(ofpact_get_NOTE(a), out);
1476 break;
1477
1478 case OFPACT_EXIT:
1479 ofputil_put_NXAST_EXIT(out);
1480 break;
1481
b02475c5
SH
1482 case OFPACT_PUSH_MPLS:
1483 ofputil_put_NXAST_PUSH_MPLS(out)->ethertype =
1484 ofpact_get_PUSH_MPLS(a)->ethertype;
1485 break;
1486
1487 case OFPACT_POP_MPLS:
1488 ofputil_put_NXAST_POP_MPLS(out)->ethertype =
1489 ofpact_get_POP_MPLS(a)->ethertype;
1490 break;
1491
f25d0cf3
BP
1492 case OFPACT_OUTPUT:
1493 case OFPACT_ENQUEUE:
1494 case OFPACT_SET_VLAN_VID:
1495 case OFPACT_SET_VLAN_PCP:
1496 case OFPACT_STRIP_VLAN:
3e34fbdd 1497 case OFPACT_PUSH_VLAN:
f25d0cf3
BP
1498 case OFPACT_SET_ETH_SRC:
1499 case OFPACT_SET_ETH_DST:
1500 case OFPACT_SET_IPV4_SRC:
1501 case OFPACT_SET_IPV4_DST:
1502 case OFPACT_SET_IPV4_DSCP:
1503 case OFPACT_SET_L4_SRC_PORT:
1504 case OFPACT_SET_L4_DST_PORT:
b19e8793 1505 case OFPACT_CLEAR_ACTIONS:
8dd54666 1506 case OFPACT_GOTO_TABLE:
f25d0cf3
BP
1507 NOT_REACHED();
1508 }
1509}
1510\f
1511/* Converting ofpacts to OpenFlow 1.0. */
1512
1513static void
1514ofpact_output_to_openflow10(const struct ofpact_output *output,
1515 struct ofpbuf *out)
1516{
d01c980f 1517 struct ofp10_action_output *oao;
f25d0cf3
BP
1518
1519 oao = ofputil_put_OFPAT10_OUTPUT(out);
1520 oao->port = htons(output->port);
1521 oao->max_len = htons(output->max_len);
1522}
1523
1524static void
1525ofpact_enqueue_to_openflow10(const struct ofpact_enqueue *enqueue,
1526 struct ofpbuf *out)
1527{
31a9e63f 1528 struct ofp10_action_enqueue *oae;
f25d0cf3
BP
1529
1530 oae = ofputil_put_OFPAT10_ENQUEUE(out);
1531 oae->port = htons(enqueue->port);
1532 oae->queue_id = htonl(enqueue->queue);
1533}
1534
1535static void
1536ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out)
1537{
1538 switch (a->type) {
1539 case OFPACT_OUTPUT:
1540 ofpact_output_to_openflow10(ofpact_get_OUTPUT(a), out);
1541 break;
1542
1543 case OFPACT_ENQUEUE:
1544 ofpact_enqueue_to_openflow10(ofpact_get_ENQUEUE(a), out);
1545 break;
1546
1547 case OFPACT_SET_VLAN_VID:
1548 ofputil_put_OFPAT10_SET_VLAN_VID(out)->vlan_vid
1549 = htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid);
1550 break;
1551
1552 case OFPACT_SET_VLAN_PCP:
1553 ofputil_put_OFPAT10_SET_VLAN_PCP(out)->vlan_pcp
1554 = ofpact_get_SET_VLAN_PCP(a)->vlan_pcp;
1555 break;
1556
1557 case OFPACT_STRIP_VLAN:
1558 ofputil_put_OFPAT10_STRIP_VLAN(out);
1559 break;
1560
1561 case OFPACT_SET_ETH_SRC:
1562 memcpy(ofputil_put_OFPAT10_SET_DL_SRC(out)->dl_addr,
1563 ofpact_get_SET_ETH_SRC(a)->mac, ETH_ADDR_LEN);
1564 break;
1565
1566 case OFPACT_SET_ETH_DST:
1567 memcpy(ofputil_put_OFPAT10_SET_DL_DST(out)->dl_addr,
1568 ofpact_get_SET_ETH_DST(a)->mac, ETH_ADDR_LEN);
1569 break;
1570
1571 case OFPACT_SET_IPV4_SRC:
1572 ofputil_put_OFPAT10_SET_NW_SRC(out)->nw_addr
1573 = ofpact_get_SET_IPV4_SRC(a)->ipv4;
1574 break;
1575
1576 case OFPACT_SET_IPV4_DST:
1577 ofputil_put_OFPAT10_SET_NW_DST(out)->nw_addr
1578 = ofpact_get_SET_IPV4_DST(a)->ipv4;
1579 break;
1580
1581 case OFPACT_SET_IPV4_DSCP:
1582 ofputil_put_OFPAT10_SET_NW_TOS(out)->nw_tos
1583 = ofpact_get_SET_IPV4_DSCP(a)->dscp;
1584 break;
1585
1586 case OFPACT_SET_L4_SRC_PORT:
1587 ofputil_put_OFPAT10_SET_TP_SRC(out)->tp_port
1588 = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
1589 break;
1590
1591 case OFPACT_SET_L4_DST_PORT:
1592 ofputil_put_OFPAT10_SET_TP_DST(out)->tp_port
1593 = htons(ofpact_get_SET_L4_DST_PORT(a)->port);
1594 break;
1595
3e34fbdd 1596 case OFPACT_PUSH_VLAN:
b19e8793 1597 case OFPACT_CLEAR_ACTIONS:
8dd54666 1598 case OFPACT_GOTO_TABLE:
5dca28b5 1599 /* XXX */
8dd54666
IY
1600 break;
1601
f25d0cf3
BP
1602 case OFPACT_CONTROLLER:
1603 case OFPACT_OUTPUT_REG:
1604 case OFPACT_BUNDLE:
1605 case OFPACT_REG_MOVE:
1606 case OFPACT_REG_LOAD:
bd85dac1
AZ
1607 case OFPACT_STACK_PUSH:
1608 case OFPACT_STACK_POP:
f25d0cf3 1609 case OFPACT_DEC_TTL:
0f3f3c3d 1610 case OFPACT_SET_MPLS_TTL:
b676167a 1611 case OFPACT_DEC_MPLS_TTL:
f25d0cf3 1612 case OFPACT_SET_TUNNEL:
4cceacb9 1613 case OFPACT_WRITE_METADATA:
f25d0cf3
BP
1614 case OFPACT_SET_QUEUE:
1615 case OFPACT_POP_QUEUE:
1616 case OFPACT_FIN_TIMEOUT:
1617 case OFPACT_RESUBMIT:
1618 case OFPACT_LEARN:
1619 case OFPACT_MULTIPATH:
f25d0cf3
BP
1620 case OFPACT_NOTE:
1621 case OFPACT_EXIT:
b02475c5
SH
1622 case OFPACT_PUSH_MPLS:
1623 case OFPACT_POP_MPLS:
f25d0cf3
BP
1624 ofpact_to_nxast(a, out);
1625 break;
1626 }
1627}
1628
d01c980f 1629/* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow 1.0
f25d0cf3
BP
1630 * actions in 'openflow', appending the actions to any existing data in
1631 * 'openflow'. */
1632void
d01c980f
BP
1633ofpacts_put_openflow10(const struct ofpact ofpacts[], size_t ofpacts_len,
1634 struct ofpbuf *openflow)
f25d0cf3
BP
1635{
1636 const struct ofpact *a;
1637
1638 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
1639 ofpact_to_openflow10(a, openflow);
1640 }
1641}
1642\f
d01c980f
BP
1643/* Converting ofpacts to OpenFlow 1.1. */
1644
1645static void
1646ofpact_output_to_openflow11(const struct ofpact_output *output,
1647 struct ofpbuf *out)
1648{
1649 struct ofp11_action_output *oao;
1650
1651 oao = ofputil_put_OFPAT11_OUTPUT(out);
1652 oao->port = ofputil_port_to_ofp11(output->port);
1653 oao->max_len = htons(output->max_len);
1654}
1655
99086062
BP
1656static void
1657ofpact_dec_ttl_to_openflow11(const struct ofpact_cnt_ids *dec_ttl,
1658 struct ofpbuf *out)
1659{
1660 if (dec_ttl->n_controllers == 1 && dec_ttl->cnt_ids[0] == 0
1661 && (!dec_ttl->ofpact.compat ||
1662 dec_ttl->ofpact.compat == OFPUTIL_OFPAT11_DEC_NW_TTL)) {
1663 ofputil_put_OFPAT11_DEC_NW_TTL(out);
1664 } else {
1665 ofpact_dec_ttl_to_nxast(dec_ttl, out);
1666 }
1667}
1668
d01c980f
BP
1669static void
1670ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
1671{
1672 switch (a->type) {
1673 case OFPACT_OUTPUT:
1674 return ofpact_output_to_openflow11(ofpact_get_OUTPUT(a), out);
1675
1676 case OFPACT_ENQUEUE:
1677 /* XXX */
1678 break;
1679
1680 case OFPACT_SET_VLAN_VID:
1681 ofputil_put_OFPAT11_SET_VLAN_VID(out)->vlan_vid
1682 = htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid);
1683 break;
1684
1685 case OFPACT_SET_VLAN_PCP:
1686 ofputil_put_OFPAT11_SET_VLAN_PCP(out)->vlan_pcp
1687 = ofpact_get_SET_VLAN_PCP(a)->vlan_pcp;
1688 break;
1689
1690 case OFPACT_STRIP_VLAN:
8e61c110 1691 ofputil_put_OFPAT11_POP_VLAN(out);
d01c980f
BP
1692 break;
1693
3e34fbdd 1694 case OFPACT_PUSH_VLAN:
5dca28b5 1695 /* XXX ETH_TYPE_VLAN_8021AD case */
3e34fbdd
IY
1696 ofputil_put_OFPAT11_PUSH_VLAN(out)->ethertype =
1697 htons(ETH_TYPE_VLAN_8021Q);
1698 break;
1699
276c4e7a
SH
1700 case OFPACT_SET_QUEUE:
1701 ofputil_put_OFPAT11_SET_QUEUE(out)->queue_id
1702 = htonl(ofpact_get_SET_QUEUE(a)->queue_id);
1703 break;
1704
d01c980f
BP
1705 case OFPACT_SET_ETH_SRC:
1706 memcpy(ofputil_put_OFPAT11_SET_DL_SRC(out)->dl_addr,
1707 ofpact_get_SET_ETH_SRC(a)->mac, ETH_ADDR_LEN);
1708 break;
1709
1710 case OFPACT_SET_ETH_DST:
1711 memcpy(ofputil_put_OFPAT11_SET_DL_DST(out)->dl_addr,
1712 ofpact_get_SET_ETH_DST(a)->mac, ETH_ADDR_LEN);
1713 break;
1714
1715 case OFPACT_SET_IPV4_SRC:
1716 ofputil_put_OFPAT11_SET_NW_SRC(out)->nw_addr
1717 = ofpact_get_SET_IPV4_SRC(a)->ipv4;
1718 break;
1719
1720 case OFPACT_SET_IPV4_DST:
1721 ofputil_put_OFPAT11_SET_NW_DST(out)->nw_addr
1722 = ofpact_get_SET_IPV4_DST(a)->ipv4;
1723 break;
1724
1725 case OFPACT_SET_IPV4_DSCP:
1726 ofputil_put_OFPAT11_SET_NW_TOS(out)->nw_tos
1727 = ofpact_get_SET_IPV4_DSCP(a)->dscp;
1728 break;
1729
1730 case OFPACT_SET_L4_SRC_PORT:
1731 ofputil_put_OFPAT11_SET_TP_SRC(out)->tp_port
1732 = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
1733 break;
1734
1735 case OFPACT_SET_L4_DST_PORT:
1736 ofputil_put_OFPAT11_SET_TP_DST(out)->tp_port
1737 = htons(ofpact_get_SET_L4_DST_PORT(a)->port);
1738 break;
1739
7bcb1506 1740 case OFPACT_DEC_TTL:
99086062 1741 ofpact_dec_ttl_to_openflow11(ofpact_get_DEC_TTL(a), out);
7bcb1506
IY
1742 break;
1743
0f3f3c3d
SH
1744 case OFPACT_SET_MPLS_TTL:
1745 ofputil_put_OFPAT11_SET_MPLS_TTL(out)->mpls_ttl
1746 = ofpact_get_SET_MPLS_TTL(a)->ttl;
1747 break;
1748
b676167a
SH
1749 case OFPACT_DEC_MPLS_TTL:
1750 ofputil_put_OFPAT11_DEC_MPLS_TTL(out);
1751 break;
1752
4cceacb9
JS
1753 case OFPACT_WRITE_METADATA:
1754 /* OpenFlow 1.1 uses OFPIT_WRITE_METADATA to express this action. */
1755 break;
1756
b02475c5
SH
1757 case OFPACT_PUSH_MPLS:
1758 ofputil_put_OFPAT11_PUSH_MPLS(out)->ethertype =
1759 ofpact_get_PUSH_MPLS(a)->ethertype;
1760 break;
1761
1762 case OFPACT_POP_MPLS:
1763 ofputil_put_OFPAT11_POP_MPLS(out)->ethertype =
1764 ofpact_get_POP_MPLS(a)->ethertype;
1765
1766 break;
1767
b19e8793 1768 case OFPACT_CLEAR_ACTIONS:
8dd54666
IY
1769 case OFPACT_GOTO_TABLE:
1770 NOT_REACHED();
1771
d01c980f
BP
1772 case OFPACT_CONTROLLER:
1773 case OFPACT_OUTPUT_REG:
1774 case OFPACT_BUNDLE:
1775 case OFPACT_REG_MOVE:
1776 case OFPACT_REG_LOAD:
bd85dac1
AZ
1777 case OFPACT_STACK_PUSH:
1778 case OFPACT_STACK_POP:
d01c980f 1779 case OFPACT_SET_TUNNEL:
d01c980f
BP
1780 case OFPACT_POP_QUEUE:
1781 case OFPACT_FIN_TIMEOUT:
1782 case OFPACT_RESUBMIT:
1783 case OFPACT_LEARN:
1784 case OFPACT_MULTIPATH:
d01c980f
BP
1785 case OFPACT_NOTE:
1786 case OFPACT_EXIT:
1787 ofpact_to_nxast(a, out);
1788 break;
1789 }
1790}
1791
1792/* Converts the ofpacts in 'ofpacts' (terminated by OFPACT_END) into OpenFlow
1793 * 1.1 actions in 'openflow', appending the actions to any existing data in
1794 * 'openflow'. */
a07c15bc 1795size_t
d01c980f
BP
1796ofpacts_put_openflow11_actions(const struct ofpact ofpacts[],
1797 size_t ofpacts_len, struct ofpbuf *openflow)
1798{
1799 const struct ofpact *a;
a07c15bc 1800 size_t start_size = openflow->size;
d01c980f
BP
1801
1802 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
1803 ofpact_to_openflow11(a, openflow);
1804 }
a07c15bc
SH
1805
1806 return openflow->size - start_size;
d01c980f
BP
1807}
1808
8dd54666
IY
1809static void
1810ofpacts_update_instruction_actions(struct ofpbuf *openflow, size_t ofs)
d01c980f
BP
1811{
1812 struct ofp11_instruction_actions *oia;
d01c980f
BP
1813
1814 /* Update the instruction's length (or, if it's empty, delete it). */
1815 oia = ofpbuf_at_assert(openflow, ofs, sizeof *oia);
1816 if (openflow->size > ofs + sizeof *oia) {
1817 oia->len = htons(openflow->size - ofs);
1818 } else {
1819 openflow->size = ofs;
1820 }
1821}
8dd54666
IY
1822
1823void
1824ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[],
1825 size_t ofpacts_len,
1826 struct ofpbuf *openflow)
1827{
1828 const struct ofpact *a;
1829
1830 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
5dca28b5 1831 /* XXX Write-Actions */
4cceacb9 1832
b19e8793 1833 if (a->type == OFPACT_CLEAR_ACTIONS) {
f606c7e9 1834 instruction_put_OFPIT11_CLEAR_ACTIONS(openflow);
b19e8793 1835 } else if (a->type == OFPACT_GOTO_TABLE) {
8dd54666
IY
1836 struct ofp11_instruction_goto_table *oigt;
1837
1838 oigt = instruction_put_OFPIT11_GOTO_TABLE(openflow);
1839 oigt->table_id = ofpact_get_GOTO_TABLE(a)->table_id;
1840 memset(oigt->pad, 0, sizeof oigt->pad);
4cceacb9
JS
1841 } else if (a->type == OFPACT_WRITE_METADATA) {
1842 const struct ofpact_metadata *om;
1843 struct ofp11_instruction_write_metadata *oiwm;
1844
1845 om = ofpact_get_WRITE_METADATA(a);
1846 oiwm = instruction_put_OFPIT11_WRITE_METADATA(openflow);
1847 oiwm->metadata = om->metadata;
1848 oiwm->metadata_mask = om->mask;
8dd54666
IY
1849 } else if (!ofpact_is_instruction(a)) {
1850 /* Apply-actions */
1851 const size_t ofs = openflow->size;
1852 const size_t ofpacts_len_left =
1853 (uint8_t*)ofpact_end(ofpacts, ofpacts_len) - (uint8_t*)a;
1854 const struct ofpact *action;
1855 const struct ofpact *processed = a;
1856
1857 instruction_put_OFPIT11_APPLY_ACTIONS(openflow);
1858 OFPACT_FOR_EACH(action, a, ofpacts_len_left) {
1859 if (ofpact_is_instruction(action)) {
1860 break;
1861 }
1862 ofpact_to_openflow11(action, openflow);
1863 processed = action;
1864 }
1865 ofpacts_update_instruction_actions(openflow, ofs);
1866 a = processed;
1867 }
1868 }
1869}
d01c980f 1870\f
f25d0cf3
BP
1871/* Returns true if 'action' outputs to 'port', false otherwise. */
1872static bool
1873ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port)
1874{
1875 switch (ofpact->type) {
1876 case OFPACT_OUTPUT:
1877 return ofpact_get_OUTPUT(ofpact)->port == port;
1878 case OFPACT_ENQUEUE:
1879 return ofpact_get_ENQUEUE(ofpact)->port == port;
1880 case OFPACT_CONTROLLER:
1881 return port == OFPP_CONTROLLER;
1882
1883 case OFPACT_OUTPUT_REG:
1884 case OFPACT_BUNDLE:
1885 case OFPACT_SET_VLAN_VID:
1886 case OFPACT_SET_VLAN_PCP:
1887 case OFPACT_STRIP_VLAN:
3e34fbdd 1888 case OFPACT_PUSH_VLAN:
f25d0cf3
BP
1889 case OFPACT_SET_ETH_SRC:
1890 case OFPACT_SET_ETH_DST:
1891 case OFPACT_SET_IPV4_SRC:
1892 case OFPACT_SET_IPV4_DST:
1893 case OFPACT_SET_IPV4_DSCP:
1894 case OFPACT_SET_L4_SRC_PORT:
1895 case OFPACT_SET_L4_DST_PORT:
1896 case OFPACT_REG_MOVE:
1897 case OFPACT_REG_LOAD:
bd85dac1
AZ
1898 case OFPACT_STACK_PUSH:
1899 case OFPACT_STACK_POP:
f25d0cf3 1900 case OFPACT_DEC_TTL:
0f3f3c3d 1901 case OFPACT_SET_MPLS_TTL:
b676167a 1902 case OFPACT_DEC_MPLS_TTL:
f25d0cf3 1903 case OFPACT_SET_TUNNEL:
4cceacb9 1904 case OFPACT_WRITE_METADATA:
f25d0cf3
BP
1905 case OFPACT_SET_QUEUE:
1906 case OFPACT_POP_QUEUE:
1907 case OFPACT_FIN_TIMEOUT:
1908 case OFPACT_RESUBMIT:
1909 case OFPACT_LEARN:
1910 case OFPACT_MULTIPATH:
f25d0cf3
BP
1911 case OFPACT_NOTE:
1912 case OFPACT_EXIT:
b02475c5
SH
1913 case OFPACT_PUSH_MPLS:
1914 case OFPACT_POP_MPLS:
b19e8793 1915 case OFPACT_CLEAR_ACTIONS:
8dd54666 1916 case OFPACT_GOTO_TABLE:
f25d0cf3
BP
1917 default:
1918 return false;
1919 }
1920}
1921
1922/* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
1923 * to 'port', false otherwise. */
1924bool
1925ofpacts_output_to_port(const struct ofpact *ofpacts, size_t ofpacts_len,
1926 uint16_t port)
1927{
1928 const struct ofpact *a;
1929
1930 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
1931 if (ofpact_outputs_to_port(a, port)) {
1932 return true;
1933 }
1934 }
1935
1936 return false;
1937}
1938
1939bool
1940ofpacts_equal(const struct ofpact *a, size_t a_len,
1941 const struct ofpact *b, size_t b_len)
1942{
1943 return a_len == b_len && !memcmp(a, b, a_len);
1944}
1945\f
1946/* Formatting ofpacts. */
1947
1948static void
1949print_note(const struct ofpact_note *note, struct ds *string)
1950{
1951 size_t i;
1952
1953 ds_put_cstr(string, "note:");
1954 for (i = 0; i < note->length; i++) {
1955 if (i) {
1956 ds_put_char(string, '.');
1957 }
1958 ds_put_format(string, "%02"PRIx8, note->data[i]);
1959 }
1960}
1961
c2d967a5
MM
1962static void
1963print_dec_ttl(const struct ofpact_cnt_ids *ids,
1964 struct ds *s)
1965{
1966 size_t i;
1967
1968 ds_put_cstr(s, "dec_ttl");
1969 if (ids->ofpact.compat == OFPUTIL_NXAST_DEC_TTL_CNT_IDS) {
1970 ds_put_cstr(s, "(");
1971 for (i = 0; i < ids->n_controllers; i++) {
1972 if (i) {
1973 ds_put_cstr(s, ",");
1974 }
1975 ds_put_format(s, "%"PRIu16, ids->cnt_ids[i]);
1976 }
1977 ds_put_cstr(s, ")");
1978 }
1979}
1980
f25d0cf3
BP
1981static void
1982print_fin_timeout(const struct ofpact_fin_timeout *fin_timeout,
1983 struct ds *s)
1984{
1985 ds_put_cstr(s, "fin_timeout(");
1986 if (fin_timeout->fin_idle_timeout) {
1987 ds_put_format(s, "idle_timeout=%"PRIu16",",
1988 fin_timeout->fin_idle_timeout);
1989 }
1990 if (fin_timeout->fin_hard_timeout) {
1991 ds_put_format(s, "hard_timeout=%"PRIu16",",
1992 fin_timeout->fin_hard_timeout);
1993 }
1994 ds_chomp(s, ',');
1995 ds_put_char(s, ')');
1996}
1997
1998static void
1999ofpact_format(const struct ofpact *a, struct ds *s)
2000{
2001 const struct ofpact_enqueue *enqueue;
2002 const struct ofpact_resubmit *resubmit;
f25d0cf3 2003 const struct ofpact_controller *controller;
4cceacb9 2004 const struct ofpact_metadata *metadata;
f25d0cf3
BP
2005 const struct ofpact_tunnel *tunnel;
2006 uint16_t port;
2007
2008 switch (a->type) {
2009 case OFPACT_OUTPUT:
2010 port = ofpact_get_OUTPUT(a)->port;
2011 if (port < OFPP_MAX) {
2012 ds_put_format(s, "output:%"PRIu16, port);
2013 } else {
2014 ofputil_format_port(port, s);
2015 if (port == OFPP_CONTROLLER) {
2016 ds_put_format(s, ":%"PRIu16, ofpact_get_OUTPUT(a)->max_len);
2017 }
2018 }
2019 break;
2020
2021 case OFPACT_CONTROLLER:
2022 controller = ofpact_get_CONTROLLER(a);
2023 if (controller->reason == OFPR_ACTION &&
2024 controller->controller_id == 0) {
2025 ds_put_format(s, "CONTROLLER:%"PRIu16,
2026 ofpact_get_CONTROLLER(a)->max_len);
2027 } else {
2028 enum ofp_packet_in_reason reason = controller->reason;
2029
2030 ds_put_cstr(s, "controller(");
2031 if (reason != OFPR_ACTION) {
2032 ds_put_format(s, "reason=%s,",
2033 ofputil_packet_in_reason_to_string(reason));
2034 }
2035 if (controller->max_len != UINT16_MAX) {
2036 ds_put_format(s, "max_len=%"PRIu16",", controller->max_len);
2037 }
2038 if (controller->controller_id != 0) {
2039 ds_put_format(s, "id=%"PRIu16",", controller->controller_id);
2040 }
2041 ds_chomp(s, ',');
2042 ds_put_char(s, ')');
2043 }
2044 break;
2045
2046 case OFPACT_ENQUEUE:
2047 enqueue = ofpact_get_ENQUEUE(a);
2048 ds_put_format(s, "enqueue:");
2049 ofputil_format_port(enqueue->port, s);
2050 ds_put_format(s, "q%"PRIu32, enqueue->queue);
2051 break;
2052
2053 case OFPACT_OUTPUT_REG:
2054 ds_put_cstr(s, "output:");
2055 mf_format_subfield(&ofpact_get_OUTPUT_REG(a)->src, s);
2056 break;
2057
2058 case OFPACT_BUNDLE:
2059 bundle_format(ofpact_get_BUNDLE(a), s);
2060 break;
2061
2062 case OFPACT_SET_VLAN_VID:
2063 ds_put_format(s, "mod_vlan_vid:%"PRIu16,
2064 ofpact_get_SET_VLAN_VID(a)->vlan_vid);
2065 break;
2066
2067 case OFPACT_SET_VLAN_PCP:
2068 ds_put_format(s, "mod_vlan_pcp:%"PRIu8,
2069 ofpact_get_SET_VLAN_PCP(a)->vlan_pcp);
2070 break;
2071
2072 case OFPACT_STRIP_VLAN:
2073 ds_put_cstr(s, "strip_vlan");
2074 break;
2075
3e34fbdd 2076 case OFPACT_PUSH_VLAN:
5dca28b5 2077 /* XXX 802.1AD case*/
3e34fbdd
IY
2078 ds_put_format(s, "push_vlan:%#"PRIx16, ETH_TYPE_VLAN_8021Q);
2079 break;
2080
f25d0cf3
BP
2081 case OFPACT_SET_ETH_SRC:
2082 ds_put_format(s, "mod_dl_src:"ETH_ADDR_FMT,
2083 ETH_ADDR_ARGS(ofpact_get_SET_ETH_SRC(a)->mac));
2084 break;
2085
2086 case OFPACT_SET_ETH_DST:
2087 ds_put_format(s, "mod_dl_dst:"ETH_ADDR_FMT,
2088 ETH_ADDR_ARGS(ofpact_get_SET_ETH_DST(a)->mac));
2089 break;
2090
2091 case OFPACT_SET_IPV4_SRC:
2092 ds_put_format(s, "mod_nw_src:"IP_FMT,
ed36537e 2093 IP_ARGS(ofpact_get_SET_IPV4_SRC(a)->ipv4));
f25d0cf3
BP
2094 break;
2095
2096 case OFPACT_SET_IPV4_DST:
2097 ds_put_format(s, "mod_nw_dst:"IP_FMT,
ed36537e 2098 IP_ARGS(ofpact_get_SET_IPV4_DST(a)->ipv4));
f25d0cf3
BP
2099 break;
2100
2101 case OFPACT_SET_IPV4_DSCP:
2102 ds_put_format(s, "mod_nw_tos:%d", ofpact_get_SET_IPV4_DSCP(a)->dscp);
2103 break;
2104
2105 case OFPACT_SET_L4_SRC_PORT:
2106 ds_put_format(s, "mod_tp_src:%d", ofpact_get_SET_L4_SRC_PORT(a)->port);
2107 break;
2108
2109 case OFPACT_SET_L4_DST_PORT:
2110 ds_put_format(s, "mod_tp_dst:%d", ofpact_get_SET_L4_DST_PORT(a)->port);
2111 break;
2112
2113 case OFPACT_REG_MOVE:
2114 nxm_format_reg_move(ofpact_get_REG_MOVE(a), s);
2115 break;
2116
2117 case OFPACT_REG_LOAD:
2118 nxm_format_reg_load(ofpact_get_REG_LOAD(a), s);
2119 break;
2120
bd85dac1
AZ
2121 case OFPACT_STACK_PUSH:
2122 nxm_format_stack_push(ofpact_get_STACK_PUSH(a), s);
2123 break;
2124
2125 case OFPACT_STACK_POP:
2126 nxm_format_stack_pop(ofpact_get_STACK_POP(a), s);
2127 break;
2128
f25d0cf3 2129 case OFPACT_DEC_TTL:
c2d967a5 2130 print_dec_ttl(ofpact_get_DEC_TTL(a), s);
f25d0cf3
BP
2131 break;
2132
0f3f3c3d
SH
2133 case OFPACT_SET_MPLS_TTL:
2134 ds_put_format(s, "set_mpls_ttl(%"PRIu8")",
2135 ofpact_get_SET_MPLS_TTL(a)->ttl);
2136 break;
2137
b676167a
SH
2138 case OFPACT_DEC_MPLS_TTL:
2139 ds_put_cstr(s, "dec_mpls_ttl");
2140 break;
2141
f25d0cf3
BP
2142 case OFPACT_SET_TUNNEL:
2143 tunnel = ofpact_get_SET_TUNNEL(a);
2144 ds_put_format(s, "set_tunnel%s:%#"PRIx64,
2145 (tunnel->tun_id > UINT32_MAX
2146 || a->compat == OFPUTIL_NXAST_SET_TUNNEL64 ? "64" : ""),
2147 tunnel->tun_id);
2148 break;
2149
2150 case OFPACT_SET_QUEUE:
2151 ds_put_format(s, "set_queue:%"PRIu32,
2152 ofpact_get_SET_QUEUE(a)->queue_id);
2153 break;
2154
2155 case OFPACT_POP_QUEUE:
2156 ds_put_cstr(s, "pop_queue");
2157 break;
2158
2159 case OFPACT_FIN_TIMEOUT:
2160 print_fin_timeout(ofpact_get_FIN_TIMEOUT(a), s);
2161 break;
2162
2163 case OFPACT_RESUBMIT:
2164 resubmit = ofpact_get_RESUBMIT(a);
2165 if (resubmit->in_port != OFPP_IN_PORT && resubmit->table_id == 255) {
c6100d92
BP
2166 ds_put_cstr(s, "resubmit:");
2167 ofputil_format_port(resubmit->in_port, s);
f25d0cf3
BP
2168 } else {
2169 ds_put_format(s, "resubmit(");
2170 if (resubmit->in_port != OFPP_IN_PORT) {
2171 ofputil_format_port(resubmit->in_port, s);
2172 }
2173 ds_put_char(s, ',');
2174 if (resubmit->table_id != 255) {
2175 ds_put_format(s, "%"PRIu8, resubmit->table_id);
2176 }
2177 ds_put_char(s, ')');
2178 }
2179 break;
2180
2181 case OFPACT_LEARN:
2182 learn_format(ofpact_get_LEARN(a), s);
2183 break;
2184
2185 case OFPACT_MULTIPATH:
2186 multipath_format(ofpact_get_MULTIPATH(a), s);
2187 break;
2188
f25d0cf3
BP
2189 case OFPACT_NOTE:
2190 print_note(ofpact_get_NOTE(a), s);
2191 break;
2192
b02475c5
SH
2193 case OFPACT_PUSH_MPLS:
2194 ds_put_format(s, "push_mpls:0x%04"PRIx16,
2195 ntohs(ofpact_get_PUSH_MPLS(a)->ethertype));
2196 break;
2197
2198 case OFPACT_POP_MPLS:
2199 ds_put_format(s, "pop_mpls:0x%04"PRIx16,
2200 ntohs(ofpact_get_POP_MPLS(a)->ethertype));
2201 break;
2202
f25d0cf3
BP
2203 case OFPACT_EXIT:
2204 ds_put_cstr(s, "exit");
2205 break;
8dd54666 2206
b19e8793
IY
2207 case OFPACT_CLEAR_ACTIONS:
2208 ds_put_format(s, "%s",
2209 ofpact_instruction_name_from_type(
2210 OVSINST_OFPIT11_CLEAR_ACTIONS));
2211 break;
2212
4cceacb9
JS
2213 case OFPACT_WRITE_METADATA:
2214 metadata = ofpact_get_WRITE_METADATA(a);
2215 ds_put_format(s, "%s:%#"PRIx64,
2216 ofpact_instruction_name_from_type(
2217 OVSINST_OFPIT11_WRITE_METADATA),
2218 ntohll(metadata->metadata));
2219 if (metadata->mask != htonll(UINT64_MAX)) {
2220 ds_put_format(s, "/%#"PRIx64, ntohll(metadata->mask));
2221 }
2222 break;
2223
8dd54666
IY
2224 case OFPACT_GOTO_TABLE:
2225 ds_put_format(s, "%s:%"PRIu8,
2226 ofpact_instruction_name_from_type(
2227 OVSINST_OFPIT11_GOTO_TABLE),
2228 ofpact_get_GOTO_TABLE(a)->table_id);
2229 break;
f25d0cf3
BP
2230 }
2231}
2232
2233/* Appends a string representing the 'ofpacts_len' bytes of ofpacts in
2234 * 'ofpacts' to 'string'. */
2235void
2236ofpacts_format(const struct ofpact *ofpacts, size_t ofpacts_len,
2237 struct ds *string)
2238{
2239 ds_put_cstr(string, "actions=");
2240 if (!ofpacts_len) {
2241 ds_put_cstr(string, "drop");
2242 } else {
2243 const struct ofpact *a;
2244
2245 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
2246 if (a != ofpacts) {
2247 ds_put_cstr(string, ",");
2248 }
8dd54666 2249
5dca28b5 2250 /* XXX write-actions */
f25d0cf3
BP
2251 ofpact_format(a, string);
2252 }
2253 }
2254}
2255\f
2256/* Internal use by helpers. */
2257
2258void *
2259ofpact_put(struct ofpbuf *ofpacts, enum ofpact_type type, size_t len)
2260{
2261 struct ofpact *ofpact;
2262
2263 ofpact_pad(ofpacts);
2264 ofpact = ofpacts->l2 = ofpbuf_put_uninit(ofpacts, len);
2265 ofpact_init(ofpact, type, len);
2266 return ofpact;
2267}
2268
2269void
2270ofpact_init(struct ofpact *ofpact, enum ofpact_type type, size_t len)
2271{
2272 memset(ofpact, 0, len);
2273 ofpact->type = type;
2274 ofpact->compat = OFPUTIL_ACTION_INVALID;
2275 ofpact->len = len;
2276}
2277\f
2278/* Updates 'ofpact->len' to the number of bytes in the tail of 'ofpacts'
2279 * starting at 'ofpact'.
2280 *
2281 * This is the correct way to update a variable-length ofpact's length after
2282 * adding the variable-length part of the payload. (See the large comment
2283 * near the end of ofp-actions.h for more information.) */
2284void
2285ofpact_update_len(struct ofpbuf *ofpacts, struct ofpact *ofpact)
2286{
cb22974d 2287 ovs_assert(ofpact == ofpacts->l2);
f25d0cf3
BP
2288 ofpact->len = (char *) ofpbuf_tail(ofpacts) - (char *) ofpact;
2289}
2290
2291/* Pads out 'ofpacts' to a multiple of OFPACT_ALIGNTO bytes in length. Each
2292 * ofpact_put_<ENUM>() calls this function automatically beforehand, but the
2293 * client must call this itself after adding the final ofpact to an array of
2294 * them.
2295 *
2296 * (The consequences of failing to call this function are probably not dire.
2297 * OFPACT_FOR_EACH will calculate a pointer beyond the end of the ofpacts, but
2298 * not dereference it. That's undefined behavior, technically, but it will not
2299 * cause a real problem on common systems. Still, it seems better to call
2300 * it.) */
2301void
2302ofpact_pad(struct ofpbuf *ofpacts)
2303{
2304 unsigned int rem = ofpacts->size % OFPACT_ALIGNTO;
2305 if (rem) {
2306 ofpbuf_put_zeros(ofpacts, OFPACT_ALIGNTO - rem);
2307 }
2308}
f5c45121
SH
2309
2310void
2311ofpact_set_field_init(struct ofpact_reg_load *load, const struct mf_field *mf,
2312 const void *src)
2313{
2314 load->ofpact.compat = OFPUTIL_OFPAT12_SET_FIELD;
2315 load->dst.field = mf;
2316 load->dst.ofs = 0;
2317 load->dst.n_bits = mf->n_bits;
2318 bitwise_copy(src, mf->n_bytes, load->dst.ofs,
2319 &load->subvalue, sizeof load->subvalue, 0, mf->n_bits);
2320}