]> git.proxmox.com Git - mirror_ovs.git/blame - lib/ofp-actions.c
meta-flow: Remove cmap dependency.
[mirror_ovs.git] / lib / ofp-actions.c
CommitLineData
f25d0cf3 1/*
72fe7578 2 * Copyright (c) 2008-2017 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>
d787ad39
JS
18#include <netinet/in.h>
19
f25d0cf3
BP
20#include "bundle.h"
21#include "byte-order.h"
b1c5bf1f 22#include "colors.h"
f25d0cf3 23#include "compiler.h"
d4abaff5 24#include "dummy.h"
ee89ea7b 25#include "openvswitch/hmap.h"
f25d0cf3 26#include "learn.h"
f25d0cf3
BP
27#include "multipath.h"
28#include "nx-match.h"
9ac0aada 29#include "odp-netlink.h"
b598f214
BW
30#include "openvswitch/dynamic-string.h"
31#include "openvswitch/meta-flow.h"
32#include "openvswitch/ofp-actions.h"
f4248336 33#include "openvswitch/ofp-util.h"
b598f214 34#include "openvswitch/ofp-parse.h"
66bd43fa 35#include "openvswitch/ofp-prop.h"
64c96779 36#include "openvswitch/ofpbuf.h"
b598f214 37#include "openvswitch/vlog.h"
c2d936a4 38#include "unaligned.h"
cb22974d 39#include "util.h"
aafee638 40#include "vl-mff-map.h"
f25d0cf3
BP
41
42VLOG_DEFINE_THIS_MODULE(ofp_actions);
43
44static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
f25d0cf3 45
c2d936a4
BP
46struct ofp_action_header;
47
aad28f47
BP
48/* Header for Open vSwitch and ONF vendor extension actions.
49 *
50 * This is the entire header for a few Open vSwitch vendor extension actions,
51 * the ones that either have no arguments or for which variable-length
52 * arguments follow the header.
53 *
54 * This cannot be used as an entirely generic vendor extension action header,
55 * because OpenFlow does not specify the location or size of the action
56 * subtype; it just happens that ONF extensions and Nicira extensions share
57 * this format. */
58struct ext_action_header {
59 ovs_be16 type; /* OFPAT_VENDOR. */
60 ovs_be16 len; /* At least 16. */
61 ovs_be32 vendor; /* NX_VENDOR_ID or ONF_VENDOR_ID. */
62 ovs_be16 subtype; /* See enum ofp_raw_action_type. */
63 uint8_t pad[6];
64};
65OFP_ASSERT(sizeof(struct ext_action_header) == 16);
66
c2d936a4
BP
67/* Raw identifiers for OpenFlow actions.
68 *
69 * Decoding and encoding OpenFlow actions across multiple versions is difficult
70 * to do in a clean, consistent way. This enumeration lays out all of the
71 * forms of actions that Open vSwitch supports.
72 *
73 * The comments here must follow a stylized form because the
74 * "extract-ofp-actions" program parses them at build time to generate data
75 * tables.
76 *
77 * - The first part of each comment specifies the vendor, OpenFlow versions,
78 * and type for each protocol that supports the action:
79 *
80 * # The vendor is OF for standard OpenFlow actions, NX for Nicira
81 * extension actions. (Support for other vendors can be added, but
82 * it can't be done just based on a vendor ID definition alone
83 * because OpenFlow doesn't define a standard way to specify a
84 * subtype for vendor actions, so other vendors might do it different
85 * from Nicira.)
86 *
87 * # The version can specify a specific OpenFlow version, a version
88 * range delimited by "-", or an open-ended range with "+".
89 *
90 * # The type, in parentheses, is the action type number (for standard
91 * OpenFlow actions) or subtype (for vendor extension actions).
92 *
93 * # Optionally one may add "is deprecated" followed by a
94 * human-readable reason in parentheses (which will be used in log
95 * messages), if a particular action should no longer be used.
96 *
97 * Multiple such specifications may be separated by commas.
98 *
99 * - The second part describes the action's wire format. It may be:
100 *
101 * # "struct <name>": The struct fully specifies the wire format. The
102 * action is exactly the size of the struct. (Thus, the struct must
103 * be an exact multiple of 8 bytes in size.)
104 *
105 * # "struct <name>, ...": The struct specifies the beginning of the
106 * wire format. An instance of the action is either the struct's
107 * exact size, or a multiple of 8 bytes longer.
108 *
109 * # "uint<N>_t" or "ovs_be<N>": The action consists of a (standard or
110 * vendor extension) header, followed by 0 or more pad bytes to align
111 * to a multiple of <N> bits, followed by an argument of the given
112 * type, followed by 0 or more pad bytes to bring the total action up
113 * to a multiple of 8 bytes.
114 *
115 * # "void": The action is just a (standard or vendor extension)
116 * header.
117 *
04f48a68
YHW
118 * # Optionally, one may add "VLMFF" in the end of the second part if
119 * the Openflow action may use a variable length meta-flow field
120 * (i.e. tun_metadata). Adding "VLMFF" will pass the per-switch based
121 * variable length meta-flow field mapping map (struct vl_mff_map) to
122 * the corresponding action decoding function.
123 *
c2d936a4
BP
124 * - Optional additional text enclosed in square brackets is commentary for
125 * the human reader.
126 */
127enum ofp_raw_action_type {
128/* ## ----------------- ## */
129/* ## Standard actions. ## */
130/* ## ----------------- ## */
131
132 /* OF1.0(0): struct ofp10_action_output. */
133 OFPAT_RAW10_OUTPUT,
134 /* OF1.1+(0): struct ofp11_action_output. */
135 OFPAT_RAW11_OUTPUT,
136
137 /* OF1.0(1): uint16_t. */
138 OFPAT_RAW10_SET_VLAN_VID,
139 /* OF1.0(2): uint8_t. */
140 OFPAT_RAW10_SET_VLAN_PCP,
141
142 /* OF1.1(1), OF1.2+(1) is deprecated (use Set-Field): uint16_t.
143 *
144 * [Semantics differ slightly between the 1.0 and 1.1 versions of the VLAN
145 * modification actions: the 1.0 versions push a VLAN header if none is
146 * present, but the 1.1 versions do not. That is the only reason that we
147 * distinguish their raw action types.] */
148 OFPAT_RAW11_SET_VLAN_VID,
149 /* OF1.1(2), OF1.2+(2) is deprecated (use Set-Field): uint8_t. */
150 OFPAT_RAW11_SET_VLAN_PCP,
151
152 /* OF1.1+(17): ovs_be16.
153 *
154 * [The argument is the Ethertype, e.g. ETH_TYPE_VLAN_8021Q, not the VID or
155 * TCI.] */
156 OFPAT_RAW11_PUSH_VLAN,
157
158 /* OF1.0(3): void. */
159 OFPAT_RAW10_STRIP_VLAN,
160 /* OF1.1+(18): void. */
161 OFPAT_RAW11_POP_VLAN,
162
163 /* OF1.0(4), OF1.1(3), OF1.2+(3) is deprecated (use Set-Field): struct
164 * ofp_action_dl_addr. */
165 OFPAT_RAW_SET_DL_SRC,
166
167 /* OF1.0(5), OF1.1(4), OF1.2+(4) is deprecated (use Set-Field): struct
168 * ofp_action_dl_addr. */
169 OFPAT_RAW_SET_DL_DST,
170
171 /* OF1.0(6), OF1.1(5), OF1.2+(5) is deprecated (use Set-Field):
172 * ovs_be32. */
173 OFPAT_RAW_SET_NW_SRC,
174
175 /* OF1.0(7), OF1.1(6), OF1.2+(6) is deprecated (use Set-Field):
176 * ovs_be32. */
177 OFPAT_RAW_SET_NW_DST,
178
179 /* OF1.0(8), OF1.1(7), OF1.2+(7) is deprecated (use Set-Field): uint8_t. */
180 OFPAT_RAW_SET_NW_TOS,
181
182 /* OF1.1(8), OF1.2+(8) is deprecated (use Set-Field): uint8_t. */
183 OFPAT_RAW11_SET_NW_ECN,
184
185 /* OF1.0(9), OF1.1(9), OF1.2+(9) is deprecated (use Set-Field):
186 * ovs_be16. */
187 OFPAT_RAW_SET_TP_SRC,
188
189 /* OF1.0(10), OF1.1(10), OF1.2+(10) is deprecated (use Set-Field):
190 * ovs_be16. */
191 OFPAT_RAW_SET_TP_DST,
192
193 /* OF1.0(11): struct ofp10_action_enqueue. */
194 OFPAT_RAW10_ENQUEUE,
195
196 /* NX1.0(30), OF1.1(13), OF1.2+(13) is deprecated (use Set-Field):
197 * ovs_be32. */
198 OFPAT_RAW_SET_MPLS_LABEL,
199
200 /* NX1.0(31), OF1.1(14), OF1.2+(14) is deprecated (use Set-Field):
201 * uint8_t. */
202 OFPAT_RAW_SET_MPLS_TC,
203
204 /* NX1.0(25), OF1.1(15), OF1.2+(15) is deprecated (use Set-Field):
205 * uint8_t. */
206 OFPAT_RAW_SET_MPLS_TTL,
207
208 /* NX1.0(26), OF1.1+(16): void. */
209 OFPAT_RAW_DEC_MPLS_TTL,
210
211 /* NX1.0(23), OF1.1+(19): ovs_be16.
212 *
213 * [The argument is the Ethertype, e.g. ETH_TYPE_MPLS, not the label.] */
214 OFPAT_RAW_PUSH_MPLS,
215
216 /* NX1.0(24), OF1.1+(20): ovs_be16.
217 *
218 * [The argument is the Ethertype, e.g. ETH_TYPE_IPV4 if at BoS or
219 * ETH_TYPE_MPLS otherwise, not the label.] */
220 OFPAT_RAW_POP_MPLS,
221
222 /* NX1.0(4), OF1.1+(21): uint32_t. */
223 OFPAT_RAW_SET_QUEUE,
224
88c8ca26
BP
225 /* NX1.0(40), OF1.1+(22): uint32_t. */
226 OFPAT_RAW_GROUP,
c2d936a4
BP
227
228 /* OF1.1+(23): uint8_t. */
229 OFPAT_RAW11_SET_NW_TTL,
230
231 /* NX1.0(18), OF1.1+(24): void. */
232 OFPAT_RAW_DEC_NW_TTL,
233 /* NX1.0+(21): struct nx_action_cnt_ids, ... */
234 NXAST_RAW_DEC_TTL_CNT_IDS,
235
04f48a68 236 /* OF1.2-1.4(25): struct ofp12_action_set_field, ... VLMFF */
c2d936a4 237 OFPAT_RAW12_SET_FIELD,
04f48a68 238 /* OF1.5+(25): struct ofp12_action_set_field, ... VLMFF */
7eb4b1f1 239 OFPAT_RAW15_SET_FIELD,
04f48a68 240 /* NX1.0-1.4(7): struct nx_action_reg_load. VLMFF
7eb4b1f1
BP
241 *
242 * [In OpenFlow 1.5, set_field is a superset of reg_load functionality, so
243 * we drop reg_load.] */
c2d936a4 244 NXAST_RAW_REG_LOAD,
04f48a68 245 /* NX1.0-1.4(33): struct ext_action_header, ... VLMFF
bad8a439
BP
246 *
247 * [In OpenFlow 1.5, set_field is a superset of reg_load2 functionality, so
248 * we drop reg_load2.] */
249 NXAST_RAW_REG_LOAD2,
c2d936a4 250
04f48a68 251 /* OF1.5+(28): struct ofp15_action_copy_field, ... VLMFF */
73178f20 252 OFPAT_RAW15_COPY_FIELD,
04f48a68 253 /* ONF1.3-1.4(3200): struct onf_action_copy_field, ... VLMFF */
914624f8 254 ONFACT_RAW13_COPY_FIELD,
04f48a68 255 /* NX1.0-1.4(6): struct nx_action_reg_move, ... VLMFF */
73178f20
BP
256 NXAST_RAW_REG_MOVE,
257
c2d936a4
BP
258/* ## ------------------------- ## */
259/* ## Nicira extension actions. ## */
260/* ## ------------------------- ## */
261
262/* Actions similar to standard actions are listed with the standard actions. */
263
264 /* NX1.0+(1): uint16_t. */
265 NXAST_RAW_RESUBMIT,
266 /* NX1.0+(14): struct nx_action_resubmit. */
267 NXAST_RAW_RESUBMIT_TABLE,
268
269 /* NX1.0+(2): uint32_t. */
270 NXAST_RAW_SET_TUNNEL,
271 /* NX1.0+(9): uint64_t. */
272 NXAST_RAW_SET_TUNNEL64,
273
274 /* NX1.0+(5): void. */
275 NXAST_RAW_POP_QUEUE,
276
c2d936a4
BP
277 /* NX1.0+(8): struct nx_action_note, ... */
278 NXAST_RAW_NOTE,
279
04f48a68 280 /* NX1.0+(10): struct nx_action_multipath. VLMFF */
c2d936a4
BP
281 NXAST_RAW_MULTIPATH,
282
283 /* NX1.0+(12): struct nx_action_bundle, ... */
284 NXAST_RAW_BUNDLE,
04f48a68 285 /* NX1.0+(13): struct nx_action_bundle, ... VLMFF */
c2d936a4
BP
286 NXAST_RAW_BUNDLE_LOAD,
287
04f48a68 288 /* NX1.0+(15): struct nx_action_output_reg. VLMFF */
c2d936a4 289 NXAST_RAW_OUTPUT_REG,
04f48a68 290 /* NX1.0+(32): struct nx_action_output_reg2. VLMFF */
bad8a439 291 NXAST_RAW_OUTPUT_REG2,
c2d936a4 292
04f48a68 293 /* NX1.0+(16): struct nx_action_learn, ... VLMFF */
c2d936a4
BP
294 NXAST_RAW_LEARN,
295
296 /* NX1.0+(17): void. */
297 NXAST_RAW_EXIT,
298
299 /* NX1.0+(19): struct nx_action_fin_timeout. */
300 NXAST_RAW_FIN_TIMEOUT,
301
302 /* NX1.0+(20): struct nx_action_controller. */
303 NXAST_RAW_CONTROLLER,
aad28f47 304 /* NX1.0+(37): struct ext_action_header, ... */
bdcad671 305 NXAST_RAW_CONTROLLER2,
c2d936a4
BP
306
307 /* NX1.0+(22): struct nx_action_write_metadata. */
308 NXAST_RAW_WRITE_METADATA,
309
04f48a68 310 /* NX1.0+(27): struct nx_action_stack. VLMFF */
c2d936a4
BP
311 NXAST_RAW_STACK_PUSH,
312
04f48a68 313 /* NX1.0+(28): struct nx_action_stack. VLMFF */
c2d936a4
BP
314 NXAST_RAW_STACK_POP,
315
316 /* NX1.0+(29): struct nx_action_sample. */
317 NXAST_RAW_SAMPLE,
f69f713b
BY
318 /* NX1.0+(38): struct nx_action_sample2. */
319 NXAST_RAW_SAMPLE2,
4930ea56
BP
320 /* NX1.0+(41): struct nx_action_sample2. */
321 NXAST_RAW_SAMPLE3,
18080541
BP
322
323 /* NX1.0+(34): struct nx_action_conjunction. */
324 NXAST_RAW_CONJUNCTION,
d4abaff5 325
04f48a68 326 /* NX1.0+(35): struct nx_action_conntrack, ... VLMFF */
07659514
JS
327 NXAST_RAW_CT,
328
9ac0aada
JR
329 /* NX1.0+(36): struct nx_action_nat, ... */
330 NXAST_RAW_NAT,
331
aaca4fe0
WT
332 /* NX1.0+(39): struct nx_action_output_trunc. */
333 NXAST_RAW_OUTPUT_TRUNC,
334
04f48a68 335 /* NX1.0+(42): struct ext_action_header, ... VLMFF */
7ae62a67
WT
336 NXAST_RAW_CLONE,
337
72fe7578
BP
338 /* NX1.0+(43): void. */
339 NXAST_RAW_CT_CLEAR,
340
d4abaff5
BP
341/* ## ------------------ ## */
342/* ## Debugging actions. ## */
343/* ## ------------------ ## */
344
345/* These are intentionally undocumented, subject to change, and ovs-vswitchd */
346/* accepts them only if started with --enable-dummy. */
347
348 /* NX1.0+(255): void. */
349 NXAST_RAW_DEBUG_RECIRC,
c2d936a4
BP
350};
351
352/* OpenFlow actions are always a multiple of 8 bytes in length. */
353#define OFP_ACTION_ALIGN 8
354
355/* Define a few functions for working with instructions. */
356#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
357 static inline const struct STRUCT * OVS_UNUSED \
358 instruction_get_##ENUM(const struct ofp11_instruction *inst)\
359 { \
360 ovs_assert(inst->type == htons(ENUM)); \
361 return ALIGNED_CAST(struct STRUCT *, inst); \
362 } \
363 \
364 static inline void OVS_UNUSED \
365 instruction_init_##ENUM(struct STRUCT *s) \
366 { \
367 memset(s, 0, sizeof *s); \
368 s->type = htons(ENUM); \
369 s->len = htons(sizeof *s); \
370 } \
371 \
372 static inline struct STRUCT * OVS_UNUSED \
373 instruction_put_##ENUM(struct ofpbuf *buf) \
374 { \
375 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
376 instruction_init_##ENUM(s); \
377 return s; \
378 }
379OVS_INSTRUCTIONS
380#undef DEFINE_INST
381
382static void ofpacts_update_instruction_actions(struct ofpbuf *openflow,
383 size_t ofs);
178742f9 384static void pad_ofpat(struct ofpbuf *openflow, size_t start_ofs);
c2d936a4
BP
385
386static enum ofperr ofpacts_verify(const struct ofpact[], size_t ofpacts_len,
d824b5b7
JS
387 uint32_t allowed_ovsinsts,
388 enum ofpact_type outer_action);
c2d936a4 389
128684a6
JR
390static void put_set_field(struct ofpbuf *openflow, enum ofp_version,
391 enum mf_field_id, uint64_t value);
c2d936a4 392
4b684612
BP
393static void put_reg_load(struct ofpbuf *openflow,
394 const struct mf_subfield *, uint64_t value);
395
c2d936a4
BP
396static enum ofperr ofpact_pull_raw(struct ofpbuf *, enum ofp_version,
397 enum ofp_raw_action_type *, uint64_t *arg);
398static void *ofpact_put_raw(struct ofpbuf *, enum ofp_version,
399 enum ofp_raw_action_type, uint64_t arg);
400
cab50449 401static char *OVS_WARN_UNUSED_RESULT ofpacts_parse(
c2d936a4 402 char *str, struct ofpbuf *ofpacts, enum ofputil_protocol *usable_protocols,
d824b5b7 403 bool allow_instructions, enum ofpact_type outer_action);
07659514
JS
404static enum ofperr ofpacts_pull_openflow_actions__(
405 struct ofpbuf *openflow, unsigned int actions_len,
406 enum ofp_version version, uint32_t allowed_ovsinsts,
04f48a68
YHW
407 struct ofpbuf *ofpacts, enum ofpact_type outer_action,
408 const struct vl_mff_map *vl_mff_map);
8e53fe8c
JS
409static char * OVS_WARN_UNUSED_RESULT ofpacts_parse_copy(
410 const char *s_, struct ofpbuf *ofpacts,
411 enum ofputil_protocol *usable_protocols,
412 bool allow_instructions, enum ofpact_type outer_action);
d824b5b7 413
4f20179d
BP
414/* Returns the ofpact following 'ofpact', except that if 'ofpact' contains
415 * nested ofpacts it returns the first one. */
416struct ofpact *
417ofpact_next_flattened(const struct ofpact *ofpact)
418{
419 switch (ofpact->type) {
420 case OFPACT_OUTPUT:
421 case OFPACT_GROUP:
422 case OFPACT_CONTROLLER:
423 case OFPACT_ENQUEUE:
424 case OFPACT_OUTPUT_REG:
aaca4fe0 425 case OFPACT_OUTPUT_TRUNC:
4f20179d
BP
426 case OFPACT_BUNDLE:
427 case OFPACT_SET_FIELD:
428 case OFPACT_SET_VLAN_VID:
429 case OFPACT_SET_VLAN_PCP:
430 case OFPACT_STRIP_VLAN:
431 case OFPACT_PUSH_VLAN:
432 case OFPACT_SET_ETH_SRC:
433 case OFPACT_SET_ETH_DST:
434 case OFPACT_SET_IPV4_SRC:
435 case OFPACT_SET_IPV4_DST:
436 case OFPACT_SET_IP_DSCP:
437 case OFPACT_SET_IP_ECN:
438 case OFPACT_SET_IP_TTL:
439 case OFPACT_SET_L4_SRC_PORT:
440 case OFPACT_SET_L4_DST_PORT:
441 case OFPACT_REG_MOVE:
442 case OFPACT_STACK_PUSH:
443 case OFPACT_STACK_POP:
444 case OFPACT_DEC_TTL:
445 case OFPACT_SET_MPLS_LABEL:
446 case OFPACT_SET_MPLS_TC:
447 case OFPACT_SET_MPLS_TTL:
448 case OFPACT_DEC_MPLS_TTL:
449 case OFPACT_PUSH_MPLS:
450 case OFPACT_POP_MPLS:
451 case OFPACT_SET_TUNNEL:
452 case OFPACT_SET_QUEUE:
453 case OFPACT_POP_QUEUE:
454 case OFPACT_FIN_TIMEOUT:
455 case OFPACT_RESUBMIT:
456 case OFPACT_LEARN:
457 case OFPACT_CONJUNCTION:
458 case OFPACT_MULTIPATH:
459 case OFPACT_NOTE:
460 case OFPACT_EXIT:
461 case OFPACT_SAMPLE:
462 case OFPACT_UNROLL_XLATE:
72fe7578 463 case OFPACT_CT_CLEAR:
4f20179d
BP
464 case OFPACT_DEBUG_RECIRC:
465 case OFPACT_METER:
466 case OFPACT_CLEAR_ACTIONS:
467 case OFPACT_WRITE_METADATA:
468 case OFPACT_GOTO_TABLE:
469 case OFPACT_NAT:
470 return ofpact_next(ofpact);
471
7ae62a67
WT
472 case OFPACT_CLONE:
473 return ofpact_get_CLONE(ofpact)->actions;
474
4f20179d
BP
475 case OFPACT_CT:
476 return ofpact_get_CT(ofpact)->actions;
477
478 case OFPACT_WRITE_ACTIONS:
479 return ofpact_get_WRITE_ACTIONS(ofpact)->actions;
480 }
481
482 OVS_NOT_REACHED();
483}
484
d824b5b7
JS
485/* Pull off existing actions or instructions. Used by nesting actions to keep
486 * ofpacts_parse() oblivious of actions nesting.
487 *
488 * Push the actions back on after nested parsing, e.g.:
489 *
490 * size_t ofs = ofpacts_pull(ofpacts);
491 * ...nested parsing...
492 * ofpbuf_push_uninit(ofpacts, ofs);
493 */
494static size_t
495ofpacts_pull(struct ofpbuf *ofpacts)
496{
497 size_t ofs;
498
d824b5b7
JS
499 ofs = ofpacts->size;
500 ofpbuf_pull(ofpacts, ofs);
501
502 return ofs;
503}
c2d936a4
BP
504
505#include "ofp-actions.inc1"
506\f
507/* Output actions. */
508
509/* Action structure for OFPAT10_OUTPUT, which sends packets out 'port'.
510 * When the 'port' is the OFPP_CONTROLLER, 'max_len' indicates the max
511 * number of bytes to send. A 'max_len' of zero means no bytes of the
512 * packet should be sent. */
513struct ofp10_action_output {
514 ovs_be16 type; /* OFPAT10_OUTPUT. */
515 ovs_be16 len; /* Length is 8. */
516 ovs_be16 port; /* Output port. */
517 ovs_be16 max_len; /* Max length to send to controller. */
e45e72f1 518};
c2d936a4
BP
519OFP_ASSERT(sizeof(struct ofp10_action_output) == 8);
520
521/* Action structure for OFPAT_OUTPUT, which sends packets out 'port'.
522 * When the 'port' is the OFPP_CONTROLLER, 'max_len' indicates the max
523 * number of bytes to send. A 'max_len' of zero means no bytes of the
524 * packet should be sent.*/
525struct ofp11_action_output {
526 ovs_be16 type; /* OFPAT11_OUTPUT. */
527 ovs_be16 len; /* Length is 16. */
528 ovs_be32 port; /* Output port. */
529 ovs_be16 max_len; /* Max length to send to controller. */
530 uint8_t pad[6]; /* Pad to 64 bits. */
531};
532OFP_ASSERT(sizeof(struct ofp11_action_output) == 16);
e45e72f1 533
f25d0cf3 534static enum ofperr
c2d936a4 535decode_OFPAT_RAW10_OUTPUT(const struct ofp10_action_output *oao,
f3cd3ac7 536 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4 537 struct ofpbuf *out)
f25d0cf3
BP
538{
539 struct ofpact_output *output;
540
541 output = ofpact_put_OUTPUT(out);
4e022ec0 542 output->port = u16_to_ofp(ntohs(oao->port));
f25d0cf3
BP
543 output->max_len = ntohs(oao->max_len);
544
57ad4e9e 545 return ofpact_check_output_port(output->port, OFPP_MAX);
f25d0cf3
BP
546}
547
548static enum ofperr
c2d936a4 549decode_OFPAT_RAW11_OUTPUT(const struct ofp11_action_output *oao,
f3cd3ac7
JS
550 enum ofp_version ofp_version OVS_UNUSED,
551 struct ofpbuf *out)
f25d0cf3 552{
c2d936a4
BP
553 struct ofpact_output *output;
554 enum ofperr error;
f25d0cf3 555
c2d936a4
BP
556 output = ofpact_put_OUTPUT(out);
557 output->max_len = ntohs(oao->max_len);
558
559 error = ofputil_port_from_ofp11(oao->port, &output->port);
560 if (error) {
561 return error;
f25d0cf3 562 }
c2d936a4
BP
563
564 return ofpact_check_output_port(output->port, OFPP_MAX);
f25d0cf3
BP
565}
566
567static void
c2d936a4
BP
568encode_OUTPUT(const struct ofpact_output *output,
569 enum ofp_version ofp_version, struct ofpbuf *out)
f25d0cf3 570{
c2d936a4
BP
571 if (ofp_version == OFP10_VERSION) {
572 struct ofp10_action_output *oao;
f25d0cf3 573
c2d936a4
BP
574 oao = put_OFPAT10_OUTPUT(out);
575 oao->port = htons(ofp_to_u16(output->port));
576 oao->max_len = htons(output->max_len);
577 } else {
578 struct ofp11_action_output *oao;
579
580 oao = put_OFPAT11_OUTPUT(out);
581 oao->port = ofputil_port_to_ofp11(output->port);
582 oao->max_len = htons(output->max_len);
583 }
f25d0cf3
BP
584}
585
aaca4fe0
WT
586static char * OVS_WARN_UNUSED_RESULT
587parse_truncate_subfield(struct ofpact_output_trunc *output_trunc,
588 const char *arg_)
589{
590 char *key, *value;
591 char *arg = CONST_CAST(char *, arg_);
592
593 while (ofputil_parse_key_value(&arg, &key, &value)) {
594 if (!strcmp(key, "port")) {
595 if (!ofputil_port_from_string(value, &output_trunc->port)) {
596 return xasprintf("output to unknown truncate port: %s",
597 value);
598 }
599 if (ofp_to_u16(output_trunc->port) > ofp_to_u16(OFPP_MAX)) {
600 if (output_trunc->port != OFPP_LOCAL &&
601 output_trunc->port != OFPP_IN_PORT)
602 return xasprintf("output to unsupported truncate port: %s",
603 value);
604 }
605 } else if (!strcmp(key, "max_len")) {
606 char *err;
607
608 err = str_to_u32(value, &output_trunc->max_len);
609 if (err) {
610 return err;
611 }
612 } else {
613 return xasprintf("invalid key '%s' in output_trunc argument",
614 key);
615 }
616 }
617 return NULL;
618}
619
cab50449 620static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
621parse_OUTPUT(const char *arg, struct ofpbuf *ofpacts,
622 enum ofputil_protocol *usable_protocols OVS_UNUSED)
f25d0cf3 623{
21b2fa61 624 if (strstr(arg, "port") && strstr(arg, "max_len")) {
aaca4fe0
WT
625 struct ofpact_output_trunc *output_trunc;
626
627 output_trunc = ofpact_put_OUTPUT_TRUNC(ofpacts);
628 return parse_truncate_subfield(output_trunc, arg);
c2d936a4 629 } else {
21b2fa61
JR
630 struct mf_subfield src;
631 char *error = mf_parse_subfield(&src, arg);
632 if (!error) {
633 struct ofpact_output_reg *output_reg;
634
635 output_reg = ofpact_put_OUTPUT_REG(ofpacts);
636 output_reg->max_len = UINT16_MAX;
637 output_reg->src = src;
638 } else {
639 free(error);
640 struct ofpact_output *output;
c2d936a4 641
21b2fa61
JR
642 output = ofpact_put_OUTPUT(ofpacts);
643 if (!ofputil_port_from_string(arg, &output->port)) {
644 return xasprintf("%s: output to unknown port", arg);
645 }
646 output->max_len = output->port == OFPP_CONTROLLER ? UINT16_MAX : 0;
c2d936a4 647 }
c2d936a4 648 return NULL;
f25d0cf3 649 }
c2d936a4 650}
f25d0cf3 651
c2d936a4
BP
652static void
653format_OUTPUT(const struct ofpact_output *a, struct ds *s)
654{
655 if (ofp_to_u16(a->port) < ofp_to_u16(OFPP_MAX)) {
94783c7c 656 ds_put_format(s, "%soutput:%s%"PRIu32,
b1c5bf1f 657 colors.special, colors.end, a->port);
c2d936a4
BP
658 } else {
659 ofputil_format_port(a->port, s);
660 if (a->port == OFPP_CONTROLLER) {
661 ds_put_format(s, ":%"PRIu16, a->max_len);
662 }
663 }
f25d0cf3 664}
c2d936a4
BP
665\f
666/* Group actions. */
f25d0cf3
BP
667
668static enum ofperr
88c8ca26 669decode_OFPAT_RAW_GROUP(uint32_t group_id,
f3cd3ac7
JS
670 enum ofp_version ofp_version OVS_UNUSED,
671 struct ofpbuf *out)
f25d0cf3 672{
c2d936a4
BP
673 ofpact_put_GROUP(out)->group_id = group_id;
674 return 0;
675}
f25d0cf3 676
c2d936a4
BP
677static void
678encode_GROUP(const struct ofpact_group *group,
679 enum ofp_version ofp_version, struct ofpbuf *out)
680{
88c8ca26 681 put_OFPAT_GROUP(out, ofp_version, group->group_id);
c2d936a4 682}
f25d0cf3 683
cab50449 684static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
685parse_GROUP(char *arg, struct ofpbuf *ofpacts,
686 enum ofputil_protocol *usable_protocols OVS_UNUSED)
687{
688 return str_to_u32(arg, &ofpact_put_GROUP(ofpacts)->group_id);
f25d0cf3
BP
689}
690
691static void
c2d936a4 692format_GROUP(const struct ofpact_group *a, struct ds *s)
f25d0cf3 693{
b1c5bf1f
QM
694 ds_put_format(s, "%sgroup:%s%"PRIu32,
695 colors.special, colors.end, a->group_id);
f25d0cf3 696}
c2d936a4
BP
697\f
698/* Action structure for NXAST_CONTROLLER.
699 *
700 * This generalizes using OFPAT_OUTPUT to send a packet to OFPP_CONTROLLER. In
701 * addition to the 'max_len' that OFPAT_OUTPUT supports, it also allows
702 * specifying:
703 *
704 * - 'reason': The reason code to use in the ofp_packet_in or nx_packet_in.
705 *
706 * - 'controller_id': The ID of the controller connection to which the
707 * ofp_packet_in should be sent. The ofp_packet_in or nx_packet_in is
708 * sent only to controllers that have the specified controller connection
709 * ID. See "struct nx_controller_id" for more information. */
710struct nx_action_controller {
711 ovs_be16 type; /* OFPAT_VENDOR. */
712 ovs_be16 len; /* Length is 16. */
713 ovs_be32 vendor; /* NX_VENDOR_ID. */
714 ovs_be16 subtype; /* NXAST_CONTROLLER. */
715 ovs_be16 max_len; /* Maximum length to send to controller. */
716 ovs_be16 controller_id; /* Controller ID to send packet-in. */
717 uint8_t reason; /* enum ofp_packet_in_reason (OFPR_*). */
718 uint8_t zero; /* Must be zero. */
719};
720OFP_ASSERT(sizeof(struct nx_action_controller) == 16);
f25d0cf3 721
77ab5fd2
BP
722/* Properties for NXAST_CONTROLLER2.
723 *
724 * For more information on the effect of NXAC2PT_PAUSE, see the large comment
725 * on NXT_PACKET_IN2 in nicira-ext.h */
bdcad671
BP
726enum nx_action_controller2_prop_type {
727 NXAC2PT_MAX_LEN, /* ovs_be16 max bytes to send (default all). */
728 NXAC2PT_CONTROLLER_ID, /* ovs_be16 dest controller ID (default 0). */
729 NXAC2PT_REASON, /* uint8_t reason (OFPR_*), default 0. */
730 NXAC2PT_USERDATA, /* Data to copy into NXPINT_USERDATA. */
77ab5fd2 731 NXAC2PT_PAUSE, /* Flag to pause pipeline to resume later. */
bdcad671
BP
732};
733
aad28f47
BP
734/* The action structure for NXAST_CONTROLLER2 is "struct ext_action_header",
735 * followed by NXAC2PT_* properties. */
bdcad671 736
c2d936a4
BP
737static enum ofperr
738decode_NXAST_RAW_CONTROLLER(const struct nx_action_controller *nac,
f3cd3ac7 739 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4 740 struct ofpbuf *out)
f25d0cf3
BP
741{
742 struct ofpact_controller *oc;
743
744 oc = ofpact_put_CONTROLLER(out);
bdcad671 745 oc->ofpact.raw = NXAST_RAW_CONTROLLER;
f25d0cf3
BP
746 oc->max_len = ntohs(nac->max_len);
747 oc->controller_id = ntohs(nac->controller_id);
748 oc->reason = nac->reason;
ce058104 749 ofpact_finish_CONTROLLER(out, &oc);
bdcad671
BP
750
751 return 0;
752}
753
754static enum ofperr
aad28f47 755decode_NXAST_RAW_CONTROLLER2(const struct ext_action_header *eah,
bdcad671
BP
756 enum ofp_version ofp_version OVS_UNUSED,
757 struct ofpbuf *out)
758{
aad28f47 759 if (!is_all_zeros(eah->pad, sizeof eah->pad)) {
bdcad671
BP
760 return OFPERR_NXBRC_MUST_BE_ZERO;
761 }
762
763 size_t start_ofs = out->size;
764 struct ofpact_controller *oc = ofpact_put_CONTROLLER(out);
765 oc->ofpact.raw = NXAST_RAW_CONTROLLER2;
766 oc->max_len = UINT16_MAX;
767 oc->reason = OFPR_ACTION;
768
769 struct ofpbuf properties;
aad28f47
BP
770 ofpbuf_use_const(&properties, eah, ntohs(eah->len));
771 ofpbuf_pull(&properties, sizeof *eah);
bdcad671
BP
772
773 while (properties.size > 0) {
774 struct ofpbuf payload;
775 uint64_t type;
776
777 enum ofperr error = ofpprop_pull(&properties, &payload, &type);
778 if (error) {
779 return error;
780 }
781
782 switch (type) {
783 case NXAC2PT_MAX_LEN:
784 error = ofpprop_parse_u16(&payload, &oc->max_len);
785 break;
786
787 case NXAC2PT_CONTROLLER_ID:
788 error = ofpprop_parse_u16(&payload, &oc->controller_id);
789 break;
790
791 case NXAC2PT_REASON: {
792 uint8_t u8;
793 error = ofpprop_parse_u8(&payload, &u8);
794 oc->reason = u8;
795 break;
796 }
797
798 case NXAC2PT_USERDATA:
799 out->size = start_ofs + OFPACT_CONTROLLER_SIZE;
800 ofpbuf_put(out, payload.msg, ofpbuf_msgsize(&payload));
801 oc = ofpbuf_at_assert(out, start_ofs, sizeof *oc);
802 oc->userdata_len = ofpbuf_msgsize(&payload);
803 break;
804
77ab5fd2
BP
805 case NXAC2PT_PAUSE:
806 oc->pause = true;
807 break;
808
bdcad671
BP
809 default:
810 error = OFPPROP_UNKNOWN(false, "NXAST_RAW_CONTROLLER2", type);
811 break;
812 }
813 if (error) {
814 return error;
815 }
816 }
817
ce058104 818 ofpact_finish_CONTROLLER(out, &oc);
bdcad671 819
c2d936a4 820 return 0;
f25d0cf3
BP
821}
822
c2d936a4
BP
823static void
824encode_CONTROLLER(const struct ofpact_controller *controller,
825 enum ofp_version ofp_version OVS_UNUSED,
826 struct ofpbuf *out)
4cceacb9 827{
bdcad671 828 if (controller->userdata_len
77ab5fd2 829 || controller->pause
bdcad671
BP
830 || controller->ofpact.raw == NXAST_RAW_CONTROLLER2) {
831 size_t start_ofs = out->size;
832 put_NXAST_CONTROLLER2(out);
833 if (controller->max_len != UINT16_MAX) {
834 ofpprop_put_u16(out, NXAC2PT_MAX_LEN, controller->max_len);
835 }
836 if (controller->controller_id != 0) {
837 ofpprop_put_u16(out, NXAC2PT_CONTROLLER_ID,
838 controller->controller_id);
839 }
840 if (controller->reason != OFPR_ACTION) {
841 ofpprop_put_u8(out, NXAC2PT_REASON, controller->reason);
842 }
843 if (controller->userdata_len != 0) {
844 ofpprop_put(out, NXAC2PT_USERDATA, controller->userdata,
845 controller->userdata_len);
846 }
77ab5fd2
BP
847 if (controller->pause) {
848 ofpprop_put_flag(out, NXAC2PT_PAUSE);
849 }
bdcad671
BP
850 pad_ofpat(out, start_ofs);
851 } else {
852 struct nx_action_controller *nac;
4cceacb9 853
bdcad671
BP
854 nac = put_NXAST_CONTROLLER(out);
855 nac->max_len = htons(controller->max_len);
856 nac->controller_id = htons(controller->controller_id);
857 nac->reason = controller->reason;
858 }
c2d936a4
BP
859}
860
cab50449 861static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
862parse_CONTROLLER(char *arg, struct ofpbuf *ofpacts,
863 enum ofputil_protocol *usable_protocols OVS_UNUSED)
864{
865 enum ofp_packet_in_reason reason = OFPR_ACTION;
866 uint16_t controller_id = 0;
867 uint16_t max_len = UINT16_MAX;
bdcad671 868 const char *userdata = NULL;
77ab5fd2 869 bool pause = false;
c2d936a4
BP
870
871 if (!arg[0]) {
872 /* Use defaults. */
873 } else if (strspn(arg, "0123456789") == strlen(arg)) {
874 char *error = str_to_u16(arg, "max_len", &max_len);
875 if (error) {
876 return error;
877 }
878 } else {
879 char *name, *value;
880
881 while (ofputil_parse_key_value(&arg, &name, &value)) {
882 if (!strcmp(name, "reason")) {
883 if (!ofputil_packet_in_reason_from_string(value, &reason)) {
884 return xasprintf("unknown reason \"%s\"", value);
885 }
886 } else if (!strcmp(name, "max_len")) {
887 char *error = str_to_u16(value, "max_len", &max_len);
888 if (error) {
889 return error;
890 }
891 } else if (!strcmp(name, "id")) {
892 char *error = str_to_u16(value, "id", &controller_id);
893 if (error) {
894 return error;
895 }
bdcad671
BP
896 } else if (!strcmp(name, "userdata")) {
897 userdata = value;
77ab5fd2
BP
898 } else if (!strcmp(name, "pause")) {
899 pause = true;
c2d936a4
BP
900 } else {
901 return xasprintf("unknown key \"%s\" parsing controller "
902 "action", name);
903 }
904 }
4cceacb9
JS
905 }
906
77ab5fd2 907 if (reason == OFPR_ACTION && controller_id == 0 && !userdata && !pause) {
c2d936a4 908 struct ofpact_output *output;
4cceacb9 909
c2d936a4
BP
910 output = ofpact_put_OUTPUT(ofpacts);
911 output->port = OFPP_CONTROLLER;
912 output->max_len = max_len;
913 } else {
914 struct ofpact_controller *controller;
915
916 controller = ofpact_put_CONTROLLER(ofpacts);
917 controller->max_len = max_len;
918 controller->reason = reason;
919 controller->controller_id = controller_id;
77ab5fd2 920 controller->pause = pause;
bdcad671
BP
921
922 if (userdata) {
923 size_t start_ofs = ofpacts->size;
924 const char *end = ofpbuf_put_hex(ofpacts, userdata, NULL);
925 if (*end) {
926 return xstrdup("bad hex digit in `controller' "
927 "action `userdata'");
928 }
929 size_t userdata_len = ofpacts->size - start_ofs;
930 controller = ofpacts->header;
931 controller->userdata_len = userdata_len;
932 }
ce058104 933 ofpact_finish_CONTROLLER(ofpacts, &controller);
c2d936a4
BP
934 }
935
936 return NULL;
4cceacb9
JS
937}
938
bdcad671
BP
939static void
940format_hex_arg(struct ds *s, const uint8_t *data, size_t len)
941{
942 for (size_t i = 0; i < len; i++) {
943 if (i) {
944 ds_put_char(s, '.');
945 }
946 ds_put_format(s, "%02"PRIx8, data[i]);
947 }
948}
949
f25d0cf3 950static void
c2d936a4 951format_CONTROLLER(const struct ofpact_controller *a, struct ds *s)
f25d0cf3 952{
77ab5fd2
BP
953 if (a->reason == OFPR_ACTION && !a->controller_id && !a->userdata_len
954 && !a->pause) {
b1c5bf1f
QM
955 ds_put_format(s, "%sCONTROLLER:%s%"PRIu16,
956 colors.special, colors.end, a->max_len);
c2d936a4
BP
957 } else {
958 enum ofp_packet_in_reason reason = a->reason;
f25d0cf3 959
b1c5bf1f 960 ds_put_format(s, "%scontroller(%s", colors.paren, colors.end);
c2d936a4
BP
961 if (reason != OFPR_ACTION) {
962 char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
963
b1c5bf1f 964 ds_put_format(s, "%sreason=%s%s,", colors.param, colors.end,
c2d936a4
BP
965 ofputil_packet_in_reason_to_string(
966 reason, reasonbuf, sizeof reasonbuf));
967 }
968 if (a->max_len != UINT16_MAX) {
b1c5bf1f
QM
969 ds_put_format(s, "%smax_len=%s%"PRIu16",",
970 colors.param, colors.end, a->max_len);
c2d936a4
BP
971 }
972 if (a->controller_id != 0) {
b1c5bf1f
QM
973 ds_put_format(s, "%sid=%s%"PRIu16",",
974 colors.param, colors.end, a->controller_id);
c2d936a4 975 }
bdcad671 976 if (a->userdata_len) {
b1c5bf1f 977 ds_put_format(s, "%suserdata=%s", colors.param, colors.end);
bdcad671
BP
978 format_hex_arg(s, a->userdata, a->userdata_len);
979 ds_put_char(s, ',');
980 }
77ab5fd2 981 if (a->pause) {
b1c5bf1f 982 ds_put_format(s, "%spause%s,", colors.value, colors.end);
77ab5fd2 983 }
c2d936a4 984 ds_chomp(s, ',');
b1c5bf1f 985 ds_put_format(s, "%s)%s", colors.paren, colors.end);
c2d936a4 986 }
f25d0cf3 987}
c2d936a4
BP
988\f
989/* Enqueue action. */
990struct ofp10_action_enqueue {
991 ovs_be16 type; /* OFPAT10_ENQUEUE. */
992 ovs_be16 len; /* Len is 16. */
993 ovs_be16 port; /* Port that queue belongs. Should
994 refer to a valid physical port
995 (i.e. < OFPP_MAX) or OFPP_IN_PORT. */
996 uint8_t pad[6]; /* Pad for 64-bit alignment. */
997 ovs_be32 queue_id; /* Where to enqueue the packets. */
998};
999OFP_ASSERT(sizeof(struct ofp10_action_enqueue) == 16);
f25d0cf3 1000
c2d967a5 1001static enum ofperr
c2d936a4 1002decode_OFPAT_RAW10_ENQUEUE(const struct ofp10_action_enqueue *oae,
f3cd3ac7 1003 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4 1004 struct ofpbuf *out)
c2d967a5 1005{
c2d936a4 1006 struct ofpact_enqueue *enqueue;
c2d967a5 1007
c2d936a4
BP
1008 enqueue = ofpact_put_ENQUEUE(out);
1009 enqueue->port = u16_to_ofp(ntohs(oae->port));
1010 enqueue->queue = ntohl(oae->queue_id);
1011 if (ofp_to_u16(enqueue->port) >= ofp_to_u16(OFPP_MAX)
1012 && enqueue->port != OFPP_IN_PORT
1013 && enqueue->port != OFPP_LOCAL) {
1014 return OFPERR_OFPBAC_BAD_OUT_PORT;
1015 }
1016 return 0;
c2d967a5
MM
1017}
1018
c2d936a4
BP
1019static void
1020encode_ENQUEUE(const struct ofpact_enqueue *enqueue,
1021 enum ofp_version ofp_version, struct ofpbuf *out)
c2d967a5 1022{
c2d936a4
BP
1023 if (ofp_version == OFP10_VERSION) {
1024 struct ofp10_action_enqueue *oae;
c2d967a5 1025
c2d936a4
BP
1026 oae = put_OFPAT10_ENQUEUE(out);
1027 oae->port = htons(ofp_to_u16(enqueue->port));
1028 oae->queue_id = htonl(enqueue->queue);
1029 } else {
0f2aaee9
BP
1030 put_OFPAT_SET_QUEUE(out, ofp_version, enqueue->queue);
1031
1032 struct ofp11_action_output *oao = put_OFPAT11_OUTPUT(out);
1033 oao->port = ofputil_port_to_ofp11(enqueue->port);
1034 oao->max_len = OVS_BE16_MAX;
1035
1036 put_NXAST_POP_QUEUE(out);
c2d967a5 1037 }
c2d936a4 1038}
c2d967a5 1039
cab50449 1040static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1041parse_ENQUEUE(char *arg, struct ofpbuf *ofpacts,
1042 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1043{
1044 char *sp = NULL;
1045 char *port = strtok_r(arg, ":q,", &sp);
1046 char *queue = strtok_r(NULL, "", &sp);
1047 struct ofpact_enqueue *enqueue;
c2d967a5 1048
c2d936a4
BP
1049 if (port == NULL || queue == NULL) {
1050 return xstrdup("\"enqueue\" syntax is \"enqueue:PORT:QUEUE\" or "
1051 "\"enqueue(PORT,QUEUE)\"");
c2d967a5
MM
1052 }
1053
c2d936a4
BP
1054 enqueue = ofpact_put_ENQUEUE(ofpacts);
1055 if (!ofputil_port_from_string(port, &enqueue->port)) {
1056 return xasprintf("%s: enqueue to unknown port", port);
1057 }
1058 return str_to_u32(queue, &enqueue->queue);
c2d967a5
MM
1059}
1060
c2d936a4
BP
1061static void
1062format_ENQUEUE(const struct ofpact_enqueue *a, struct ds *s)
29089a54 1063{
b1c5bf1f 1064 ds_put_format(s, "%senqueue:%s", colors.param, colors.end);
c2d936a4
BP
1065 ofputil_format_port(a->port, s);
1066 ds_put_format(s, ":%"PRIu32, a->queue);
1067}
1068\f
1069/* Action structure for NXAST_OUTPUT_REG.
1070 *
1071 * Outputs to the OpenFlow port number written to src[ofs:ofs+nbits].
1072 *
1073 * The format and semantics of 'src' and 'ofs_nbits' are similar to those for
1074 * the NXAST_REG_LOAD action.
1075 *
1076 * The acceptable nxm_header values for 'src' are the same as the acceptable
1077 * nxm_header values for the 'src' field of NXAST_REG_MOVE.
1078 *
1079 * The 'max_len' field indicates the number of bytes to send when the chosen
1080 * port is OFPP_CONTROLLER. Its semantics are equivalent to the 'max_len'
1081 * field of OFPAT_OUTPUT.
1082 *
1083 * The 'zero' field is required to be zeroed for forward compatibility. */
1084struct nx_action_output_reg {
1085 ovs_be16 type; /* OFPAT_VENDOR. */
1086 ovs_be16 len; /* 24. */
1087 ovs_be32 vendor; /* NX_VENDOR_ID. */
1088 ovs_be16 subtype; /* NXAST_OUTPUT_REG. */
29089a54 1089
c2d936a4
BP
1090 ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
1091 ovs_be32 src; /* Source. */
29089a54 1092
c2d936a4 1093 ovs_be16 max_len; /* Max length to send to controller. */
29089a54 1094
c2d936a4
BP
1095 uint8_t zero[6]; /* Reserved, must be zero. */
1096};
1097OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
29089a54 1098
bad8a439
BP
1099/* Action structure for NXAST_OUTPUT_REG2.
1100 *
1101 * Like the NXAST_OUTPUT_REG but organized so that there is room for a 64-bit
1102 * experimenter OXM as 'src'.
1103 */
1104struct nx_action_output_reg2 {
1105 ovs_be16 type; /* OFPAT_VENDOR. */
1106 ovs_be16 len; /* 24. */
1107 ovs_be32 vendor; /* NX_VENDOR_ID. */
1108 ovs_be16 subtype; /* NXAST_OUTPUT_REG2. */
1109
1110 ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
1111 ovs_be16 max_len; /* Max length to send to controller. */
1112
1113 /* Followed by:
1114 * - 'src', as an OXM/NXM header (either 4 or 8 bytes).
1115 * - Enough 0-bytes to pad the action out to 24 bytes. */
1116 uint8_t pad[10];
1117};
1118OFP_ASSERT(sizeof(struct nx_action_output_reg2) == 24);
1119
a7a2d006 1120static enum ofperr
c2d936a4 1121decode_NXAST_RAW_OUTPUT_REG(const struct nx_action_output_reg *naor,
f3cd3ac7 1122 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 1123 const struct vl_mff_map *vl_mff_map,
c2d936a4 1124 struct ofpbuf *out)
a7a2d006 1125{
c2d936a4 1126 struct ofpact_output_reg *output_reg;
a7a2d006 1127
c2d936a4 1128 if (!is_all_zeros(naor->zero, sizeof naor->zero)) {
a7a2d006
JS
1129 return OFPERR_OFPBAC_BAD_ARGUMENT;
1130 }
a7a2d006 1131
c2d936a4 1132 output_reg = ofpact_put_OUTPUT_REG(out);
bad8a439 1133 output_reg->ofpact.raw = NXAST_RAW_OUTPUT_REG;
04f48a68 1134 output_reg->src.field = mf_from_nxm_header(ntohl(naor->src), vl_mff_map);
c2d936a4
BP
1135 output_reg->src.ofs = nxm_decode_ofs(naor->ofs_nbits);
1136 output_reg->src.n_bits = nxm_decode_n_bits(naor->ofs_nbits);
1137 output_reg->max_len = ntohs(naor->max_len);
1138
04f48a68
YHW
1139 if (mf_vl_mff_invalid(output_reg->src.field, vl_mff_map)) {
1140 return OFPERR_NXFMFC_INVALID_TLV_FIELD;
1141 }
1142
c2d936a4 1143 return mf_check_src(&output_reg->src, NULL);
a7a2d006
JS
1144}
1145
bad8a439
BP
1146static enum ofperr
1147decode_NXAST_RAW_OUTPUT_REG2(const struct nx_action_output_reg2 *naor,
f3cd3ac7 1148 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 1149 const struct vl_mff_map *vl_mff_map,
f3cd3ac7 1150 struct ofpbuf *out)
bad8a439
BP
1151{
1152 struct ofpact_output_reg *output_reg;
bad8a439
BP
1153 output_reg = ofpact_put_OUTPUT_REG(out);
1154 output_reg->ofpact.raw = NXAST_RAW_OUTPUT_REG2;
1155 output_reg->src.ofs = nxm_decode_ofs(naor->ofs_nbits);
1156 output_reg->src.n_bits = nxm_decode_n_bits(naor->ofs_nbits);
1157 output_reg->max_len = ntohs(naor->max_len);
1158
0a2869d5 1159 struct ofpbuf b = ofpbuf_const_initializer(naor, ntohs(naor->len));
bad8a439 1160 ofpbuf_pull(&b, OBJECT_OFFSETOF(naor, pad));
0a2869d5 1161
04f48a68
YHW
1162 enum ofperr error = nx_pull_header(&b, vl_mff_map, &output_reg->src.field,
1163 NULL);
bad8a439
BP
1164 if (error) {
1165 return error;
1166 }
6fd6ed71 1167 if (!is_all_zeros(b.data, b.size)) {
bad8a439
BP
1168 return OFPERR_NXBRC_MUST_BE_ZERO;
1169 }
1170
1171 return mf_check_src(&output_reg->src, NULL);
1172}
1173
c2d936a4
BP
1174static void
1175encode_OUTPUT_REG(const struct ofpact_output_reg *output_reg,
1176 enum ofp_version ofp_version OVS_UNUSED,
1177 struct ofpbuf *out)
f25d0cf3 1178{
bad8a439
BP
1179 /* If 'output_reg' came in as an NXAST_RAW_OUTPUT_REG2 action, or if it
1180 * cannot be encoded in the older form, encode it as
1181 * NXAST_RAW_OUTPUT_REG2. */
1182 if (output_reg->ofpact.raw == NXAST_RAW_OUTPUT_REG2
1183 || !mf_nxm_header(output_reg->src.field->id)) {
1184 struct nx_action_output_reg2 *naor = put_NXAST_OUTPUT_REG2(out);
6fd6ed71 1185 size_t size = out->size;
bad8a439
BP
1186
1187 naor->ofs_nbits = nxm_encode_ofs_nbits(output_reg->src.ofs,
1188 output_reg->src.n_bits);
1189 naor->max_len = htons(output_reg->max_len);
1190
6fd6ed71 1191 out->size = size - sizeof naor->pad;
04f48a68 1192 nx_put_mff_header(out, output_reg->src.field, 0, false);
6fd6ed71 1193 out->size = size;
bad8a439
BP
1194 } else {
1195 struct nx_action_output_reg *naor = put_NXAST_OUTPUT_REG(out);
f25d0cf3 1196
bad8a439
BP
1197 naor->ofs_nbits = nxm_encode_ofs_nbits(output_reg->src.ofs,
1198 output_reg->src.n_bits);
04f48a68 1199 naor->src = htonl(nxm_header_from_mff(output_reg->src.field));
bad8a439
BP
1200 naor->max_len = htons(output_reg->max_len);
1201 }
f25d0cf3
BP
1202}
1203
cab50449 1204static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1205parse_OUTPUT_REG(const char *arg, struct ofpbuf *ofpacts,
1206 enum ofputil_protocol *usable_protocols OVS_UNUSED)
f25d0cf3 1207{
c2d936a4 1208 return parse_OUTPUT(arg, ofpacts, usable_protocols);
f25d0cf3
BP
1209}
1210
c2d936a4
BP
1211static void
1212format_OUTPUT_REG(const struct ofpact_output_reg *a, struct ds *s)
f25d0cf3 1213{
b1c5bf1f 1214 ds_put_format(s, "%soutput:%s", colors.special, colors.end);
c2d936a4
BP
1215 mf_format_subfield(&a->src, s);
1216}
1217\f
1218/* Action structure for NXAST_BUNDLE and NXAST_BUNDLE_LOAD.
1219 *
1220 * The bundle actions choose a slave from a supplied list of options.
1221 * NXAST_BUNDLE outputs to its selection. NXAST_BUNDLE_LOAD writes its
1222 * selection to a register.
1223 *
1224 * The list of possible slaves follows the nx_action_bundle structure. The size
1225 * of each slave is governed by its type as indicated by the 'slave_type'
1226 * parameter. The list of slaves should be padded at its end with zeros to make
1227 * the total length of the action a multiple of 8.
1228 *
1229 * Switches infer from the 'slave_type' parameter the size of each slave. All
1230 * implementations must support the NXM_OF_IN_PORT 'slave_type' which indicates
1231 * that the slaves are OpenFlow port numbers with NXM_LENGTH(NXM_OF_IN_PORT) ==
1232 * 2 byte width. Switches should reject actions which indicate unknown or
1233 * unsupported slave types.
1234 *
1235 * Switches use a strategy dictated by the 'algorithm' parameter to choose a
1236 * slave. If the switch does not support the specified 'algorithm' parameter,
1237 * it should reject the action.
1238 *
1239 * Several algorithms take into account liveness when selecting slaves. The
1240 * liveness of a slave is implementation defined (with one exception), but will
1241 * generally take into account things like its carrier status and the results
1242 * of any link monitoring protocols which happen to be running on it. In order
1243 * to give controllers a place-holder value, the OFPP_NONE port is always
63460a30
TLSC
1244 * considered live, that is, NXAST_BUNDLE_LOAD stores OFPP_NONE in the output
1245 * register if no slave is live.
c2d936a4
BP
1246 *
1247 * Some slave selection strategies require the use of a hash function, in which
1248 * case the 'fields' and 'basis' parameters should be populated. The 'fields'
1249 * parameter (one of NX_HASH_FIELDS_*) designates which parts of the flow to
1250 * hash. Refer to the definition of "enum nx_hash_fields" for details. The
1251 * 'basis' parameter is used as a universal hash parameter. Different values
1252 * of 'basis' yield different hash results.
1253 *
1254 * The 'zero' parameter at the end of the action structure is reserved for
1255 * future use. Switches are required to reject actions which have nonzero
1256 * bytes in the 'zero' field.
1257 *
1258 * NXAST_BUNDLE actions should have 'ofs_nbits' and 'dst' zeroed. Switches
1259 * should reject actions which have nonzero bytes in either of these fields.
1260 *
1261 * NXAST_BUNDLE_LOAD stores the OpenFlow port number of the selected slave in
1262 * dst[ofs:ofs+n_bits]. The format and semantics of 'dst' and 'ofs_nbits' are
1263 * similar to those for the NXAST_REG_LOAD action. */
1264struct nx_action_bundle {
1265 ovs_be16 type; /* OFPAT_VENDOR. */
1266 ovs_be16 len; /* Length including slaves. */
1267 ovs_be32 vendor; /* NX_VENDOR_ID. */
1268 ovs_be16 subtype; /* NXAST_BUNDLE or NXAST_BUNDLE_LOAD. */
f25d0cf3 1269
c2d936a4
BP
1270 /* Slave choice algorithm to apply to hash value. */
1271 ovs_be16 algorithm; /* One of NX_BD_ALG_*. */
4cceacb9 1272
c2d936a4
BP
1273 /* What fields to hash and how. */
1274 ovs_be16 fields; /* One of NX_HASH_FIELDS_*. */
1275 ovs_be16 basis; /* Universal hash parameter. */
f25d0cf3 1276
c2d936a4
BP
1277 ovs_be32 slave_type; /* NXM_OF_IN_PORT. */
1278 ovs_be16 n_slaves; /* Number of slaves. */
f25d0cf3 1279
c2d936a4
BP
1280 ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
1281 ovs_be32 dst; /* Destination. */
f25d0cf3 1282
c2d936a4
BP
1283 uint8_t zero[4]; /* Reserved. Must be zero. */
1284};
1285OFP_ASSERT(sizeof(struct nx_action_bundle) == 32);
f25d0cf3 1286
c2d936a4
BP
1287static enum ofperr
1288decode_bundle(bool load, const struct nx_action_bundle *nab,
04f48a68 1289 const struct vl_mff_map *vl_mff_map, struct ofpbuf *ofpacts)
c2d936a4
BP
1290{
1291 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
1292 struct ofpact_bundle *bundle;
1293 uint32_t slave_type;
1294 size_t slaves_size, i;
1295 enum ofperr error;
bd85dac1 1296
c2d936a4
BP
1297 bundle = ofpact_put_BUNDLE(ofpacts);
1298
1299 bundle->n_slaves = ntohs(nab->n_slaves);
1300 bundle->basis = ntohs(nab->basis);
1301 bundle->fields = ntohs(nab->fields);
1302 bundle->algorithm = ntohs(nab->algorithm);
1303 slave_type = ntohl(nab->slave_type);
1304 slaves_size = ntohs(nab->len) - sizeof *nab;
1305
1306 error = OFPERR_OFPBAC_BAD_ARGUMENT;
1307 if (!flow_hash_fields_valid(bundle->fields)) {
1308 VLOG_WARN_RL(&rl, "unsupported fields %d", (int) bundle->fields);
1309 } else if (bundle->n_slaves > BUNDLE_MAX_SLAVES) {
1310 VLOG_WARN_RL(&rl, "too many slaves");
1311 } else if (bundle->algorithm != NX_BD_ALG_HRW
1312 && bundle->algorithm != NX_BD_ALG_ACTIVE_BACKUP) {
1313 VLOG_WARN_RL(&rl, "unsupported algorithm %d", (int) bundle->algorithm);
508a9338 1314 } else if (slave_type != mf_nxm_header(MFF_IN_PORT)) {
c2d936a4
BP
1315 VLOG_WARN_RL(&rl, "unsupported slave type %"PRIu16, slave_type);
1316 } else {
1317 error = 0;
1318 }
bd85dac1 1319
c2d936a4
BP
1320 if (!is_all_zeros(nab->zero, sizeof nab->zero)) {
1321 VLOG_WARN_RL(&rl, "reserved field is nonzero");
1322 error = OFPERR_OFPBAC_BAD_ARGUMENT;
1323 }
f25d0cf3 1324
c2d936a4 1325 if (load) {
04f48a68 1326 bundle->dst.field = mf_from_nxm_header(ntohl(nab->dst), vl_mff_map);
c2d936a4
BP
1327 bundle->dst.ofs = nxm_decode_ofs(nab->ofs_nbits);
1328 bundle->dst.n_bits = nxm_decode_n_bits(nab->ofs_nbits);
04f48a68
YHW
1329 if (mf_vl_mff_invalid(bundle->dst.field, vl_mff_map)) {
1330 return OFPERR_NXFMFC_INVALID_TLV_FIELD;
1331 }
f25d0cf3 1332
c2d936a4
BP
1333 if (bundle->dst.n_bits < 16) {
1334 VLOG_WARN_RL(&rl, "bundle_load action requires at least 16 bit "
1335 "destination.");
1336 error = OFPERR_OFPBAC_BAD_ARGUMENT;
1337 }
1338 } else {
1339 if (nab->ofs_nbits || nab->dst) {
1340 VLOG_WARN_RL(&rl, "bundle action has nonzero reserved fields");
1341 error = OFPERR_OFPBAC_BAD_ARGUMENT;
1342 }
1343 }
f25d0cf3 1344
c2d936a4
BP
1345 if (slaves_size < bundle->n_slaves * sizeof(ovs_be16)) {
1346 VLOG_WARN_RL(&rl, "Nicira action %s only has %"PRIuSIZE" bytes "
1347 "allocated for slaves. %"PRIuSIZE" bytes are required "
1348 "for %"PRIu16" slaves.",
1349 load ? "bundle_load" : "bundle", slaves_size,
1350 bundle->n_slaves * sizeof(ovs_be16), bundle->n_slaves);
1351 error = OFPERR_OFPBAC_BAD_LEN;
1352 }
f25d0cf3 1353
c2d936a4 1354 for (i = 0; i < bundle->n_slaves; i++) {
117d7249 1355 ofp_port_t ofp_port = u16_to_ofp(ntohs(((ovs_be16 *)(nab + 1))[i]));
c2d936a4 1356 ofpbuf_put(ofpacts, &ofp_port, sizeof ofp_port);
19b58f3c 1357 bundle = ofpacts->header;
c2d936a4 1358 }
f25d0cf3 1359
ce058104 1360 ofpact_finish_BUNDLE(ofpacts, &bundle);
c2d936a4
BP
1361 if (!error) {
1362 error = bundle_check(bundle, OFPP_MAX, NULL);
1363 }
1364 return error;
1365}
f25d0cf3 1366
c2d936a4 1367static enum ofperr
f3cd3ac7
JS
1368decode_NXAST_RAW_BUNDLE(const struct nx_action_bundle *nab,
1369 enum ofp_version ofp_version OVS_UNUSED,
1370 struct ofpbuf *out)
c2d936a4 1371{
04f48a68 1372 return decode_bundle(false, nab, NULL, out);
c2d936a4 1373}
f25d0cf3 1374
c2d936a4
BP
1375static enum ofperr
1376decode_NXAST_RAW_BUNDLE_LOAD(const struct nx_action_bundle *nab,
f3cd3ac7 1377 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 1378 const struct vl_mff_map *vl_mff_map,
c2d936a4
BP
1379 struct ofpbuf *out)
1380{
04f48a68 1381 return decode_bundle(true, nab, vl_mff_map, out);
c2d936a4 1382}
c2d967a5 1383
c2d936a4
BP
1384static void
1385encode_BUNDLE(const struct ofpact_bundle *bundle,
1386 enum ofp_version ofp_version OVS_UNUSED,
1387 struct ofpbuf *out)
1388{
1389 int slaves_len = ROUND_UP(2 * bundle->n_slaves, OFP_ACTION_ALIGN);
1390 struct nx_action_bundle *nab;
1391 ovs_be16 *slaves;
1392 size_t i;
f25d0cf3 1393
c2d936a4
BP
1394 nab = (bundle->dst.field
1395 ? put_NXAST_BUNDLE_LOAD(out)
1396 : put_NXAST_BUNDLE(out));
1397 nab->len = htons(ntohs(nab->len) + slaves_len);
1398 nab->algorithm = htons(bundle->algorithm);
1399 nab->fields = htons(bundle->fields);
1400 nab->basis = htons(bundle->basis);
508a9338 1401 nab->slave_type = htonl(mf_nxm_header(MFF_IN_PORT));
c2d936a4
BP
1402 nab->n_slaves = htons(bundle->n_slaves);
1403 if (bundle->dst.field) {
1404 nab->ofs_nbits = nxm_encode_ofs_nbits(bundle->dst.ofs,
1405 bundle->dst.n_bits);
04f48a68 1406 nab->dst = htonl(nxm_header_from_mff(bundle->dst.field));
c2d936a4 1407 }
f25d0cf3 1408
c2d936a4
BP
1409 slaves = ofpbuf_put_zeros(out, slaves_len);
1410 for (i = 0; i < bundle->n_slaves; i++) {
1411 slaves[i] = htons(ofp_to_u16(bundle->slaves[i]));
1412 }
1413}
b02475c5 1414
cab50449 1415static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1416parse_BUNDLE(const char *arg, struct ofpbuf *ofpacts,
1417 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1418{
1419 return bundle_parse(arg, ofpacts);
1420}
b02475c5 1421
cab50449 1422static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1423parse_bundle_load(const char *arg, struct ofpbuf *ofpacts)
1424{
1425 return bundle_parse_load(arg, ofpacts);
1426}
097d4939 1427
c2d936a4
BP
1428static void
1429format_BUNDLE(const struct ofpact_bundle *a, struct ds *s)
1430{
1431 bundle_format(a, s);
1432}
1433\f
1434/* Set VLAN actions. */
097d4939 1435
c2d936a4
BP
1436static enum ofperr
1437decode_set_vlan_vid(uint16_t vid, bool push_vlan_if_needed, struct ofpbuf *out)
1438{
1439 if (vid & ~0xfff) {
1440 return OFPERR_OFPBAC_BAD_ARGUMENT;
1441 } else {
1442 struct ofpact_vlan_vid *vlan_vid = ofpact_put_SET_VLAN_VID(out);
1443 vlan_vid->vlan_vid = vid;
1444 vlan_vid->push_vlan_if_needed = push_vlan_if_needed;
1445 return 0;
1446 }
1447}
0f3f3c3d 1448
c2d936a4 1449static enum ofperr
f3cd3ac7
JS
1450decode_OFPAT_RAW10_SET_VLAN_VID(uint16_t vid,
1451 enum ofp_version ofp_version OVS_UNUSED,
1452 struct ofpbuf *out)
c2d936a4
BP
1453{
1454 return decode_set_vlan_vid(vid, true, out);
1455}
b676167a 1456
c2d936a4 1457static enum ofperr
f3cd3ac7
JS
1458decode_OFPAT_RAW11_SET_VLAN_VID(uint16_t vid,
1459 enum ofp_version ofp_version OVS_UNUSED,
1460 struct ofpbuf *out)
c2d936a4
BP
1461{
1462 return decode_set_vlan_vid(vid, false, out);
1463}
29089a54 1464
c2d936a4
BP
1465static void
1466encode_SET_VLAN_VID(const struct ofpact_vlan_vid *vlan_vid,
1467 enum ofp_version ofp_version, struct ofpbuf *out)
1468{
1469 uint16_t vid = vlan_vid->vlan_vid;
1470
1471 /* Push a VLAN tag, if none is present and this form of the action calls
1472 * for such a feature. */
1473 if (ofp_version > OFP10_VERSION
1474 && vlan_vid->push_vlan_if_needed
1475 && !vlan_vid->flow_has_vlan) {
1476 put_OFPAT11_PUSH_VLAN(out, htons(ETH_TYPE_VLAN_8021Q));
f25d0cf3
BP
1477 }
1478
c2d936a4
BP
1479 if (ofp_version == OFP10_VERSION) {
1480 put_OFPAT10_SET_VLAN_VID(out, vid);
1481 } else if (ofp_version == OFP11_VERSION) {
1482 put_OFPAT11_SET_VLAN_VID(out, vid);
1483 } else {
128684a6 1484 put_set_field(out, ofp_version, MFF_VLAN_VID, vid | OFPVID12_PRESENT);
c2d936a4 1485 }
f25d0cf3
BP
1486}
1487
cab50449 1488static char * OVS_WARN_UNUSED_RESULT
c2d936a4 1489parse_set_vlan_vid(char *arg, struct ofpbuf *ofpacts, bool push_vlan_if_needed)
d01c980f 1490{
ca287d20 1491 struct ofpact_vlan_vid *vlan_vid;
c2d936a4
BP
1492 uint16_t vid;
1493 char *error;
d01c980f 1494
c2d936a4 1495 error = str_to_u16(arg, "VLAN VID", &vid);
d01c980f
BP
1496 if (error) {
1497 return error;
1498 }
1499
c2d936a4
BP
1500 if (vid & ~VLAN_VID_MASK) {
1501 return xasprintf("%s: not a valid VLAN VID", arg);
d01c980f 1502 }
c2d936a4
BP
1503 vlan_vid = ofpact_put_SET_VLAN_VID(ofpacts);
1504 vlan_vid->vlan_vid = vid;
1505 vlan_vid->push_vlan_if_needed = push_vlan_if_needed;
1506 return NULL;
1507}
d01c980f 1508
cab50449 1509static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1510parse_SET_VLAN_VID(char *arg, struct ofpbuf *ofpacts,
1511 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1512{
1513 return parse_set_vlan_vid(arg, ofpacts, false);
d01c980f
BP
1514}
1515
c2d936a4
BP
1516static void
1517format_SET_VLAN_VID(const struct ofpact_vlan_vid *a, struct ds *s)
1518{
b1c5bf1f 1519 ds_put_format(s, "%s%s:%s%"PRIu16, colors.param,
c2d936a4 1520 a->push_vlan_if_needed ? "mod_vlan_vid" : "set_vlan_vid",
b1c5bf1f 1521 colors.end, a->vlan_vid);
c2d936a4
BP
1522}
1523\f
1524/* Set PCP actions. */
e3f8f887 1525
c2d936a4
BP
1526static enum ofperr
1527decode_set_vlan_pcp(uint8_t pcp, bool push_vlan_if_needed, struct ofpbuf *out)
f25d0cf3 1528{
c2d936a4
BP
1529 if (pcp & ~7) {
1530 return OFPERR_OFPBAC_BAD_ARGUMENT;
1531 } else {
1532 struct ofpact_vlan_pcp *vlan_pcp = ofpact_put_SET_VLAN_PCP(out);
1533 vlan_pcp->vlan_pcp = pcp;
1534 vlan_pcp->push_vlan_if_needed = push_vlan_if_needed;
1535 return 0;
1536 }
f25d0cf3
BP
1537}
1538
c2d936a4 1539static enum ofperr
f3cd3ac7
JS
1540decode_OFPAT_RAW10_SET_VLAN_PCP(uint8_t pcp,
1541 enum ofp_version ofp_version OVS_UNUSED,
1542 struct ofpbuf *out)
f25d0cf3 1543{
c2d936a4 1544 return decode_set_vlan_pcp(pcp, true, out);
f25d0cf3
BP
1545}
1546
c2d936a4 1547static enum ofperr
f3cd3ac7
JS
1548decode_OFPAT_RAW11_SET_VLAN_PCP(uint8_t pcp,
1549 enum ofp_version ofp_version OVS_UNUSED,
1550 struct ofpbuf *out)
c2d936a4
BP
1551{
1552 return decode_set_vlan_pcp(pcp, false, out);
1553}
f25d0cf3 1554
699dddf1 1555static void
c2d936a4
BP
1556encode_SET_VLAN_PCP(const struct ofpact_vlan_pcp *vlan_pcp,
1557 enum ofp_version ofp_version, struct ofpbuf *out)
699dddf1 1558{
c2d936a4
BP
1559 uint8_t pcp = vlan_pcp->vlan_pcp;
1560
1561 /* Push a VLAN tag, if none is present and this form of the action calls
1562 * for such a feature. */
1563 if (ofp_version > OFP10_VERSION
1564 && vlan_pcp->push_vlan_if_needed
1565 && !vlan_pcp->flow_has_vlan) {
1566 put_OFPAT11_PUSH_VLAN(out, htons(ETH_TYPE_VLAN_8021Q));
1567 }
699dddf1 1568
c2d936a4
BP
1569 if (ofp_version == OFP10_VERSION) {
1570 put_OFPAT10_SET_VLAN_PCP(out, pcp);
1571 } else if (ofp_version == OFP11_VERSION) {
1572 put_OFPAT11_SET_VLAN_PCP(out, pcp);
1573 } else {
128684a6 1574 put_set_field(out, ofp_version, MFF_VLAN_PCP, pcp);
699dddf1
BP
1575 }
1576}
1577
cab50449 1578static char * OVS_WARN_UNUSED_RESULT
c2d936a4 1579parse_set_vlan_pcp(char *arg, struct ofpbuf *ofpacts, bool push_vlan_if_needed)
f25d0cf3 1580{
c2d936a4
BP
1581 struct ofpact_vlan_pcp *vlan_pcp;
1582 uint8_t pcp;
1583 char *error;
e3f8f887 1584
c2d936a4
BP
1585 error = str_to_u8(arg, "VLAN PCP", &pcp);
1586 if (error) {
699dddf1 1587 return error;
f25d0cf3
BP
1588 }
1589
c2d936a4
BP
1590 if (pcp & ~7) {
1591 return xasprintf("%s: not a valid VLAN PCP", arg);
1592 }
1593 vlan_pcp = ofpact_put_SET_VLAN_PCP(ofpacts);
1594 vlan_pcp->vlan_pcp = pcp;
1595 vlan_pcp->push_vlan_if_needed = push_vlan_if_needed;
1596 return NULL;
1597}
1598
cab50449 1599static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1600parse_SET_VLAN_PCP(char *arg, struct ofpbuf *ofpacts,
1601 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1602{
1603 return parse_set_vlan_pcp(arg, ofpacts, false);
1604}
1605
1606static void
1607format_SET_VLAN_PCP(const struct ofpact_vlan_pcp *a, struct ds *s)
1608{
b1c5bf1f 1609 ds_put_format(s, "%s%s:%s%"PRIu8, colors.param,
c2d936a4 1610 a->push_vlan_if_needed ? "mod_vlan_pcp" : "set_vlan_pcp",
b1c5bf1f 1611 colors.end, a->vlan_pcp);
c2d936a4
BP
1612}
1613\f
1614/* Strip VLAN actions. */
1615
1616static enum ofperr
1617decode_OFPAT_RAW10_STRIP_VLAN(struct ofpbuf *out)
1618{
1619 ofpact_put_STRIP_VLAN(out)->ofpact.raw = OFPAT_RAW10_STRIP_VLAN;
f25d0cf3
BP
1620 return 0;
1621}
1622
8f2cded4 1623static enum ofperr
c2d936a4 1624decode_OFPAT_RAW11_POP_VLAN(struct ofpbuf *out)
8f2cded4 1625{
c2d936a4
BP
1626 ofpact_put_STRIP_VLAN(out)->ofpact.raw = OFPAT_RAW11_POP_VLAN;
1627 return 0;
1628}
f25d0cf3 1629
c2d936a4
BP
1630static void
1631encode_STRIP_VLAN(const struct ofpact_null *null OVS_UNUSED,
1632 enum ofp_version ofp_version, struct ofpbuf *out)
1633{
1634 if (ofp_version == OFP10_VERSION) {
1635 put_OFPAT10_STRIP_VLAN(out);
1636 } else {
1637 put_OFPAT11_POP_VLAN(out);
1638 }
1639}
f25d0cf3 1640
cab50449 1641static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1642parse_STRIP_VLAN(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
1643 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1644{
1645 ofpact_put_STRIP_VLAN(ofpacts)->ofpact.raw = OFPAT_RAW10_STRIP_VLAN;
1646 return NULL;
1647}
1648
cab50449 1649static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1650parse_pop_vlan(struct ofpbuf *ofpacts)
1651{
1652 ofpact_put_STRIP_VLAN(ofpacts)->ofpact.raw = OFPAT_RAW11_POP_VLAN;
1653 return NULL;
1654}
1655
1656static void
1657format_STRIP_VLAN(const struct ofpact_null *a, struct ds *s)
1658{
b1c5bf1f
QM
1659 ds_put_format(s, (a->ofpact.raw == OFPAT_RAW11_POP_VLAN
1660 ? "%spop_vlan%s"
1661 : "%sstrip_vlan%s"),
1662 colors.value, colors.end);
c2d936a4
BP
1663}
1664\f
1665/* Push VLAN action. */
1666
1667static enum ofperr
f3cd3ac7
JS
1668decode_OFPAT_RAW11_PUSH_VLAN(ovs_be16 eth_type,
1669 enum ofp_version ofp_version OVS_UNUSED,
1670 struct ofpbuf *out)
c2d936a4
BP
1671{
1672 if (eth_type != htons(ETH_TYPE_VLAN_8021Q)) {
1673 /* XXX 802.1AD(QinQ) isn't supported at the moment */
1674 return OFPERR_OFPBAC_BAD_ARGUMENT;
f25d0cf3 1675 }
c2d936a4
BP
1676 ofpact_put_PUSH_VLAN(out);
1677 return 0;
1678}
f25d0cf3 1679
c2d936a4
BP
1680static void
1681encode_PUSH_VLAN(const struct ofpact_null *null OVS_UNUSED,
1682 enum ofp_version ofp_version, struct ofpbuf *out)
1683{
1684 if (ofp_version == OFP10_VERSION) {
1685 /* PUSH is a side effect of a SET_VLAN_VID/PCP, which should
1686 * follow this action. */
1687 } else {
1688 /* XXX ETH_TYPE_VLAN_8021AD case */
1689 put_OFPAT11_PUSH_VLAN(out, htons(ETH_TYPE_VLAN_8021Q));
f25d0cf3 1690 }
c2d936a4 1691}
f25d0cf3 1692
cab50449 1693static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1694parse_PUSH_VLAN(char *arg, struct ofpbuf *ofpacts,
1695 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1696{
1697 uint16_t ethertype;
1698 char *error;
1699
1700 *usable_protocols &= OFPUTIL_P_OF11_UP;
1701 error = str_to_u16(arg, "ethertype", &ethertype);
4cceacb9 1702 if (error) {
4cceacb9
JS
1703 return error;
1704 }
1705
c2d936a4
BP
1706 if (ethertype != ETH_TYPE_VLAN_8021Q) {
1707 /* XXX ETH_TYPE_VLAN_8021AD case isn't supported */
1708 return xasprintf("%s: not a valid VLAN ethertype", arg);
f25d0cf3 1709 }
c2d936a4
BP
1710
1711 ofpact_put_PUSH_VLAN(ofpacts);
1712 return NULL;
d01c980f
BP
1713}
1714
c2d936a4
BP
1715static void
1716format_PUSH_VLAN(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
8f2cded4 1717{
c2d936a4 1718 /* XXX 802.1AD case*/
b1c5bf1f
QM
1719 ds_put_format(s, "%spush_vlan:%s%#"PRIx16,
1720 colors.param, colors.end, ETH_TYPE_VLAN_8021Q);
8f2cded4 1721}
d01c980f 1722\f
c2d936a4
BP
1723/* Action structure for OFPAT10_SET_DL_SRC/DST and OFPAT11_SET_DL_SRC/DST. */
1724struct ofp_action_dl_addr {
1725 ovs_be16 type; /* Type. */
1726 ovs_be16 len; /* Length is 16. */
74ff3298 1727 struct eth_addr dl_addr; /* Ethernet address. */
c2d936a4
BP
1728 uint8_t pad[6];
1729};
1730OFP_ASSERT(sizeof(struct ofp_action_dl_addr) == 16);
d01c980f 1731
d01c980f 1732static enum ofperr
c2d936a4 1733decode_OFPAT_RAW_SET_DL_SRC(const struct ofp_action_dl_addr *a,
f3cd3ac7 1734 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4 1735 struct ofpbuf *out)
d01c980f 1736{
74ff3298 1737 ofpact_put_SET_ETH_SRC(out)->mac = a->dl_addr;
c2d936a4
BP
1738 return 0;
1739}
3ddcaf2d 1740
c2d936a4
BP
1741static enum ofperr
1742decode_OFPAT_RAW_SET_DL_DST(const struct ofp_action_dl_addr *a,
f3cd3ac7 1743 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4
BP
1744 struct ofpbuf *out)
1745{
74ff3298 1746 ofpact_put_SET_ETH_DST(out)->mac = a->dl_addr;
c2d936a4
BP
1747 return 0;
1748}
d01c980f 1749
c2d936a4
BP
1750static void
1751encode_SET_ETH_addr(const struct ofpact_mac *mac, enum ofp_version ofp_version,
1752 enum ofp_raw_action_type raw, enum mf_field_id field,
1753 struct ofpbuf *out)
1754{
c2d936a4
BP
1755 if (ofp_version < OFP12_VERSION) {
1756 struct ofp_action_dl_addr *oada;
1757
1758 oada = ofpact_put_raw(out, ofp_version, raw, 0);
74ff3298 1759 oada->dl_addr = mac->mac;
c2d936a4 1760 } else {
128684a6 1761 put_set_field(out, ofp_version, field, eth_addr_to_uint64(mac->mac));
d01c980f
BP
1762 }
1763}
1764
c2d936a4
BP
1765static void
1766encode_SET_ETH_SRC(const struct ofpact_mac *mac, enum ofp_version ofp_version,
1767 struct ofpbuf *out)
b2dd70be 1768{
c2d936a4
BP
1769 encode_SET_ETH_addr(mac, ofp_version, OFPAT_RAW_SET_DL_SRC, MFF_ETH_SRC,
1770 out);
b2dd70be 1771
c2d936a4 1772}
b2dd70be 1773
c2d936a4
BP
1774static void
1775encode_SET_ETH_DST(const struct ofpact_mac *mac,
1776 enum ofp_version ofp_version,
1777 struct ofpbuf *out)
1778{
1779 encode_SET_ETH_addr(mac, ofp_version, OFPAT_RAW_SET_DL_DST, MFF_ETH_DST,
1780 out);
b2dd70be 1781
c2d936a4 1782}
b2dd70be 1783
cab50449 1784static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1785parse_SET_ETH_SRC(char *arg, struct ofpbuf *ofpacts,
1786 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1787{
74ff3298 1788 return str_to_mac(arg, &ofpact_put_SET_ETH_SRC(ofpacts)->mac);
c2d936a4
BP
1789}
1790
cab50449 1791static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1792parse_SET_ETH_DST(char *arg, struct ofpbuf *ofpacts,
1793 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1794{
74ff3298 1795 return str_to_mac(arg, &ofpact_put_SET_ETH_DST(ofpacts)->mac);
b2dd70be
JR
1796}
1797
1798static void
c2d936a4 1799format_SET_ETH_SRC(const struct ofpact_mac *a, struct ds *s)
b2dd70be 1800{
b1c5bf1f
QM
1801 ds_put_format(s, "%smod_dl_src:%s"ETH_ADDR_FMT,
1802 colors.param, colors.end, ETH_ADDR_ARGS(a->mac));
c2d936a4 1803}
b2dd70be 1804
c2d936a4
BP
1805static void
1806format_SET_ETH_DST(const struct ofpact_mac *a, struct ds *s)
1807{
b1c5bf1f
QM
1808 ds_put_format(s, "%smod_dl_dst:%s"ETH_ADDR_FMT,
1809 colors.param, colors.end, ETH_ADDR_ARGS(a->mac));
c2d936a4
BP
1810}
1811\f
1812/* Set IPv4 address actions. */
b2dd70be 1813
c2d936a4 1814static enum ofperr
f3cd3ac7
JS
1815decode_OFPAT_RAW_SET_NW_SRC(ovs_be32 ipv4,
1816 enum ofp_version ofp_version OVS_UNUSED,
1817 struct ofpbuf *out)
c2d936a4
BP
1818{
1819 ofpact_put_SET_IPV4_SRC(out)->ipv4 = ipv4;
1820 return 0;
b2dd70be
JR
1821}
1822
c2d936a4 1823static enum ofperr
f3cd3ac7
JS
1824decode_OFPAT_RAW_SET_NW_DST(ovs_be32 ipv4,
1825 enum ofp_version ofp_version OVS_UNUSED,
1826 struct ofpbuf *out)
b2dd70be 1827{
c2d936a4
BP
1828 ofpact_put_SET_IPV4_DST(out)->ipv4 = ipv4;
1829 return 0;
1830}
b2dd70be 1831
c2d936a4
BP
1832static void
1833encode_SET_IPV4_addr(const struct ofpact_ipv4 *ipv4,
1834 enum ofp_version ofp_version,
1835 enum ofp_raw_action_type raw, enum mf_field_id field,
1836 struct ofpbuf *out)
1837{
1838 ovs_be32 addr = ipv4->ipv4;
1839 if (ofp_version < OFP12_VERSION) {
1840 ofpact_put_raw(out, ofp_version, raw, ntohl(addr));
b2dd70be 1841 } else {
128684a6 1842 put_set_field(out, ofp_version, field, ntohl(addr));
b2dd70be
JR
1843 }
1844}
1845
a6fd70bb 1846static void
c2d936a4
BP
1847encode_SET_IPV4_SRC(const struct ofpact_ipv4 *ipv4,
1848 enum ofp_version ofp_version, struct ofpbuf *out)
a6fd70bb 1849{
c2d936a4
BP
1850 encode_SET_IPV4_addr(ipv4, ofp_version, OFPAT_RAW_SET_NW_SRC, MFF_IPV4_SRC,
1851 out);
1852}
a6fd70bb 1853
c2d936a4
BP
1854static void
1855encode_SET_IPV4_DST(const struct ofpact_ipv4 *ipv4,
1856 enum ofp_version ofp_version, struct ofpbuf *out)
1857{
1858 encode_SET_IPV4_addr(ipv4, ofp_version, OFPAT_RAW_SET_NW_DST, MFF_IPV4_DST,
1859 out);
1860}
a6fd70bb 1861
cab50449 1862static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1863parse_SET_IPV4_SRC(char *arg, struct ofpbuf *ofpacts,
1864 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1865{
1866 return str_to_ip(arg, &ofpact_put_SET_IPV4_SRC(ofpacts)->ipv4);
1867}
a6fd70bb 1868
cab50449 1869static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1870parse_SET_IPV4_DST(char *arg, struct ofpbuf *ofpacts,
1871 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1872{
1873 return str_to_ip(arg, &ofpact_put_SET_IPV4_DST(ofpacts)->ipv4);
1874}
a6fd70bb 1875
c2d936a4
BP
1876static void
1877format_SET_IPV4_SRC(const struct ofpact_ipv4 *a, struct ds *s)
1878{
b1c5bf1f
QM
1879 ds_put_format(s, "%smod_nw_src:%s"IP_FMT,
1880 colors.param, colors.end, IP_ARGS(a->ipv4));
c2d936a4 1881}
097d4939 1882
c2d936a4
BP
1883static void
1884format_SET_IPV4_DST(const struct ofpact_ipv4 *a, struct ds *s)
1885{
b1c5bf1f
QM
1886 ds_put_format(s, "%smod_nw_dst:%s"IP_FMT,
1887 colors.param, colors.end, IP_ARGS(a->ipv4));
c2d936a4
BP
1888}
1889\f
1890/* Set IPv4/v6 TOS actions. */
097d4939 1891
c2d936a4 1892static enum ofperr
f3cd3ac7
JS
1893decode_OFPAT_RAW_SET_NW_TOS(uint8_t dscp,
1894 enum ofp_version ofp_version OVS_UNUSED,
1895 struct ofpbuf *out)
c2d936a4
BP
1896{
1897 if (dscp & ~IP_DSCP_MASK) {
1898 return OFPERR_OFPBAC_BAD_ARGUMENT;
1899 } else {
1900 ofpact_put_SET_IP_DSCP(out)->dscp = dscp;
1901 return 0;
a6fd70bb
JR
1902 }
1903}
1904
a6fd70bb 1905static void
c2d936a4
BP
1906encode_SET_IP_DSCP(const struct ofpact_dscp *dscp,
1907 enum ofp_version ofp_version, struct ofpbuf *out)
a6fd70bb 1908{
c2d936a4
BP
1909 if (ofp_version < OFP12_VERSION) {
1910 put_OFPAT_SET_NW_TOS(out, ofp_version, dscp->dscp);
1911 } else {
128684a6 1912 put_set_field(out, ofp_version, MFF_IP_DSCP_SHIFTED, dscp->dscp >> 2);
c2d936a4
BP
1913 }
1914}
a6fd70bb 1915
cab50449 1916static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1917parse_SET_IP_DSCP(char *arg, struct ofpbuf *ofpacts,
1918 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1919{
1920 uint8_t tos;
1921 char *error;
a6fd70bb 1922
c2d936a4
BP
1923 error = str_to_u8(arg, "TOS", &tos);
1924 if (error) {
1925 return error;
1926 }
a6fd70bb 1927
c2d936a4
BP
1928 if (tos & ~IP_DSCP_MASK) {
1929 return xasprintf("%s: not a valid TOS", arg);
a6fd70bb 1930 }
c2d936a4
BP
1931 ofpact_put_SET_IP_DSCP(ofpacts)->dscp = tos;
1932 return NULL;
a6fd70bb
JR
1933}
1934
b2dd70be 1935static void
c2d936a4 1936format_SET_IP_DSCP(const struct ofpact_dscp *a, struct ds *s)
b2dd70be 1937{
b1c5bf1f 1938 ds_put_format(s, "%smod_nw_tos:%s%d", colors.param, colors.end, a->dscp);
c2d936a4
BP
1939}
1940\f
1941/* Set IPv4/v6 ECN actions. */
b2dd70be 1942
c2d936a4 1943static enum ofperr
f3cd3ac7
JS
1944decode_OFPAT_RAW11_SET_NW_ECN(uint8_t ecn,
1945 enum ofp_version ofp_version OVS_UNUSED,
1946 struct ofpbuf *out)
c2d936a4
BP
1947{
1948 if (ecn & ~IP_ECN_MASK) {
1949 return OFPERR_OFPBAC_BAD_ARGUMENT;
b2dd70be 1950 } else {
c2d936a4
BP
1951 ofpact_put_SET_IP_ECN(out)->ecn = ecn;
1952 return 0;
b2dd70be
JR
1953 }
1954}
1955
c2d936a4
BP
1956static void
1957encode_SET_IP_ECN(const struct ofpact_ecn *ip_ecn,
1958 enum ofp_version ofp_version, struct ofpbuf *out)
d01c980f 1959{
c2d936a4
BP
1960 uint8_t ecn = ip_ecn->ecn;
1961 if (ofp_version == OFP10_VERSION) {
4b684612
BP
1962 struct mf_subfield dst = { .field = mf_from_id(MFF_IP_ECN),
1963 .ofs = 0, .n_bits = 2 };
1964 put_reg_load(out, &dst, ecn);
c2d936a4
BP
1965 } else if (ofp_version == OFP11_VERSION) {
1966 put_OFPAT11_SET_NW_ECN(out, ecn);
1967 } else {
128684a6 1968 put_set_field(out, ofp_version, MFF_IP_ECN, ecn);
c2d936a4
BP
1969 }
1970}
d01c980f 1971
cab50449 1972static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
1973parse_SET_IP_ECN(char *arg, struct ofpbuf *ofpacts,
1974 enum ofputil_protocol *usable_protocols OVS_UNUSED)
1975{
1976 uint8_t ecn;
1977 char *error;
d01c980f 1978
c2d936a4 1979 error = str_to_u8(arg, "ECN", &ecn);
d01c980f
BP
1980 if (error) {
1981 return error;
1982 }
1983
c2d936a4
BP
1984 if (ecn & ~IP_ECN_MASK) {
1985 return xasprintf("%s: not a valid ECN", arg);
1986 }
1987 ofpact_put_SET_IP_ECN(ofpacts)->ecn = ecn;
1988 return NULL;
d01c980f
BP
1989}
1990
c2d936a4
BP
1991static void
1992format_SET_IP_ECN(const struct ofpact_ecn *a, struct ds *s)
1993{
b1c5bf1f
QM
1994 ds_put_format(s, "%smod_nw_ecn:%s%d",
1995 colors.param, colors.end, a->ecn);
c2d936a4
BP
1996}
1997\f
1998/* Set IPv4/v6 TTL actions. */
1999
d01c980f 2000static enum ofperr
f3cd3ac7
JS
2001decode_OFPAT_RAW11_SET_NW_TTL(uint8_t ttl,
2002 enum ofp_version ofp_version OVS_UNUSED,
2003 struct ofpbuf *out)
d01c980f 2004{
c2d936a4
BP
2005 ofpact_put_SET_IP_TTL(out)->ttl = ttl;
2006 return 0;
2007}
2008
2009static void
2010encode_SET_IP_TTL(const struct ofpact_ip_ttl *ttl,
2011 enum ofp_version ofp_version, struct ofpbuf *out)
2012{
2013 if (ofp_version >= OFP11_VERSION) {
2014 put_OFPAT11_SET_NW_TTL(out, ttl->ttl);
2015 } else {
56a91749
BP
2016 struct mf_subfield dst = { .field = mf_from_id(MFF_IP_TTL),
2017 .ofs = 0, .n_bits = 8 };
2018 put_reg_load(out, &dst, ttl->ttl);
c2d936a4
BP
2019 }
2020}
2021
cab50449 2022static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
2023parse_SET_IP_TTL(char *arg, struct ofpbuf *ofpacts,
2024 enum ofputil_protocol *usable_protocols OVS_UNUSED)
2025{
2026 uint8_t ttl;
2027 char *error;
d01c980f 2028
c2d936a4 2029 error = str_to_u8(arg, "TTL", &ttl);
d01c980f
BP
2030 if (error) {
2031 return error;
2032 }
2033
c2d936a4
BP
2034 ofpact_put_SET_IP_TTL(ofpacts)->ttl = ttl;
2035 return NULL;
2036}
d01c980f 2037
c2d936a4
BP
2038static void
2039format_SET_IP_TTL(const struct ofpact_ip_ttl *a, struct ds *s)
2040{
b1c5bf1f 2041 ds_put_format(s, "%smod_nw_ttl:%s%d", colors.param, colors.end, a->ttl);
c2d936a4
BP
2042}
2043\f
2044/* Set TCP/UDP/SCTP port actions. */
d01c980f 2045
c2d936a4 2046static enum ofperr
f3cd3ac7
JS
2047decode_OFPAT_RAW_SET_TP_SRC(ovs_be16 port,
2048 enum ofp_version ofp_version OVS_UNUSED,
2049 struct ofpbuf *out)
c2d936a4
BP
2050{
2051 ofpact_put_SET_L4_SRC_PORT(out)->port = ntohs(port);
2052 return 0;
2053}
d01c980f 2054
c2d936a4 2055static enum ofperr
f3cd3ac7
JS
2056decode_OFPAT_RAW_SET_TP_DST(ovs_be16 port,
2057 enum ofp_version ofp_version OVS_UNUSED,
2058 struct ofpbuf *out)
c2d936a4
BP
2059{
2060 ofpact_put_SET_L4_DST_PORT(out)->port = ntohs(port);
2061 return 0;
2062}
d01c980f 2063
c2d936a4
BP
2064static void
2065encode_SET_L4_port(const struct ofpact_l4_port *l4_port,
2066 enum ofp_version ofp_version, enum ofp_raw_action_type raw,
2067 enum mf_field_id field, struct ofpbuf *out)
2068{
2069 uint16_t port = l4_port->port;
3e34fbdd 2070
c2d936a4 2071 if (ofp_version >= OFP12_VERSION && field != MFF_N_IDS) {
128684a6 2072 put_set_field(out, ofp_version, field, port);
c2d936a4
BP
2073 } else {
2074 ofpact_put_raw(out, ofp_version, raw, port);
2075 }
2076}
8e61c110 2077
c2d936a4
BP
2078static void
2079encode_SET_L4_SRC_PORT(const struct ofpact_l4_port *l4_port,
2080 enum ofp_version ofp_version, struct ofpbuf *out)
2081{
2082 uint8_t proto = l4_port->flow_ip_proto;
2083 enum mf_field_id field = (proto == IPPROTO_TCP ? MFF_TCP_SRC
2084 : proto == IPPROTO_UDP ? MFF_UDP_SRC
2085 : proto == IPPROTO_SCTP ? MFF_SCTP_SRC
2086 : MFF_N_IDS);
276c4e7a 2087
c2d936a4
BP
2088 encode_SET_L4_port(l4_port, ofp_version, OFPAT_RAW_SET_TP_SRC, field, out);
2089}
d01c980f 2090
c2d936a4
BP
2091static void
2092encode_SET_L4_DST_PORT(const struct ofpact_l4_port *l4_port,
2093 enum ofp_version ofp_version,
2094 struct ofpbuf *out)
2095{
2096 uint8_t proto = l4_port->flow_ip_proto;
2097 enum mf_field_id field = (proto == IPPROTO_TCP ? MFF_TCP_DST
2098 : proto == IPPROTO_UDP ? MFF_UDP_DST
2099 : proto == IPPROTO_SCTP ? MFF_SCTP_DST
2100 : MFF_N_IDS);
d01c980f 2101
c2d936a4
BP
2102 encode_SET_L4_port(l4_port, ofp_version, OFPAT_RAW_SET_TP_DST, field, out);
2103}
7bcb1506 2104
cab50449 2105static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
2106parse_SET_L4_SRC_PORT(char *arg, struct ofpbuf *ofpacts,
2107 enum ofputil_protocol *usable_protocols OVS_UNUSED)
2108{
2109 return str_to_u16(arg, "source port",
2110 &ofpact_put_SET_L4_SRC_PORT(ofpacts)->port);
2111}
d01c980f 2112
cab50449 2113static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
2114parse_SET_L4_DST_PORT(char *arg, struct ofpbuf *ofpacts,
2115 enum ofputil_protocol *usable_protocols OVS_UNUSED)
2116{
2117 return str_to_u16(arg, "destination port",
2118 &ofpact_put_SET_L4_DST_PORT(ofpacts)->port);
2119}
d01c980f 2120
c2d936a4
BP
2121static void
2122format_SET_L4_SRC_PORT(const struct ofpact_l4_port *a, struct ds *s)
2123{
b1c5bf1f 2124 ds_put_format(s, "%smod_tp_src:%s%d", colors.param, colors.end, a->port);
c2d936a4 2125}
d01c980f 2126
c2d936a4
BP
2127static void
2128format_SET_L4_DST_PORT(const struct ofpact_l4_port *a, struct ds *s)
2129{
b1c5bf1f 2130 ds_put_format(s, "%smod_tp_dst:%s%d", colors.param, colors.end, a->port);
c2d936a4
BP
2131}
2132\f
73178f20
BP
2133/* Action structure for OFPAT_COPY_FIELD. */
2134struct ofp15_action_copy_field {
2135 ovs_be16 type; /* OFPAT_COPY_FIELD. */
2136 ovs_be16 len; /* Length is padded to 64 bits. */
2137 ovs_be16 n_bits; /* Number of bits to copy. */
2138 ovs_be16 src_offset; /* Starting bit offset in source. */
2139 ovs_be16 dst_offset; /* Starting bit offset in destination. */
650763d8 2140 uint8_t pad[2];
f13cdd73
BP
2141 /* Followed by:
2142 * - OXM header for source field.
2143 * - OXM header for destination field.
2144 * - Padding with 0-bytes to a multiple of 8 bytes.
650763d8
BP
2145 * The "pad2" member is the beginning of the above. */
2146 uint8_t pad2[4];
73178f20 2147};
f13cdd73 2148OFP_ASSERT(sizeof(struct ofp15_action_copy_field) == 16);
73178f20 2149
914624f8
BP
2150/* Action structure for OpenFlow 1.3 extension copy-field action.. */
2151struct onf_action_copy_field {
2152 ovs_be16 type; /* OFPAT_EXPERIMENTER. */
2153 ovs_be16 len; /* Length is padded to 64 bits. */
2154 ovs_be32 experimenter; /* ONF_VENDOR_ID. */
2155 ovs_be16 exp_type; /* 3200. */
2156 uint8_t pad[2]; /* Not used. */
2157 ovs_be16 n_bits; /* Number of bits to copy. */
2158 ovs_be16 src_offset; /* Starting bit offset in source. */
2159 ovs_be16 dst_offset; /* Starting bit offset in destination. */
2160 uint8_t pad2[2]; /* Not used. */
2161 /* Followed by:
2162 * - OXM header for source field.
2163 * - OXM header for destination field.
2164 * - Padding with 0-bytes (either 0 or 4 of them) to a multiple of 8 bytes.
2165 * The "pad3" member is the beginning of the above. */
2166 uint8_t pad3[4]; /* Not used. */
2167};
2168OFP_ASSERT(sizeof(struct onf_action_copy_field) == 24);
2169
c2d936a4
BP
2170/* Action structure for NXAST_REG_MOVE.
2171 *
2172 * Copies src[src_ofs:src_ofs+n_bits] to dst[dst_ofs:dst_ofs+n_bits], where
2173 * a[b:c] denotes the bits within 'a' numbered 'b' through 'c' (not including
2174 * bit 'c'). Bit numbering starts at 0 for the least-significant bit, 1 for
2175 * the next most significant bit, and so on.
2176 *
2177 * 'src' and 'dst' are nxm_header values with nxm_hasmask=0. (It doesn't make
2178 * sense to use nxm_hasmask=1 because the action does not do any kind of
2179 * matching; it uses the actual value of a field.)
2180 *
2181 * The following nxm_header values are potentially acceptable as 'src':
2182 *
2183 * - NXM_OF_IN_PORT
2184 * - NXM_OF_ETH_DST
2185 * - NXM_OF_ETH_SRC
2186 * - NXM_OF_ETH_TYPE
2187 * - NXM_OF_VLAN_TCI
2188 * - NXM_OF_IP_TOS
2189 * - NXM_OF_IP_PROTO
2190 * - NXM_OF_IP_SRC
2191 * - NXM_OF_IP_DST
2192 * - NXM_OF_TCP_SRC
2193 * - NXM_OF_TCP_DST
2194 * - NXM_OF_UDP_SRC
2195 * - NXM_OF_UDP_DST
2196 * - NXM_OF_ICMP_TYPE
2197 * - NXM_OF_ICMP_CODE
2198 * - NXM_OF_ARP_OP
2199 * - NXM_OF_ARP_SPA
2200 * - NXM_OF_ARP_TPA
2201 * - NXM_NX_TUN_ID
2202 * - NXM_NX_ARP_SHA
2203 * - NXM_NX_ARP_THA
2204 * - NXM_NX_ICMPV6_TYPE
2205 * - NXM_NX_ICMPV6_CODE
2206 * - NXM_NX_ND_SLL
2207 * - NXM_NX_ND_TLL
2208 * - NXM_NX_REG(idx) for idx in the switch's accepted range.
2209 * - NXM_NX_PKT_MARK
2210 * - NXM_NX_TUN_IPV4_SRC
2211 * - NXM_NX_TUN_IPV4_DST
2212 *
2213 * The following nxm_header values are potentially acceptable as 'dst':
2214 *
2215 * - NXM_OF_ETH_DST
2216 * - NXM_OF_ETH_SRC
2217 * - NXM_OF_IP_TOS
2218 * - NXM_OF_IP_SRC
2219 * - NXM_OF_IP_DST
2220 * - NXM_OF_TCP_SRC
2221 * - NXM_OF_TCP_DST
2222 * - NXM_OF_UDP_SRC
2223 * - NXM_OF_UDP_DST
f6ecf944
JP
2224 * - NXM_OF_ICMP_TYPE
2225 * - NXM_OF_ICMP_CODE
2226 * - NXM_NX_ICMPV6_TYPE
2227 * - NXM_NX_ICMPV6_CODE
c2d936a4
BP
2228 * - NXM_NX_ARP_SHA
2229 * - NXM_NX_ARP_THA
2230 * - NXM_OF_ARP_OP
2231 * - NXM_OF_ARP_SPA
2232 * - NXM_OF_ARP_TPA
2233 * Modifying any of the above fields changes the corresponding packet
2234 * header.
2235 *
2236 * - NXM_OF_IN_PORT
2237 *
2238 * - NXM_NX_REG(idx) for idx in the switch's accepted range.
2239 *
2240 * - NXM_NX_PKT_MARK
2241 *
2242 * - NXM_OF_VLAN_TCI. Modifying this field's value has side effects on the
2243 * packet's 802.1Q header. Setting a value with CFI=0 removes the 802.1Q
2244 * header (if any), ignoring the other bits. Setting a value with CFI=1
2245 * adds or modifies the 802.1Q header appropriately, setting the TCI field
2246 * to the field's new value (with the CFI bit masked out).
2247 *
2248 * - NXM_NX_TUN_ID, NXM_NX_TUN_IPV4_SRC, NXM_NX_TUN_IPV4_DST. Modifying
2249 * any of these values modifies the corresponding tunnel header field used
2250 * for the packet's next tunnel encapsulation, if allowed by the
2251 * configuration of the output tunnel port.
2252 *
2253 * A given nxm_header value may be used as 'src' or 'dst' only on a flow whose
2254 * nx_match satisfies its prerequisites. For example, NXM_OF_IP_TOS may be
2255 * used only if the flow's nx_match includes an nxm_entry that specifies
2256 * nxm_type=NXM_OF_ETH_TYPE, nxm_hasmask=0, and nxm_value=0x0800.
2257 *
2258 * The switch will reject actions for which src_ofs+n_bits is greater than the
2259 * width of 'src' or dst_ofs+n_bits is greater than the width of 'dst' with
2260 * error type OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
2261 *
2262 * This action behaves properly when 'src' overlaps with 'dst', that is, it
2263 * behaves as if 'src' were copied out to a temporary buffer, then the
2264 * temporary buffer copied to 'dst'.
2265 */
2266struct nx_action_reg_move {
2267 ovs_be16 type; /* OFPAT_VENDOR. */
2268 ovs_be16 len; /* Length is 24. */
2269 ovs_be32 vendor; /* NX_VENDOR_ID. */
2270 ovs_be16 subtype; /* NXAST_REG_MOVE. */
2271 ovs_be16 n_bits; /* Number of bits. */
2272 ovs_be16 src_ofs; /* Starting bit offset in source. */
2273 ovs_be16 dst_ofs; /* Starting bit offset in destination. */
bad8a439
BP
2274 /* Followed by:
2275 * - OXM/NXM header for source field (4 or 8 bytes).
2276 * - OXM/NXM header for destination field (4 or 8 bytes).
2277 * - Padding with 0-bytes to a multiple of 8 bytes, if necessary. */
c2d936a4 2278};
bad8a439 2279OFP_ASSERT(sizeof(struct nx_action_reg_move) == 16);
ff14eb7a 2280
73178f20 2281static enum ofperr
914624f8
BP
2282decode_copy_field__(ovs_be16 src_offset, ovs_be16 dst_offset, ovs_be16 n_bits,
2283 const void *action, ovs_be16 action_len, size_t oxm_offset,
04f48a68 2284 const struct vl_mff_map *vl_mff_map,
914624f8 2285 struct ofpbuf *ofpacts)
73178f20 2286{
0a2869d5 2287 struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts);
914624f8
BP
2288 move->ofpact.raw = ONFACT_RAW13_COPY_FIELD;
2289 move->src.ofs = ntohs(src_offset);
2290 move->src.n_bits = ntohs(n_bits);
2291 move->dst.ofs = ntohs(dst_offset);
2292 move->dst.n_bits = ntohs(n_bits);
2293
0a2869d5 2294 struct ofpbuf b = ofpbuf_const_initializer(action, ntohs(action_len));
914624f8 2295 ofpbuf_pull(&b, oxm_offset);
0a2869d5 2296
04f48a68 2297 enum ofperr error = nx_pull_header(&b, vl_mff_map, &move->src.field, NULL);
f13cdd73
BP
2298 if (error) {
2299 return error;
2300 }
04f48a68 2301 error = nx_pull_header(&b, vl_mff_map, &move->dst.field, NULL);
f13cdd73
BP
2302 if (error) {
2303 return error;
2304 }
f13cdd73 2305
6fd6ed71 2306 if (!is_all_zeros(b.data, b.size)) {
f13cdd73
BP
2307 return OFPERR_NXBRC_MUST_BE_ZERO;
2308 }
2309
73178f20
BP
2310 return nxm_reg_move_check(move, NULL);
2311}
2312
914624f8
BP
2313static enum ofperr
2314decode_OFPAT_RAW15_COPY_FIELD(const struct ofp15_action_copy_field *oacf,
f3cd3ac7 2315 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2316 const struct vl_mff_map *vl_mff_map,
914624f8
BP
2317 struct ofpbuf *ofpacts)
2318{
2319 return decode_copy_field__(oacf->src_offset, oacf->dst_offset,
2320 oacf->n_bits, oacf, oacf->len,
04f48a68
YHW
2321 OBJECT_OFFSETOF(oacf, pad2), vl_mff_map,
2322 ofpacts);
914624f8
BP
2323}
2324
2325static enum ofperr
2326decode_ONFACT_RAW13_COPY_FIELD(const struct onf_action_copy_field *oacf,
f3cd3ac7 2327 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2328 const struct vl_mff_map *vl_mff_map,
914624f8
BP
2329 struct ofpbuf *ofpacts)
2330{
2331 return decode_copy_field__(oacf->src_offset, oacf->dst_offset,
2332 oacf->n_bits, oacf, oacf->len,
04f48a68
YHW
2333 OBJECT_OFFSETOF(oacf, pad3), vl_mff_map,
2334 ofpacts);
914624f8
BP
2335}
2336
c2d936a4
BP
2337static enum ofperr
2338decode_NXAST_RAW_REG_MOVE(const struct nx_action_reg_move *narm,
f3cd3ac7 2339 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2340 const struct vl_mff_map *vl_mff_map,
c2d936a4
BP
2341 struct ofpbuf *ofpacts)
2342{
0a2869d5 2343 struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts);
914624f8 2344 move->ofpact.raw = NXAST_RAW_REG_MOVE;
c2d936a4
BP
2345 move->src.ofs = ntohs(narm->src_ofs);
2346 move->src.n_bits = ntohs(narm->n_bits);
c2d936a4
BP
2347 move->dst.ofs = ntohs(narm->dst_ofs);
2348 move->dst.n_bits = ntohs(narm->n_bits);
d01c980f 2349
0a2869d5 2350 struct ofpbuf b = ofpbuf_const_initializer(narm, ntohs(narm->len));
bad8a439 2351 ofpbuf_pull(&b, sizeof *narm);
0a2869d5 2352
04f48a68 2353 enum ofperr error = nx_pull_header(&b, vl_mff_map, &move->src.field, NULL);
bad8a439
BP
2354 if (error) {
2355 return error;
2356 }
04f48a68 2357 error = nx_pull_header(&b, vl_mff_map, &move->dst.field, NULL);
bad8a439
BP
2358 if (error) {
2359 return error;
2360 }
04f48a68 2361
6fd6ed71 2362 if (!is_all_zeros(b.data, b.size)) {
bad8a439
BP
2363 return OFPERR_NXBRC_MUST_BE_ZERO;
2364 }
2365
c2d936a4
BP
2366 return nxm_reg_move_check(move, NULL);
2367}
d01c980f 2368
c2d936a4
BP
2369static void
2370encode_REG_MOVE(const struct ofpact_reg_move *move,
73178f20
BP
2371 enum ofp_version ofp_version, struct ofpbuf *out)
2372{
914624f8
BP
2373 /* For OpenFlow 1.3, the choice of ONFACT_RAW13_COPY_FIELD versus
2374 * NXAST_RAW_REG_MOVE is somewhat difficult. Neither one is guaranteed to
2375 * be supported by every OpenFlow 1.3 implementation. It would be ideal to
2376 * probe for support. Until we have that ability, we currently prefer
2377 * NXAST_RAW_REG_MOVE for backward compatibility with older Open vSwitch
2378 * versions. */
6fd6ed71 2379 size_t start_ofs = out->size;
73178f20 2380 if (ofp_version >= OFP15_VERSION) {
bad8a439 2381 struct ofp15_action_copy_field *copy = put_OFPAT15_COPY_FIELD(out);
73178f20
BP
2382 copy->n_bits = htons(move->dst.n_bits);
2383 copy->src_offset = htons(move->src.ofs);
2384 copy->dst_offset = htons(move->dst.ofs);
6fd6ed71 2385 out->size = out->size - sizeof copy->pad2;
04f48a68
YHW
2386 nx_put_mff_header(out, move->src.field, ofp_version, false);
2387 nx_put_mff_header(out, move->dst.field, ofp_version, false);
914624f8
BP
2388 } else if (ofp_version == OFP13_VERSION
2389 && move->ofpact.raw == ONFACT_RAW13_COPY_FIELD) {
2390 struct onf_action_copy_field *copy = put_ONFACT13_COPY_FIELD(out);
2391 copy->n_bits = htons(move->dst.n_bits);
2392 copy->src_offset = htons(move->src.ofs);
2393 copy->dst_offset = htons(move->dst.ofs);
6fd6ed71 2394 out->size = out->size - sizeof copy->pad3;
04f48a68
YHW
2395 nx_put_mff_header(out, move->src.field, ofp_version, false);
2396 nx_put_mff_header(out, move->dst.field, ofp_version, false);
73178f20 2397 } else {
bad8a439 2398 struct nx_action_reg_move *narm = put_NXAST_REG_MOVE(out);
73178f20
BP
2399 narm->n_bits = htons(move->dst.n_bits);
2400 narm->src_ofs = htons(move->src.ofs);
2401 narm->dst_ofs = htons(move->dst.ofs);
04f48a68
YHW
2402 nx_put_mff_header(out, move->src.field, 0, false);
2403 nx_put_mff_header(out, move->dst.field, 0, false);
73178f20 2404 }
bad8a439 2405 pad_ofpat(out, start_ofs);
c2d936a4 2406}
e9536ecb 2407
cab50449 2408static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
2409parse_REG_MOVE(const char *arg, struct ofpbuf *ofpacts,
2410 enum ofputil_protocol *usable_protocols OVS_UNUSED)
2411{
2412 struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts);
21b2fa61 2413 return nxm_parse_reg_move(move, arg);
c2d936a4 2414}
0f3f3c3d 2415
c2d936a4
BP
2416static void
2417format_REG_MOVE(const struct ofpact_reg_move *a, struct ds *s)
2418{
2419 nxm_format_reg_move(a, s);
2420}
2421\f
7eb4b1f1
BP
2422/* Action structure for OFPAT12_SET_FIELD. */
2423struct ofp12_action_set_field {
2424 ovs_be16 type; /* OFPAT12_SET_FIELD. */
2425 ovs_be16 len; /* Length is padded to 64 bits. */
2426
2427 /* Followed by:
2428 * - An OXM header, value, and (in OpenFlow 1.5+) optionally a mask.
2429 * - Enough 0-bytes to pad out to a multiple of 64 bits.
2430 *
2431 * The "pad" member is the beginning of the above. */
2432 uint8_t pad[4];
2433};
2434OFP_ASSERT(sizeof(struct ofp12_action_set_field) == 8);
2435
c2d936a4
BP
2436/* Action structure for NXAST_REG_LOAD.
2437 *
2438 * Copies value[0:n_bits] to dst[ofs:ofs+n_bits], where a[b:c] denotes the bits
2439 * within 'a' numbered 'b' through 'c' (not including bit 'c'). Bit numbering
2440 * starts at 0 for the least-significant bit, 1 for the next most significant
2441 * bit, and so on.
2442 *
2443 * 'dst' is an nxm_header with nxm_hasmask=0. See the documentation for
2444 * NXAST_REG_MOVE, above, for the permitted fields and for the side effects of
2445 * loading them.
2446 *
2447 * The 'ofs' and 'n_bits' fields are combined into a single 'ofs_nbits' field
2448 * to avoid enlarging the structure by another 8 bytes. To allow 'n_bits' to
2449 * take a value between 1 and 64 (inclusive) while taking up only 6 bits, it is
2450 * also stored as one less than its true value:
2451 *
2452 * 15 6 5 0
2453 * +------------------------------+------------------+
2454 * | ofs | n_bits - 1 |
2455 * +------------------------------+------------------+
2456 *
2457 * The switch will reject actions for which ofs+n_bits is greater than the
2458 * width of 'dst', or in which any bits in 'value' with value 2**n_bits or
2459 * greater are set to 1, with error type OFPET_BAD_ACTION, code
2460 * OFPBAC_BAD_ARGUMENT.
2461 */
2462struct nx_action_reg_load {
2463 ovs_be16 type; /* OFPAT_VENDOR. */
2464 ovs_be16 len; /* Length is 24. */
2465 ovs_be32 vendor; /* NX_VENDOR_ID. */
2466 ovs_be16 subtype; /* NXAST_REG_LOAD. */
2467 ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
2468 ovs_be32 dst; /* Destination register. */
2469 ovs_be64 value; /* Immediate value. */
2470};
2471OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24);
b676167a 2472
aad28f47
BP
2473/* The NXAST_REG_LOAD2 action structure is "struct ext_action_header",
2474 * followed by:
bad8a439 2475 *
aad28f47
BP
2476 * - An NXM/OXM header, value, and optionally a mask.
2477 * - Enough 0-bytes to pad out to a multiple of 64 bits.
2478 *
2479 * The "pad" member is the beginning of the above. */
bad8a439 2480
c2d936a4 2481static enum ofperr
7eb4b1f1 2482decode_ofpat_set_field(const struct ofp12_action_set_field *oasf,
04f48a68
YHW
2483 bool may_mask, const struct vl_mff_map *vl_mff_map,
2484 struct ofpbuf *ofpacts)
7fdb60a7 2485{
0a2869d5 2486 struct ofpbuf b = ofpbuf_const_initializer(oasf, ntohs(oasf->len));
7eb4b1f1 2487 ofpbuf_pull(&b, OBJECT_OFFSETOF(oasf, pad));
0a2869d5 2488
128684a6
JR
2489 union mf_value value, mask;
2490 const struct mf_field *field;
04f48a68 2491 enum ofperr error = nx_pull_entry(&b, vl_mff_map, &field, &value,
128684a6 2492 may_mask ? &mask : NULL);
178742f9 2493 if (error) {
178742f9
BP
2494 return (error == OFPERR_OFPBMC_BAD_MASK
2495 ? OFPERR_OFPBAC_BAD_SET_MASK
2496 : error);
c2d936a4 2497 }
7eb4b1f1 2498 if (!may_mask) {
128684a6 2499 memset(&mask, 0xff, field->n_bytes);
7eb4b1f1 2500 }
178742f9 2501
6fd6ed71 2502 if (!is_all_zeros(b.data, b.size)) {
c2d936a4
BP
2503 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
2504 }
7fdb60a7 2505
178742f9
BP
2506 /* OpenFlow says specifically that one may not set OXM_OF_IN_PORT via
2507 * Set-Field. */
128684a6 2508 if (field->id == MFF_IN_PORT_OXM) {
178742f9 2509 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
c2d936a4 2510 }
178742f9 2511
c2d936a4 2512 /* oxm_length is now validated to be compatible with mf_value. */
128684a6 2513 if (!field->writable) {
178742f9 2514 VLOG_WARN_RL(&rl, "destination field %s is not writable",
128684a6 2515 field->name);
c2d936a4
BP
2516 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
2517 }
c2d936a4 2518
d3cb080e 2519 /* The value must be valid for match. OpenFlow 1.5 also says,
7eb4b1f1
BP
2520 * "In an OXM_OF_VLAN_VID set-field action, the OFPVID_PRESENT bit must be
2521 * a 1-bit in oxm_value and in oxm_mask." */
128684a6
JR
2522 if (!mf_is_value_valid(field, &value)
2523 || (field->id == MFF_VLAN_VID
2524 && (!(mask.be16 & htons(OFPVID12_PRESENT))
2525 || !(value.be16 & htons(OFPVID12_PRESENT))))) {
c2d936a4 2526 struct ds ds = DS_EMPTY_INITIALIZER;
128684a6 2527 mf_format(field, &value, NULL, &ds);
c2d936a4 2528 VLOG_WARN_RL(&rl, "Invalid value for set field %s: %s",
128684a6 2529 field->name, ds_cstr(&ds));
c2d936a4
BP
2530 ds_destroy(&ds);
2531
2532 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
7fdb60a7 2533 }
128684a6
JR
2534
2535 ofpact_put_set_field(ofpacts, field, &value, &mask);
c2d936a4 2536 return 0;
7fdb60a7
SH
2537}
2538
7eb4b1f1
BP
2539static enum ofperr
2540decode_OFPAT_RAW12_SET_FIELD(const struct ofp12_action_set_field *oasf,
f3cd3ac7 2541 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2542 const struct vl_mff_map *vl_mff_map,
7eb4b1f1
BP
2543 struct ofpbuf *ofpacts)
2544{
04f48a68 2545 return decode_ofpat_set_field(oasf, false, vl_mff_map, ofpacts);
7eb4b1f1
BP
2546}
2547
2548static enum ofperr
2549decode_OFPAT_RAW15_SET_FIELD(const struct ofp12_action_set_field *oasf,
f3cd3ac7 2550 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2551 const struct vl_mff_map *vl_mff_map,
7eb4b1f1
BP
2552 struct ofpbuf *ofpacts)
2553{
04f48a68 2554 return decode_ofpat_set_field(oasf, true, vl_mff_map, ofpacts);
7eb4b1f1
BP
2555}
2556
2557static enum ofperr
2558decode_NXAST_RAW_REG_LOAD(const struct nx_action_reg_load *narl,
f3cd3ac7 2559 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2560 const struct vl_mff_map *vl_mff_map,
7eb4b1f1
BP
2561 struct ofpbuf *out)
2562{
7eb4b1f1
BP
2563 struct mf_subfield dst;
2564 enum ofperr error;
2565
04f48a68 2566 dst.field = mf_from_nxm_header(ntohl(narl->dst), vl_mff_map);
7eb4b1f1
BP
2567 dst.ofs = nxm_decode_ofs(narl->ofs_nbits);
2568 dst.n_bits = nxm_decode_n_bits(narl->ofs_nbits);
04f48a68
YHW
2569 if (mf_vl_mff_invalid(dst.field, vl_mff_map)) {
2570 return OFPERR_NXFMFC_INVALID_TLV_FIELD;
2571 }
2572
7eb4b1f1
BP
2573 error = mf_check_dst(&dst, NULL);
2574 if (error) {
2575 return error;
2576 }
2577
2578 /* Reject 'narl' if a bit numbered 'n_bits' or higher is set to 1 in
2579 * narl->value. */
2580 if (dst.n_bits < 64 && ntohll(narl->value) >> dst.n_bits) {
2581 return OFPERR_OFPBAC_BAD_ARGUMENT;
2582 }
2583
128684a6
JR
2584 struct ofpact_set_field *sf = ofpact_put_reg_load(out, dst.field, NULL,
2585 NULL);
7eb4b1f1 2586 bitwise_put(ntohll(narl->value),
128684a6 2587 sf->value, dst.field->n_bytes, dst.ofs,
7eb4b1f1
BP
2588 dst.n_bits);
2589 bitwise_put(UINT64_MAX,
128684a6 2590 ofpact_set_field_mask(sf), dst.field->n_bytes, dst.ofs,
7eb4b1f1 2591 dst.n_bits);
7eb4b1f1
BP
2592 return 0;
2593}
2594
bad8a439 2595static enum ofperr
aad28f47 2596decode_NXAST_RAW_REG_LOAD2(const struct ext_action_header *eah,
f3cd3ac7 2597 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 2598 const struct vl_mff_map *vl_mff_map,
bad8a439
BP
2599 struct ofpbuf *out)
2600{
aad28f47
BP
2601 struct ofpbuf b = ofpbuf_const_initializer(eah, ntohs(eah->len));
2602 ofpbuf_pull(&b, OBJECT_OFFSETOF(eah, pad));
0a2869d5 2603
128684a6
JR
2604 union mf_value value, mask;
2605 const struct mf_field *field;
04f48a68 2606 enum ofperr error = nx_pull_entry(&b, vl_mff_map, &field, &value, &mask);
bad8a439
BP
2607 if (error) {
2608 return error;
2609 }
6fd6ed71 2610 if (!is_all_zeros(b.data, b.size)) {
bad8a439
BP
2611 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
2612 }
2613
128684a6
JR
2614 if (!field->writable) {
2615 VLOG_WARN_RL(&rl, "destination field %s is not writable", field->name);
bad8a439
BP
2616 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
2617 }
128684a6
JR
2618
2619 /* Put value and mask. */
2620 ofpact_put_reg_load2(out, field, &value, &mask);
bad8a439
BP
2621 return 0;
2622}
2623
7fdb60a7 2624static void
128684a6
JR
2625put_set_field(struct ofpbuf *openflow, enum ofp_version ofp_version,
2626 enum mf_field_id field, uint64_t value_)
7fdb60a7 2627{
7eb4b1f1 2628 struct ofp12_action_set_field *oasf OVS_UNUSED;
178742f9 2629 int n_bytes = mf_from_id(field)->n_bytes;
6fd6ed71 2630 size_t start_ofs = openflow->size;
178742f9 2631 union mf_value value;
7fdb60a7 2632
178742f9 2633 value.be64 = htonll(value_ << (8 * (8 - n_bytes)));
7fdb60a7 2634
7eb4b1f1 2635 oasf = put_OFPAT12_SET_FIELD(openflow);
6fd6ed71 2636 openflow->size = openflow->size - sizeof oasf->pad;
04f48a68 2637 nx_put_entry(openflow, mf_from_id(field), ofp_version, &value, NULL);
178742f9 2638 pad_ofpat(openflow, start_ofs);
7fdb60a7
SH
2639}
2640
4b684612
BP
2641static void
2642put_reg_load(struct ofpbuf *openflow,
2643 const struct mf_subfield *dst, uint64_t value)
2644{
2645 ovs_assert(dst->n_bits <= 64);
2646
2647 struct nx_action_reg_load *narl = put_NXAST_REG_LOAD(openflow);
2648 narl->ofs_nbits = nxm_encode_ofs_nbits(dst->ofs, dst->n_bits);
04f48a68 2649 narl->dst = htonl(nxm_header_from_mff(dst->field));
4b684612
BP
2650 narl->value = htonll(value);
2651}
2652
7eb4b1f1
BP
2653static bool
2654next_load_segment(const struct ofpact_set_field *sf,
2655 struct mf_subfield *dst, uint64_t *value)
2656{
fa078489
BP
2657 int n_bits = sf->field->n_bits;
2658 int n_bytes = sf->field->n_bytes;
7eb4b1f1
BP
2659 int start = dst->ofs + dst->n_bits;
2660
fa078489 2661 if (start < n_bits) {
7eb4b1f1 2662 dst->field = sf->field;
128684a6
JR
2663 dst->ofs = bitwise_scan(ofpact_set_field_mask(sf), n_bytes, 1, start,
2664 n_bits);
fa078489 2665 if (dst->ofs < n_bits) {
128684a6
JR
2666 dst->n_bits = bitwise_scan(ofpact_set_field_mask(sf), n_bytes, 0,
2667 dst->ofs + 1,
fa078489 2668 MIN(dst->ofs + 64, n_bits)) - dst->ofs;
128684a6 2669 *value = bitwise_get(sf->value, n_bytes, dst->ofs, dst->n_bits);
7eb4b1f1
BP
2670 return true;
2671 }
2672 }
2673 return false;
2674}
178742f9 2675
7eb4b1f1 2676/* Convert 'sf' to a series of REG_LOADs. */
7fdb60a7 2677static void
c2d936a4 2678set_field_to_nxast(const struct ofpact_set_field *sf, struct ofpbuf *openflow)
7fdb60a7 2679{
bad8a439 2680 /* If 'sf' cannot be encoded as NXAST_REG_LOAD because it requires an
4fe04a7e
JG
2681 * experimenter OXM or is variable length (or if it came in as
2682 * NXAST_REG_LOAD2), encode as NXAST_REG_LOAD2. Otherwise use
2683 * NXAST_REG_LOAD, which is backward compatible. */
bad8a439 2684 if (sf->ofpact.raw == NXAST_RAW_REG_LOAD2
4fe04a7e 2685 || !mf_nxm_header(sf->field->id) || sf->field->variable_len) {
aad28f47 2686 struct ext_action_header *eah OVS_UNUSED;
6fd6ed71 2687 size_t start_ofs = openflow->size;
bad8a439 2688
aad28f47
BP
2689 eah = put_NXAST_REG_LOAD2(openflow);
2690 openflow->size = openflow->size - sizeof eah->pad;
04f48a68 2691 nx_put_entry(openflow, sf->field, 0, sf->value,
128684a6 2692 ofpact_set_field_mask(sf));
bad8a439
BP
2693 pad_ofpat(openflow, start_ofs);
2694 } else {
2695 struct mf_subfield dst;
2696 uint64_t value;
7eb4b1f1 2697
bad8a439
BP
2698 dst.ofs = dst.n_bits = 0;
2699 while (next_load_segment(sf, &dst, &value)) {
4b684612 2700 put_reg_load(openflow, &dst, value);
bad8a439 2701 }
7fdb60a7
SH
2702 }
2703}
2704
7eb4b1f1
BP
2705/* Convert 'sf', which must set an entire field, to standard OpenFlow 1.0/1.1
2706 * actions, if we can, falling back to Nicira extensions if we must.
7fdb60a7 2707 *
c2d936a4
BP
2708 * We check only meta-flow types that can appear within set field actions and
2709 * that have a mapping to compatible action types. These struct mf_field
2710 * definitions have a defined OXM or NXM header value and specify the field as
2711 * writable. */
2712static void
2713set_field_to_legacy_openflow(const struct ofpact_set_field *sf,
2714 enum ofp_version ofp_version,
2715 struct ofpbuf *out)
7fdb60a7 2716{
c2d936a4
BP
2717 switch ((int) sf->field->id) {
2718 case MFF_VLAN_TCI: {
128684a6 2719 ovs_be16 tci = sf->value->be16;
c2d936a4
BP
2720 bool cfi = (tci & htons(VLAN_CFI)) != 0;
2721 uint16_t vid = vlan_tci_to_vid(tci);
2722 uint8_t pcp = vlan_tci_to_pcp(tci);
2723
2724 if (ofp_version < OFP11_VERSION) {
2725 /* NXM_OF_VLAN_TCI to OpenFlow 1.0 mapping:
2726 *
2727 * If CFI=1, Add or modify VLAN VID & PCP.
2728 * If CFI=0, strip VLAN header, if any.
2729 */
2730 if (cfi) {
2731 put_OFPAT10_SET_VLAN_VID(out, vid);
2732 put_OFPAT10_SET_VLAN_PCP(out, pcp);
2733 } else {
2734 put_OFPAT10_STRIP_VLAN(out);
2735 }
2736 } else {
2737 /* NXM_OF_VLAN_TCI to OpenFlow 1.1 mapping:
2738 *
2739 * If CFI=1, Add or modify VLAN VID & PCP.
2740 * OpenFlow 1.1 set actions only apply if the packet
2741 * already has VLAN tags. To be sure that is the case
2742 * we have to push a VLAN header. As we do not support
2743 * multiple layers of VLANs, this is a no-op, if a VLAN
2744 * header already exists. This may backfire, however,
2745 * when we start supporting multiple layers of VLANs.
2746 * If CFI=0, strip VLAN header, if any.
2747 */
2748 if (cfi) {
2749 /* Push a VLAN tag, if one was not seen at action validation
2750 * time. */
2751 if (!sf->flow_has_vlan) {
2752 put_OFPAT11_PUSH_VLAN(out, htons(ETH_TYPE_VLAN_8021Q));
2753 }
2754 put_OFPAT11_SET_VLAN_VID(out, vid);
2755 put_OFPAT11_SET_VLAN_PCP(out, pcp);
2756 } else {
2757 /* If the flow did not match on vlan, we have no way of
2758 * knowing if the vlan tag exists, so we must POP just to be
2759 * sure. */
2760 put_OFPAT11_POP_VLAN(out);
2761 }
2762 }
2763 break;
2764 }
7fdb60a7 2765
c2d936a4 2766 case MFF_VLAN_VID: {
128684a6 2767 uint16_t vid = ntohs(sf->value->be16) & VLAN_VID_MASK;
c2d936a4
BP
2768 if (ofp_version == OFP10_VERSION) {
2769 put_OFPAT10_SET_VLAN_VID(out, vid);
2770 } else {
2771 put_OFPAT11_SET_VLAN_VID(out, vid);
2772 }
2773 break;
2774 }
2775
2776 case MFF_VLAN_PCP:
2777 if (ofp_version == OFP10_VERSION) {
128684a6 2778 put_OFPAT10_SET_VLAN_PCP(out, sf->value->u8);
c2d936a4 2779 } else {
128684a6 2780 put_OFPAT11_SET_VLAN_PCP(out, sf->value->u8);
c2d936a4
BP
2781 }
2782 break;
2783
2784 case MFF_ETH_SRC:
128684a6 2785 put_OFPAT_SET_DL_SRC(out, ofp_version)->dl_addr = sf->value->mac;
c2d936a4
BP
2786 break;
2787
2788 case MFF_ETH_DST:
128684a6 2789 put_OFPAT_SET_DL_DST(out, ofp_version)->dl_addr = sf->value->mac;
c2d936a4
BP
2790 break;
2791
2792 case MFF_IPV4_SRC:
128684a6 2793 put_OFPAT_SET_NW_SRC(out, ofp_version, sf->value->be32);
c2d936a4
BP
2794 break;
2795
2796 case MFF_IPV4_DST:
128684a6 2797 put_OFPAT_SET_NW_DST(out, ofp_version, sf->value->be32);
c2d936a4
BP
2798 break;
2799
2800 case MFF_IP_DSCP:
128684a6 2801 put_OFPAT_SET_NW_TOS(out, ofp_version, sf->value->u8);
c2d936a4
BP
2802 break;
2803
2804 case MFF_IP_DSCP_SHIFTED:
128684a6 2805 put_OFPAT_SET_NW_TOS(out, ofp_version, sf->value->u8 << 2);
c2d936a4
BP
2806 break;
2807
4b684612 2808 case MFF_IP_ECN:
128684a6 2809 put_OFPAT11_SET_NW_ECN(out, sf->value->u8);
4b684612
BP
2810 break;
2811
c2d936a4
BP
2812 case MFF_TCP_SRC:
2813 case MFF_UDP_SRC:
128684a6 2814 put_OFPAT_SET_TP_SRC(out, sf->value->be16);
c2d936a4
BP
2815 break;
2816
2817 case MFF_TCP_DST:
2818 case MFF_UDP_DST:
128684a6 2819 put_OFPAT_SET_TP_DST(out, sf->value->be16);
c2d936a4
BP
2820 break;
2821
2822 default:
2823 set_field_to_nxast(sf, out);
2824 break;
7fdb60a7
SH
2825 }
2826}
2827
7eb4b1f1
BP
2828static void
2829set_field_to_set_field(const struct ofpact_set_field *sf,
2830 enum ofp_version ofp_version, struct ofpbuf *out)
2831{
2832 struct ofp12_action_set_field *oasf OVS_UNUSED;
6fd6ed71 2833 size_t start_ofs = out->size;
7eb4b1f1
BP
2834
2835 oasf = put_OFPAT12_SET_FIELD(out);
6fd6ed71 2836 out->size = out->size - sizeof oasf->pad;
04f48a68 2837 nx_put_entry(out, sf->field, ofp_version, sf->value,
128684a6 2838 ofpact_set_field_mask(sf));
7eb4b1f1
BP
2839 pad_ofpat(out, start_ofs);
2840}
2841
c2d936a4
BP
2842static void
2843encode_SET_FIELD(const struct ofpact_set_field *sf,
2844 enum ofp_version ofp_version, struct ofpbuf *out)
2845{
7eb4b1f1 2846 if (ofp_version >= OFP15_VERSION) {
bad8a439
BP
2847 /* OF1.5+ only has Set-Field (reg_load is redundant so we drop it
2848 * entirely). */
7eb4b1f1 2849 set_field_to_set_field(sf, ofp_version, out);
bad8a439
BP
2850 } else if (sf->ofpact.raw == NXAST_RAW_REG_LOAD ||
2851 sf->ofpact.raw == NXAST_RAW_REG_LOAD2) {
2852 /* It came in as reg_load, send it out the same way. */
7eb4b1f1
BP
2853 set_field_to_nxast(sf, out);
2854 } else if (ofp_version < OFP12_VERSION) {
2855 /* OpenFlow 1.0 and 1.1 don't have Set-Field. */
c2d936a4 2856 set_field_to_legacy_openflow(sf, ofp_version, out);
128684a6 2857 } else if (is_all_ones(ofpact_set_field_mask(sf), sf->field->n_bytes)) {
7eb4b1f1
BP
2858 /* We're encoding to OpenFlow 1.2, 1.3, or 1.4. The action sets an
2859 * entire field, so encode it as OFPAT_SET_FIELD. */
2860 set_field_to_set_field(sf, ofp_version, out);
c2d936a4 2861 } else {
7eb4b1f1
BP
2862 /* We're encoding to OpenFlow 1.2, 1.3, or 1.4. The action cannot be
2863 * encoded as OFPAT_SET_FIELD because it does not set an entire field,
2864 * so encode it as reg_load. */
2865 set_field_to_nxast(sf, out);
c2d936a4
BP
2866 }
2867}
2868
36b43aa6
JS
2869/* Parses the input argument 'arg' into the key, value, and delimiter
2870 * components that are common across the reg_load and set_field action format.
2871 *
2872 * With an argument like "1->metadata", sets the following pointers to
2873 * point within 'arg':
2874 * key: "metadata"
2875 * value: "1"
2876 * delim: "->"
2877 *
2878 * Returns NULL if successful, otherwise a malloc()'d string describing the
2879 * error. The caller is responsible for freeing the returned string. */
2880static char * OVS_WARN_UNUSED_RESULT
2881set_field_split_str(char *arg, char **key, char **value, char **delim)
2882{
2883 char *value_end;
2884
2885 *value = arg;
2886 value_end = strstr(arg, "->");
2887 *key = value_end + strlen("->");
2888 if (delim) {
2889 *delim = value_end;
2890 }
2891
2892 if (!value_end) {
2893 return xasprintf("%s: missing `->'", arg);
2894 }
2895 if (strlen(value_end) <= strlen("->")) {
2896 return xasprintf("%s: missing field name following `->'", arg);
2897 }
2898
2899 return NULL;
2900}
2901
c2d936a4
BP
2902/* Parses a "set_field" action with argument 'arg', appending the parsed
2903 * action to 'ofpacts'.
2904 *
2905 * Returns NULL if successful, otherwise a malloc()'d string describing the
2906 * error. The caller is responsible for freeing the returned string. */
cab50449 2907static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
2908set_field_parse__(char *arg, struct ofpbuf *ofpacts,
2909 enum ofputil_protocol *usable_protocols)
7fdb60a7 2910{
c2d936a4
BP
2911 char *value;
2912 char *delim;
2913 char *key;
2914 const struct mf_field *mf;
128684a6 2915 union mf_value sf_value, sf_mask;
c2d936a4 2916 char *error;
7fdb60a7 2917
36b43aa6
JS
2918 error = set_field_split_str(arg, &key, &value, &delim);
2919 if (error) {
2920 return error;
c2d936a4 2921 }
e3f8f887 2922
c2d936a4
BP
2923 mf = mf_from_name(key);
2924 if (!mf) {
2925 return xasprintf("%s is not a valid OXM field name", key);
2926 }
2927 if (!mf->writable) {
2928 return xasprintf("%s is read-only", key);
2929 }
128684a6 2930
c2d936a4 2931 delim[0] = '\0';
128684a6 2932 error = mf_parse(mf, value, &sf_value, &sf_mask);
7fdb60a7
SH
2933 if (error) {
2934 return error;
2935 }
2936
128684a6 2937 if (!mf_is_value_valid(mf, &sf_value)) {
c2d936a4 2938 return xasprintf("%s is not a valid value for field %s", value, key);
7fdb60a7
SH
2939 }
2940
a4ce8b25 2941 *usable_protocols &= mf->usable_protocols_exact;
128684a6
JR
2942
2943 ofpact_put_set_field(ofpacts, mf, &sf_value, &sf_mask);
c2d936a4 2944 return NULL;
7fdb60a7
SH
2945}
2946
c2d936a4
BP
2947/* Parses 'arg' as the argument to a "set_field" action, and appends such an
2948 * action to 'ofpacts'.
2949 *
2950 * Returns NULL if successful, otherwise a malloc()'d string describing the
2951 * error. The caller is responsible for freeing the returned string. */
cab50449 2952static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
2953parse_SET_FIELD(const char *arg, struct ofpbuf *ofpacts,
2954 enum ofputil_protocol *usable_protocols)
2955{
2956 char *copy = xstrdup(arg);
2957 char *error = set_field_parse__(copy, ofpacts, usable_protocols);
2958 free(copy);
2959 return error;
2960}
a359d5ad 2961
cab50449 2962static char * OVS_WARN_UNUSED_RESULT
7eb4b1f1
BP
2963parse_reg_load(char *arg, struct ofpbuf *ofpacts)
2964{
7eb4b1f1 2965 struct mf_subfield dst;
36b43aa6 2966 char *key, *value_str;
81270993 2967 union mf_value value;
7eb4b1f1
BP
2968 char *error;
2969
36b43aa6
JS
2970 error = set_field_split_str(arg, &key, &value_str, NULL);
2971 if (error) {
2972 return error;
7eb4b1f1 2973 }
36b43aa6
JS
2974
2975 error = mf_parse_subfield(&dst, key);
7eb4b1f1
BP
2976 if (error) {
2977 return error;
2978 }
2979
81270993
JS
2980 if (parse_int_string(value_str, (uint8_t *)&value, dst.field->n_bytes,
2981 &key)) {
2982 return xasprintf("%s: cannot parse integer value", arg);
2983 }
2984
2985 if (!bitwise_is_all_zeros(&value, dst.field->n_bytes, dst.n_bits,
2986 dst.field->n_bytes * 8 - dst.n_bits)) {
2987 struct ds ds;
2988
2989 ds_init(&ds);
2990 mf_format(dst.field, &value, NULL, &ds);
2991 error = xasprintf("%s: value %s does not fit into %d bits",
2992 arg, ds_cstr(&ds), dst.n_bits);
2993 ds_destroy(&ds);
2994 return error;
7eb4b1f1
BP
2995 }
2996
128684a6
JR
2997 struct ofpact_set_field *sf = ofpact_put_reg_load(ofpacts, dst.field, NULL,
2998 NULL);
81270993 2999
128684a6
JR
3000 bitwise_copy(&value, dst.field->n_bytes, 0, sf->value,
3001 dst.field->n_bytes, dst.ofs, dst.n_bits);
3002 bitwise_one(ofpact_set_field_mask(sf), dst.field->n_bytes, dst.ofs,
3003 dst.n_bits);
7eb4b1f1
BP
3004 return NULL;
3005}
3006
c2d936a4
BP
3007static void
3008format_SET_FIELD(const struct ofpact_set_field *a, struct ds *s)
3009{
7eb4b1f1
BP
3010 if (a->ofpact.raw == NXAST_RAW_REG_LOAD) {
3011 struct mf_subfield dst;
3012 uint64_t value;
3013
3014 dst.ofs = dst.n_bits = 0;
3015 while (next_load_segment(a, &dst, &value)) {
b1c5bf1f
QM
3016 ds_put_format(s, "%sload:%s%#"PRIx64"%s->%s",
3017 colors.special, colors.end, value,
3018 colors.special, colors.end);
7eb4b1f1
BP
3019 mf_format_subfield(&dst, s);
3020 ds_put_char(s, ',');
3021 }
3022 ds_chomp(s, ',');
3023 } else {
b1c5bf1f 3024 ds_put_format(s, "%sset_field:%s", colors.special, colors.end);
128684a6 3025 mf_format(a->field, a->value, ofpact_set_field_mask(a), s);
b1c5bf1f
QM
3026 ds_put_format(s, "%s->%s%s",
3027 colors.special, colors.end, a->field->name);
7eb4b1f1
BP
3028 }
3029}
3030
128684a6
JR
3031/* Appends an OFPACT_SET_FIELD ofpact with enough space for the value and mask
3032 * for the 'field' to 'ofpacts' and returns it. Fills in the value from
3033 * 'value', if non-NULL, and mask from 'mask' if non-NULL. If 'value' is
3034 * non-NULL and 'mask' is NULL, an all-ones mask will be filled in. */
3035struct ofpact_set_field *
3036ofpact_put_set_field(struct ofpbuf *ofpacts, const struct mf_field *field,
3037 const void *value, const void *mask)
3038{
3039 struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
3040 sf->field = field;
3041
3042 /* Fill in the value and mask if given, otherwise put zeroes so that the
3043 * caller may fill in the value and mask itself. */
3044 if (value) {
3045 ofpbuf_put_uninit(ofpacts, 2 * field->n_bytes);
3046 sf = ofpacts->header;
3047 memcpy(sf->value, value, field->n_bytes);
3048 if (mask) {
3049 memcpy(ofpact_set_field_mask(sf), mask, field->n_bytes);
3050 } else {
3051 memset(ofpact_set_field_mask(sf), 0xff, field->n_bytes);
3052 }
3053 } else {
3054 ofpbuf_put_zeros(ofpacts, 2 * field->n_bytes);
3055 sf = ofpacts->header;
3056 }
3057 /* Update length. */
3058 ofpact_finish_SET_FIELD(ofpacts, &sf);
3059
3060 return sf;
3061}
3062
7eb4b1f1
BP
3063/* Appends an OFPACT_SET_FIELD ofpact to 'ofpacts' and returns it. The ofpact
3064 * is marked such that, if possible, it will be translated to OpenFlow as
3065 * NXAST_REG_LOAD extension actions rather than OFPAT_SET_FIELD, either because
3066 * that was the way that the action was expressed when it came into OVS or for
3067 * backward compatibility. */
3068struct ofpact_set_field *
128684a6
JR
3069ofpact_put_reg_load(struct ofpbuf *ofpacts, const struct mf_field *field,
3070 const void *value, const void *mask)
7eb4b1f1 3071{
128684a6
JR
3072 struct ofpact_set_field *sf = ofpact_put_set_field(ofpacts, field, value,
3073 mask);
7eb4b1f1 3074 sf->ofpact.raw = NXAST_RAW_REG_LOAD;
128684a6 3075
7eb4b1f1 3076 return sf;
c2d936a4 3077}
128684a6
JR
3078
3079struct ofpact_set_field *
3080ofpact_put_reg_load2(struct ofpbuf *ofpacts, const struct mf_field *field,
3081 const void *value, const void *mask)
3082{
3083 struct ofpact_set_field *sf = ofpact_put_set_field(ofpacts, field, value,
3084 mask);
3085 sf->ofpact.raw = NXAST_RAW_REG_LOAD2;
3086
3087 return sf;
3088}
3089
c2d936a4
BP
3090\f
3091/* Action structure for NXAST_STACK_PUSH and NXAST_STACK_POP.
3092 *
3093 * Pushes (or pops) field[offset: offset + n_bits] to (or from)
3094 * top of the stack.
3095 */
3096struct nx_action_stack {
3097 ovs_be16 type; /* OFPAT_VENDOR. */
3098 ovs_be16 len; /* Length is 16. */
3099 ovs_be32 vendor; /* NX_VENDOR_ID. */
3100 ovs_be16 subtype; /* NXAST_STACK_PUSH or NXAST_STACK_POP. */
3101 ovs_be16 offset; /* Bit offset into the field. */
bad8a439
BP
3102 /* Followed by:
3103 * - OXM/NXM header for field to push or pop (4 or 8 bytes).
3104 * - ovs_be16 'n_bits', the number of bits to extract from the field.
3105 * - Enough 0-bytes to pad out the action to 24 bytes. */
3106 uint8_t pad[12]; /* See above. */
a359d5ad 3107};
c2d936a4 3108OFP_ASSERT(sizeof(struct nx_action_stack) == 24);
a359d5ad 3109
bad8a439 3110static enum ofperr
c2d936a4 3111decode_stack_action(const struct nx_action_stack *nasp,
04f48a68 3112 const struct vl_mff_map *vl_mff_map,
c2d936a4 3113 struct ofpact_stack *stack_action)
a359d5ad 3114{
c2d936a4 3115 stack_action->subfield.ofs = ntohs(nasp->offset);
bad8a439 3116
0a2869d5 3117 struct ofpbuf b = ofpbuf_const_initializer(nasp, sizeof *nasp);
bad8a439 3118 ofpbuf_pull(&b, OBJECT_OFFSETOF(nasp, pad));
04f48a68
YHW
3119 enum ofperr error = nx_pull_header(&b, vl_mff_map,
3120 &stack_action->subfield.field, NULL);
bad8a439
BP
3121 if (error) {
3122 return error;
3123 }
6fd6ed71 3124 stack_action->subfield.n_bits = ntohs(*(const ovs_be16 *) b.data);
bad8a439 3125 ofpbuf_pull(&b, 2);
6fd6ed71 3126 if (!is_all_zeros(b.data, b.size)) {
bad8a439
BP
3127 return OFPERR_NXBRC_MUST_BE_ZERO;
3128 }
3129
3130 return 0;
a359d5ad
IY
3131}
3132
c2d936a4
BP
3133static enum ofperr
3134decode_NXAST_RAW_STACK_PUSH(const struct nx_action_stack *nasp,
f3cd3ac7 3135 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 3136 const struct vl_mff_map *vl_mff_map,
f3cd3ac7 3137 struct ofpbuf *ofpacts)
a359d5ad 3138{
c2d936a4 3139 struct ofpact_stack *push = ofpact_put_STACK_PUSH(ofpacts);
04f48a68 3140 enum ofperr error = decode_stack_action(nasp, vl_mff_map, push);
bad8a439 3141 return error ? error : nxm_stack_push_check(push, NULL);
a359d5ad
IY
3142}
3143
c2d936a4
BP
3144static enum ofperr
3145decode_NXAST_RAW_STACK_POP(const struct nx_action_stack *nasp,
f3cd3ac7 3146 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 3147 const struct vl_mff_map *vl_mff_map,
c2d936a4 3148 struct ofpbuf *ofpacts)
084c53de 3149{
c2d936a4 3150 struct ofpact_stack *pop = ofpact_put_STACK_POP(ofpacts);
04f48a68 3151 enum ofperr error = decode_stack_action(nasp, vl_mff_map, pop);
bad8a439 3152 return error ? error : nxm_stack_pop_check(pop, NULL);
084c53de
BP
3153}
3154
c2d936a4
BP
3155static void
3156encode_STACK_op(const struct ofpact_stack *stack_action,
3157 struct nx_action_stack *nasp)
c0621c39 3158{
bad8a439
BP
3159 struct ofpbuf b;
3160 ovs_be16 n_bits;
3161
c2d936a4 3162 nasp->offset = htons(stack_action->subfield.ofs);
bad8a439
BP
3163
3164 ofpbuf_use_stack(&b, nasp, ntohs(nasp->len));
3165 ofpbuf_put_uninit(&b, OBJECT_OFFSETOF(nasp, pad));
04f48a68 3166 nx_put_mff_header(&b, stack_action->subfield.field, 0, false);
bad8a439
BP
3167 n_bits = htons(stack_action->subfield.n_bits);
3168 ofpbuf_put(&b, &n_bits, sizeof n_bits);
c0621c39
AW
3169}
3170
c2d936a4
BP
3171static void
3172encode_STACK_PUSH(const struct ofpact_stack *stack,
3173 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
3174{
3175 encode_STACK_op(stack, put_NXAST_STACK_PUSH(out));
3176}
8e97815e 3177
c2d936a4
BP
3178static void
3179encode_STACK_POP(const struct ofpact_stack *stack,
3180 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
8e97815e 3181{
c2d936a4
BP
3182 encode_STACK_op(stack, put_NXAST_STACK_POP(out));
3183}
8e97815e 3184
cab50449 3185static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3186parse_STACK_PUSH(char *arg, struct ofpbuf *ofpacts,
3187 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3188{
3189 return nxm_parse_stack_action(ofpact_put_STACK_PUSH(ofpacts), arg);
3190}
8e97815e 3191
cab50449 3192static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3193parse_STACK_POP(char *arg, struct ofpbuf *ofpacts,
3194 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3195{
3196 return nxm_parse_stack_action(ofpact_put_STACK_POP(ofpacts), arg);
8e97815e
BP
3197}
3198
c2d936a4
BP
3199static void
3200format_STACK_PUSH(const struct ofpact_stack *a, struct ds *s)
8e97815e 3201{
c2d936a4
BP
3202 nxm_format_stack_push(a, s);
3203}
8e97815e 3204
c2d936a4
BP
3205static void
3206format_STACK_POP(const struct ofpact_stack *a, struct ds *s)
3207{
3208 nxm_format_stack_pop(a, s);
3209}
3210\f
3211/* Action structure for NXAST_DEC_TTL_CNT_IDS.
3212 *
3213 * If the packet is not IPv4 or IPv6, does nothing. For IPv4 or IPv6, if the
3214 * TTL or hop limit is at least 2, decrements it by 1. Otherwise, if TTL or
3215 * hop limit is 0 or 1, sends a packet-in to the controllers with each of the
3216 * 'n_controllers' controller IDs specified in 'cnt_ids'.
3217 *
3218 * (This differs from NXAST_DEC_TTL in that for NXAST_DEC_TTL the packet-in is
3219 * sent only to controllers with id 0.)
3220 */
3221struct nx_action_cnt_ids {
3222 ovs_be16 type; /* OFPAT_VENDOR. */
3223 ovs_be16 len; /* Length including slaves. */
3224 ovs_be32 vendor; /* NX_VENDOR_ID. */
3225 ovs_be16 subtype; /* NXAST_DEC_TTL_CNT_IDS. */
3226
3227 ovs_be16 n_controllers; /* Number of controllers. */
3228 uint8_t zeros[4]; /* Must be zero. */
3229
3230 /* Followed by 1 or more controller ids.
3231 *
3232 * uint16_t cnt_ids[]; // Controller ids.
3233 * uint8_t pad[]; // Must be 0 to 8-byte align cnt_ids[].
3234 */
3235};
3236OFP_ASSERT(sizeof(struct nx_action_cnt_ids) == 16);
3237
3238static enum ofperr
3239decode_OFPAT_RAW_DEC_NW_TTL(struct ofpbuf *out)
3240{
3241 uint16_t id = 0;
3242 struct ofpact_cnt_ids *ids;
3243 enum ofperr error = 0;
3244
3245 ids = ofpact_put_DEC_TTL(out);
3246 ids->n_controllers = 1;
3247 ofpbuf_put(out, &id, sizeof id);
6fd6ed71 3248 ids = out->header;
ce058104 3249 ofpact_finish_DEC_TTL(out, &ids);
c2d936a4
BP
3250 return error;
3251}
3252
3253static enum ofperr
3254decode_NXAST_RAW_DEC_TTL_CNT_IDS(const struct nx_action_cnt_ids *nac_ids,
f3cd3ac7 3255 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4
BP
3256 struct ofpbuf *out)
3257{
3258 struct ofpact_cnt_ids *ids;
3259 size_t ids_size;
3260 int i;
3261
3262 ids = ofpact_put_DEC_TTL(out);
3263 ids->ofpact.raw = NXAST_RAW_DEC_TTL_CNT_IDS;
3264 ids->n_controllers = ntohs(nac_ids->n_controllers);
3265 ids_size = ntohs(nac_ids->len) - sizeof *nac_ids;
3266
3267 if (!is_all_zeros(nac_ids->zeros, sizeof nac_ids->zeros)) {
3268 return OFPERR_NXBRC_MUST_BE_ZERO;
8e97815e 3269 }
c2d936a4
BP
3270
3271 if (ids_size < ids->n_controllers * sizeof(ovs_be16)) {
3272 VLOG_WARN_RL(&rl, "Nicira action dec_ttl_cnt_ids only has %"PRIuSIZE" "
3273 "bytes allocated for controller ids. %"PRIuSIZE" bytes "
3274 "are required for %"PRIu16" controllers.",
3275 ids_size, ids->n_controllers * sizeof(ovs_be16),
3276 ids->n_controllers);
3277 return OFPERR_OFPBAC_BAD_LEN;
3278 }
3279
3280 for (i = 0; i < ids->n_controllers; i++) {
3281 uint16_t id = ntohs(((ovs_be16 *)(nac_ids + 1))[i]);
3282 ofpbuf_put(out, &id, sizeof id);
6fd6ed71 3283 ids = out->header;
c2d936a4
BP
3284 }
3285
ce058104 3286 ofpact_finish_DEC_TTL(out, &ids);
c2d936a4
BP
3287
3288 return 0;
8e97815e
BP
3289}
3290
c2d936a4
BP
3291static void
3292encode_DEC_TTL(const struct ofpact_cnt_ids *dec_ttl,
3293 enum ofp_version ofp_version, struct ofpbuf *out)
8e97815e 3294{
c2d936a4
BP
3295 if (dec_ttl->ofpact.raw == NXAST_RAW_DEC_TTL_CNT_IDS
3296 || dec_ttl->n_controllers != 1
3297 || dec_ttl->cnt_ids[0] != 0) {
3298 struct nx_action_cnt_ids *nac_ids = put_NXAST_DEC_TTL_CNT_IDS(out);
3299 int ids_len = ROUND_UP(2 * dec_ttl->n_controllers, OFP_ACTION_ALIGN);
3300 ovs_be16 *ids;
3301 size_t i;
8e97815e 3302
c2d936a4
BP
3303 nac_ids->len = htons(ntohs(nac_ids->len) + ids_len);
3304 nac_ids->n_controllers = htons(dec_ttl->n_controllers);
3305
3306 ids = ofpbuf_put_zeros(out, ids_len);
3307 for (i = 0; i < dec_ttl->n_controllers; i++) {
3308 ids[i] = htons(dec_ttl->cnt_ids[i]);
8e97815e 3309 }
c2d936a4
BP
3310 } else {
3311 put_OFPAT_DEC_NW_TTL(out, ofp_version);
8e97815e 3312 }
8e97815e
BP
3313}
3314
c2d936a4
BP
3315static void
3316parse_noargs_dec_ttl(struct ofpbuf *ofpacts)
d01c980f 3317{
c2d936a4
BP
3318 struct ofpact_cnt_ids *ids;
3319 uint16_t id = 0;
3320
3321 ofpact_put_DEC_TTL(ofpacts);
3322 ofpbuf_put(ofpacts, &id, sizeof id);
6fd6ed71 3323 ids = ofpacts->header;
c2d936a4 3324 ids->n_controllers++;
ce058104 3325 ofpact_finish_DEC_TTL(ofpacts, &ids);
d01c980f
BP
3326}
3327
cab50449 3328static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3329parse_DEC_TTL(char *arg, struct ofpbuf *ofpacts,
3330 enum ofputil_protocol *usable_protocols OVS_UNUSED)
d01c980f 3331{
c2d936a4
BP
3332 if (*arg == '\0') {
3333 parse_noargs_dec_ttl(ofpacts);
3334 } else {
3335 struct ofpact_cnt_ids *ids;
3336 char *cntr;
3337
3338 ids = ofpact_put_DEC_TTL(ofpacts);
3339 ids->ofpact.raw = NXAST_RAW_DEC_TTL_CNT_IDS;
3340 for (cntr = strtok_r(arg, ", ", &arg); cntr != NULL;
3341 cntr = strtok_r(NULL, ", ", &arg)) {
3342 uint16_t id = atoi(cntr);
3343
3344 ofpbuf_put(ofpacts, &id, sizeof id);
6fd6ed71 3345 ids = ofpacts->header;
c2d936a4
BP
3346 ids->n_controllers++;
3347 }
3348 if (!ids->n_controllers) {
3349 return xstrdup("dec_ttl_cnt_ids: expected at least one controller "
3350 "id.");
3351 }
ce058104 3352 ofpact_finish_DEC_TTL(ofpacts, &ids);
c2d936a4
BP
3353 }
3354 return NULL;
d01c980f
BP
3355}
3356
c2d936a4
BP
3357static void
3358format_DEC_TTL(const struct ofpact_cnt_ids *a, struct ds *s)
d01c980f 3359{
c2d936a4 3360 size_t i;
d01c980f 3361
b1c5bf1f 3362 ds_put_format(s, "%sdec_ttl%s", colors.paren, colors.end);
c2d936a4 3363 if (a->ofpact.raw == NXAST_RAW_DEC_TTL_CNT_IDS) {
b1c5bf1f 3364 ds_put_format(s, "%s(%s", colors.paren, colors.end);
c2d936a4
BP
3365 for (i = 0; i < a->n_controllers; i++) {
3366 if (i) {
3367 ds_put_cstr(s, ",");
d01c980f 3368 }
c2d936a4
BP
3369 ds_put_format(s, "%"PRIu16, a->cnt_ids[i]);
3370 }
b1c5bf1f 3371 ds_put_format(s, "%s)%s", colors.paren, colors.end);
d01c980f
BP
3372 }
3373}
c2d936a4
BP
3374\f
3375/* Set MPLS label actions. */
d01c980f
BP
3376
3377static enum ofperr
f3cd3ac7
JS
3378decode_OFPAT_RAW_SET_MPLS_LABEL(ovs_be32 label,
3379 enum ofp_version ofp_version OVS_UNUSED,
3380 struct ofpbuf *out)
d01c980f 3381{
c2d936a4
BP
3382 ofpact_put_SET_MPLS_LABEL(out)->label = label;
3383 return 0;
3384}
d01c980f 3385
c2d936a4
BP
3386static void
3387encode_SET_MPLS_LABEL(const struct ofpact_mpls_label *label,
3388 enum ofp_version ofp_version,
3389 struct ofpbuf *out)
3390{
3391 if (ofp_version < OFP12_VERSION) {
3392 put_OFPAT_SET_MPLS_LABEL(out, ofp_version, label->label);
3393 } else {
128684a6 3394 put_set_field(out, ofp_version, MFF_MPLS_LABEL, ntohl(label->label));
d01c980f 3395 }
c2d936a4 3396}
d01c980f 3397
cab50449 3398static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3399parse_SET_MPLS_LABEL(char *arg, struct ofpbuf *ofpacts,
3400 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3401{
3402 struct ofpact_mpls_label *mpls_label = ofpact_put_SET_MPLS_LABEL(ofpacts);
3403 if (*arg == '\0') {
3404 return xstrdup("set_mpls_label: expected label.");
d01c980f 3405 }
c2d936a4
BP
3406
3407 mpls_label->label = htonl(atoi(arg));
3408 return NULL;
d01c980f
BP
3409}
3410
3411static void
c2d936a4 3412format_SET_MPLS_LABEL(const struct ofpact_mpls_label *a, struct ds *s)
d01c980f 3413{
b1c5bf1f
QM
3414 ds_put_format(s, "%sset_mpls_label(%s%"PRIu32"%s)%s",
3415 colors.paren, colors.end, ntohl(a->label),
3416 colors.paren, colors.end);
d01c980f 3417}
c2d936a4
BP
3418\f
3419/* Set MPLS TC actions. */
d01c980f 3420
c2d936a4 3421static enum ofperr
f3cd3ac7
JS
3422decode_OFPAT_RAW_SET_MPLS_TC(uint8_t tc,
3423 enum ofp_version ofp_version OVS_UNUSED,
3424 struct ofpbuf *out)
d01c980f 3425{
c2d936a4
BP
3426 ofpact_put_SET_MPLS_TC(out)->tc = tc;
3427 return 0;
3428}
d01c980f 3429
c2d936a4
BP
3430static void
3431encode_SET_MPLS_TC(const struct ofpact_mpls_tc *tc,
3432 enum ofp_version ofp_version, struct ofpbuf *out)
3433{
3434 if (ofp_version < OFP12_VERSION) {
3435 put_OFPAT_SET_MPLS_TC(out, ofp_version, tc->tc);
3436 } else {
128684a6 3437 put_set_field(out, ofp_version, MFF_MPLS_TC, tc->tc);
8f2cded4 3438 }
c2d936a4 3439}
8f2cded4 3440
cab50449 3441static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3442parse_SET_MPLS_TC(char *arg, struct ofpbuf *ofpacts,
3443 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3444{
3445 struct ofpact_mpls_tc *mpls_tc = ofpact_put_SET_MPLS_TC(ofpacts);
d01c980f 3446
c2d936a4
BP
3447 if (*arg == '\0') {
3448 return xstrdup("set_mpls_tc: expected tc.");
d01c980f
BP
3449 }
3450
c2d936a4
BP
3451 mpls_tc->tc = atoi(arg);
3452 return NULL;
3453}
d01c980f 3454
c2d936a4
BP
3455static void
3456format_SET_MPLS_TC(const struct ofpact_mpls_tc *a, struct ds *s)
3457{
b1c5bf1f
QM
3458 ds_put_format(s, "%sset_mpls_ttl(%s%"PRIu8"%s)%s",
3459 colors.paren, colors.end, a->tc,
3460 colors.paren, colors.end);
c2d936a4
BP
3461}
3462\f
3463/* Set MPLS TTL actions. */
d01c980f 3464
c2d936a4 3465static enum ofperr
f3cd3ac7
JS
3466decode_OFPAT_RAW_SET_MPLS_TTL(uint8_t ttl,
3467 enum ofp_version ofp_version OVS_UNUSED,
3468 struct ofpbuf *out)
c2d936a4
BP
3469{
3470 ofpact_put_SET_MPLS_TTL(out)->ttl = ttl;
3471 return 0;
3472}
638a19b0 3473
c2d936a4
BP
3474static void
3475encode_SET_MPLS_TTL(const struct ofpact_mpls_ttl *ttl,
3476 enum ofp_version ofp_version, struct ofpbuf *out)
3477{
3478 put_OFPAT_SET_MPLS_TTL(out, ofp_version, ttl->ttl);
3479}
638a19b0 3480
c2d936a4
BP
3481/* Parses 'arg' as the argument to a "set_mpls_ttl" action, and appends such an
3482 * action to 'ofpacts'.
3483 *
3484 * Returns NULL if successful, otherwise a malloc()'d string describing the
3485 * error. The caller is responsible for freeing the returned string. */
cab50449 3486static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3487parse_SET_MPLS_TTL(char *arg, struct ofpbuf *ofpacts,
3488 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3489{
3490 struct ofpact_mpls_ttl *mpls_ttl = ofpact_put_SET_MPLS_TTL(ofpacts);
d01c980f 3491
c2d936a4
BP
3492 if (*arg == '\0') {
3493 return xstrdup("set_mpls_ttl: expected ttl.");
b19e8793 3494 }
7fdb60a7 3495
c2d936a4
BP
3496 mpls_ttl->ttl = atoi(arg);
3497 return NULL;
3498}
4cceacb9 3499
c2d936a4
BP
3500static void
3501format_SET_MPLS_TTL(const struct ofpact_mpls_ttl *a, struct ds *s)
3502{
b1c5bf1f
QM
3503 ds_put_format(s, "%sset_mpls_ttl(%s%"PRIu8"%s)%s",
3504 colors.paren, colors.end, a->ttl,
3505 colors.paren, colors.end);
c2d936a4
BP
3506}
3507\f
3508/* Decrement MPLS TTL actions. */
4cceacb9 3509
c2d936a4
BP
3510static enum ofperr
3511decode_OFPAT_RAW_DEC_MPLS_TTL(struct ofpbuf *out)
3512{
3513 ofpact_put_DEC_MPLS_TTL(out);
3514 return 0;
3515}
8dd54666 3516
c2d936a4
BP
3517static void
3518encode_DEC_MPLS_TTL(const struct ofpact_null *null OVS_UNUSED,
3519 enum ofp_version ofp_version, struct ofpbuf *out)
3520{
3521 put_OFPAT_DEC_MPLS_TTL(out, ofp_version);
3522}
3523
cab50449 3524static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3525parse_DEC_MPLS_TTL(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
3526 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3527{
3528 ofpact_put_DEC_MPLS_TTL(ofpacts);
3529 return NULL;
3530}
3531
3532static void
3533format_DEC_MPLS_TTL(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
3534{
b1c5bf1f 3535 ds_put_format(s, "%sdec_mpls_ttl%s", colors.value, colors.end);
c2d936a4
BP
3536}
3537\f
3538/* Push MPLS label action. */
3539
3540static enum ofperr
f3cd3ac7
JS
3541decode_OFPAT_RAW_PUSH_MPLS(ovs_be16 ethertype,
3542 enum ofp_version ofp_version OVS_UNUSED,
3543 struct ofpbuf *out)
c2d936a4
BP
3544{
3545 struct ofpact_push_mpls *oam;
3546
3547 if (!eth_type_mpls(ethertype)) {
3548 return OFPERR_OFPBAC_BAD_ARGUMENT;
8dd54666 3549 }
c2d936a4
BP
3550 oam = ofpact_put_PUSH_MPLS(out);
3551 oam->ethertype = ethertype;
d01c980f 3552
c2d936a4
BP
3553 return 0;
3554}
3555
3556static void
3557encode_PUSH_MPLS(const struct ofpact_push_mpls *push_mpls,
3558 enum ofp_version ofp_version, struct ofpbuf *out)
3559{
3560 put_OFPAT_PUSH_MPLS(out, ofp_version, push_mpls->ethertype);
3561}
3562
cab50449 3563static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3564parse_PUSH_MPLS(char *arg, struct ofpbuf *ofpacts,
3565 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3566{
3567 uint16_t ethertype;
3568 char *error;
3569
3570 error = str_to_u16(arg, "push_mpls", &ethertype);
3571 if (!error) {
3572 ofpact_put_PUSH_MPLS(ofpacts)->ethertype = htons(ethertype);
d01c980f
BP
3573 }
3574 return error;
3575}
c2d936a4
BP
3576
3577static void
3578format_PUSH_MPLS(const struct ofpact_push_mpls *a, struct ds *s)
3579{
b1c5bf1f
QM
3580 ds_put_format(s, "%spush_mpls:%s0x%04"PRIx16,
3581 colors.param, colors.end, ntohs(a->ethertype));
c2d936a4 3582}
d01c980f 3583\f
c2d936a4
BP
3584/* Pop MPLS label action. */
3585
3586static enum ofperr
f3cd3ac7
JS
3587decode_OFPAT_RAW_POP_MPLS(ovs_be16 ethertype,
3588 enum ofp_version ofp_version OVS_UNUSED,
3589 struct ofpbuf *out)
57ad4e9e 3590{
c2d936a4
BP
3591 ofpact_put_POP_MPLS(out)->ethertype = ethertype;
3592 return 0;
3593}
57ad4e9e 3594
c2d936a4
BP
3595static void
3596encode_POP_MPLS(const struct ofpact_pop_mpls *pop_mpls,
3597 enum ofp_version ofp_version, struct ofpbuf *out)
3598{
3599 put_OFPAT_POP_MPLS(out, ofp_version, pop_mpls->ethertype);
3600}
3601
cab50449 3602static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3603parse_POP_MPLS(char *arg, struct ofpbuf *ofpacts,
3604 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3605{
3606 uint16_t ethertype;
3607 char *error;
3608
3609 error = str_to_u16(arg, "pop_mpls", &ethertype);
3610 if (!error) {
3611 ofpact_put_POP_MPLS(ofpacts)->ethertype = htons(ethertype);
57ad4e9e 3612 }
c2d936a4 3613 return error;
57ad4e9e
BP
3614}
3615
ba2fe8e9 3616static void
c2d936a4 3617format_POP_MPLS(const struct ofpact_pop_mpls *a, struct ds *s)
ba2fe8e9 3618{
b1c5bf1f
QM
3619 ds_put_format(s, "%spop_mpls:%s0x%04"PRIx16,
3620 colors.param, colors.end, ntohs(a->ethertype));
ba2fe8e9 3621}
c2d936a4
BP
3622\f
3623/* Set tunnel ID actions. */
ba2fe8e9 3624
f25d0cf3 3625static enum ofperr
f3cd3ac7
JS
3626decode_NXAST_RAW_SET_TUNNEL(uint32_t tun_id,
3627 enum ofp_version ofp_version OVS_UNUSED,
3628 struct ofpbuf *out)
f25d0cf3 3629{
c2d936a4
BP
3630 struct ofpact_tunnel *tunnel = ofpact_put_SET_TUNNEL(out);
3631 tunnel->ofpact.raw = NXAST_RAW_SET_TUNNEL;
3632 tunnel->tun_id = tun_id;
3633 return 0;
3634}
f25d0cf3 3635
c2d936a4 3636static enum ofperr
f3cd3ac7
JS
3637decode_NXAST_RAW_SET_TUNNEL64(uint64_t tun_id,
3638 enum ofp_version ofp_version OVS_UNUSED,
3639 struct ofpbuf *out)
c2d936a4
BP
3640{
3641 struct ofpact_tunnel *tunnel = ofpact_put_SET_TUNNEL(out);
3642 tunnel->ofpact.raw = NXAST_RAW_SET_TUNNEL64;
3643 tunnel->tun_id = tun_id;
3644 return 0;
3645}
f25d0cf3 3646
c2d936a4
BP
3647static void
3648encode_SET_TUNNEL(const struct ofpact_tunnel *tunnel,
3649 enum ofp_version ofp_version, struct ofpbuf *out)
3650{
3651 uint64_t tun_id = tunnel->tun_id;
f25d0cf3 3652
c2d936a4
BP
3653 if (ofp_version < OFP12_VERSION) {
3654 if (tun_id <= UINT32_MAX
3655 && tunnel->ofpact.raw != NXAST_RAW_SET_TUNNEL64) {
3656 put_NXAST_SET_TUNNEL(out, tun_id);
3657 } else {
3658 put_NXAST_SET_TUNNEL64(out, tun_id);
f25d0cf3 3659 }
c2d936a4 3660 } else {
128684a6 3661 put_set_field(out, ofp_version, MFF_TUN_ID, tun_id);
c2d936a4
BP
3662 }
3663}
f25d0cf3 3664
cab50449 3665static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3666parse_set_tunnel(char *arg, struct ofpbuf *ofpacts,
3667 enum ofp_raw_action_type raw)
3668{
3669 struct ofpact_tunnel *tunnel;
ca287d20 3670
c2d936a4
BP
3671 tunnel = ofpact_put_SET_TUNNEL(ofpacts);
3672 tunnel->ofpact.raw = raw;
3673 return str_to_u64(arg, &tunnel->tun_id);
3674}
8621547c 3675
cab50449 3676static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3677parse_SET_TUNNEL(char *arg, struct ofpbuf *ofpacts,
3678 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3679{
3680 return parse_set_tunnel(arg, ofpacts, NXAST_RAW_SET_TUNNEL);
3681}
8621547c 3682
c2d936a4
BP
3683static void
3684format_SET_TUNNEL(const struct ofpact_tunnel *a, struct ds *s)
3685{
b1c5bf1f 3686 ds_put_format(s, "%sset_tunnel%s:%s%#"PRIx64, colors.param,
c2d936a4
BP
3687 (a->tun_id > UINT32_MAX
3688 || a->ofpact.raw == NXAST_RAW_SET_TUNNEL64 ? "64" : ""),
b1c5bf1f 3689 colors.end, a->tun_id);
c2d936a4
BP
3690}
3691\f
3692/* Set queue action. */
8621547c 3693
c2d936a4 3694static enum ofperr
f3cd3ac7
JS
3695decode_OFPAT_RAW_SET_QUEUE(uint32_t queue_id,
3696 enum ofp_version ofp_version OVS_UNUSED,
3697 struct ofpbuf *out)
c2d936a4
BP
3698{
3699 ofpact_put_SET_QUEUE(out)->queue_id = queue_id;
3700 return 0;
3701}
8621547c 3702
c2d936a4
BP
3703static void
3704encode_SET_QUEUE(const struct ofpact_queue *queue,
3705 enum ofp_version ofp_version, struct ofpbuf *out)
3706{
3707 put_OFPAT_SET_QUEUE(out, ofp_version, queue->queue_id);
3708}
8621547c 3709
cab50449 3710static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3711parse_SET_QUEUE(char *arg, struct ofpbuf *ofpacts,
3712 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3713{
3714 return str_to_u32(arg, &ofpact_put_SET_QUEUE(ofpacts)->queue_id);
3715}
8621547c 3716
c2d936a4
BP
3717static void
3718format_SET_QUEUE(const struct ofpact_queue *a, struct ds *s)
3719{
b1c5bf1f
QM
3720 ds_put_format(s, "%sset_queue:%s%"PRIu32,
3721 colors.param, colors.end, a->queue_id);
c2d936a4
BP
3722}
3723\f
3724/* Pop queue action. */
1e7db674 3725
c2d936a4
BP
3726static enum ofperr
3727decode_NXAST_RAW_POP_QUEUE(struct ofpbuf *out)
3728{
3729 ofpact_put_POP_QUEUE(out);
3730 return 0;
3731}
f25d0cf3 3732
c2d936a4
BP
3733static void
3734encode_POP_QUEUE(const struct ofpact_null *null OVS_UNUSED,
3735 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
3736{
3737 put_NXAST_POP_QUEUE(out);
3738}
f25d0cf3 3739
cab50449 3740static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3741parse_POP_QUEUE(const char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
3742 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3743{
3744 ofpact_put_POP_QUEUE(ofpacts);
3745 return NULL;
3746}
f25d0cf3 3747
c2d936a4
BP
3748static void
3749format_POP_QUEUE(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
3750{
b1c5bf1f 3751 ds_put_format(s, "%spop_queue%s", colors.value, colors.end);
c2d936a4
BP
3752}
3753\f
3754/* Action structure for NXAST_FIN_TIMEOUT.
3755 *
3756 * This action changes the idle timeout or hard timeout, or both, of this
3757 * OpenFlow rule when the rule matches a TCP packet with the FIN or RST flag.
3758 * When such a packet is observed, the action reduces the rule's idle timeout
3759 * to 'fin_idle_timeout' and its hard timeout to 'fin_hard_timeout'. This
3760 * action has no effect on an existing timeout that is already shorter than the
3761 * one that the action specifies. A 'fin_idle_timeout' or 'fin_hard_timeout'
3762 * of zero has no effect on the respective timeout.
3763 *
3764 * 'fin_idle_timeout' and 'fin_hard_timeout' are measured in seconds.
3765 * 'fin_hard_timeout' specifies time since the flow's creation, not since the
3766 * receipt of the FIN or RST.
3767 *
3768 * This is useful for quickly discarding learned TCP flows that otherwise will
3769 * take a long time to expire.
3770 *
3771 * This action is intended for use with an OpenFlow rule that matches only a
3772 * single TCP flow. If the rule matches multiple TCP flows (e.g. it wildcards
3773 * all TCP traffic, or all TCP traffic to a particular port), then any FIN or
3774 * RST in any of those flows will cause the entire OpenFlow rule to expire
3775 * early, which is not normally desirable.
3776 */
3777struct nx_action_fin_timeout {
3778 ovs_be16 type; /* OFPAT_VENDOR. */
3779 ovs_be16 len; /* 16. */
3780 ovs_be32 vendor; /* NX_VENDOR_ID. */
3781 ovs_be16 subtype; /* NXAST_FIN_TIMEOUT. */
3782 ovs_be16 fin_idle_timeout; /* New idle timeout, if nonzero. */
3783 ovs_be16 fin_hard_timeout; /* New hard timeout, if nonzero. */
3784 ovs_be16 pad; /* Must be zero. */
3785};
3786OFP_ASSERT(sizeof(struct nx_action_fin_timeout) == 16);
f25d0cf3 3787
c2d936a4
BP
3788static enum ofperr
3789decode_NXAST_RAW_FIN_TIMEOUT(const struct nx_action_fin_timeout *naft,
f3cd3ac7 3790 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4
BP
3791 struct ofpbuf *out)
3792{
3793 struct ofpact_fin_timeout *oft;
8621547c 3794
c2d936a4
BP
3795 oft = ofpact_put_FIN_TIMEOUT(out);
3796 oft->fin_idle_timeout = ntohs(naft->fin_idle_timeout);
3797 oft->fin_hard_timeout = ntohs(naft->fin_hard_timeout);
3798 return 0;
3799}
f25d0cf3 3800
c2d936a4
BP
3801static void
3802encode_FIN_TIMEOUT(const struct ofpact_fin_timeout *fin_timeout,
3803 enum ofp_version ofp_version OVS_UNUSED,
3804 struct ofpbuf *out)
3805{
3806 struct nx_action_fin_timeout *naft = put_NXAST_FIN_TIMEOUT(out);
3807 naft->fin_idle_timeout = htons(fin_timeout->fin_idle_timeout);
3808 naft->fin_hard_timeout = htons(fin_timeout->fin_hard_timeout);
3809}
f25d0cf3 3810
cab50449 3811static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3812parse_FIN_TIMEOUT(char *arg, struct ofpbuf *ofpacts,
3813 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3814{
3815 struct ofpact_fin_timeout *oft = ofpact_put_FIN_TIMEOUT(ofpacts);
3816 char *key, *value;
f25d0cf3 3817
c2d936a4
BP
3818 while (ofputil_parse_key_value(&arg, &key, &value)) {
3819 char *error;
b02475c5 3820
c2d936a4
BP
3821 if (!strcmp(key, "idle_timeout")) {
3822 error = str_to_u16(value, key, &oft->fin_idle_timeout);
3823 } else if (!strcmp(key, "hard_timeout")) {
3824 error = str_to_u16(value, key, &oft->fin_hard_timeout);
3825 } else {
3826 error = xasprintf("invalid key '%s' in 'fin_timeout' argument",
3827 key);
8621547c 3828 }
8dd54666 3829
c2d936a4
BP
3830 if (error) {
3831 return error;
9cae45dc 3832 }
9cae45dc 3833 }
c2d936a4
BP
3834 return NULL;
3835}
e3b56933 3836
c2d936a4
BP
3837static void
3838format_FIN_TIMEOUT(const struct ofpact_fin_timeout *a, struct ds *s)
3839{
b1c5bf1f 3840 ds_put_format(s, "%sfin_timeout(%s", colors.paren, colors.end);
c2d936a4 3841 if (a->fin_idle_timeout) {
b1c5bf1f
QM
3842 ds_put_format(s, "%sidle_timeout=%s%"PRIu16",",
3843 colors.param, colors.end, a->fin_idle_timeout);
7e9f8266 3844 }
c2d936a4 3845 if (a->fin_hard_timeout) {
b1c5bf1f
QM
3846 ds_put_format(s, "%shard_timeout=%s%"PRIu16",",
3847 colors.param, colors.end, a->fin_hard_timeout);
f25d0cf3 3848 }
c2d936a4 3849 ds_chomp(s, ',');
b1c5bf1f 3850 ds_put_format(s, "%s)%s", colors.paren, colors.end);
f25d0cf3 3851}
c2d936a4
BP
3852\f
3853/* Action structures for NXAST_RESUBMIT and NXAST_RESUBMIT_TABLE.
eca39bce 3854 *
c2d936a4 3855 * These actions search one of the switch's flow tables:
ba2fe8e9 3856 *
c2d936a4
BP
3857 * - For NXAST_RESUBMIT_TABLE only, if the 'table' member is not 255, then
3858 * it specifies the table to search.
ca287d20 3859 *
c2d936a4
BP
3860 * - Otherwise (for NXAST_RESUBMIT_TABLE with a 'table' of 255, or for
3861 * NXAST_RESUBMIT regardless of 'table'), it searches the current flow
3862 * table, that is, the OpenFlow flow table that contains the flow from
3863 * which this action was obtained. If this action did not come from a
3864 * flow table (e.g. it came from an OFPT_PACKET_OUT message), then table 0
3865 * is the current table.
3866 *
3867 * The flow table lookup uses a flow that may be slightly modified from the
3868 * original lookup:
3869 *
3870 * - For NXAST_RESUBMIT, the 'in_port' member of struct nx_action_resubmit
3871 * is used as the flow's in_port.
3872 *
3873 * - For NXAST_RESUBMIT_TABLE, if the 'in_port' member is not OFPP_IN_PORT,
3874 * then its value is used as the flow's in_port. Otherwise, the original
3875 * in_port is used.
3876 *
3877 * - If actions that modify the flow (e.g. OFPAT_SET_VLAN_VID) precede the
3878 * resubmit action, then the flow is updated with the new values.
3879 *
3880 * Following the lookup, the original in_port is restored.
3881 *
3882 * If the modified flow matched in the flow table, then the corresponding
3883 * actions are executed. Afterward, actions following the resubmit in the
3884 * original set of actions, if any, are executed; any changes made to the
3885 * packet (e.g. changes to VLAN) by secondary actions persist when those
3886 * actions are executed, although the original in_port is restored.
3887 *
3888 * Resubmit actions may be used any number of times within a set of actions.
3889 *
790c5d26
BP
3890 * Resubmit actions may nest. To prevent infinite loops and excessive resource
3891 * use, the implementation may limit nesting depth and the total number of
3892 * resubmits:
3893 *
3894 * - Open vSwitch 1.0.1 and earlier did not support recursion.
3895 *
3896 * - Open vSwitch 1.0.2 and 1.0.3 limited recursion to 8 levels.
3897 *
3898 * - Open vSwitch 1.1 and 1.2 limited recursion to 16 levels.
3899 *
3900 * - Open vSwitch 1.2 through 1.8 limited recursion to 32 levels.
3901 *
3902 * - Open vSwitch 1.9 through 2.0 limited recursion to 64 levels.
3903 *
3904 * - Open vSwitch 2.1 through 2.5 limited recursion to 64 levels and impose
3905 * a total limit of 4,096 resubmits per flow translation (earlier versions
3906 * did not impose any total limit).
c2d936a4
BP
3907 *
3908 * NXAST_RESUBMIT ignores 'table' and 'pad'. NXAST_RESUBMIT_TABLE requires
3909 * 'pad' to be all-bits-zero.
3910 *
3911 * Open vSwitch 1.0.1 and earlier did not support recursion. Open vSwitch
3912 * before 1.2.90 did not support NXAST_RESUBMIT_TABLE.
3913 */
3914struct nx_action_resubmit {
3915 ovs_be16 type; /* OFPAT_VENDOR. */
3916 ovs_be16 len; /* Length is 16. */
3917 ovs_be32 vendor; /* NX_VENDOR_ID. */
3918 ovs_be16 subtype; /* NXAST_RESUBMIT. */
3919 ovs_be16 in_port; /* New in_port for checking flow table. */
3920 uint8_t table; /* NXAST_RESUBMIT_TABLE: table to use. */
3921 uint8_t pad[3];
3922};
3923OFP_ASSERT(sizeof(struct nx_action_resubmit) == 16);
3924
3925static enum ofperr
f3cd3ac7
JS
3926decode_NXAST_RAW_RESUBMIT(uint16_t port,
3927 enum ofp_version ofp_version OVS_UNUSED,
3928 struct ofpbuf *out)
f25d0cf3 3929{
c2d936a4 3930 struct ofpact_resubmit *resubmit;
f25d0cf3 3931
c2d936a4
BP
3932 resubmit = ofpact_put_RESUBMIT(out);
3933 resubmit->ofpact.raw = NXAST_RAW_RESUBMIT;
3934 resubmit->in_port = u16_to_ofp(port);
3935 resubmit->table_id = 0xff;
3936 return 0;
f25d0cf3 3937}
4cceacb9 3938
c2d936a4
BP
3939static enum ofperr
3940decode_NXAST_RAW_RESUBMIT_TABLE(const struct nx_action_resubmit *nar,
f3cd3ac7 3941 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4 3942 struct ofpbuf *out)
ba2fe8e9 3943{
c2d936a4 3944 struct ofpact_resubmit *resubmit;
ba2fe8e9 3945
c2d936a4
BP
3946 if (nar->pad[0] || nar->pad[1] || nar->pad[2]) {
3947 return OFPERR_OFPBAC_BAD_ARGUMENT;
3948 }
3949
3950 resubmit = ofpact_put_RESUBMIT(out);
3951 resubmit->ofpact.raw = NXAST_RAW_RESUBMIT_TABLE;
3952 resubmit->in_port = u16_to_ofp(ntohs(nar->in_port));
3953 resubmit->table_id = nar->table;
3954 return 0;
ba2fe8e9
BP
3955}
3956
c2d936a4
BP
3957static void
3958encode_RESUBMIT(const struct ofpact_resubmit *resubmit,
3959 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
4cceacb9 3960{
c2d936a4 3961 uint16_t in_port = ofp_to_u16(resubmit->in_port);
4cceacb9 3962
c2d936a4
BP
3963 if (resubmit->table_id == 0xff
3964 && resubmit->ofpact.raw != NXAST_RAW_RESUBMIT_TABLE) {
3965 put_NXAST_RESUBMIT(out, in_port);
3966 } else {
3967 struct nx_action_resubmit *nar = put_NXAST_RESUBMIT_TABLE(out);
3968 nar->table = resubmit->table_id;
3969 nar->in_port = htons(in_port);
3970 }
3971}
6813ee7c 3972
cab50449 3973static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
3974parse_RESUBMIT(char *arg, struct ofpbuf *ofpacts,
3975 enum ofputil_protocol *usable_protocols OVS_UNUSED)
3976{
3977 struct ofpact_resubmit *resubmit;
3978 char *in_port_s, *table_s;
6813ee7c 3979
c2d936a4 3980 resubmit = ofpact_put_RESUBMIT(ofpacts);
8f2cded4 3981
c2d936a4
BP
3982 in_port_s = strsep(&arg, ",");
3983 if (in_port_s && in_port_s[0]) {
3984 if (!ofputil_port_from_string(in_port_s, &resubmit->in_port)) {
3985 return xasprintf("%s: resubmit to unknown port", in_port_s);
8f2cded4 3986 }
c2d936a4
BP
3987 } else {
3988 resubmit->in_port = OFPP_IN_PORT;
3989 }
4cceacb9 3990
c2d936a4
BP
3991 table_s = strsep(&arg, ",");
3992 if (table_s && table_s[0]) {
3993 uint32_t table_id = 0;
3994 char *error;
3995
3996 error = str_to_u32(table_s, &table_id);
3997 if (error) {
3998 return error;
3999 }
4000 resubmit->table_id = table_id;
4001 } else {
4002 resubmit->table_id = 255;
4cceacb9
JS
4003 }
4004
c2d936a4
BP
4005 if (resubmit->in_port == OFPP_IN_PORT && resubmit->table_id == 255) {
4006 return xstrdup("at least one \"in_port\" or \"table\" must be "
4007 "specified on resubmit");
4008 }
4009 return NULL;
4010}
4011
4012static void
4013format_RESUBMIT(const struct ofpact_resubmit *a, struct ds *s)
4014{
4015 if (a->in_port != OFPP_IN_PORT && a->table_id == 255) {
b1c5bf1f 4016 ds_put_format(s, "%sresubmit:%s", colors.special, colors.end);
c2d936a4
BP
4017 ofputil_format_port(a->in_port, s);
4018 } else {
b1c5bf1f 4019 ds_put_format(s, "%sresubmit(%s", colors.paren, colors.end);
c2d936a4
BP
4020 if (a->in_port != OFPP_IN_PORT) {
4021 ofputil_format_port(a->in_port, s);
4022 }
4023 ds_put_char(s, ',');
4024 if (a->table_id != 255) {
4025 ds_put_format(s, "%"PRIu8, a->table_id);
4026 }
b1c5bf1f 4027 ds_put_format(s, "%s)%s", colors.paren, colors.end);
c2d936a4
BP
4028 }
4029}
4030\f
4031/* Action structure for NXAST_LEARN.
4032 *
4033 * This action adds or modifies a flow in an OpenFlow table, similar to
4034 * OFPT_FLOW_MOD with OFPFC_MODIFY_STRICT as 'command'. The new flow has the
4035 * specified idle timeout, hard timeout, priority, cookie, and flags. The new
4036 * flow's match criteria and actions are built by applying each of the series
4037 * of flow_mod_spec elements included as part of the action.
4038 *
4039 * A flow_mod_spec starts with a 16-bit header. A header that is all-bits-0 is
4040 * a no-op used for padding the action as a whole to a multiple of 8 bytes in
4041 * length. Otherwise, the flow_mod_spec can be thought of as copying 'n_bits'
4042 * bits from a source to a destination. In this case, the header contains
4043 * multiple fields:
4044 *
4045 * 15 14 13 12 11 10 0
4046 * +------+---+------+---------------------------------+
4047 * | 0 |src| dst | n_bits |
4048 * +------+---+------+---------------------------------+
4049 *
4050 * The meaning and format of a flow_mod_spec depends on 'src' and 'dst'. The
4051 * following table summarizes the meaning of each possible combination.
4052 * Details follow the table:
4053 *
4054 * src dst meaning
4055 * --- --- ----------------------------------------------------------
4056 * 0 0 Add match criteria based on value in a field.
4057 * 1 0 Add match criteria based on an immediate value.
4058 * 0 1 Add NXAST_REG_LOAD action to copy field into a different field.
4059 * 1 1 Add NXAST_REG_LOAD action to load immediate value into a field.
4060 * 0 2 Add OFPAT_OUTPUT action to output to port from specified field.
4061 * All other combinations are undefined and not allowed.
4062 *
4063 * The flow_mod_spec header is followed by a source specification and a
4064 * destination specification. The format and meaning of the source
4065 * specification depends on 'src':
4066 *
4067 * - If 'src' is 0, the source bits are taken from a field in the flow to
4068 * which this action is attached. (This should be a wildcarded field. If
4069 * its value is fully specified then the source bits being copied have
4070 * constant values.)
4071 *
4072 * The source specification is an ovs_be32 'field' and an ovs_be16 'ofs'.
4073 * 'field' is an nxm_header with nxm_hasmask=0, and 'ofs' the starting bit
4074 * offset within that field. The source bits are field[ofs:ofs+n_bits-1].
4075 * 'field' and 'ofs' are subject to the same restrictions as the source
4076 * field in NXAST_REG_MOVE.
4077 *
4078 * - If 'src' is 1, the source bits are a constant value. The source
4079 * specification is (n_bits+15)/16*2 bytes long. Taking those bytes as a
4080 * number in network order, the source bits are the 'n_bits'
4081 * least-significant bits. The switch will report an error if other bits
4082 * in the constant are nonzero.
4083 *
4084 * The flow_mod_spec destination specification, for 'dst' of 0 or 1, is an
4085 * ovs_be32 'field' and an ovs_be16 'ofs'. 'field' is an nxm_header with
4086 * nxm_hasmask=0 and 'ofs' is a starting bit offset within that field. The
4087 * meaning of the flow_mod_spec depends on 'dst':
4088 *
4089 * - If 'dst' is 0, the flow_mod_spec specifies match criteria for the new
4090 * flow. The new flow matches only if bits field[ofs:ofs+n_bits-1] in a
4091 * packet equal the source bits. 'field' may be any nxm_header with
4092 * nxm_hasmask=0 that is allowed in NXT_FLOW_MOD.
4093 *
4094 * Order is significant. Earlier flow_mod_specs must satisfy any
4095 * prerequisites for matching fields specified later, by copying constant
4096 * values into prerequisite fields.
4097 *
4098 * The switch will reject flow_mod_specs that do not satisfy NXM masking
4099 * restrictions.
4100 *
4101 * - If 'dst' is 1, the flow_mod_spec specifies an NXAST_REG_LOAD action for
4102 * the new flow. The new flow copies the source bits into
4103 * field[ofs:ofs+n_bits-1]. Actions are executed in the same order as the
4104 * flow_mod_specs.
4105 *
4106 * A single NXAST_REG_LOAD action writes no more than 64 bits, so n_bits
4107 * greater than 64 yields multiple NXAST_REG_LOAD actions.
4108 *
4109 * The flow_mod_spec destination spec for 'dst' of 2 (when 'src' is 0) is
4110 * empty. It has the following meaning:
4111 *
4112 * - The flow_mod_spec specifies an OFPAT_OUTPUT action for the new flow.
4113 * The new flow outputs to the OpenFlow port specified by the source field.
4114 * Of the special output ports with value OFPP_MAX or larger, OFPP_IN_PORT,
4115 * OFPP_FLOOD, OFPP_LOCAL, and OFPP_ALL are supported. Other special ports
4116 * may not be used.
4117 *
4118 * Resource Management
4119 * -------------------
4120 *
4121 * A switch has a finite amount of flow table space available for learning.
4122 * When this space is exhausted, no new learning table entries will be learned
4123 * until some existing flow table entries expire. The controller should be
4124 * prepared to handle this by flooding (which can be implemented as a
4125 * low-priority flow).
4126 *
4127 * If a learned flow matches a single TCP stream with a relatively long
4128 * timeout, one may make the best of resource constraints by setting
4129 * 'fin_idle_timeout' or 'fin_hard_timeout' (both measured in seconds), or
4130 * both, to shorter timeouts. When either of these is specified as a nonzero
4131 * value, OVS adds a NXAST_FIN_TIMEOUT action, with the specified timeouts, to
4132 * the learned flow.
4133 *
4134 * Examples
4135 * --------
4136 *
4137 * The following examples give a prose description of the flow_mod_specs along
4138 * with informal notation for how those would be represented and a hex dump of
4139 * the bytes that would be required.
4140 *
4141 * These examples could work with various nx_action_learn parameters. Typical
4142 * values would be idle_timeout=OFP_FLOW_PERMANENT, hard_timeout=60,
4143 * priority=OFP_DEFAULT_PRIORITY, flags=0, table_id=10.
4144 *
4145 * 1. Learn input port based on the source MAC, with lookup into
4146 * NXM_NX_REG1[16:31] by resubmit to in_port=99:
4147 *
4148 * Match on in_port=99:
4149 * ovs_be16(src=1, dst=0, n_bits=16), 20 10
4150 * ovs_be16(99), 00 63
4151 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
4152 *
4153 * Match Ethernet destination on Ethernet source from packet:
4154 * ovs_be16(src=0, dst=0, n_bits=48), 00 30
4155 * ovs_be32(NXM_OF_ETH_SRC), ovs_be16(0) 00 00 04 06 00 00
4156 * ovs_be32(NXM_OF_ETH_DST), ovs_be16(0) 00 00 02 06 00 00
4157 *
4158 * Set NXM_NX_REG1[16:31] to the packet's input port:
4159 * ovs_be16(src=0, dst=1, n_bits=16), 08 10
4160 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
4161 * ovs_be32(NXM_NX_REG1), ovs_be16(16) 00 01 02 04 00 10
4162 *
4163 * Given a packet that arrived on port A with Ethernet source address B,
4164 * this would set up the flow "in_port=99, dl_dst=B,
4165 * actions=load:A->NXM_NX_REG1[16..31]".
4166 *
4167 * In syntax accepted by ovs-ofctl, this action is: learn(in_port=99,
4168 * NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
4169 * load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
4170 *
4171 * 2. Output to input port based on the source MAC and VLAN VID, with lookup
4172 * into NXM_NX_REG1[16:31]:
4173 *
4174 * Match on same VLAN ID as packet:
4175 * ovs_be16(src=0, dst=0, n_bits=12), 00 0c
4176 * ovs_be32(NXM_OF_VLAN_TCI), ovs_be16(0) 00 00 08 02 00 00
4177 * ovs_be32(NXM_OF_VLAN_TCI), ovs_be16(0) 00 00 08 02 00 00
4178 *
4179 * Match Ethernet destination on Ethernet source from packet:
4180 * ovs_be16(src=0, dst=0, n_bits=48), 00 30
4181 * ovs_be32(NXM_OF_ETH_SRC), ovs_be16(0) 00 00 04 06 00 00
4182 * ovs_be32(NXM_OF_ETH_DST), ovs_be16(0) 00 00 02 06 00 00
4183 *
4184 * Output to the packet's input port:
4185 * ovs_be16(src=0, dst=2, n_bits=16), 10 10
4186 * ovs_be32(NXM_OF_IN_PORT), ovs_be16(0) 00 00 00 02 00 00
4187 *
4188 * Given a packet that arrived on port A with Ethernet source address B in
4189 * VLAN C, this would set up the flow "dl_dst=B, vlan_vid=C,
4190 * actions=output:A".
4191 *
4192 * In syntax accepted by ovs-ofctl, this action is:
4193 * learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
4194 * output:NXM_OF_IN_PORT[])
4195 *
4196 * 3. Here's a recipe for a very simple-minded MAC learning switch. It uses a
4197 * 10-second MAC expiration time to make it easier to see what's going on
4198 *
4199 * ovs-vsctl del-controller br0
4200 * ovs-ofctl del-flows br0
4201 * ovs-ofctl add-flow br0 "table=0 actions=learn(table=1, \
4202 hard_timeout=10, NXM_OF_VLAN_TCI[0..11], \
4203 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
4204 output:NXM_OF_IN_PORT[]), resubmit(,1)"
4205 * ovs-ofctl add-flow br0 "table=1 priority=0 actions=flood"
4206 *
4207 * You can then dump the MAC learning table with:
4208 *
4209 * ovs-ofctl dump-flows br0 table=1
4210 *
4211 * Usage Advice
4212 * ------------
4213 *
4214 * For best performance, segregate learned flows into a table that is not used
4215 * for any other flows except possibly for a lowest-priority "catch-all" flow
4216 * (a flow with no match criteria). If different learning actions specify
4217 * different match criteria, use different tables for the learned flows.
4218 *
4219 * The meaning of 'hard_timeout' and 'idle_timeout' can be counterintuitive.
4220 * These timeouts apply to the flow that is added, which means that a flow with
4221 * an idle timeout will expire when no traffic has been sent *to* the learned
4222 * address. This is not usually the intent in MAC learning; instead, we want
4223 * the MAC learn entry to expire when no traffic has been sent *from* the
4224 * learned address. Use a hard timeout for that.
39c94593
JR
4225 *
4226 *
4227 * Visibility of Changes
4228 * ---------------------
4229 *
4230 * Prior to Open vSwitch 2.4, any changes made by a "learn" action in a given
4231 * flow translation are visible to flow table lookups made later in the flow
4232 * translation. This means that, in the example above, a MAC learned by the
4233 * learn action in table 0 would be found in table 1 (if the packet being
4234 * processed had the same source and destination MAC address).
4235 *
4236 * In Open vSwitch 2.4 and later, changes to a flow table (whether to add or
4237 * modify a flow) by a "learn" action are visible only for later flow
4238 * translations, not for later lookups within the same flow translation. In
4239 * the MAC learning example, a MAC learned by the learn action in table 0 would
4240 * not be found in table 1 if the flow translation would resubmit to table 1
4241 * after the processing of the learn action, meaning that if this MAC had not
4242 * been learned before then the packet would be flooded. */
c2d936a4
BP
4243struct nx_action_learn {
4244 ovs_be16 type; /* OFPAT_VENDOR. */
4245 ovs_be16 len; /* At least 24. */
4246 ovs_be32 vendor; /* NX_VENDOR_ID. */
4247 ovs_be16 subtype; /* NXAST_LEARN. */
4248 ovs_be16 idle_timeout; /* Idle time before discarding (seconds). */
4249 ovs_be16 hard_timeout; /* Max time before discarding (seconds). */
4250 ovs_be16 priority; /* Priority level of flow entry. */
4251 ovs_be64 cookie; /* Cookie for new flow. */
4252 ovs_be16 flags; /* NX_LEARN_F_*. */
4253 uint8_t table_id; /* Table to insert flow entry. */
4254 uint8_t pad; /* Must be zero. */
4255 ovs_be16 fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */
4256 ovs_be16 fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */
4257 /* Followed by a sequence of flow_mod_spec elements, as described above,
4258 * until the end of the action is reached. */
4259};
4260OFP_ASSERT(sizeof(struct nx_action_learn) == 32);
4261
4262static ovs_be16
4263get_be16(const void **pp)
4264{
4265 const ovs_be16 *p = *pp;
4266 ovs_be16 value = *p;
4267 *pp = p + 1;
4268 return value;
4269}
4270
4271static ovs_be32
4272get_be32(const void **pp)
4273{
4274 const ovs_be32 *p = *pp;
4275 ovs_be32 value = get_unaligned_be32(p);
4276 *pp = p + 1;
4277 return value;
4278}
4279
04f48a68
YHW
4280static enum ofperr
4281get_subfield(int n_bits, const void **p, struct mf_subfield *sf,
4282 const struct vl_mff_map *vl_mff_map)
c2d936a4 4283{
04f48a68 4284 sf->field = mf_from_nxm_header(ntohl(get_be32(p)), vl_mff_map);
c2d936a4
BP
4285 sf->ofs = ntohs(get_be16(p));
4286 sf->n_bits = n_bits;
04f48a68
YHW
4287 if (mf_vl_mff_invalid(sf->field, vl_mff_map)) {
4288 return OFPERR_NXFMFC_INVALID_TLV_FIELD;
4289 }
4290 return 0;
c2d936a4
BP
4291}
4292
4293static unsigned int
4294learn_min_len(uint16_t header)
4295{
4296 int n_bits = header & NX_LEARN_N_BITS_MASK;
4297 int src_type = header & NX_LEARN_SRC_MASK;
4298 int dst_type = header & NX_LEARN_DST_MASK;
4299 unsigned int min_len;
4300
4301 min_len = 0;
4302 if (src_type == NX_LEARN_SRC_FIELD) {
4303 min_len += sizeof(ovs_be32); /* src_field */
4304 min_len += sizeof(ovs_be16); /* src_ofs */
4305 } else {
4306 min_len += DIV_ROUND_UP(n_bits, 16);
4307 }
4308 if (dst_type == NX_LEARN_DST_MATCH ||
4309 dst_type == NX_LEARN_DST_LOAD) {
4310 min_len += sizeof(ovs_be32); /* dst_field */
4311 min_len += sizeof(ovs_be16); /* dst_ofs */
4312 }
4313 return min_len;
4314}
4315
4316/* Converts 'nal' into a "struct ofpact_learn" and appends that struct to
4317 * 'ofpacts'. Returns 0 if successful, otherwise an OFPERR_*. */
4318static enum ofperr
4319decode_NXAST_RAW_LEARN(const struct nx_action_learn *nal,
f3cd3ac7 4320 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 4321 const struct vl_mff_map *vl_mff_map,
c2d936a4
BP
4322 struct ofpbuf *ofpacts)
4323{
4324 struct ofpact_learn *learn;
4325 const void *p, *end;
4326
4327 if (nal->pad) {
4328 return OFPERR_OFPBAC_BAD_ARGUMENT;
4329 }
4330
4331 learn = ofpact_put_LEARN(ofpacts);
4332
4333 learn->idle_timeout = ntohs(nal->idle_timeout);
4334 learn->hard_timeout = ntohs(nal->hard_timeout);
4335 learn->priority = ntohs(nal->priority);
4336 learn->cookie = nal->cookie;
4337 learn->table_id = nal->table_id;
4338 learn->fin_idle_timeout = ntohs(nal->fin_idle_timeout);
4339 learn->fin_hard_timeout = ntohs(nal->fin_hard_timeout);
4340
4341 learn->flags = ntohs(nal->flags);
4342 if (learn->flags & ~(NX_LEARN_F_SEND_FLOW_REM |
4343 NX_LEARN_F_DELETE_LEARNED)) {
4344 return OFPERR_OFPBAC_BAD_ARGUMENT;
4345 }
4346
4347 if (learn->table_id == 0xff) {
4348 return OFPERR_OFPBAC_BAD_ARGUMENT;
4349 }
4350
4351 end = (char *) nal + ntohs(nal->len);
4352 for (p = nal + 1; p != end; ) {
4353 struct ofpact_learn_spec *spec;
4354 uint16_t header = ntohs(get_be16(&p));
4355
4356 if (!header) {
4357 break;
4358 }
4359
4360 spec = ofpbuf_put_zeros(ofpacts, sizeof *spec);
6fd6ed71 4361 learn = ofpacts->header;
c2d936a4
BP
4362
4363 spec->src_type = header & NX_LEARN_SRC_MASK;
4364 spec->dst_type = header & NX_LEARN_DST_MASK;
4365 spec->n_bits = header & NX_LEARN_N_BITS_MASK;
4366
4367 /* Check for valid src and dst type combination. */
4368 if (spec->dst_type == NX_LEARN_DST_MATCH ||
4369 spec->dst_type == NX_LEARN_DST_LOAD ||
4370 (spec->dst_type == NX_LEARN_DST_OUTPUT &&
4371 spec->src_type == NX_LEARN_SRC_FIELD)) {
4372 /* OK. */
4373 } else {
4374 return OFPERR_OFPBAC_BAD_ARGUMENT;
4375 }
4376
4377 /* Check that the arguments don't overrun the end of the action. */
4378 if ((char *) end - (char *) p < learn_min_len(header)) {
4379 return OFPERR_OFPBAC_BAD_LEN;
4380 }
4381
4382 /* Get the source. */
dfe191d5
JR
4383 const uint8_t *imm = NULL;
4384 unsigned int imm_bytes = 0;
04f48a68 4385 enum ofperr error;
c2d936a4 4386 if (spec->src_type == NX_LEARN_SRC_FIELD) {
04f48a68
YHW
4387 error = get_subfield(spec->n_bits, &p, &spec->src, vl_mff_map);
4388 if (error) {
4389 return error;
4390 }
c2d936a4
BP
4391 } else {
4392 int p_bytes = 2 * DIV_ROUND_UP(spec->n_bits, 16);
c2d936a4 4393 p = (const uint8_t *) p + p_bytes;
dfe191d5
JR
4394
4395 imm_bytes = DIV_ROUND_UP(spec->n_bits, 8);
4396 imm = (const uint8_t *) p - imm_bytes;
c2d936a4
BP
4397 }
4398
4399 /* Get the destination. */
4400 if (spec->dst_type == NX_LEARN_DST_MATCH ||
4401 spec->dst_type == NX_LEARN_DST_LOAD) {
04f48a68
YHW
4402 error = get_subfield(spec->n_bits, &p, &spec->dst, vl_mff_map);
4403 if (error) {
4404 return error;
4405 }
c2d936a4 4406 }
dfe191d5
JR
4407
4408 if (imm) {
4409 uint8_t *src_imm = ofpbuf_put_zeros(ofpacts,
4410 OFPACT_ALIGN(imm_bytes));
4411 memcpy(src_imm, imm, imm_bytes);
4412
4413 learn = ofpacts->header;
4414 }
c2d936a4 4415 }
ce058104 4416 ofpact_finish_LEARN(ofpacts, &learn);
c2d936a4
BP
4417
4418 if (!is_all_zeros(p, (char *) end - (char *) p)) {
4419 return OFPERR_OFPBAC_BAD_ARGUMENT;
4420 }
4421
4422 return 0;
4423}
4424
4425static void
4426put_be16(struct ofpbuf *b, ovs_be16 x)
4427{
4428 ofpbuf_put(b, &x, sizeof x);
4429}
4430
4431static void
4432put_be32(struct ofpbuf *b, ovs_be32 x)
4433{
4434 ofpbuf_put(b, &x, sizeof x);
4435}
4436
4437static void
4438put_u16(struct ofpbuf *b, uint16_t x)
4439{
4440 put_be16(b, htons(x));
4441}
4442
4443static void
4444put_u32(struct ofpbuf *b, uint32_t x)
4445{
4446 put_be32(b, htonl(x));
4447}
4448
4449static void
4450encode_LEARN(const struct ofpact_learn *learn,
4451 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
4452{
4453 const struct ofpact_learn_spec *spec;
4454 struct nx_action_learn *nal;
4455 size_t start_ofs;
4456
6fd6ed71 4457 start_ofs = out->size;
c2d936a4
BP
4458 nal = put_NXAST_LEARN(out);
4459 nal->idle_timeout = htons(learn->idle_timeout);
4460 nal->hard_timeout = htons(learn->hard_timeout);
4461 nal->fin_idle_timeout = htons(learn->fin_idle_timeout);
4462 nal->fin_hard_timeout = htons(learn->fin_hard_timeout);
4463 nal->priority = htons(learn->priority);
4464 nal->cookie = learn->cookie;
4465 nal->flags = htons(learn->flags);
4466 nal->table_id = learn->table_id;
4467
c65a31e2 4468 OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) {
c2d936a4
BP
4469 put_u16(out, spec->n_bits | spec->dst_type | spec->src_type);
4470
4471 if (spec->src_type == NX_LEARN_SRC_FIELD) {
04f48a68 4472 put_u32(out, nxm_header_from_mff(spec->src.field));
c2d936a4
BP
4473 put_u16(out, spec->src.ofs);
4474 } else {
4475 size_t n_dst_bytes = 2 * DIV_ROUND_UP(spec->n_bits, 16);
4476 uint8_t *bits = ofpbuf_put_zeros(out, n_dst_bytes);
507a9a16 4477 unsigned int n_bytes = DIV_ROUND_UP(spec->n_bits, 8);
dfe191d5 4478
507a9a16
JR
4479 memcpy(bits + n_dst_bytes - n_bytes, ofpact_learn_spec_imm(spec),
4480 n_bytes);
c2d936a4
BP
4481 }
4482
4483 if (spec->dst_type == NX_LEARN_DST_MATCH ||
4484 spec->dst_type == NX_LEARN_DST_LOAD) {
04f48a68 4485 put_u32(out, nxm_header_from_mff(spec->dst.field));
c2d936a4
BP
4486 put_u16(out, spec->dst.ofs);
4487 }
4488 }
4489
178742f9 4490 pad_ofpat(out, start_ofs);
c2d936a4
BP
4491}
4492
cab50449 4493static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
4494parse_LEARN(char *arg, struct ofpbuf *ofpacts,
4495 enum ofputil_protocol *usable_protocols OVS_UNUSED)
4496{
4497 return learn_parse(arg, ofpacts);
4498}
4499
4500static void
4501format_LEARN(const struct ofpact_learn *a, struct ds *s)
4502{
4503 learn_format(a, s);
4504}
4505\f
18080541
BP
4506/* Action structure for NXAST_CONJUNCTION. */
4507struct nx_action_conjunction {
4508 ovs_be16 type; /* OFPAT_VENDOR. */
4509 ovs_be16 len; /* At least 16. */
4510 ovs_be32 vendor; /* NX_VENDOR_ID. */
4511 ovs_be16 subtype; /* See enum ofp_raw_action_type. */
4512 uint8_t clause;
4513 uint8_t n_clauses;
4514 ovs_be32 id;
4515};
4516OFP_ASSERT(sizeof(struct nx_action_conjunction) == 16);
4517
4518static void
4519add_conjunction(struct ofpbuf *out,
4520 uint32_t id, uint8_t clause, uint8_t n_clauses)
4521{
4522 struct ofpact_conjunction *oc;
4523
4524 oc = ofpact_put_CONJUNCTION(out);
4525 oc->id = id;
4526 oc->clause = clause;
4527 oc->n_clauses = n_clauses;
4528}
4529
4530static enum ofperr
4531decode_NXAST_RAW_CONJUNCTION(const struct nx_action_conjunction *nac,
f3cd3ac7 4532 enum ofp_version ofp_version OVS_UNUSED,
18080541
BP
4533 struct ofpbuf *out)
4534{
4535 if (nac->n_clauses < 2 || nac->n_clauses > 64
4536 || nac->clause >= nac->n_clauses) {
4537 return OFPERR_NXBAC_BAD_CONJUNCTION;
4538 } else {
4539 add_conjunction(out, ntohl(nac->id), nac->clause, nac->n_clauses);
4540 return 0;
4541 }
4542}
4543
4544static void
4545encode_CONJUNCTION(const struct ofpact_conjunction *oc,
4546 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
4547{
4548 struct nx_action_conjunction *nac = put_NXAST_CONJUNCTION(out);
4549 nac->clause = oc->clause;
4550 nac->n_clauses = oc->n_clauses;
4551 nac->id = htonl(oc->id);
4552}
4553
4554static void
4555format_CONJUNCTION(const struct ofpact_conjunction *oc, struct ds *s)
4556{
b1c5bf1f
QM
4557 ds_put_format(s, "%sconjunction(%s%"PRIu32",%"PRIu8"/%"PRIu8"%s)%s",
4558 colors.paren, colors.end,
4559 oc->id, oc->clause + 1, oc->n_clauses,
4560 colors.paren, colors.end);
18080541
BP
4561}
4562
4563static char * OVS_WARN_UNUSED_RESULT
4564parse_CONJUNCTION(const char *arg, struct ofpbuf *ofpacts,
4565 enum ofputil_protocol *usable_protocols OVS_UNUSED)
4566{
4567 uint8_t n_clauses;
4568 uint8_t clause;
4569 uint32_t id;
4570 int n;
4571
4572 if (!ovs_scan(arg, "%"SCNi32" , %"SCNu8" / %"SCNu8" %n",
4573 &id, &clause, &n_clauses, &n) || n != strlen(arg)) {
4574 return xstrdup("\"conjunction\" syntax is \"conjunction(id,i/n)\"");
4575 }
4576
4577 if (n_clauses < 2) {
4578 return xstrdup("conjunction must have at least 2 clauses");
4579 } else if (n_clauses > 64) {
4580 return xstrdup("conjunction must have at most 64 clauses");
4581 } else if (clause < 1) {
4582 return xstrdup("clause index must be positive");
4583 } else if (clause > n_clauses) {
4584 return xstrdup("clause index must be less than or equal to "
4585 "number of clauses");
4586 }
4587
4588 add_conjunction(ofpacts, id, clause - 1, n_clauses);
4589 return NULL;
4590}
4591\f
c2d936a4
BP
4592/* Action structure for NXAST_MULTIPATH.
4593 *
4594 * This action performs the following steps in sequence:
4595 *
4596 * 1. Hashes the fields designated by 'fields', one of NX_HASH_FIELDS_*.
4597 * Refer to the definition of "enum nx_mp_fields" for details.
4598 *
4599 * The 'basis' value is used as a universal hash parameter, that is,
4600 * different values of 'basis' yield different hash functions. The
4601 * particular universal hash function used is implementation-defined.
4602 *
4603 * The hashed fields' values are drawn from the current state of the
4604 * flow, including all modifications that have been made by actions up to
4605 * this point.
4606 *
4607 * 2. Applies the multipath link choice algorithm specified by 'algorithm',
4608 * one of NX_MP_ALG_*. Refer to the definition of "enum nx_mp_algorithm"
4609 * for details.
4610 *
4611 * The output of the algorithm is 'link', an unsigned integer less than
4612 * or equal to 'max_link'.
4613 *
4614 * Some algorithms use 'arg' as an additional argument.
4615 *
4616 * 3. Stores 'link' in dst[ofs:ofs+n_bits]. The format and semantics of
4617 * 'dst' and 'ofs_nbits' are similar to those for the NXAST_REG_LOAD
4618 * action.
4619 *
4620 * The switch will reject actions that have an unknown 'fields', or an unknown
4621 * 'algorithm', or in which ofs+n_bits is greater than the width of 'dst', or
4622 * in which 'max_link' is greater than or equal to 2**n_bits, with error type
4623 * OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
4624 */
4625struct nx_action_multipath {
4626 ovs_be16 type; /* OFPAT_VENDOR. */
4627 ovs_be16 len; /* Length is 32. */
4628 ovs_be32 vendor; /* NX_VENDOR_ID. */
4629 ovs_be16 subtype; /* NXAST_MULTIPATH. */
4630
4631 /* What fields to hash and how. */
4632 ovs_be16 fields; /* One of NX_HASH_FIELDS_*. */
4633 ovs_be16 basis; /* Universal hash parameter. */
4634 ovs_be16 pad0;
4635
4636 /* Multipath link choice algorithm to apply to hash value. */
4637 ovs_be16 algorithm; /* One of NX_MP_ALG_*. */
4638 ovs_be16 max_link; /* Number of output links, minus 1. */
4639 ovs_be32 arg; /* Algorithm-specific argument. */
4640 ovs_be16 pad1;
4641
4642 /* Where to store the result. */
4643 ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
4644 ovs_be32 dst; /* Destination. */
4645};
4646OFP_ASSERT(sizeof(struct nx_action_multipath) == 32);
4647
4648static enum ofperr
4649decode_NXAST_RAW_MULTIPATH(const struct nx_action_multipath *nam,
f3cd3ac7 4650 enum ofp_version ofp_version OVS_UNUSED,
04f48a68 4651 const struct vl_mff_map *vl_mff_map,
c2d936a4
BP
4652 struct ofpbuf *out)
4653{
4654 uint32_t n_links = ntohs(nam->max_link) + 1;
4655 size_t min_n_bits = log_2_ceil(n_links);
4656 struct ofpact_multipath *mp;
4657
4658 mp = ofpact_put_MULTIPATH(out);
4659 mp->fields = ntohs(nam->fields);
4660 mp->basis = ntohs(nam->basis);
4661 mp->algorithm = ntohs(nam->algorithm);
4662 mp->max_link = ntohs(nam->max_link);
4663 mp->arg = ntohl(nam->arg);
04f48a68 4664 mp->dst.field = mf_from_nxm_header(ntohl(nam->dst), vl_mff_map);
c2d936a4
BP
4665 mp->dst.ofs = nxm_decode_ofs(nam->ofs_nbits);
4666 mp->dst.n_bits = nxm_decode_n_bits(nam->ofs_nbits);
4667
04f48a68
YHW
4668 if (mf_vl_mff_invalid(mp->dst.field, vl_mff_map)) {
4669 return OFPERR_NXFMFC_INVALID_TLV_FIELD;
4670 }
4671
c2d936a4
BP
4672 if (!flow_hash_fields_valid(mp->fields)) {
4673 VLOG_WARN_RL(&rl, "unsupported fields %d", (int) mp->fields);
4674 return OFPERR_OFPBAC_BAD_ARGUMENT;
4675 } else if (mp->algorithm != NX_MP_ALG_MODULO_N
4676 && mp->algorithm != NX_MP_ALG_HASH_THRESHOLD
4677 && mp->algorithm != NX_MP_ALG_HRW
4678 && mp->algorithm != NX_MP_ALG_ITER_HASH) {
4679 VLOG_WARN_RL(&rl, "unsupported algorithm %d", (int) mp->algorithm);
4680 return OFPERR_OFPBAC_BAD_ARGUMENT;
4681 } else if (mp->dst.n_bits < min_n_bits) {
4682 VLOG_WARN_RL(&rl, "multipath action requires at least %"PRIuSIZE" bits for "
4683 "%"PRIu32" links", min_n_bits, n_links);
4684 return OFPERR_OFPBAC_BAD_ARGUMENT;
4685 }
4686
4687 return multipath_check(mp, NULL);
4688}
4689
4690static void
4691encode_MULTIPATH(const struct ofpact_multipath *mp,
4692 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
4693{
4694 struct nx_action_multipath *nam = put_NXAST_MULTIPATH(out);
4695
4696 nam->fields = htons(mp->fields);
4697 nam->basis = htons(mp->basis);
4698 nam->algorithm = htons(mp->algorithm);
4699 nam->max_link = htons(mp->max_link);
4700 nam->arg = htonl(mp->arg);
4701 nam->ofs_nbits = nxm_encode_ofs_nbits(mp->dst.ofs, mp->dst.n_bits);
04f48a68 4702 nam->dst = htonl(nxm_header_from_mff(mp->dst.field));
c2d936a4
BP
4703}
4704
cab50449 4705static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
4706parse_MULTIPATH(const char *arg, struct ofpbuf *ofpacts,
4707 enum ofputil_protocol *usable_protocols OVS_UNUSED)
4708{
4709 return multipath_parse(ofpact_put_MULTIPATH(ofpacts), arg);
4710}
4711
4712static void
4713format_MULTIPATH(const struct ofpact_multipath *a, struct ds *s)
4714{
4715 multipath_format(a, s);
4716}
4717\f
4718/* Action structure for NXAST_NOTE.
4719 *
4720 * This action has no effect. It is variable length. The switch does not
4721 * attempt to interpret the user-defined 'note' data in any way. A controller
4722 * can use this action to attach arbitrary metadata to a flow.
4723 *
4724 * This action might go away in the future.
4725 */
4726struct nx_action_note {
4727 ovs_be16 type; /* OFPAT_VENDOR. */
4728 ovs_be16 len; /* A multiple of 8, but at least 16. */
4729 ovs_be32 vendor; /* NX_VENDOR_ID. */
4730 ovs_be16 subtype; /* NXAST_NOTE. */
4731 uint8_t note[6]; /* Start of user-defined data. */
4732 /* Possibly followed by additional user-defined data. */
4733};
4734OFP_ASSERT(sizeof(struct nx_action_note) == 16);
4735
4736static enum ofperr
f3cd3ac7
JS
4737decode_NXAST_RAW_NOTE(const struct nx_action_note *nan,
4738 enum ofp_version ofp_version OVS_UNUSED,
4739 struct ofpbuf *out)
c2d936a4
BP
4740{
4741 struct ofpact_note *note;
4742 unsigned int length;
4743
4744 length = ntohs(nan->len) - offsetof(struct nx_action_note, note);
2bd318de 4745 note = ofpact_put_NOTE(out);
c2d936a4 4746 note->length = length;
2bd318de 4747 ofpbuf_put(out, nan->note, length);
ace39a6f 4748 note = out->header;
ce058104 4749 ofpact_finish_NOTE(out, &note);
c2d936a4
BP
4750
4751 return 0;
4752}
4753
4754static void
4755encode_NOTE(const struct ofpact_note *note,
4756 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
4757{
6fd6ed71 4758 size_t start_ofs = out->size;
c2d936a4 4759 struct nx_action_note *nan;
c2d936a4
BP
4760
4761 put_NXAST_NOTE(out);
6fd6ed71 4762 out->size = out->size - sizeof nan->note;
c2d936a4
BP
4763
4764 ofpbuf_put(out, note->data, note->length);
9ac0aada 4765 pad_ofpat(out, start_ofs);
c2d936a4
BP
4766}
4767
cab50449 4768static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
4769parse_NOTE(const char *arg, struct ofpbuf *ofpacts,
4770 enum ofputil_protocol *usable_protocols OVS_UNUSED)
4771{
27aa8793
BP
4772 size_t start_ofs = ofpacts->size;
4773 ofpact_put_NOTE(ofpacts);
4774 arg = ofpbuf_put_hex(ofpacts, arg, NULL);
4775 if (arg[0]) {
4776 return xstrdup("bad hex digit in `note' argument");
4777 }
4778 struct ofpact_note *note = ofpbuf_at_assert(ofpacts, start_ofs,
4779 sizeof *note);
4780 note->length = ofpacts->size - (start_ofs + sizeof *note);
ce058104 4781 ofpact_finish_NOTE(ofpacts, &note);
c2d936a4
BP
4782 return NULL;
4783}
4784
4785static void
4786format_NOTE(const struct ofpact_note *a, struct ds *s)
4787{
b1c5bf1f 4788 ds_put_format(s, "%snote:%s", colors.param, colors.end);
bdcad671 4789 format_hex_arg(s, a->data, a->length);
c2d936a4
BP
4790}
4791\f
4792/* Exit action. */
4793
4794static enum ofperr
4795decode_NXAST_RAW_EXIT(struct ofpbuf *out)
4796{
4797 ofpact_put_EXIT(out);
4798 return 0;
4799}
4800
4801static void
4802encode_EXIT(const struct ofpact_null *null OVS_UNUSED,
4803 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
4804{
4805 put_NXAST_EXIT(out);
4806}
4807
cab50449 4808static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
4809parse_EXIT(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
4810 enum ofputil_protocol *usable_protocols OVS_UNUSED)
4811{
4812 ofpact_put_EXIT(ofpacts);
4813 return NULL;
4814}
4815
4816static void
4817format_EXIT(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
4818{
b1c5bf1f 4819 ds_put_format(s, "%sexit%s", colors.special, colors.end);
c2d936a4
BP
4820}
4821\f
e672ff9b
JR
4822/* Unroll xlate action. */
4823
4824static void
4825encode_UNROLL_XLATE(const struct ofpact_unroll_xlate *unroll OVS_UNUSED,
4826 enum ofp_version ofp_version OVS_UNUSED,
4827 struct ofpbuf *out OVS_UNUSED)
4828{
4829 OVS_NOT_REACHED();
4830}
4831
4832static char * OVS_WARN_UNUSED_RESULT
4833parse_UNROLL_XLATE(char *arg OVS_UNUSED, struct ofpbuf *ofpacts OVS_UNUSED,
4834 enum ofputil_protocol *usable_protocols OVS_UNUSED)
4835{
4836 OVS_NOT_REACHED();
4837 return NULL;
4838}
4839
4840static void
28632a8a 4841format_UNROLL_XLATE(const struct ofpact_unroll_xlate *a, struct ds *s)
e672ff9b 4842{
b1c5bf1f
QM
4843 ds_put_format(s, "%sunroll_xlate(%s%stable=%s%"PRIu8
4844 ", %scookie=%s%"PRIu64"%s)%s",
4845 colors.paren, colors.end,
4846 colors.special, colors.end, a->rule_table_id,
4847 colors.param, colors.end, ntohll(a->rule_cookie),
4848 colors.paren, colors.end);
e672ff9b
JR
4849}
4850\f
7ae62a67
WT
4851/* The NXAST_CLONE action is "struct ext_action_header", followed by zero or
4852 * more embedded OpenFlow actions. */
4853
4854static enum ofperr
4855decode_NXAST_RAW_CLONE(const struct ext_action_header *eah,
04f48a68
YHW
4856 enum ofp_version ofp_version,
4857 const struct vl_mff_map *vl_mff_map,
4858 struct ofpbuf *out)
7ae62a67
WT
4859{
4860 int error;
4861 struct ofpbuf openflow;
4862 const size_t clone_offset = ofpacts_pull(out);
4863 struct ofpact_nest *clone = ofpact_put_CLONE(out);
4864
4865 /* decode action list */
4866 ofpbuf_pull(out, sizeof(*clone));
4867 openflow = ofpbuf_const_initializer(
4868 eah + 1, ntohs(eah->len) - sizeof *eah);
4869 error = ofpacts_pull_openflow_actions__(&openflow, openflow.size,
4870 ofp_version,
4871 1u << OVSINST_OFPIT11_APPLY_ACTIONS,
04f48a68 4872 out, 0, vl_mff_map);
7ae62a67
WT
4873 clone = ofpbuf_push_uninit(out, sizeof *clone);
4874 out->header = &clone->ofpact;
4875 ofpact_finish_CLONE(out, &clone);
4876 ofpbuf_push_uninit(out, clone_offset);
4877 return error;
4878}
4879
4880static void
4881encode_CLONE(const struct ofpact_nest *clone,
4882 enum ofp_version ofp_version, struct ofpbuf *out)
4883{
4884 size_t len;
4885 const size_t ofs = out->size;
4886 struct ext_action_header *eah;
4887
4888 eah = put_NXAST_CLONE(out);
4889 len = ofpacts_put_openflow_actions(clone->actions,
4890 ofpact_nest_get_action_len(clone),
4891 out, ofp_version);
4892 len += sizeof *eah;
4893 eah = ofpbuf_at(out, ofs, sizeof *eah);
4894 eah->len = htons(len);
4895}
4896
4897static char * OVS_WARN_UNUSED_RESULT
4898parse_CLONE(char *arg, struct ofpbuf *ofpacts,
4899 enum ofputil_protocol *usable_protocols)
4900{
4901 const size_t clone_offset = ofpacts_pull(ofpacts);
4902 struct ofpact_nest *clone = ofpact_put_CLONE(ofpacts);
4903 char *error;
4904
4905 ofpbuf_pull(ofpacts, sizeof *clone);
4906 error = ofpacts_parse_copy(arg, ofpacts, usable_protocols, false, 0);
4907 /* header points to the action list */
4908 ofpacts->header = ofpbuf_push_uninit(ofpacts, sizeof *clone);
4909 clone = ofpacts->header;
4910
4911 ofpact_finish_CLONE(ofpacts, &clone);
4912 ofpbuf_push_uninit(ofpacts, clone_offset);
4913 return error;
4914}
4915
4916static void
4917format_CLONE(const struct ofpact_nest *a, struct ds *s)
4918{
4919 ds_put_format(s, "%sclone(%s", colors.paren, colors.end);
4920 ofpacts_format(a->actions, ofpact_nest_get_action_len(a), s);
4921 ds_put_format(s, "%s)%s", colors.paren, colors.end);
4922}
4923\f
c2d936a4
BP
4924/* Action structure for NXAST_SAMPLE.
4925 *
4926 * Samples matching packets with the given probability and sends them
4927 * each to the set of collectors identified with the given ID. The
4928 * probability is expressed as a number of packets to be sampled out
4929 * of USHRT_MAX packets, and must be >0.
4930 *
4931 * When sending packet samples to IPFIX collectors, the IPFIX flow
4932 * record sent for each sampled packet is associated with the given
4933 * observation domain ID and observation point ID. Each IPFIX flow
4934 * record contain the sampled packet's headers when executing this
4935 * rule. If a sampled packet's headers are modified by previous
4936 * actions in the flow, those modified headers are sent. */
4937struct nx_action_sample {
4938 ovs_be16 type; /* OFPAT_VENDOR. */
4939 ovs_be16 len; /* Length is 24. */
4940 ovs_be32 vendor; /* NX_VENDOR_ID. */
4941 ovs_be16 subtype; /* NXAST_SAMPLE. */
4942 ovs_be16 probability; /* Fraction of packets to sample. */
4943 ovs_be32 collector_set_id; /* ID of collector set in OVSDB. */
4944 ovs_be32 obs_domain_id; /* ID of sampling observation domain. */
4945 ovs_be32 obs_point_id; /* ID of sampling observation point. */
4946};
4947OFP_ASSERT(sizeof(struct nx_action_sample) == 24);
4948
4930ea56 4949/* Action structure for NXAST_SAMPLE2 and NXAST_SAMPLE3.
f69f713b 4950 *
4930ea56
BP
4951 * NXAST_SAMPLE2 was added in Open vSwitch 2.5.90. Compared to NXAST_SAMPLE,
4952 * it adds support for exporting egress tunnel information.
4953 *
4954 * NXAST_SAMPLE3 was added in Open vSwitch 2.6.90. Compared to NXAST_SAMPLE2,
4955 * it adds support for the 'direction' field. */
f69f713b
BY
4956struct nx_action_sample2 {
4957 ovs_be16 type; /* OFPAT_VENDOR. */
4958 ovs_be16 len; /* Length is 32. */
4959 ovs_be32 vendor; /* NX_VENDOR_ID. */
4960 ovs_be16 subtype; /* NXAST_SAMPLE. */
4961 ovs_be16 probability; /* Fraction of packets to sample. */
4962 ovs_be32 collector_set_id; /* ID of collector set in OVSDB. */
4963 ovs_be32 obs_domain_id; /* ID of sampling observation domain. */
4964 ovs_be32 obs_point_id; /* ID of sampling observation point. */
4965 ovs_be16 sampling_port; /* Sampling port. */
4930ea56
BP
4966 uint8_t direction; /* NXAST_SAMPLE3 only. */
4967 uint8_t zeros[5]; /* Pad to a multiple of 8 bytes */
f69f713b
BY
4968 };
4969 OFP_ASSERT(sizeof(struct nx_action_sample2) == 32);
4970
c2d936a4 4971static enum ofperr
f3cd3ac7
JS
4972decode_NXAST_RAW_SAMPLE(const struct nx_action_sample *nas,
4973 enum ofp_version ofp_version OVS_UNUSED,
4974 struct ofpbuf *out)
c2d936a4
BP
4975{
4976 struct ofpact_sample *sample;
4977
4978 sample = ofpact_put_SAMPLE(out);
f69f713b
BY
4979 sample->ofpact.raw = NXAST_RAW_SAMPLE;
4980 sample->probability = ntohs(nas->probability);
4981 sample->collector_set_id = ntohl(nas->collector_set_id);
4982 sample->obs_domain_id = ntohl(nas->obs_domain_id);
4983 sample->obs_point_id = ntohl(nas->obs_point_id);
f69f713b 4984 sample->sampling_port = OFPP_NONE;
4930ea56 4985 sample->direction = NX_ACTION_SAMPLE_DEFAULT;
f69f713b
BY
4986
4987 if (sample->probability == 0) {
4988 return OFPERR_OFPBAC_BAD_ARGUMENT;
4989 }
4990
4991 return 0;
4992}
4993
4994static enum ofperr
4930ea56
BP
4995decode_SAMPLE2(const struct nx_action_sample2 *nas,
4996 enum ofp_raw_action_type raw,
4997 enum nx_action_sample_direction direction,
4998 struct ofpact_sample *sample)
f69f713b 4999{
4930ea56 5000 sample->ofpact.raw = raw;
c2d936a4
BP
5001 sample->probability = ntohs(nas->probability);
5002 sample->collector_set_id = ntohl(nas->collector_set_id);
5003 sample->obs_domain_id = ntohl(nas->obs_domain_id);
5004 sample->obs_point_id = ntohl(nas->obs_point_id);
f69f713b 5005 sample->sampling_port = u16_to_ofp(ntohs(nas->sampling_port));
4930ea56 5006 sample->direction = direction;
c2d936a4
BP
5007
5008 if (sample->probability == 0) {
5009 return OFPERR_OFPBAC_BAD_ARGUMENT;
5010 }
5011
5012 return 0;
5013}
5014
4930ea56
BP
5015static enum ofperr
5016decode_NXAST_RAW_SAMPLE2(const struct nx_action_sample2 *nas,
5017 enum ofp_version ofp_version OVS_UNUSED,
5018 struct ofpbuf *out)
5019{
5020 return decode_SAMPLE2(nas, NXAST_RAW_SAMPLE2, NX_ACTION_SAMPLE_DEFAULT,
5021 ofpact_put_SAMPLE(out));
5022}
5023
5024static enum ofperr
5025decode_NXAST_RAW_SAMPLE3(const struct nx_action_sample2 *nas,
5026 enum ofp_version ofp_version OVS_UNUSED,
5027 struct ofpbuf *out)
5028{
5029 struct ofpact_sample *sample = ofpact_put_SAMPLE(out);
5030 if (!is_all_zeros(nas->zeros, sizeof nas->zeros)) {
5031 return OFPERR_NXBRC_MUST_BE_ZERO;
5032 }
5033 if (nas->direction != NX_ACTION_SAMPLE_DEFAULT &&
5034 nas->direction != NX_ACTION_SAMPLE_INGRESS &&
5035 nas->direction != NX_ACTION_SAMPLE_EGRESS) {
5036 VLOG_WARN_RL(&rl, "invalid sample direction %"PRIu8, nas->direction);
5037 return OFPERR_OFPBAC_BAD_ARGUMENT;
5038 }
5039 return decode_SAMPLE2(nas, NXAST_RAW_SAMPLE3, nas->direction, sample);
5040}
5041
5042static void
5043encode_SAMPLE2(const struct ofpact_sample *sample,
5044 struct nx_action_sample2 *nas)
5045{
5046 nas->probability = htons(sample->probability);
5047 nas->collector_set_id = htonl(sample->collector_set_id);
5048 nas->obs_domain_id = htonl(sample->obs_domain_id);
5049 nas->obs_point_id = htonl(sample->obs_point_id);
5050 nas->sampling_port = htons(ofp_to_u16(sample->sampling_port));
5051 nas->direction = sample->direction;
5052}
5053
c2d936a4
BP
5054static void
5055encode_SAMPLE(const struct ofpact_sample *sample,
5056 enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
5057{
4930ea56
BP
5058 if (sample->ofpact.raw == NXAST_RAW_SAMPLE3
5059 || sample->direction != NX_ACTION_SAMPLE_DEFAULT) {
5060 encode_SAMPLE2(sample, put_NXAST_SAMPLE3(out));
5061 } else if (sample->ofpact.raw == NXAST_RAW_SAMPLE2
5062 || sample->sampling_port != OFPP_NONE) {
5063 encode_SAMPLE2(sample, put_NXAST_SAMPLE2(out));
f69f713b
BY
5064 } else {
5065 struct nx_action_sample *nas = put_NXAST_SAMPLE(out);
5066 nas->probability = htons(sample->probability);
5067 nas->collector_set_id = htonl(sample->collector_set_id);
5068 nas->obs_domain_id = htonl(sample->obs_domain_id);
5069 nas->obs_point_id = htonl(sample->obs_point_id);
5070 }
c2d936a4
BP
5071}
5072
5073/* Parses 'arg' as the argument to a "sample" action, and appends such an
5074 * action to 'ofpacts'.
5075 *
5076 * Returns NULL if successful, otherwise a malloc()'d string describing the
5077 * error. The caller is responsible for freeing the returned string. */
cab50449 5078static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
5079parse_SAMPLE(char *arg, struct ofpbuf *ofpacts,
5080 enum ofputil_protocol *usable_protocols OVS_UNUSED)
5081{
5082 struct ofpact_sample *os = ofpact_put_SAMPLE(ofpacts);
f69f713b 5083 os->sampling_port = OFPP_NONE;
4930ea56 5084 os->direction = NX_ACTION_SAMPLE_DEFAULT;
c2d936a4 5085
f69f713b 5086 char *key, *value;
c2d936a4
BP
5087 while (ofputil_parse_key_value(&arg, &key, &value)) {
5088 char *error = NULL;
5089
5090 if (!strcmp(key, "probability")) {
5091 error = str_to_u16(value, "probability", &os->probability);
5092 if (!error && os->probability == 0) {
5093 error = xasprintf("invalid probability value \"%s\"", value);
5094 }
5095 } else if (!strcmp(key, "collector_set_id")) {
5096 error = str_to_u32(value, &os->collector_set_id);
5097 } else if (!strcmp(key, "obs_domain_id")) {
5098 error = str_to_u32(value, &os->obs_domain_id);
5099 } else if (!strcmp(key, "obs_point_id")) {
5100 error = str_to_u32(value, &os->obs_point_id);
f69f713b
BY
5101 } else if (!strcmp(key, "sampling_port")) {
5102 if (!ofputil_port_from_string(value, &os->sampling_port)) {
5103 error = xasprintf("%s: unknown port", value);
5104 }
4930ea56
BP
5105 } else if (!strcmp(key, "ingress")) {
5106 os->direction = NX_ACTION_SAMPLE_INGRESS;
5107 } else if (!strcmp(key, "egress")) {
5108 os->direction = NX_ACTION_SAMPLE_EGRESS;
c2d936a4
BP
5109 } else {
5110 error = xasprintf("invalid key \"%s\" in \"sample\" argument",
5111 key);
5112 }
5113 if (error) {
5114 return error;
5115 }
5116 }
5117 if (os->probability == 0) {
5118 return xstrdup("non-zero \"probability\" must be specified on sample");
5119 }
f69f713b 5120
c2d936a4
BP
5121 return NULL;
5122}
5123
5124static void
5125format_SAMPLE(const struct ofpact_sample *a, struct ds *s)
5126{
b1c5bf1f
QM
5127 ds_put_format(s, "%ssample(%s%sprobability=%s%"PRIu16
5128 ",%scollector_set_id=%s%"PRIu32
5129 ",%sobs_domain_id=%s%"PRIu32
f69f713b 5130 ",%sobs_point_id=%s%"PRIu32,
b1c5bf1f
QM
5131 colors.paren, colors.end,
5132 colors.param, colors.end, a->probability,
5133 colors.param, colors.end, a->collector_set_id,
5134 colors.param, colors.end, a->obs_domain_id,
f69f713b
BY
5135 colors.param, colors.end, a->obs_point_id);
5136 if (a->sampling_port != OFPP_NONE) {
94783c7c 5137 ds_put_format(s, ",%ssampling_port=%s%"PRIu32,
f69f713b
BY
5138 colors.param, colors.end, a->sampling_port);
5139 }
4930ea56
BP
5140 if (a->direction == NX_ACTION_SAMPLE_INGRESS) {
5141 ds_put_format(s, ",%singress%s", colors.param, colors.end);
5142 } else if (a->direction == NX_ACTION_SAMPLE_EGRESS) {
5143 ds_put_format(s, ",%segress%s", colors.param, colors.end);
5144 }
f69f713b 5145 ds_put_format(s, "%s)%s", colors.paren, colors.end);
c2d936a4
BP
5146}
5147\f
d4abaff5
BP
5148/* debug_recirc instruction. */
5149
5150static bool enable_debug;
5151
5152void
5153ofpact_dummy_enable(void)
5154{
5155 enable_debug = true;
5156}
5157
5158static enum ofperr
5159decode_NXAST_RAW_DEBUG_RECIRC(struct ofpbuf *out)
5160{
5161 if (!enable_debug) {
5162 return OFPERR_OFPBAC_BAD_VENDOR_TYPE;
5163 }
5164
5165 ofpact_put_DEBUG_RECIRC(out);
5166 return 0;
5167}
5168
5169static void
5170encode_DEBUG_RECIRC(const struct ofpact_null *n OVS_UNUSED,
5171 enum ofp_version ofp_version OVS_UNUSED,
5172 struct ofpbuf *out)
5173{
5174 put_NXAST_DEBUG_RECIRC(out);
5175}
5176
5177static char * OVS_WARN_UNUSED_RESULT
5178parse_DEBUG_RECIRC(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
5179 enum ofputil_protocol *usable_protocols OVS_UNUSED)
5180{
5181 ofpact_put_DEBUG_RECIRC(ofpacts);
5182 return NULL;
5183}
5184
5185static void
5186format_DEBUG_RECIRC(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
5187{
b1c5bf1f 5188 ds_put_format(s, "%sdebug_recirc%s", colors.value, colors.end);
d4abaff5 5189}
07659514
JS
5190
5191/* Action structure for NXAST_CT.
5192 *
5193 * Pass traffic to the connection tracker.
5194 *
5195 * There are two important concepts to understanding the connection tracking
5196 * interface: Packet state and Connection state. Packets may be "Untracked" or
5197 * "Tracked". Connections may be "Uncommitted" or "Committed".
5198 *
5199 * - Packet State:
5200 *
5201 * Untracked packets have not yet passed through the connection tracker,
5202 * and the connection state for such packets is unknown. In most cases,
5203 * packets entering the OpenFlow pipeline will initially be in the
5204 * untracked state. Untracked packets may become tracked by executing
5205 * NXAST_CT with a "recirc_table" specified. This makes various aspects
5206 * about the connection available, in particular the connection state.
5207 *
5208 * Tracked packets have previously passed through the connection tracker.
5209 * These packets will remain tracked through until the end of the OpenFlow
5210 * pipeline. Tracked packets which have NXAST_CT executed with a
5211 * "recirc_table" specified will return to the tracked state.
5212 *
5213 * The packet state is only significant for the duration of packet
5214 * processing within the OpenFlow pipeline.
5215 *
5216 * - Connection State:
5217 *
5218 * Multiple packets may be associated with a single connection. Initially,
5219 * all connections are uncommitted. The connection state corresponding to
5220 * a packet is available in the NXM_NX_CT_STATE field for tracked packets.
5221 *
5222 * Uncommitted connections have no state stored about them. Uncommitted
5223 * connections may transition into the committed state by executing
5224 * NXAST_CT with the NX_CT_F_COMMIT flag.
5225 *
5226 * Once a connection becomes committed, information may be gathered about
5227 * the connection by passing subsequent packets through the connection
5228 * tracker, and the state of the connection will be stored beyond the
5229 * lifetime of packet processing.
5230 *
5231 * Connections may transition back into the uncommitted state due to
5232 * external timers, or due to the contents of packets that are sent to the
5233 * connection tracker. This behaviour is outside of the scope of the
5234 * OpenFlow interface.
5235 *
5236 * The "zone" specifies a context within which the tracking is done:
5237 *
5238 * The connection tracking zone is a 16-bit number. Each zone is an
5239 * independent connection tracking context. The connection state for each
5240 * connection is completely separate for each zone, so if a connection
5241 * is committed to zone A, then it will remain uncommitted in zone B.
5242 * If NXAST_CT is executed with the same zone multiple times, later
5243 * executions have no effect.
5244 *
5245 * If 'zone_src' is nonzero, this specifies that the zone should be
5246 * sourced from a field zone_src[ofs:ofs+nbits]. The format and semantics
5247 * of 'zone_src' and 'zone_ofs_nbits' are similar to those for the
5248 * NXAST_REG_LOAD action. The acceptable nxm_header values for 'zone_src'
5249 * are the same as the acceptable nxm_header values for the 'src' field of
5250 * NXAST_REG_MOVE.
5251 *
5252 * If 'zone_src' is zero, then the value of 'zone_imm' will be used as the
5253 * connection tracking zone.
5254 *
5255 * The "recirc_table" allows NXM_NX_CT_* fields to become available:
5256 *
5257 * If "recirc_table" has a value other than NX_CT_RECIRC_NONE, then the
5258 * packet will be logically cloned prior to executing this action. One
5259 * copy will be sent to the connection tracker, then will be re-injected
5260 * into the OpenFlow pipeline beginning at the OpenFlow table specified in
5261 * this field. When the packet re-enters the pipeline, the NXM_NX_CT_*
5262 * fields will be populated. The original instance of the packet will
5263 * continue the current actions list. This can be thought of as similar to
5264 * the effect of the "output" action: One copy is sent out (in this case,
5265 * to the connection tracker), but the current copy continues processing.
5266 *
5267 * It is strongly recommended that this table is later than the current
5268 * table, to prevent loops.
8e53fe8c 5269 *
d787ad39
JS
5270 * The "alg" attaches protocol-specific behaviour to this action:
5271 *
5272 * The ALG is a 16-bit number which specifies that additional
5273 * processing should be applied to this traffic.
5274 *
5275 * Protocol | Value | Meaning
5276 * --------------------------------------------------------------------
5277 * None | 0 | No protocol-specific behaviour.
5278 * FTP | 21 | Parse FTP control connections and observe the
5279 * | | negotiation of related data connections.
5280 * Other | Other | Unsupported protocols.
5281 *
5282 * By way of example, if FTP control connections have this action applied
5283 * with the ALG set to FTP (21), then the connection tracker will observe
5284 * the negotiation of data connections. This allows the connection
5285 * tracker to identify subsequent data connections as "related" to this
5286 * existing connection. The "related" flag will be populated in the
5287 * NXM_NX_CT_STATE field for such connections if the 'recirc_table' is
5288 * specified.
5289 *
8e53fe8c
JS
5290 * Zero or more actions may immediately follow this action. These actions will
5291 * be executed within the context of the connection tracker, and they require
5292 * the NX_CT_F_COMMIT flag to be set.
07659514
JS
5293 */
5294struct nx_action_conntrack {
5295 ovs_be16 type; /* OFPAT_VENDOR. */
5296 ovs_be16 len; /* At least 24. */
5297 ovs_be32 vendor; /* NX_VENDOR_ID. */
5298 ovs_be16 subtype; /* NXAST_CT. */
5299 ovs_be16 flags; /* Zero or more NX_CT_F_* flags.
5300 * Unspecified flag bits must be zero. */
5301 ovs_be32 zone_src; /* Connection tracking context. */
5302 union {
5303 ovs_be16 zone_ofs_nbits;/* Range to use from source field. */
5304 ovs_be16 zone_imm; /* Immediate value for zone. */
5305 };
5306 uint8_t recirc_table; /* Recirculate to a specific table, or
5307 NX_CT_RECIRC_NONE for no recirculation. */
d787ad39
JS
5308 uint8_t pad[3]; /* Zeroes */
5309 ovs_be16 alg; /* Well-known port number for the protocol.
5310 * 0 indicates no ALG is required. */
07659514
JS
5311 /* Followed by a sequence of zero or more OpenFlow actions. The length of
5312 * these is included in 'len'. */
5313};
5314OFP_ASSERT(sizeof(struct nx_action_conntrack) == 24);
5315
5316static enum ofperr
5317decode_ct_zone(const struct nx_action_conntrack *nac,
04f48a68
YHW
5318 struct ofpact_conntrack *out,
5319 const struct vl_mff_map *vl_mff_map)
07659514
JS
5320{
5321 if (nac->zone_src) {
5322 enum ofperr error;
5323
04f48a68
YHW
5324 out->zone_src.field = mf_from_nxm_header(ntohl(nac->zone_src),
5325 vl_mff_map);
07659514
JS
5326 out->zone_src.ofs = nxm_decode_ofs(nac->zone_ofs_nbits);
5327 out->zone_src.n_bits = nxm_decode_n_bits(nac->zone_ofs_nbits);
04f48a68
YHW
5328 if (mf_vl_mff_invalid(out->zone_src.field, vl_mff_map)) {
5329 return OFPERR_NXFMFC_INVALID_TLV_FIELD;
5330 }
5331
07659514
JS
5332 error = mf_check_src(&out->zone_src, NULL);
5333 if (error) {
5334 return error;
5335 }
5336
5337 if (out->zone_src.n_bits != 16) {
5338 VLOG_WARN_RL(&rl, "zone n_bits %d not within valid range [16..16]",
5339 out->zone_src.n_bits);
5340 return OFPERR_OFPBAC_BAD_SET_LEN;
5341 }
5342 } else {
5343 out->zone_src.field = NULL;
5344 out->zone_imm = ntohs(nac->zone_imm);
5345 }
5346
5347 return 0;
5348}
5349
5350static enum ofperr
5351decode_NXAST_RAW_CT(const struct nx_action_conntrack *nac,
04f48a68
YHW
5352 enum ofp_version ofp_version,
5353 const struct vl_mff_map *vl_mff_map, struct ofpbuf *out)
07659514 5354{
8e53fe8c 5355 const size_t ct_offset = ofpacts_pull(out);
0a2869d5 5356 struct ofpact_conntrack *conntrack = ofpact_put_CT(out);
07659514 5357 conntrack->flags = ntohs(nac->flags);
0a2869d5 5358
04f48a68 5359 int error = decode_ct_zone(nac, conntrack, vl_mff_map);
07659514
JS
5360 if (error) {
5361 goto out;
5362 }
5363 conntrack->recirc_table = nac->recirc_table;
d787ad39 5364 conntrack->alg = ntohs(nac->alg);
07659514 5365
8e53fe8c
JS
5366 ofpbuf_pull(out, sizeof(*conntrack));
5367
0a2869d5
BP
5368 struct ofpbuf openflow = ofpbuf_const_initializer(
5369 nac + 1, ntohs(nac->len) - sizeof(*nac));
8e53fe8c
JS
5370 error = ofpacts_pull_openflow_actions__(&openflow, openflow.size,
5371 ofp_version,
5372 1u << OVSINST_OFPIT11_APPLY_ACTIONS,
04f48a68 5373 out, OFPACT_CT, vl_mff_map);
8e53fe8c
JS
5374 if (error) {
5375 goto out;
5376 }
5377
5378 conntrack = ofpbuf_push_uninit(out, sizeof(*conntrack));
5379 out->header = &conntrack->ofpact;
ce058104 5380 ofpact_finish_CT(out, &conntrack);
8e53fe8c
JS
5381
5382 if (conntrack->ofpact.len > sizeof(*conntrack)
5383 && !(conntrack->flags & NX_CT_F_COMMIT)) {
9ac0aada
JR
5384 const struct ofpact *a;
5385 size_t ofpacts_len = conntrack->ofpact.len - sizeof(*conntrack);
5386
5387 OFPACT_FOR_EACH (a, conntrack->actions, ofpacts_len) {
5388 if (a->type != OFPACT_NAT || ofpact_get_NAT(a)->flags
5389 || ofpact_get_NAT(a)->range_af != AF_UNSPEC) {
5390 VLOG_WARN_RL(&rl, "CT action requires commit flag if actions "
5391 "other than NAT without arguments are specified.");
5392 error = OFPERR_OFPBAC_BAD_ARGUMENT;
5393 goto out;
5394 }
5395 }
8e53fe8c
JS
5396 }
5397
07659514 5398out:
8e53fe8c 5399 ofpbuf_push_uninit(out, ct_offset);
07659514
JS
5400 return error;
5401}
5402
5403static void
5404encode_CT(const struct ofpact_conntrack *conntrack,
8e53fe8c 5405 enum ofp_version ofp_version, struct ofpbuf *out)
07659514
JS
5406{
5407 struct nx_action_conntrack *nac;
8e53fe8c
JS
5408 const size_t ofs = out->size;
5409 size_t len;
07659514
JS
5410
5411 nac = put_NXAST_CT(out);
5412 nac->flags = htons(conntrack->flags);
5413 if (conntrack->zone_src.field) {
04f48a68 5414 nac->zone_src = htonl(nxm_header_from_mff(conntrack->zone_src.field));
07659514
JS
5415 nac->zone_ofs_nbits = nxm_encode_ofs_nbits(conntrack->zone_src.ofs,
5416 conntrack->zone_src.n_bits);
5417 } else {
5418 nac->zone_src = htonl(0);
5419 nac->zone_imm = htons(conntrack->zone_imm);
5420 }
5421 nac->recirc_table = conntrack->recirc_table;
d787ad39 5422 nac->alg = htons(conntrack->alg);
8e53fe8c
JS
5423
5424 len = ofpacts_put_openflow_actions(conntrack->actions,
5425 ofpact_ct_get_action_len(conntrack),
5426 out, ofp_version);
5427 len += sizeof(*nac);
5428 nac = ofpbuf_at(out, ofs, sizeof(*nac));
5429 nac->len = htons(len);
07659514
JS
5430}
5431
9ac0aada
JR
5432static char * OVS_WARN_UNUSED_RESULT parse_NAT(char *arg, struct ofpbuf *,
5433 enum ofputil_protocol * OVS_UNUSED);
5434
07659514
JS
5435/* Parses 'arg' as the argument to a "ct" action, and appends such an
5436 * action to 'ofpacts'.
5437 *
5438 * Returns NULL if successful, otherwise a malloc()'d string describing the
5439 * error. The caller is responsible for freeing the returned string. */
5440static char * OVS_WARN_UNUSED_RESULT
5441parse_CT(char *arg, struct ofpbuf *ofpacts,
8e53fe8c 5442 enum ofputil_protocol *usable_protocols)
07659514 5443{
8e53fe8c 5444 const size_t ct_offset = ofpacts_pull(ofpacts);
07659514
JS
5445 struct ofpact_conntrack *oc;
5446 char *error = NULL;
5447 char *key, *value;
5448
5449 oc = ofpact_put_CT(ofpacts);
5450 oc->flags = 0;
5451 oc->recirc_table = NX_CT_RECIRC_NONE;
5452 while (ofputil_parse_key_value(&arg, &key, &value)) {
5453 if (!strcmp(key, "commit")) {
5454 oc->flags |= NX_CT_F_COMMIT;
5455 } else if (!strcmp(key, "table")) {
5456 error = str_to_u8(value, "recirc_table", &oc->recirc_table);
5457 if (!error && oc->recirc_table == NX_CT_RECIRC_NONE) {
5458 error = xasprintf("invalid table %#"PRIx16, oc->recirc_table);
5459 }
5460 } else if (!strcmp(key, "zone")) {
5461 error = str_to_u16(value, "zone", &oc->zone_imm);
5462
5463 if (error) {
5464 free(error);
5465 error = mf_parse_subfield(&oc->zone_src, value);
5466 if (error) {
5467 return error;
5468 }
5469 }
d787ad39
JS
5470 } else if (!strcmp(key, "alg")) {
5471 error = str_to_connhelper(value, &oc->alg);
9ac0aada
JR
5472 } else if (!strcmp(key, "nat")) {
5473 const size_t nat_offset = ofpacts_pull(ofpacts);
5474
5475 error = parse_NAT(value, ofpacts, usable_protocols);
9ac0aada
JR
5476 /* Update CT action pointer and length. */
5477 ofpacts->header = ofpbuf_push_uninit(ofpacts, nat_offset);
5478 oc = ofpacts->header;
8e53fe8c
JS
5479 } else if (!strcmp(key, "exec")) {
5480 /* Hide existing actions from ofpacts_parse_copy(), so the
5481 * nesting can be handled transparently. */
76e3e669 5482 enum ofputil_protocol usable_protocols2;
9ac0aada 5483 const size_t exec_offset = ofpacts_pull(ofpacts);
76e3e669 5484
76e3e669
JR
5485 /* Initializes 'usable_protocol2', fold it back to
5486 * '*usable_protocols' afterwards, so that we do not lose
5487 * restrictions already in there. */
5488 error = ofpacts_parse_copy(value, ofpacts, &usable_protocols2,
5489 false, OFPACT_CT);
5490 *usable_protocols &= usable_protocols2;
9ac0aada 5491 ofpacts->header = ofpbuf_push_uninit(ofpacts, exec_offset);
8e53fe8c 5492 oc = ofpacts->header;
07659514
JS
5493 } else {
5494 error = xasprintf("invalid argument to \"ct\" action: `%s'", key);
5495 }
5496 if (error) {
5497 break;
5498 }
5499 }
5500
ce058104 5501 ofpact_finish_CT(ofpacts, &oc);
8e53fe8c 5502 ofpbuf_push_uninit(ofpacts, ct_offset);
07659514
JS
5503 return error;
5504}
5505
d787ad39
JS
5506static void
5507format_alg(int port, struct ds *s)
5508{
40c7b2fc
JS
5509 switch(port) {
5510 case IPPORT_FTP:
b1c5bf1f 5511 ds_put_format(s, "%salg=%sftp,", colors.param, colors.end);
40c7b2fc
JS
5512 break;
5513 case IPPORT_TFTP:
5514 ds_put_format(s, "%salg=%stftp,", colors.param, colors.end);
5515 break;
5516 case 0:
5517 /* Don't print. */
5518 break;
5519 default:
b1c5bf1f 5520 ds_put_format(s, "%salg=%s%d,", colors.param, colors.end, port);
40c7b2fc 5521 break;
d787ad39
JS
5522 }
5523}
5524
9ac0aada
JR
5525static void format_NAT(const struct ofpact_nat *a, struct ds *ds);
5526
07659514
JS
5527static void
5528format_CT(const struct ofpact_conntrack *a, struct ds *s)
5529{
b1c5bf1f 5530 ds_put_format(s, "%sct(%s", colors.paren, colors.end);
07659514 5531 if (a->flags & NX_CT_F_COMMIT) {
b1c5bf1f 5532 ds_put_format(s, "%scommit%s,", colors.value, colors.end);
07659514
JS
5533 }
5534 if (a->recirc_table != NX_CT_RECIRC_NONE) {
b1c5bf1f
QM
5535 ds_put_format(s, "%stable=%s%"PRIu8",",
5536 colors.special, colors.end, a->recirc_table);
07659514
JS
5537 }
5538 if (a->zone_src.field) {
b1c5bf1f 5539 ds_put_format(s, "%szone=%s", colors.param, colors.end);
07659514
JS
5540 mf_format_subfield(&a->zone_src, s);
5541 ds_put_char(s, ',');
5542 } else if (a->zone_imm) {
b1c5bf1f
QM
5543 ds_put_format(s, "%szone=%s%"PRIu16",",
5544 colors.param, colors.end, a->zone_imm);
07659514 5545 }
9ac0aada
JR
5546 /* If the first action is a NAT action, format it outside of the 'exec'
5547 * envelope. */
5548 const struct ofpact *action = a->actions;
5549 size_t actions_len = ofpact_ct_get_action_len(a);
5550 if (actions_len && action->type == OFPACT_NAT) {
5551 format_NAT(ofpact_get_NAT(action), s);
5552 ds_put_char(s, ',');
5553 actions_len -= OFPACT_ALIGN(action->len);
5554 action = ofpact_next(action);
5555 }
5556 if (actions_len) {
b1c5bf1f 5557 ds_put_format(s, "%sexec(%s", colors.paren, colors.end);
9ac0aada 5558 ofpacts_format(action, actions_len, s);
b1c5bf1f 5559 ds_put_format(s, "%s),%s", colors.paren, colors.end);
8e53fe8c 5560 }
d787ad39 5561 format_alg(a->alg, s);
07659514 5562 ds_chomp(s, ',');
b1c5bf1f 5563 ds_put_format(s, "%s)%s", colors.paren, colors.end);
07659514 5564}
9ac0aada 5565\f
72fe7578
BP
5566/* ct_clear action. */
5567
5568static enum ofperr
5569decode_NXAST_RAW_CT_CLEAR(struct ofpbuf *out)
5570{
5571 ofpact_put_CT_CLEAR(out);
5572 return 0;
5573}
5574
5575static void
5576encode_CT_CLEAR(const struct ofpact_null *null OVS_UNUSED,
5577 enum ofp_version ofp_version OVS_UNUSED,
5578 struct ofpbuf *out)
5579{
5580 put_NXAST_CT_CLEAR(out);
5581}
5582
5583static char * OVS_WARN_UNUSED_RESULT
5584parse_CT_CLEAR(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
5585 enum ofputil_protocol *usable_protocols OVS_UNUSED)
5586{
5587 ofpact_put_CT_CLEAR(ofpacts);
5588 return NULL;
5589}
5590
5591static void
5592format_CT_CLEAR(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
5593{
5594 ds_put_format(s, "%sct_clear%s", colors.value, colors.end);
5595}\f
9ac0aada
JR
5596/* NAT action. */
5597
5598/* Which optional fields are present? */
5599enum nx_nat_range {
5600 NX_NAT_RANGE_IPV4_MIN = 1 << 0, /* ovs_be32 */
5601 NX_NAT_RANGE_IPV4_MAX = 1 << 1, /* ovs_be32 */
5602 NX_NAT_RANGE_IPV6_MIN = 1 << 2, /* struct in6_addr */
5603 NX_NAT_RANGE_IPV6_MAX = 1 << 3, /* struct in6_addr */
5604 NX_NAT_RANGE_PROTO_MIN = 1 << 4, /* ovs_be16 */
5605 NX_NAT_RANGE_PROTO_MAX = 1 << 5, /* ovs_be16 */
5606};
5607
5608/* Action structure for NXAST_NAT. */
5609struct nx_action_nat {
5610 ovs_be16 type; /* OFPAT_VENDOR. */
5611 ovs_be16 len; /* At least 16. */
5612 ovs_be32 vendor; /* NX_VENDOR_ID. */
5613 ovs_be16 subtype; /* NXAST_NAT. */
5614 uint8_t pad[2]; /* Must be zero. */
5615 ovs_be16 flags; /* Zero or more NX_NAT_F_* flags.
5616 * Unspecified flag bits must be zero. */
5617 ovs_be16 range_present; /* NX_NAT_RANGE_* */
5618 /* Followed by optional parameters as specified by 'range_present' */
5619};
5620OFP_ASSERT(sizeof(struct nx_action_nat) == 16);
5621
5622static void
5623encode_NAT(const struct ofpact_nat *nat,
5624 enum ofp_version ofp_version OVS_UNUSED,
5625 struct ofpbuf *out)
5626{
5627 struct nx_action_nat *nan;
5628 const size_t ofs = out->size;
5629 uint16_t range_present = 0;
5630
5631 nan = put_NXAST_NAT(out);
5632 nan->flags = htons(nat->flags);
5633 if (nat->range_af == AF_INET) {
5634 if (nat->range.addr.ipv4.min) {
5635 ovs_be32 *min = ofpbuf_put_uninit(out, sizeof *min);
5636 *min = nat->range.addr.ipv4.min;
5637 range_present |= NX_NAT_RANGE_IPV4_MIN;
5638 }
5639 if (nat->range.addr.ipv4.max) {
5640 ovs_be32 *max = ofpbuf_put_uninit(out, sizeof *max);
5641 *max = nat->range.addr.ipv4.max;
5642 range_present |= NX_NAT_RANGE_IPV4_MAX;
5643 }
5644 } else if (nat->range_af == AF_INET6) {
5645 if (!ipv6_mask_is_any(&nat->range.addr.ipv6.min)) {
5646 struct in6_addr *min = ofpbuf_put_uninit(out, sizeof *min);
5647 *min = nat->range.addr.ipv6.min;
5648 range_present |= NX_NAT_RANGE_IPV6_MIN;
5649 }
5650 if (!ipv6_mask_is_any(&nat->range.addr.ipv6.max)) {
5651 struct in6_addr *max = ofpbuf_put_uninit(out, sizeof *max);
5652 *max = nat->range.addr.ipv6.max;
5653 range_present |= NX_NAT_RANGE_IPV6_MAX;
5654 }
5655 }
5656 if (nat->range_af != AF_UNSPEC) {
5657 if (nat->range.proto.min) {
5658 ovs_be16 *min = ofpbuf_put_uninit(out, sizeof *min);
5659 *min = htons(nat->range.proto.min);
5660 range_present |= NX_NAT_RANGE_PROTO_MIN;
5661 }
5662 if (nat->range.proto.max) {
5663 ovs_be16 *max = ofpbuf_put_uninit(out, sizeof *max);
5664 *max = htons(nat->range.proto.max);
5665 range_present |= NX_NAT_RANGE_PROTO_MAX;
5666 }
5667 }
5668 pad_ofpat(out, ofs);
5669 nan = ofpbuf_at(out, ofs, sizeof *nan);
5670 nan->range_present = htons(range_present);
5671}
5672
5673static enum ofperr
5674decode_NXAST_RAW_NAT(const struct nx_action_nat *nan,
5675 enum ofp_version ofp_version OVS_UNUSED,
5676 struct ofpbuf *out)
5677{
5678 struct ofpact_nat *nat;
5679 uint16_t range_present = ntohs(nan->range_present);
5680 const char *opts = (char *)(nan + 1);
5681 uint16_t len = ntohs(nan->len) - sizeof *nan;
5682
5683 nat = ofpact_put_NAT(out);
5684 nat->flags = ntohs(nan->flags);
5685
ae8b9260
JR
5686 /* Check for unknown or mutually exclusive flags. */
5687 if ((nat->flags & ~NX_NAT_F_MASK)
5688 || (nat->flags & NX_NAT_F_SRC && nat->flags & NX_NAT_F_DST)
5689 || (nat->flags & NX_NAT_F_PROTO_HASH
5690 && nat->flags & NX_NAT_F_PROTO_RANDOM)) {
5691 return OFPERR_OFPBAC_BAD_ARGUMENT;
5692 }
5693
9ac0aada
JR
5694#define NX_NAT_GET_OPT(DST, SRC, LEN, TYPE) \
5695 (LEN >= sizeof(TYPE) \
5696 ? (memcpy(DST, SRC, sizeof(TYPE)), LEN -= sizeof(TYPE), \
5697 SRC += sizeof(TYPE)) \
5698 : NULL)
5699
5700 nat->range_af = AF_UNSPEC;
5701 if (range_present & NX_NAT_RANGE_IPV4_MIN) {
5702 if (range_present & (NX_NAT_RANGE_IPV6_MIN | NX_NAT_RANGE_IPV6_MAX)) {
5703 return OFPERR_OFPBAC_BAD_ARGUMENT;
5704 }
5705
5706 if (!NX_NAT_GET_OPT(&nat->range.addr.ipv4.min, opts, len, ovs_be32)
5707 || !nat->range.addr.ipv4.min) {
5708 return OFPERR_OFPBAC_BAD_ARGUMENT;
5709 }
5710
5711 nat->range_af = AF_INET;
5712
5713 if (range_present & NX_NAT_RANGE_IPV4_MAX) {
5714 if (!NX_NAT_GET_OPT(&nat->range.addr.ipv4.max, opts, len,
5715 ovs_be32)) {
5716 return OFPERR_OFPBAC_BAD_ARGUMENT;
5717 }
5718 if (ntohl(nat->range.addr.ipv4.max)
5719 < ntohl(nat->range.addr.ipv4.min)) {
5720 return OFPERR_OFPBAC_BAD_ARGUMENT;
5721 }
5722 }
5723 } else if (range_present & NX_NAT_RANGE_IPV4_MAX) {
5724 return OFPERR_OFPBAC_BAD_ARGUMENT;
5725 } else if (range_present & NX_NAT_RANGE_IPV6_MIN) {
5726 if (!NX_NAT_GET_OPT(&nat->range.addr.ipv6.min, opts, len,
5727 struct in6_addr)
5728 || ipv6_mask_is_any(&nat->range.addr.ipv6.min)) {
5729 return OFPERR_OFPBAC_BAD_ARGUMENT;
5730 }
5731
5732 nat->range_af = AF_INET6;
5733
5734 if (range_present & NX_NAT_RANGE_IPV6_MAX) {
5735 if (!NX_NAT_GET_OPT(&nat->range.addr.ipv6.max, opts, len,
5736 struct in6_addr)) {
5737 return OFPERR_OFPBAC_BAD_ARGUMENT;
5738 }
5739 if (memcmp(&nat->range.addr.ipv6.max, &nat->range.addr.ipv6.min,
5740 sizeof(struct in6_addr)) < 0) {
5741 return OFPERR_OFPBAC_BAD_ARGUMENT;
5742 }
5743 }
5744 } else if (range_present & NX_NAT_RANGE_IPV6_MAX) {
5745 return OFPERR_OFPBAC_BAD_ARGUMENT;
5746 }
5747
5748 if (range_present & NX_NAT_RANGE_PROTO_MIN) {
5749 ovs_be16 proto;
5750
5751 if (nat->range_af == AF_UNSPEC) {
5752 return OFPERR_OFPBAC_BAD_ARGUMENT;
5753 }
5754 if (!NX_NAT_GET_OPT(&proto, opts, len, ovs_be16) || proto == 0) {
5755 return OFPERR_OFPBAC_BAD_ARGUMENT;
5756 }
5757 nat->range.proto.min = ntohs(proto);
5758 if (range_present & NX_NAT_RANGE_PROTO_MAX) {
5759 if (!NX_NAT_GET_OPT(&proto, opts, len, ovs_be16)) {
5760 return OFPERR_OFPBAC_BAD_ARGUMENT;
5761 }
5762 nat->range.proto.max = ntohs(proto);
5763 if (nat->range.proto.max < nat->range.proto.min) {
5764 return OFPERR_OFPBAC_BAD_ARGUMENT;
5765 }
5766 }
5767 } else if (range_present & NX_NAT_RANGE_PROTO_MAX) {
5768 return OFPERR_OFPBAC_BAD_ARGUMENT;
5769 }
5770
5771 return 0;
5772}
5773
5774static void
5775format_NAT(const struct ofpact_nat *a, struct ds *ds)
5776{
b1c5bf1f 5777 ds_put_format(ds, "%snat%s", colors.paren, colors.end);
9ac0aada
JR
5778
5779 if (a->flags & (NX_NAT_F_SRC | NX_NAT_F_DST)) {
b1c5bf1f
QM
5780 ds_put_format(ds, "%s(%s", colors.paren, colors.end);
5781 ds_put_format(ds, a->flags & NX_NAT_F_SRC ? "%ssrc%s" : "%sdst%s",
5782 colors.param, colors.end);
9ac0aada
JR
5783
5784 if (a->range_af != AF_UNSPEC) {
b1c5bf1f 5785 ds_put_format(ds, "%s=%s", colors.param, colors.end);
9ac0aada
JR
5786
5787 if (a->range_af == AF_INET) {
5788 ds_put_format(ds, IP_FMT, IP_ARGS(a->range.addr.ipv4.min));
5789
5790 if (a->range.addr.ipv4.max
5791 && a->range.addr.ipv4.max != a->range.addr.ipv4.min) {
5792 ds_put_format(ds, "-"IP_FMT,
5793 IP_ARGS(a->range.addr.ipv4.max));
5794 }
5795 } else if (a->range_af == AF_INET6) {
5796 ipv6_format_addr_bracket(&a->range.addr.ipv6.min, ds,
5797 a->range.proto.min);
5798
5799 if (!ipv6_mask_is_any(&a->range.addr.ipv6.max)
5800 && memcmp(&a->range.addr.ipv6.max, &a->range.addr.ipv6.min,
5801 sizeof(struct in6_addr)) != 0) {
5802 ds_put_char(ds, '-');
5803 ipv6_format_addr_bracket(&a->range.addr.ipv6.max, ds,
5804 a->range.proto.min);
5805 }
5806 }
5807 if (a->range.proto.min) {
5808 ds_put_char(ds, ':');
5809 ds_put_format(ds, "%"PRIu16, a->range.proto.min);
5810
5811 if (a->range.proto.max
5812 && a->range.proto.max != a->range.proto.min) {
5813 ds_put_format(ds, "-%"PRIu16, a->range.proto.max);
5814 }
5815 }
5816 ds_put_char(ds, ',');
5817
5818 if (a->flags & NX_NAT_F_PERSISTENT) {
b1c5bf1f
QM
5819 ds_put_format(ds, "%spersistent%s,",
5820 colors.value, colors.end);
9ac0aada
JR
5821 }
5822 if (a->flags & NX_NAT_F_PROTO_HASH) {
b1c5bf1f 5823 ds_put_format(ds, "%shash%s,", colors.value, colors.end);
9ac0aada
JR
5824 }
5825 if (a->flags & NX_NAT_F_PROTO_RANDOM) {
b1c5bf1f 5826 ds_put_format(ds, "%srandom%s,", colors.value, colors.end);
9ac0aada
JR
5827 }
5828 }
5829 ds_chomp(ds, ',');
b1c5bf1f 5830 ds_put_format(ds, "%s)%s", colors.paren, colors.end);
9ac0aada
JR
5831 }
5832}
5833
5834static char * OVS_WARN_UNUSED_RESULT
5835str_to_nat_range(const char *s, struct ofpact_nat *on)
5836{
5837 char ipv6_s[IPV6_SCAN_LEN + 1];
5838 int n = 0;
5839
5840 on->range_af = AF_UNSPEC;
5841 if (ovs_scan_len(s, &n, IP_SCAN_FMT,
5842 IP_SCAN_ARGS(&on->range.addr.ipv4.min))) {
5843 on->range_af = AF_INET;
5844
5845 if (s[n] == '-') {
5846 n++;
5847 if (!ovs_scan_len(s, &n, IP_SCAN_FMT,
5848 IP_SCAN_ARGS(&on->range.addr.ipv4.max))
5849 || (ntohl(on->range.addr.ipv4.max)
5850 < ntohl(on->range.addr.ipv4.min))) {
5851 goto error;
5852 }
5853 }
5854 } else if ((ovs_scan_len(s, &n, IPV6_SCAN_FMT, ipv6_s)
5855 || ovs_scan_len(s, &n, "["IPV6_SCAN_FMT"]", ipv6_s))
5856 && inet_pton(AF_INET6, ipv6_s, &on->range.addr.ipv6.min) == 1) {
5857 on->range_af = AF_INET6;
5858
5859 if (s[n] == '-') {
5860 n++;
5861 if (!(ovs_scan_len(s, &n, IPV6_SCAN_FMT, ipv6_s)
5862 || ovs_scan_len(s, &n, "["IPV6_SCAN_FMT"]", ipv6_s))
5863 || inet_pton(AF_INET6, ipv6_s, &on->range.addr.ipv6.max) != 1
5864 || memcmp(&on->range.addr.ipv6.max, &on->range.addr.ipv6.min,
5865 sizeof on->range.addr.ipv6.max) < 0) {
5866 goto error;
5867 }
5868 }
5869 }
5870 if (on->range_af != AF_UNSPEC && s[n] == ':') {
5871 n++;
5872 if (!ovs_scan_len(s, &n, "%"SCNu16, &on->range.proto.min)) {
5873 goto error;
5874 }
5875 if (s[n] == '-') {
5876 n++;
5877 if (!ovs_scan_len(s, &n, "%"SCNu16, &on->range.proto.max)
5878 || on->range.proto.max < on->range.proto.min) {
5879 goto error;
5880 }
5881 }
5882 }
5883 if (strlen(s) != n) {
5884 return xasprintf("garbage (%s) after nat range \"%s\" (pos: %d)",
5885 &s[n], s, n);
5886 }
5887 return NULL;
5888error:
5889 return xasprintf("invalid nat range \"%s\"", s);
5890}
5891
5892
5893/* Parses 'arg' as the argument to a "nat" action, and appends such an
5894 * action to 'ofpacts'.
5895 *
5896 * Returns NULL if successful, otherwise a malloc()'d string describing the
5897 * error. The caller is responsible for freeing the returned string. */
5898static char * OVS_WARN_UNUSED_RESULT
5899parse_NAT(char *arg, struct ofpbuf *ofpacts,
5900 enum ofputil_protocol *usable_protocols OVS_UNUSED)
5901{
5902 struct ofpact_nat *on = ofpact_put_NAT(ofpacts);
5903 char *key, *value;
5904
5905 on->flags = 0;
5906 on->range_af = AF_UNSPEC;
5907
5908 while (ofputil_parse_key_value(&arg, &key, &value)) {
5909 char *error = NULL;
5910
5911 if (!strcmp(key, "src")) {
5912 on->flags |= NX_NAT_F_SRC;
5913 error = str_to_nat_range(value, on);
5914 } else if (!strcmp(key, "dst")) {
5915 on->flags |= NX_NAT_F_DST;
5916 error = str_to_nat_range(value, on);
5917 } else if (!strcmp(key, "persistent")) {
5918 on->flags |= NX_NAT_F_PERSISTENT;
5919 } else if (!strcmp(key, "hash")) {
5920 on->flags |= NX_NAT_F_PROTO_HASH;
5921 } else if (!strcmp(key, "random")) {
5922 on->flags |= NX_NAT_F_PROTO_RANDOM;
5923 } else {
5924 error = xasprintf("invalid key \"%s\" in \"nat\" argument",
5925 key);
5926 }
5927 if (error) {
5928 return error;
5929 }
5930 }
5931 if (on->flags & NX_NAT_F_SRC && on->flags & NX_NAT_F_DST) {
ae8b9260 5932 return xasprintf("May only specify one of \"src\" or \"dst\".");
9ac0aada
JR
5933 }
5934 if (!(on->flags & NX_NAT_F_SRC || on->flags & NX_NAT_F_DST)) {
5935 if (on->flags) {
ae8b9260 5936 return xasprintf("Flags allowed only with \"src\" or \"dst\".");
9ac0aada
JR
5937 }
5938 if (on->range_af != AF_UNSPEC) {
ae8b9260 5939 return xasprintf("Range allowed only with \"src\" or \"dst\".");
9ac0aada
JR
5940 }
5941 }
ae8b9260
JR
5942 if (on->flags & NX_NAT_F_PROTO_HASH && on->flags & NX_NAT_F_PROTO_RANDOM) {
5943 return xasprintf("Both \"hash\" and \"random\" are not allowed.");
5944 }
5945
9ac0aada
JR
5946 return NULL;
5947}
5948
aaca4fe0
WT
5949/* Truncate output action. */
5950struct nx_action_output_trunc {
5951 ovs_be16 type; /* OFPAT_VENDOR. */
5952 ovs_be16 len; /* At least 16. */
5953 ovs_be32 vendor; /* NX_VENDOR_ID. */
5954 ovs_be16 subtype; /* NXAST_OUTPUT_TRUNC. */
5955 ovs_be16 port; /* Output port */
5956 ovs_be32 max_len; /* Truncate packet to size bytes */
5957};
5958OFP_ASSERT(sizeof(struct nx_action_output_trunc) == 16);
5959
5960static enum ofperr
5961decode_NXAST_RAW_OUTPUT_TRUNC(const struct nx_action_output_trunc *natrc,
5962 enum ofp_version ofp_version OVS_UNUSED,
5963 struct ofpbuf *out)
5964{
5965 struct ofpact_output_trunc *output_trunc;
5966
5967 output_trunc = ofpact_put_OUTPUT_TRUNC(out);
5968 output_trunc->max_len = ntohl(natrc->max_len);
5969 output_trunc->port = u16_to_ofp(ntohs(natrc->port));
5970
5971 if (output_trunc->max_len < ETH_HEADER_LEN) {
5972 return OFPERR_OFPBAC_BAD_ARGUMENT;
5973 }
5974 return 0;
5975}
5976
5977static void
5978encode_OUTPUT_TRUNC(const struct ofpact_output_trunc *output_trunc,
5979 enum ofp_version ofp_version OVS_UNUSED,
5980 struct ofpbuf *out)
5981{
5982 struct nx_action_output_trunc *natrc = put_NXAST_OUTPUT_TRUNC(out);
5983
5984 natrc->max_len = htonl(output_trunc->max_len);
5985 natrc->port = htons(ofp_to_u16(output_trunc->port));
5986}
5987
5988static char * OVS_WARN_UNUSED_RESULT
5989parse_OUTPUT_TRUNC(const char *arg, struct ofpbuf *ofpacts OVS_UNUSED,
5990 enum ofputil_protocol *usable_protocols OVS_UNUSED)
5991{
5992 /* Disable output_trunc parsing. Expose as output(port=N,max_len=M) and
5993 * reuse parse_OUTPUT to parse output_trunc action. */
5994 return xasprintf("unknown action %s", arg);
5995}
5996
5997static void
5998format_OUTPUT_TRUNC(const struct ofpact_output_trunc *a, struct ds *s)
5999{
94783c7c 6000 ds_put_format(s, "%soutput%s(port=%"PRIu32",max_len=%"PRIu32")",
aaca4fe0
WT
6001 colors.special, colors.end, a->port, a->max_len);
6002}
6003
d4abaff5 6004\f
c2d936a4
BP
6005/* Meter instruction. */
6006
6007static void
6008encode_METER(const struct ofpact_meter *meter,
6009 enum ofp_version ofp_version, struct ofpbuf *out)
6010{
6011 if (ofp_version >= OFP13_VERSION) {
6012 instruction_put_OFPIT13_METER(out)->meter_id = htonl(meter->meter_id);
6013 }
6014}
6015
cab50449 6016static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
6017parse_METER(char *arg, struct ofpbuf *ofpacts,
6018 enum ofputil_protocol *usable_protocols)
6019{
6020 *usable_protocols &= OFPUTIL_P_OF13_UP;
6021 return str_to_u32(arg, &ofpact_put_METER(ofpacts)->meter_id);
6022}
6023
6024static void
6025format_METER(const struct ofpact_meter *a, struct ds *s)
6026{
b1c5bf1f
QM
6027 ds_put_format(s, "%smeter:%s%"PRIu32,
6028 colors.param, colors.end, a->meter_id);
c2d936a4
BP
6029}
6030\f
6031/* Clear-Actions instruction. */
6032
6033static void
6034encode_CLEAR_ACTIONS(const struct ofpact_null *null OVS_UNUSED,
6035 enum ofp_version ofp_version OVS_UNUSED,
6036 struct ofpbuf *out OVS_UNUSED)
6037{
6038 if (ofp_version > OFP10_VERSION) {
6039 instruction_put_OFPIT11_CLEAR_ACTIONS(out);
6040 }
6041}
6042
cab50449 6043static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
6044parse_CLEAR_ACTIONS(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
6045 enum ofputil_protocol *usable_protocols OVS_UNUSED)
6046{
6047 ofpact_put_CLEAR_ACTIONS(ofpacts);
6048 return NULL;
6049}
6050
6051static void
6052format_CLEAR_ACTIONS(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
6053{
b1c5bf1f 6054 ds_put_format(s, "%sclear_actions%s", colors.value, colors.end);
c2d936a4
BP
6055}
6056\f
6057/* Write-Actions instruction. */
6058
6059static void
6060encode_WRITE_ACTIONS(const struct ofpact_nest *actions,
6061 enum ofp_version ofp_version, struct ofpbuf *out)
6062{
6063 if (ofp_version > OFP10_VERSION) {
6fd6ed71 6064 const size_t ofs = out->size;
c2d936a4
BP
6065
6066 instruction_put_OFPIT11_WRITE_ACTIONS(out);
6067 ofpacts_put_openflow_actions(actions->actions,
6068 ofpact_nest_get_action_len(actions),
6069 out, ofp_version);
6070 ofpacts_update_instruction_actions(out, ofs);
6071 }
6072}
6073
cab50449 6074static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
6075parse_WRITE_ACTIONS(char *arg, struct ofpbuf *ofpacts,
6076 enum ofputil_protocol *usable_protocols)
6077{
d824b5b7 6078 size_t ofs = ofpacts_pull(ofpacts);
c2d936a4
BP
6079 struct ofpact_nest *on;
6080 char *error;
c2d936a4
BP
6081
6082 /* Add a Write-Actions instruction and then pull it off. */
6083 ofpact_put(ofpacts, OFPACT_WRITE_ACTIONS, sizeof *on);
6084 ofpbuf_pull(ofpacts, sizeof *on);
6085
6086 /* Parse nested actions.
6087 *
6088 * We pulled off "write-actions" and the previous actions because the
6089 * OFPACT_WRITE_ACTIONS is only partially constructed: its length is such
6090 * that it doesn't actually include the nested actions. That means that
6091 * ofpacts_parse() would reject them as being part of an Apply-Actions that
6092 * follows a Write-Actions, which is an invalid order. */
d824b5b7
JS
6093 error = ofpacts_parse(arg, ofpacts, usable_protocols, false,
6094 OFPACT_WRITE_ACTIONS);
c2d936a4
BP
6095
6096 /* Put the Write-Actions back on and update its length. */
6097 on = ofpbuf_push_uninit(ofpacts, sizeof *on);
6fd6ed71 6098 on->ofpact.len = ofpacts->size;
c2d936a4
BP
6099
6100 /* Put any previous actions or instructions back on. */
6101 ofpbuf_push_uninit(ofpacts, ofs);
6102
6103 return error;
6104}
6105
6106static void
6107format_WRITE_ACTIONS(const struct ofpact_nest *a, struct ds *s)
6108{
b1c5bf1f 6109 ds_put_format(s, "%swrite_actions(%s", colors.paren, colors.end);
c2d936a4 6110 ofpacts_format(a->actions, ofpact_nest_get_action_len(a), s);
b1c5bf1f 6111 ds_put_format(s, "%s)%s", colors.paren, colors.end);
c2d936a4
BP
6112}
6113\f
6114/* Action structure for NXAST_WRITE_METADATA.
6115 *
6116 * Modifies the 'mask' bits of the metadata value. */
6117struct nx_action_write_metadata {
6118 ovs_be16 type; /* OFPAT_VENDOR. */
6119 ovs_be16 len; /* Length is 32. */
6120 ovs_be32 vendor; /* NX_VENDOR_ID. */
6121 ovs_be16 subtype; /* NXAST_WRITE_METADATA. */
6122 uint8_t zeros[6]; /* Must be zero. */
6123 ovs_be64 metadata; /* Metadata register. */
6124 ovs_be64 mask; /* Metadata mask. */
6125};
6126OFP_ASSERT(sizeof(struct nx_action_write_metadata) == 32);
6127
6128static enum ofperr
6129decode_NXAST_RAW_WRITE_METADATA(const struct nx_action_write_metadata *nawm,
f3cd3ac7 6130 enum ofp_version ofp_version OVS_UNUSED,
c2d936a4
BP
6131 struct ofpbuf *out)
6132{
6133 struct ofpact_metadata *om;
6134
6135 if (!is_all_zeros(nawm->zeros, sizeof nawm->zeros)) {
6136 return OFPERR_NXBRC_MUST_BE_ZERO;
6137 }
6138
6139 om = ofpact_put_WRITE_METADATA(out);
6140 om->metadata = nawm->metadata;
6141 om->mask = nawm->mask;
6142
6143 return 0;
6144}
6145
6146static void
6147encode_WRITE_METADATA(const struct ofpact_metadata *metadata,
6148 enum ofp_version ofp_version, struct ofpbuf *out)
6149{
6150 if (ofp_version == OFP10_VERSION) {
6151 struct nx_action_write_metadata *nawm;
6152
6153 nawm = put_NXAST_WRITE_METADATA(out);
6154 nawm->metadata = metadata->metadata;
6155 nawm->mask = metadata->mask;
6156 } else {
6157 struct ofp11_instruction_write_metadata *oiwm;
6158
6159 oiwm = instruction_put_OFPIT11_WRITE_METADATA(out);
6160 oiwm->metadata = metadata->metadata;
6161 oiwm->metadata_mask = metadata->mask;
6162 }
6163}
6164
cab50449 6165static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
6166parse_WRITE_METADATA(char *arg, struct ofpbuf *ofpacts,
6167 enum ofputil_protocol *usable_protocols)
6168{
6169 struct ofpact_metadata *om;
6170 char *mask = strchr(arg, '/');
6171
6172 *usable_protocols &= OFPUTIL_P_NXM_OF11_UP;
6173
6174 om = ofpact_put_WRITE_METADATA(ofpacts);
6175 if (mask) {
6176 char *error;
6177
6178 *mask = '\0';
6179 error = str_to_be64(mask + 1, &om->mask);
6180 if (error) {
6181 return error;
6182 }
6183 } else {
6184 om->mask = OVS_BE64_MAX;
6185 }
6186
6187 return str_to_be64(arg, &om->metadata);
6188}
6189
6190static void
6191format_WRITE_METADATA(const struct ofpact_metadata *a, struct ds *s)
6192{
b1c5bf1f
QM
6193 ds_put_format(s, "%swrite_metadata:%s%#"PRIx64,
6194 colors.param, colors.end, ntohll(a->metadata));
c2d936a4
BP
6195 if (a->mask != OVS_BE64_MAX) {
6196 ds_put_format(s, "/%#"PRIx64, ntohll(a->mask));
6197 }
4cceacb9 6198}
f25d0cf3 6199\f
c2d936a4 6200/* Goto-Table instruction. */
f25d0cf3
BP
6201
6202static void
c2d936a4
BP
6203encode_GOTO_TABLE(const struct ofpact_goto_table *goto_table,
6204 enum ofp_version ofp_version, struct ofpbuf *out)
f25d0cf3 6205{
c2d936a4
BP
6206 if (ofp_version == OFP10_VERSION) {
6207 struct nx_action_resubmit *nar;
f25d0cf3 6208
c2d936a4
BP
6209 nar = put_NXAST_RESUBMIT_TABLE(out);
6210 nar->table = goto_table->table_id;
6211 nar->in_port = htons(ofp_to_u16(OFPP_IN_PORT));
6212 } else {
6213 struct ofp11_instruction_goto_table *oigt;
6214
6215 oigt = instruction_put_OFPIT11_GOTO_TABLE(out);
6216 oigt->table_id = goto_table->table_id;
6217 memset(oigt->pad, 0, sizeof oigt->pad);
6218 }
6219}
6220
cab50449 6221static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
6222parse_GOTO_TABLE(char *arg, struct ofpbuf *ofpacts,
6223 enum ofputil_protocol *usable_protocols OVS_UNUSED)
6224{
6225 struct ofpact_goto_table *ogt = ofpact_put_GOTO_TABLE(ofpacts);
6226 char *table_s = strsep(&arg, ",");
6227 if (!table_s || !table_s[0]) {
6228 return xstrdup("instruction goto-table needs table id");
6229 }
6230 return str_to_u8(table_s, "table", &ogt->table_id);
6231}
6232
6233static void
6234format_GOTO_TABLE(const struct ofpact_goto_table *a, struct ds *s)
6235{
b1c5bf1f
QM
6236 ds_put_format(s, "%sgoto_table:%s%"PRIu8,
6237 colors.param, colors.end, a->table_id);
c2d936a4
BP
6238}
6239\f
6240static void
5ad4b3f8 6241log_bad_action(const struct ofp_action_header *actions, size_t actions_len,
c2d936a4
BP
6242 const struct ofp_action_header *bad_action, enum ofperr error)
6243{
6244 if (!VLOG_DROP_WARN(&rl)) {
6245 struct ds s;
6246
6247 ds_init(&s);
5ad4b3f8 6248 ds_put_hex_dump(&s, actions, actions_len, 0, false);
c2d936a4
BP
6249 VLOG_WARN("bad action at offset %#"PRIxPTR" (%s):\n%s",
6250 (char *)bad_action - (char *)actions,
6251 ofperr_get_name(error), ds_cstr(&s));
6252 ds_destroy(&s);
6253 }
6254}
6255
6256static enum ofperr
6257ofpacts_decode(const void *actions, size_t actions_len,
04f48a68
YHW
6258 enum ofp_version ofp_version,
6259 const struct vl_mff_map *vl_mff_map, struct ofpbuf *ofpacts)
c2d936a4 6260{
0a2869d5 6261 struct ofpbuf openflow = ofpbuf_const_initializer(actions, actions_len);
6fd6ed71
PS
6262 while (openflow.size) {
6263 const struct ofp_action_header *action = openflow.data;
c2d936a4
BP
6264 enum ofp_raw_action_type raw;
6265 enum ofperr error;
6266 uint64_t arg;
6267
6268 error = ofpact_pull_raw(&openflow, ofp_version, &raw, &arg);
6269 if (!error) {
04f48a68
YHW
6270 error = ofpact_decode(action, raw, ofp_version, arg, vl_mff_map,
6271 ofpacts);
c2d936a4
BP
6272 }
6273
6274 if (error) {
5ad4b3f8 6275 log_bad_action(actions, actions_len, action, error);
c2d936a4
BP
6276 return error;
6277 }
6278 }
c2d936a4
BP
6279 return 0;
6280}
6281
6282static enum ofperr
6283ofpacts_pull_openflow_actions__(struct ofpbuf *openflow,
6284 unsigned int actions_len,
6285 enum ofp_version version,
6286 uint32_t allowed_ovsinsts,
d824b5b7 6287 struct ofpbuf *ofpacts,
04f48a68
YHW
6288 enum ofpact_type outer_action,
6289 const struct vl_mff_map *vl_mff_map)
c2d936a4
BP
6290{
6291 const struct ofp_action_header *actions;
9abca1e5 6292 size_t orig_size = ofpacts->size;
c2d936a4
BP
6293 enum ofperr error;
6294
c2d936a4
BP
6295 if (actions_len % OFP_ACTION_ALIGN != 0) {
6296 VLOG_WARN_RL(&rl, "OpenFlow message actions length %u is not a "
6297 "multiple of %d", actions_len, OFP_ACTION_ALIGN);
6298 return OFPERR_OFPBRC_BAD_LEN;
6299 }
6300
6301 actions = ofpbuf_try_pull(openflow, actions_len);
6302 if (actions == NULL) {
6303 VLOG_WARN_RL(&rl, "OpenFlow message actions length %u exceeds "
6304 "remaining message length (%"PRIu32")",
6fd6ed71 6305 actions_len, openflow->size);
c2d936a4
BP
6306 return OFPERR_OFPBRC_BAD_LEN;
6307 }
6308
04f48a68 6309 error = ofpacts_decode(actions, actions_len, version, vl_mff_map, ofpacts);
c2d936a4 6310 if (error) {
9abca1e5 6311 ofpacts->size = orig_size;
c2d936a4
BP
6312 return error;
6313 }
6314
d824b5b7
JS
6315 error = ofpacts_verify(ofpacts->data, ofpacts->size, allowed_ovsinsts,
6316 outer_action);
c2d936a4 6317 if (error) {
9abca1e5 6318 ofpacts->size = orig_size;
c2d936a4
BP
6319 }
6320 return error;
6321}
6322
9abca1e5
BP
6323/* Attempts to convert 'actions_len' bytes of OpenFlow actions from the front
6324 * of 'openflow' into ofpacts. On success, appends the converted actions to
6325 * 'ofpacts'; on failure, 'ofpacts' is unchanged (but might be reallocated) .
c2d936a4
BP
6326 * Returns 0 if successful, otherwise an OpenFlow error.
6327 *
6328 * Actions are processed according to their OpenFlow version which
6329 * is provided in the 'version' parameter.
6330 *
6331 * In most places in OpenFlow, actions appear encapsulated in instructions, so
6332 * you should call ofpacts_pull_openflow_instructions() instead of this
6333 * function.
6334 *
6335 * The parsed actions are valid generically, but they may not be valid in a
6336 * specific context. For example, port numbers up to OFPP_MAX are valid
6337 * generically, but specific datapaths may only support port numbers in a
6338 * smaller range. Use ofpacts_check() to additional check whether actions are
6339 * valid in a specific context. */
6340enum ofperr
6341ofpacts_pull_openflow_actions(struct ofpbuf *openflow,
6342 unsigned int actions_len,
6343 enum ofp_version version,
04f48a68 6344 const struct vl_mff_map *vl_mff_map,
c2d936a4
BP
6345 struct ofpbuf *ofpacts)
6346{
6347 return ofpacts_pull_openflow_actions__(openflow, actions_len, version,
6348 1u << OVSINST_OFPIT11_APPLY_ACTIONS,
04f48a68 6349 ofpacts, 0, vl_mff_map);
c2d936a4
BP
6350}
6351\f
6352/* OpenFlow 1.1 actions. */
6353
6354
6355/* True if an action sets the value of a field
6356 * in a way that is compatibile with the action set.
1b0ee636 6357 * The field can be set via either a set or a move action.
c2d936a4
BP
6358 * False otherwise. */
6359static bool
1b0ee636 6360ofpact_is_set_or_move_action(const struct ofpact *a)
c2d936a4
BP
6361{
6362 switch (a->type) {
6363 case OFPACT_SET_FIELD:
1b0ee636 6364 case OFPACT_REG_MOVE:
c2d936a4
BP
6365 case OFPACT_SET_ETH_DST:
6366 case OFPACT_SET_ETH_SRC:
6367 case OFPACT_SET_IP_DSCP:
6368 case OFPACT_SET_IP_ECN:
6369 case OFPACT_SET_IP_TTL:
6370 case OFPACT_SET_IPV4_DST:
6371 case OFPACT_SET_IPV4_SRC:
6372 case OFPACT_SET_L4_DST_PORT:
6373 case OFPACT_SET_L4_SRC_PORT:
6374 case OFPACT_SET_MPLS_LABEL:
6375 case OFPACT_SET_MPLS_TC:
6376 case OFPACT_SET_MPLS_TTL:
6377 case OFPACT_SET_QUEUE:
6378 case OFPACT_SET_TUNNEL:
6379 case OFPACT_SET_VLAN_PCP:
6380 case OFPACT_SET_VLAN_VID:
6381 return true;
6382 case OFPACT_BUNDLE:
6383 case OFPACT_CLEAR_ACTIONS:
07659514 6384 case OFPACT_CT:
72fe7578 6385 case OFPACT_CT_CLEAR:
7ae62a67 6386 case OFPACT_CLONE:
9ac0aada 6387 case OFPACT_NAT:
c2d936a4
BP
6388 case OFPACT_CONTROLLER:
6389 case OFPACT_DEC_MPLS_TTL:
6390 case OFPACT_DEC_TTL:
6391 case OFPACT_ENQUEUE:
6392 case OFPACT_EXIT:
e672ff9b 6393 case OFPACT_UNROLL_XLATE:
c2d936a4
BP
6394 case OFPACT_FIN_TIMEOUT:
6395 case OFPACT_GOTO_TABLE:
6396 case OFPACT_GROUP:
6397 case OFPACT_LEARN:
18080541 6398 case OFPACT_CONJUNCTION:
c2d936a4
BP
6399 case OFPACT_METER:
6400 case OFPACT_MULTIPATH:
6401 case OFPACT_NOTE:
6402 case OFPACT_OUTPUT:
6403 case OFPACT_OUTPUT_REG:
aaca4fe0 6404 case OFPACT_OUTPUT_TRUNC:
c2d936a4
BP
6405 case OFPACT_POP_MPLS:
6406 case OFPACT_POP_QUEUE:
6407 case OFPACT_PUSH_MPLS:
6408 case OFPACT_PUSH_VLAN:
c2d936a4
BP
6409 case OFPACT_RESUBMIT:
6410 case OFPACT_SAMPLE:
6411 case OFPACT_STACK_POP:
6412 case OFPACT_STACK_PUSH:
6413 case OFPACT_STRIP_VLAN:
6414 case OFPACT_WRITE_ACTIONS:
6415 case OFPACT_WRITE_METADATA:
d4abaff5 6416 case OFPACT_DEBUG_RECIRC:
c2d936a4
BP
6417 return false;
6418 default:
6419 OVS_NOT_REACHED();
6420 }
6421}
6422
6423/* True if an action is allowed in the action set.
6424 * False otherwise. */
6425static bool
6426ofpact_is_allowed_in_actions_set(const struct ofpact *a)
6427{
6428 switch (a->type) {
6429 case OFPACT_DEC_MPLS_TTL:
6430 case OFPACT_DEC_TTL:
6431 case OFPACT_GROUP:
6432 case OFPACT_OUTPUT:
aaca4fe0 6433 case OFPACT_OUTPUT_TRUNC:
c2d936a4
BP
6434 case OFPACT_POP_MPLS:
6435 case OFPACT_PUSH_MPLS:
6436 case OFPACT_PUSH_VLAN:
1b0ee636 6437 case OFPACT_REG_MOVE:
c2d936a4
BP
6438 case OFPACT_SET_FIELD:
6439 case OFPACT_SET_ETH_DST:
6440 case OFPACT_SET_ETH_SRC:
6441 case OFPACT_SET_IP_DSCP:
6442 case OFPACT_SET_IP_ECN:
6443 case OFPACT_SET_IP_TTL:
6444 case OFPACT_SET_IPV4_DST:
6445 case OFPACT_SET_IPV4_SRC:
6446 case OFPACT_SET_L4_DST_PORT:
6447 case OFPACT_SET_L4_SRC_PORT:
6448 case OFPACT_SET_MPLS_LABEL:
6449 case OFPACT_SET_MPLS_TC:
6450 case OFPACT_SET_MPLS_TTL:
6451 case OFPACT_SET_QUEUE:
6452 case OFPACT_SET_TUNNEL:
6453 case OFPACT_SET_VLAN_PCP:
6454 case OFPACT_SET_VLAN_VID:
6455 case OFPACT_STRIP_VLAN:
6456 return true;
6457
6458 /* In general these actions are excluded because they are not part of
6459 * the OpenFlow specification nor map to actions that are defined in
6460 * the specification. Thus the order in which they should be applied
6461 * in the action set is undefined. */
6462 case OFPACT_BUNDLE:
7ae62a67 6463 case OFPACT_CLONE:
c2d936a4 6464 case OFPACT_CONTROLLER:
07659514 6465 case OFPACT_CT:
72fe7578 6466 case OFPACT_CT_CLEAR:
9ac0aada 6467 case OFPACT_NAT:
c2d936a4
BP
6468 case OFPACT_ENQUEUE:
6469 case OFPACT_EXIT:
e672ff9b 6470 case OFPACT_UNROLL_XLATE:
c2d936a4
BP
6471 case OFPACT_FIN_TIMEOUT:
6472 case OFPACT_LEARN:
18080541 6473 case OFPACT_CONJUNCTION:
c2d936a4
BP
6474 case OFPACT_MULTIPATH:
6475 case OFPACT_NOTE:
6476 case OFPACT_OUTPUT_REG:
6477 case OFPACT_POP_QUEUE:
c2d936a4
BP
6478 case OFPACT_RESUBMIT:
6479 case OFPACT_SAMPLE:
6480 case OFPACT_STACK_POP:
6481 case OFPACT_STACK_PUSH:
d4abaff5 6482 case OFPACT_DEBUG_RECIRC:
c2d936a4
BP
6483
6484 /* The action set may only include actions and thus
6485 * may not include any instructions */
6486 case OFPACT_CLEAR_ACTIONS:
6487 case OFPACT_GOTO_TABLE:
6488 case OFPACT_METER:
6489 case OFPACT_WRITE_ACTIONS:
6490 case OFPACT_WRITE_METADATA:
6491 return false;
6492 default:
6493 OVS_NOT_REACHED();
6494 }
f25d0cf3
BP
6495}
6496
c2d936a4 6497/* Append ofpact 'a' onto the tail of 'out' */
f25d0cf3 6498static void
c2d936a4 6499ofpact_copy(struct ofpbuf *out, const struct ofpact *a)
f25d0cf3 6500{
c2d936a4 6501 ofpbuf_put(out, a, OFPACT_ALIGN(a->len));
f25d0cf3
BP
6502}
6503
c2d936a4
BP
6504/* Copies the last ofpact whose type is 'filter' from 'in' to 'out'. */
6505static bool
6506ofpacts_copy_last(struct ofpbuf *out, const struct ofpbuf *in,
6507 enum ofpact_type filter)
f25d0cf3 6508{
c2d936a4
BP
6509 const struct ofpact *target;
6510 const struct ofpact *a;
f25d0cf3 6511
c2d936a4 6512 target = NULL;
6fd6ed71 6513 OFPACT_FOR_EACH (a, in->data, in->size) {
c2d936a4
BP
6514 if (a->type == filter) {
6515 target = a;
6516 }
6517 }
6518 if (target) {
6519 ofpact_copy(out, target);
f25d0cf3 6520 }
c2d936a4 6521 return target != NULL;
f25d0cf3
BP
6522}
6523
c2d936a4
BP
6524/* Append all ofpacts, for which 'filter' returns true, from 'in' to 'out'.
6525 * The order of appended ofpacts is preserved between 'in' and 'out' */
4cceacb9 6526static void
c2d936a4
BP
6527ofpacts_copy_all(struct ofpbuf *out, const struct ofpbuf *in,
6528 bool (*filter)(const struct ofpact *))
4cceacb9 6529{
c2d936a4 6530 const struct ofpact *a;
4cceacb9 6531
6fd6ed71 6532 OFPACT_FOR_EACH (a, in->data, in->size) {
c2d936a4
BP
6533 if (filter(a)) {
6534 ofpact_copy(out, a);
6535 }
6536 }
4cceacb9
JS
6537}
6538
c2d936a4
BP
6539/* Reads 'action_set', which contains ofpacts accumulated by
6540 * OFPACT_WRITE_ACTIONS instructions, and writes equivalent actions to be
6541 * executed directly into 'action_list'. (These names correspond to the
6542 * "Action Set" and "Action List" terms used in OpenFlow 1.1+.)
6543 *
6544 * In general this involves appending the last instance of each action that is
e672ff9b 6545 * admissible in the action set in the order described in the OpenFlow
c2d936a4
BP
6546 * specification.
6547 *
6548 * Exceptions:
6549 * + output action is only appended if no group action was present in 'in'.
6550 * + As a simplification all set actions are copied in the order the are
6551 * provided in 'in' as many set actions applied to a field has the same
6552 * affect as only applying the last action that sets a field and
6553 * duplicates are removed by do_xlate_actions().
6554 * This has an unwanted side-effect of compsoting multiple
6555 * LOAD_REG actions that touch different regions of the same field. */
6556void
6557ofpacts_execute_action_set(struct ofpbuf *action_list,
6558 const struct ofpbuf *action_set)
f25d0cf3 6559{
c2d936a4
BP
6560 /* The OpenFlow spec "Action Set" section specifies this order. */
6561 ofpacts_copy_last(action_list, action_set, OFPACT_STRIP_VLAN);
6562 ofpacts_copy_last(action_list, action_set, OFPACT_POP_MPLS);
6563 ofpacts_copy_last(action_list, action_set, OFPACT_PUSH_MPLS);
6564 ofpacts_copy_last(action_list, action_set, OFPACT_PUSH_VLAN);
6565 ofpacts_copy_last(action_list, action_set, OFPACT_DEC_TTL);
6566 ofpacts_copy_last(action_list, action_set, OFPACT_DEC_MPLS_TTL);
1b0ee636 6567 ofpacts_copy_all(action_list, action_set, ofpact_is_set_or_move_action);
c2d936a4 6568 ofpacts_copy_last(action_list, action_set, OFPACT_SET_QUEUE);
f25d0cf3 6569
c2d936a4
BP
6570 /* If both OFPACT_GROUP and OFPACT_OUTPUT are present, OpenFlow says that
6571 * we should execute only OFPACT_GROUP.
6572 *
6573 * If neither OFPACT_GROUP nor OFPACT_OUTPUT is present, then we can drop
6574 * all the actions because there's no point in modifying a packet that will
6575 * not be sent anywhere. */
6576 if (!ofpacts_copy_last(action_list, action_set, OFPACT_GROUP) &&
2e34a6a3 6577 !ofpacts_copy_last(action_list, action_set, OFPACT_OUTPUT) &&
2c66ebe4
JR
6578 !ofpacts_copy_last(action_list, action_set, OFPACT_RESUBMIT) &&
6579 !ofpacts_copy_last(action_list, action_set, OFPACT_CT)) {
c2d936a4 6580 ofpbuf_clear(action_list);
f25d0cf3 6581 }
f25d0cf3
BP
6582}
6583
f25d0cf3 6584
c2d936a4
BP
6585static enum ofperr
6586ofpacts_decode_for_action_set(const struct ofp_action_header *in,
6587 size_t n_in, enum ofp_version version,
04f48a68 6588 const struct vl_mff_map *vl_mff_map,
c2d936a4 6589 struct ofpbuf *out)
c2d967a5 6590{
c2d936a4
BP
6591 enum ofperr error;
6592 struct ofpact *a;
6fd6ed71 6593 size_t start = out->size;
c2d967a5 6594
04f48a68 6595 error = ofpacts_decode(in, n_in, version, vl_mff_map, out);
c2d967a5 6596
c2d936a4
BP
6597 if (error) {
6598 return error;
6599 }
6600
6fd6ed71 6601 OFPACT_FOR_EACH (a, ofpact_end(out->data, start), out->size - start) {
c2d936a4
BP
6602 if (!ofpact_is_allowed_in_actions_set(a)) {
6603 VLOG_WARN_RL(&rl, "disallowed action in action set");
6604 return OFPERR_OFPBAC_BAD_TYPE;
c2d967a5
MM
6605 }
6606 }
c2d936a4
BP
6607
6608 return 0;
c2d967a5 6609}
c2d936a4
BP
6610\f
6611/* OpenFlow 1.1 instructions. */
c2d967a5 6612
c2d936a4
BP
6613struct instruction_type_info {
6614 enum ovs_instruction_type type;
6615 const char *name;
6616};
6617
6618static const struct instruction_type_info inst_info[] = {
6619#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) {OVSINST_##ENUM, NAME},
6620OVS_INSTRUCTIONS
6621#undef DEFINE_INST
6622};
6623
6624const char *
6625ovs_instruction_name_from_type(enum ovs_instruction_type type)
f25d0cf3 6626{
c2d936a4 6627 return inst_info[type].name;
f25d0cf3
BP
6628}
6629
c2d936a4
BP
6630int
6631ovs_instruction_type_from_name(const char *name)
29089a54 6632{
c2d936a4
BP
6633 const struct instruction_type_info *p;
6634 for (p = inst_info; p < &inst_info[ARRAY_SIZE(inst_info)]; p++) {
6635 if (!strcasecmp(name, p->name)) {
6636 return p->type;
6637 }
6638 }
6639 return -1;
29089a54
RL
6640}
6641
c2d936a4
BP
6642enum ovs_instruction_type
6643ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
f25d0cf3 6644{
c2d936a4
BP
6645 switch (type) {
6646 case OFPACT_METER:
6647 return OVSINST_OFPIT13_METER;
6648 case OFPACT_CLEAR_ACTIONS:
6649 return OVSINST_OFPIT11_CLEAR_ACTIONS;
6650 case OFPACT_WRITE_ACTIONS:
6651 return OVSINST_OFPIT11_WRITE_ACTIONS;
6652 case OFPACT_WRITE_METADATA:
6653 return OVSINST_OFPIT11_WRITE_METADATA;
6654 case OFPACT_GOTO_TABLE:
6655 return OVSINST_OFPIT11_GOTO_TABLE;
6656 case OFPACT_OUTPUT:
6657 case OFPACT_GROUP:
7ae62a67 6658 case OFPACT_CLONE:
f25d0cf3 6659 case OFPACT_CONTROLLER:
c2d936a4 6660 case OFPACT_ENQUEUE:
f25d0cf3 6661 case OFPACT_OUTPUT_REG:
aaca4fe0 6662 case OFPACT_OUTPUT_TRUNC:
f25d0cf3 6663 case OFPACT_BUNDLE:
c2d936a4
BP
6664 case OFPACT_SET_VLAN_VID:
6665 case OFPACT_SET_VLAN_PCP:
6666 case OFPACT_STRIP_VLAN:
6667 case OFPACT_PUSH_VLAN:
6668 case OFPACT_SET_ETH_SRC:
6669 case OFPACT_SET_ETH_DST:
6670 case OFPACT_SET_IPV4_SRC:
6671 case OFPACT_SET_IPV4_DST:
6672 case OFPACT_SET_IP_DSCP:
6673 case OFPACT_SET_IP_ECN:
6674 case OFPACT_SET_IP_TTL:
6675 case OFPACT_SET_L4_SRC_PORT:
6676 case OFPACT_SET_L4_DST_PORT:
f25d0cf3 6677 case OFPACT_REG_MOVE:
c2d936a4 6678 case OFPACT_SET_FIELD:
bd85dac1 6679 case OFPACT_STACK_PUSH:
bd85dac1 6680 case OFPACT_STACK_POP:
f25d0cf3 6681 case OFPACT_DEC_TTL:
097d4939 6682 case OFPACT_SET_MPLS_LABEL:
097d4939 6683 case OFPACT_SET_MPLS_TC:
0f3f3c3d 6684 case OFPACT_SET_MPLS_TTL:
b676167a 6685 case OFPACT_DEC_MPLS_TTL:
c2d936a4
BP
6686 case OFPACT_PUSH_MPLS:
6687 case OFPACT_POP_MPLS:
f25d0cf3 6688 case OFPACT_SET_TUNNEL:
c2d936a4
BP
6689 case OFPACT_SET_QUEUE:
6690 case OFPACT_POP_QUEUE:
6691 case OFPACT_FIN_TIMEOUT:
6692 case OFPACT_RESUBMIT:
6693 case OFPACT_LEARN:
18080541 6694 case OFPACT_CONJUNCTION:
c2d936a4
BP
6695 case OFPACT_MULTIPATH:
6696 case OFPACT_NOTE:
6697 case OFPACT_EXIT:
e672ff9b 6698 case OFPACT_UNROLL_XLATE:
c2d936a4 6699 case OFPACT_SAMPLE:
d4abaff5 6700 case OFPACT_DEBUG_RECIRC:
07659514 6701 case OFPACT_CT:
72fe7578 6702 case OFPACT_CT_CLEAR:
9ac0aada 6703 case OFPACT_NAT:
c2d936a4
BP
6704 default:
6705 return OVSINST_OFPIT11_APPLY_ACTIONS;
6706 }
6707}
6708
6709enum ofperr
6710ovs_instruction_type_from_inst_type(enum ovs_instruction_type *instruction_type,
6711 const uint16_t inst_type)
6712{
6713 switch (inst_type) {
6714
6715#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
6716 case ENUM: \
6717 *instruction_type = OVSINST_##ENUM; \
6718 return 0;
6719OVS_INSTRUCTIONS
6720#undef DEFINE_INST
6721
6722 default:
6723 return OFPERR_OFPBIC_UNKNOWN_INST;
6724 }
6725}
6726
6727/* Two-way translation between OVS's internal "OVSINST_*" representation of
6728 * instructions and the "OFPIT_*" representation used in OpenFlow. */
6729struct ovsinst_map {
6730 enum ovs_instruction_type ovsinst; /* Internal name for instruction. */
6731 int ofpit; /* OFPIT_* number from OpenFlow spec. */
6732};
6733
6734static const struct ovsinst_map *
6735get_ovsinst_map(enum ofp_version version)
6736{
6737 /* OpenFlow 1.1 and 1.2 instructions. */
6738 static const struct ovsinst_map of11[] = {
6739 { OVSINST_OFPIT11_GOTO_TABLE, 1 },
6740 { OVSINST_OFPIT11_WRITE_METADATA, 2 },
6741 { OVSINST_OFPIT11_WRITE_ACTIONS, 3 },
6742 { OVSINST_OFPIT11_APPLY_ACTIONS, 4 },
6743 { OVSINST_OFPIT11_CLEAR_ACTIONS, 5 },
6744 { 0, -1 },
6745 };
f25d0cf3 6746
c2d936a4
BP
6747 /* OpenFlow 1.3+ instructions. */
6748 static const struct ovsinst_map of13[] = {
6749 { OVSINST_OFPIT11_GOTO_TABLE, 1 },
6750 { OVSINST_OFPIT11_WRITE_METADATA, 2 },
6751 { OVSINST_OFPIT11_WRITE_ACTIONS, 3 },
6752 { OVSINST_OFPIT11_APPLY_ACTIONS, 4 },
6753 { OVSINST_OFPIT11_CLEAR_ACTIONS, 5 },
6754 { OVSINST_OFPIT13_METER, 6 },
6755 { 0, -1 },
6756 };
4cceacb9 6757
c2d936a4
BP
6758 return version < OFP13_VERSION ? of11 : of13;
6759}
f25d0cf3 6760
c2d936a4
BP
6761/* Converts 'ovsinst_bitmap', a bitmap whose bits correspond to OVSINST_*
6762 * values, into a bitmap of instructions suitable for OpenFlow 'version'
6763 * (OFP11_VERSION or later), and returns the result. */
6764ovs_be32
6765ovsinst_bitmap_to_openflow(uint32_t ovsinst_bitmap, enum ofp_version version)
6766{
6767 uint32_t ofpit_bitmap = 0;
6768 const struct ovsinst_map *x;
f25d0cf3 6769
c2d936a4
BP
6770 for (x = get_ovsinst_map(version); x->ofpit >= 0; x++) {
6771 if (ovsinst_bitmap & (1u << x->ovsinst)) {
6772 ofpit_bitmap |= 1u << x->ofpit;
6773 }
6774 }
6775 return htonl(ofpit_bitmap);
6776}
f25d0cf3 6777
c2d936a4
BP
6778/* Converts 'ofpit_bitmap', a bitmap of instructions from an OpenFlow message
6779 * with the given 'version' (OFP11_VERSION or later) into a bitmap whose bits
6780 * correspond to OVSINST_* values, and returns the result. */
6781uint32_t
6782ovsinst_bitmap_from_openflow(ovs_be32 ofpit_bitmap, enum ofp_version version)
6783{
6784 uint32_t ovsinst_bitmap = 0;
6785 const struct ovsinst_map *x;
f25d0cf3 6786
c2d936a4
BP
6787 for (x = get_ovsinst_map(version); x->ofpit >= 0; x++) {
6788 if (ofpit_bitmap & htonl(1u << x->ofpit)) {
6789 ovsinst_bitmap |= 1u << x->ovsinst;
6790 }
6791 }
6792 return ovsinst_bitmap;
6793}
f25d0cf3 6794
c2d936a4
BP
6795static inline struct ofp11_instruction *
6796instruction_next(const struct ofp11_instruction *inst)
6797{
6798 return ((struct ofp11_instruction *) (void *)
6799 ((uint8_t *) inst + ntohs(inst->len)));
6800}
f25d0cf3 6801
c2d936a4
BP
6802static inline bool
6803instruction_is_valid(const struct ofp11_instruction *inst,
6804 size_t n_instructions)
6805{
6806 uint16_t len = ntohs(inst->len);
6807 return (!(len % OFP11_INSTRUCTION_ALIGN)
6808 && len >= sizeof *inst
6809 && len / sizeof *inst <= n_instructions);
6810}
f25d0cf3 6811
c2d936a4
BP
6812/* This macro is careful to check for instructions with bad lengths. */
6813#define INSTRUCTION_FOR_EACH(ITER, LEFT, INSTRUCTIONS, N_INSTRUCTIONS) \
6814 for ((ITER) = (INSTRUCTIONS), (LEFT) = (N_INSTRUCTIONS); \
6815 (LEFT) > 0 && instruction_is_valid(ITER, LEFT); \
6816 ((LEFT) -= (ntohs((ITER)->len) \
6817 / sizeof(struct ofp11_instruction)), \
6818 (ITER) = instruction_next(ITER)))
f25d0cf3 6819
c2d936a4
BP
6820static enum ofperr
6821decode_openflow11_instruction(const struct ofp11_instruction *inst,
6822 enum ovs_instruction_type *type)
6823{
6824 uint16_t len = ntohs(inst->len);
b02475c5 6825
c2d936a4
BP
6826 switch (inst->type) {
6827 case CONSTANT_HTONS(OFPIT11_EXPERIMENTER):
6828 return OFPERR_OFPBIC_BAD_EXPERIMENTER;
b02475c5 6829
c2d936a4
BP
6830#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \
6831 case CONSTANT_HTONS(ENUM): \
6832 if (EXTENSIBLE \
6833 ? len >= sizeof(struct STRUCT) \
6834 : len == sizeof(struct STRUCT)) { \
6835 *type = OVSINST_##ENUM; \
6836 return 0; \
6837 } else { \
6838 return OFPERR_OFPBIC_BAD_LEN; \
6839 }
6840OVS_INSTRUCTIONS
6841#undef DEFINE_INST
29089a54 6842
c2d936a4
BP
6843 default:
6844 return OFPERR_OFPBIC_UNKNOWN_INST;
f25d0cf3
BP
6845 }
6846}
f25d0cf3 6847
c2d936a4
BP
6848static enum ofperr
6849decode_openflow11_instructions(const struct ofp11_instruction insts[],
6850 size_t n_insts,
6851 const struct ofp11_instruction *out[])
f25d0cf3 6852{
c2d936a4
BP
6853 const struct ofp11_instruction *inst;
6854 size_t left;
f25d0cf3 6855
c2d936a4
BP
6856 memset(out, 0, N_OVS_INSTRUCTIONS * sizeof *out);
6857 INSTRUCTION_FOR_EACH (inst, left, insts, n_insts) {
6858 enum ovs_instruction_type type;
6859 enum ofperr error;
f25d0cf3 6860
c2d936a4
BP
6861 error = decode_openflow11_instruction(inst, &type);
6862 if (error) {
6863 return error;
6864 }
f25d0cf3 6865
c2d936a4
BP
6866 if (out[type]) {
6867 return OFPERR_OFPBIC_DUP_INST;
6868 }
6869 out[type] = inst;
6870 }
6871
6872 if (left) {
6873 VLOG_WARN_RL(&rl, "bad instruction format at offset %"PRIuSIZE,
6874 (n_insts - left) * sizeof *inst);
6875 return OFPERR_OFPBIC_BAD_LEN;
6876 }
6877 return 0;
f25d0cf3
BP
6878}
6879
6880static void
c2d936a4
BP
6881get_actions_from_instruction(const struct ofp11_instruction *inst,
6882 const struct ofp_action_header **actions,
6883 size_t *actions_len)
f25d0cf3 6884{
c2d936a4
BP
6885 *actions = ALIGNED_CAST(const struct ofp_action_header *, inst + 1);
6886 *actions_len = ntohs(inst->len) - sizeof *inst;
6887}
f25d0cf3 6888
c2d936a4
BP
6889enum ofperr
6890ofpacts_pull_openflow_instructions(struct ofpbuf *openflow,
6891 unsigned int instructions_len,
6892 enum ofp_version version,
04f48a68 6893 const struct vl_mff_map *vl_mff_map,
c2d936a4
BP
6894 struct ofpbuf *ofpacts)
6895{
6896 const struct ofp11_instruction *instructions;
6897 const struct ofp11_instruction *insts[N_OVS_INSTRUCTIONS];
6898 enum ofperr error;
f25d0cf3 6899
9abca1e5 6900 ofpbuf_clear(ofpacts);
c2d936a4
BP
6901 if (version == OFP10_VERSION) {
6902 return ofpacts_pull_openflow_actions__(openflow, instructions_len,
6903 version,
6904 (1u << N_OVS_INSTRUCTIONS) - 1,
04f48a68 6905 ofpacts, 0, vl_mff_map);
c2d936a4 6906 }
f25d0cf3 6907
c2d936a4
BP
6908 if (instructions_len % OFP11_INSTRUCTION_ALIGN != 0) {
6909 VLOG_WARN_RL(&rl, "OpenFlow message instructions length %u is not a "
6910 "multiple of %d",
6911 instructions_len, OFP11_INSTRUCTION_ALIGN);
6912 error = OFPERR_OFPBIC_BAD_LEN;
6913 goto exit;
6914 }
f25d0cf3 6915
c2d936a4
BP
6916 instructions = ofpbuf_try_pull(openflow, instructions_len);
6917 if (instructions == NULL) {
6918 VLOG_WARN_RL(&rl, "OpenFlow message instructions length %u exceeds "
6919 "remaining message length (%"PRIu32")",
6fd6ed71 6920 instructions_len, openflow->size);
c2d936a4
BP
6921 error = OFPERR_OFPBIC_BAD_LEN;
6922 goto exit;
6923 }
f25d0cf3 6924
c2d936a4
BP
6925 error = decode_openflow11_instructions(
6926 instructions, instructions_len / OFP11_INSTRUCTION_ALIGN,
6927 insts);
6928 if (error) {
6929 goto exit;
6930 }
f25d0cf3 6931
c2d936a4
BP
6932 if (insts[OVSINST_OFPIT13_METER]) {
6933 const struct ofp13_instruction_meter *oim;
6934 struct ofpact_meter *om;
f25d0cf3 6935
c2d936a4
BP
6936 oim = ALIGNED_CAST(const struct ofp13_instruction_meter *,
6937 insts[OVSINST_OFPIT13_METER]);
f25d0cf3 6938
c2d936a4
BP
6939 om = ofpact_put_METER(ofpacts);
6940 om->meter_id = ntohl(oim->meter_id);
6941 }
6942 if (insts[OVSINST_OFPIT11_APPLY_ACTIONS]) {
6943 const struct ofp_action_header *actions;
6944 size_t actions_len;
f25d0cf3 6945
c2d936a4
BP
6946 get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS],
6947 &actions, &actions_len);
04f48a68
YHW
6948 error = ofpacts_decode(actions, actions_len, version, vl_mff_map,
6949 ofpacts);
c2d936a4
BP
6950 if (error) {
6951 goto exit;
6952 }
6953 }
6954 if (insts[OVSINST_OFPIT11_CLEAR_ACTIONS]) {
6955 instruction_get_OFPIT11_CLEAR_ACTIONS(
6956 insts[OVSINST_OFPIT11_CLEAR_ACTIONS]);
6957 ofpact_put_CLEAR_ACTIONS(ofpacts);
6958 }
6959 if (insts[OVSINST_OFPIT11_WRITE_ACTIONS]) {
6960 struct ofpact_nest *on;
6961 const struct ofp_action_header *actions;
6962 size_t actions_len;
2bd318de 6963 size_t start = ofpacts->size;
255a54ea
BP
6964 ofpact_put(ofpacts, OFPACT_WRITE_ACTIONS,
6965 offsetof(struct ofpact_nest, actions));
c2d936a4
BP
6966 get_actions_from_instruction(insts[OVSINST_OFPIT11_WRITE_ACTIONS],
6967 &actions, &actions_len);
6968 error = ofpacts_decode_for_action_set(actions, actions_len,
04f48a68 6969 version, vl_mff_map, ofpacts);
c2d936a4
BP
6970 if (error) {
6971 goto exit;
6972 }
6973 on = ofpbuf_at_assert(ofpacts, start, sizeof *on);
6fd6ed71 6974 on->ofpact.len = ofpacts->size - start;
c2d936a4
BP
6975 }
6976 if (insts[OVSINST_OFPIT11_WRITE_METADATA]) {
6977 const struct ofp11_instruction_write_metadata *oiwm;
6978 struct ofpact_metadata *om;
ca287d20 6979
c2d936a4
BP
6980 oiwm = ALIGNED_CAST(const struct ofp11_instruction_write_metadata *,
6981 insts[OVSINST_OFPIT11_WRITE_METADATA]);
8dd54666 6982
c2d936a4
BP
6983 om = ofpact_put_WRITE_METADATA(ofpacts);
6984 om->metadata = oiwm->metadata;
6985 om->mask = oiwm->metadata_mask;
6986 }
6987 if (insts[OVSINST_OFPIT11_GOTO_TABLE]) {
6988 const struct ofp11_instruction_goto_table *oigt;
6989 struct ofpact_goto_table *ogt;
7395c052 6990
c2d936a4
BP
6991 oigt = instruction_get_OFPIT11_GOTO_TABLE(
6992 insts[OVSINST_OFPIT11_GOTO_TABLE]);
6993 ogt = ofpact_put_GOTO_TABLE(ofpacts);
6994 ogt->table_id = oigt->table_id;
6995 }
e3f8f887 6996
6fd6ed71 6997 error = ofpacts_verify(ofpacts->data, ofpacts->size,
d824b5b7 6998 (1u << N_OVS_INSTRUCTIONS) - 1, 0);
c2d936a4
BP
6999exit:
7000 if (error) {
7001 ofpbuf_clear(ofpacts);
f25d0cf3 7002 }
c2d936a4 7003 return error;
f25d0cf3 7004}
d01c980f 7005
c2d936a4
BP
7006/* Update the length of the instruction that begins at offset 'ofs' within
7007 * 'openflow' and contains nested actions that extend to the end of 'openflow'.
7008 * If the instruction contains no nested actions, deletes it entirely. */
d01c980f 7009static void
c2d936a4 7010ofpacts_update_instruction_actions(struct ofpbuf *openflow, size_t ofs)
d01c980f 7011{
c2d936a4 7012 struct ofp11_instruction_actions *oia;
d01c980f 7013
c2d936a4 7014 oia = ofpbuf_at_assert(openflow, ofs, sizeof *oia);
6fd6ed71
PS
7015 if (openflow->size > ofs + sizeof *oia) {
7016 oia->len = htons(openflow->size - ofs);
c2d936a4 7017 } else {
6fd6ed71 7018 openflow->size = ofs;
c2d936a4 7019 }
d01c980f 7020}
c2d936a4
BP
7021\f
7022/* Checks that 'port' is a valid output port for OFPACT_OUTPUT, given that the
7023 * switch will never have more than 'max_ports' ports. Returns 0 if 'port' is
7024 * valid, otherwise an OpenFlow error code. */
7025enum ofperr
7026ofpact_check_output_port(ofp_port_t port, ofp_port_t max_ports)
99086062 7027{
c2d936a4
BP
7028 switch (port) {
7029 case OFPP_IN_PORT:
7030 case OFPP_TABLE:
7031 case OFPP_NORMAL:
7032 case OFPP_FLOOD:
7033 case OFPP_ALL:
7034 case OFPP_CONTROLLER:
c2d936a4
BP
7035 case OFPP_LOCAL:
7036 return 0;
7037
13d2c689
BP
7038 case OFPP_NONE:
7039 return OFPERR_OFPBAC_BAD_OUT_PORT;
7040
c2d936a4
BP
7041 default:
7042 if (ofp_to_u16(port) < ofp_to_u16(max_ports)) {
7043 return 0;
7044 }
7045 return OFPERR_OFPBAC_BAD_OUT_PORT;
99086062
BP
7046 }
7047}
7048
c2d936a4
BP
7049/* Removes the protocols that require consistency between match and actions
7050 * (that's everything but OpenFlow 1.0) from '*usable_protocols'.
7051 *
7052 * (An example of an inconsistency between match and actions is a flow that
7053 * does not match on an MPLS Ethertype but has an action that pops an MPLS
7054 * label.) */
d01c980f 7055static void
c2d936a4
BP
7056inconsistent_match(enum ofputil_protocol *usable_protocols)
7057{
7058 *usable_protocols &= OFPUTIL_P_OF10_ANY;
7059}
7060
7061/* May modify flow->dl_type, flow->nw_proto and flow->vlan_tci,
7062 * caller must restore them.
7063 *
7064 * Modifies some actions, filling in fields that could not be properly set
7065 * without context. */
7066static enum ofperr
7067ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
7068 struct flow *flow, ofp_port_t max_ports,
7069 uint8_t table_id, uint8_t n_tables)
d01c980f 7070{
c2d936a4
BP
7071 const struct ofpact_enqueue *enqueue;
7072 const struct mf_field *mf;
7073
d01c980f
BP
7074 switch (a->type) {
7075 case OFPACT_OUTPUT:
c2d936a4
BP
7076 return ofpact_check_output_port(ofpact_get_OUTPUT(a)->port,
7077 max_ports);
7078
7079 case OFPACT_CONTROLLER:
7080 return 0;
d01c980f
BP
7081
7082 case OFPACT_ENQUEUE:
c2d936a4
BP
7083 enqueue = ofpact_get_ENQUEUE(a);
7084 if (ofp_to_u16(enqueue->port) >= ofp_to_u16(max_ports)
7085 && enqueue->port != OFPP_IN_PORT
7086 && enqueue->port != OFPP_LOCAL) {
7087 return OFPERR_OFPBAC_BAD_OUT_PORT;
7088 }
7089 return 0;
7090
7091 case OFPACT_OUTPUT_REG:
7092 return mf_check_src(&ofpact_get_OUTPUT_REG(a)->src, flow);
7093
aaca4fe0
WT
7094 case OFPACT_OUTPUT_TRUNC:
7095 return ofpact_check_output_port(ofpact_get_OUTPUT_TRUNC(a)->port,
7096 max_ports);
7097
c2d936a4
BP
7098 case OFPACT_BUNDLE:
7099 return bundle_check(ofpact_get_BUNDLE(a), max_ports, flow);
d01c980f
BP
7100
7101 case OFPACT_SET_VLAN_VID:
c2d936a4
BP
7102 /* Remember if we saw a vlan tag in the flow to aid translating to
7103 * OpenFlow 1.1+ if need be. */
7104 ofpact_get_SET_VLAN_VID(a)->flow_has_vlan =
7105 (flow->vlan_tci & htons(VLAN_CFI)) == htons(VLAN_CFI);
7106 if (!(flow->vlan_tci & htons(VLAN_CFI)) &&
7107 !ofpact_get_SET_VLAN_VID(a)->push_vlan_if_needed) {
7108 inconsistent_match(usable_protocols);
7109 }
7110 /* Temporary mark that we have a vlan tag. */
7111 flow->vlan_tci |= htons(VLAN_CFI);
7112 return 0;
d01c980f
BP
7113
7114 case OFPACT_SET_VLAN_PCP:
c2d936a4
BP
7115 /* Remember if we saw a vlan tag in the flow to aid translating to
7116 * OpenFlow 1.1+ if need be. */
7117 ofpact_get_SET_VLAN_PCP(a)->flow_has_vlan =
7118 (flow->vlan_tci & htons(VLAN_CFI)) == htons(VLAN_CFI);
7119 if (!(flow->vlan_tci & htons(VLAN_CFI)) &&
7120 !ofpact_get_SET_VLAN_PCP(a)->push_vlan_if_needed) {
7121 inconsistent_match(usable_protocols);
7122 }
7123 /* Temporary mark that we have a vlan tag. */
7124 flow->vlan_tci |= htons(VLAN_CFI);
7125 return 0;
d01c980f
BP
7126
7127 case OFPACT_STRIP_VLAN:
c2d936a4
BP
7128 if (!(flow->vlan_tci & htons(VLAN_CFI))) {
7129 inconsistent_match(usable_protocols);
7130 }
7131 /* Temporary mark that we have no vlan tag. */
7132 flow->vlan_tci = htons(0);
7133 return 0;
d01c980f 7134
3e34fbdd 7135 case OFPACT_PUSH_VLAN:
c2d936a4
BP
7136 if (flow->vlan_tci & htons(VLAN_CFI)) {
7137 /* Multiple VLAN headers not supported. */
7138 return OFPERR_OFPBAC_BAD_TAG;
7139 }
7140 /* Temporary mark that we have a vlan tag. */
7141 flow->vlan_tci |= htons(VLAN_CFI);
7142 return 0;
276c4e7a 7143
d01c980f 7144 case OFPACT_SET_ETH_SRC:
d01c980f 7145 case OFPACT_SET_ETH_DST:
c2d936a4 7146 return 0;
d01c980f
BP
7147
7148 case OFPACT_SET_IPV4_SRC:
d01c980f 7149 case OFPACT_SET_IPV4_DST:
c2d936a4
BP
7150 if (flow->dl_type != htons(ETH_TYPE_IP)) {
7151 inconsistent_match(usable_protocols);
7152 }
7153 return 0;
d01c980f 7154
04f01c24 7155 case OFPACT_SET_IP_DSCP:
ff14eb7a 7156 case OFPACT_SET_IP_ECN:
0c20dbe4 7157 case OFPACT_SET_IP_TTL:
7bcb1506 7158 case OFPACT_DEC_TTL:
c2d936a4
BP
7159 if (!is_ip_any(flow)) {
7160 inconsistent_match(usable_protocols);
7161 }
7162 return 0;
b02475c5 7163
c2d936a4 7164 case OFPACT_SET_L4_SRC_PORT:
c2d936a4 7165 case OFPACT_SET_L4_DST_PORT:
b8778a0d 7166 if (!is_ip_any(flow) || (flow->nw_frag & FLOW_NW_FRAG_LATER) ||
c2d936a4
BP
7167 (flow->nw_proto != IPPROTO_TCP && flow->nw_proto != IPPROTO_UDP
7168 && flow->nw_proto != IPPROTO_SCTP)) {
7169 inconsistent_match(usable_protocols);
7170 }
7171 /* Note on which transport protocol the port numbers are set.
7172 * This allows this set action to be converted to an OF1.2 set field
7173 * action. */
b8778a0d
JR
7174 if (a->type == OFPACT_SET_L4_SRC_PORT) {
7175 ofpact_get_SET_L4_SRC_PORT(a)->flow_ip_proto = flow->nw_proto;
7176 } else {
7177 ofpact_get_SET_L4_DST_PORT(a)->flow_ip_proto = flow->nw_proto;
7178 }
c2d936a4 7179 return 0;
b02475c5 7180
c2d936a4
BP
7181 case OFPACT_REG_MOVE:
7182 return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow);
8dd54666 7183
e3f8f887 7184 case OFPACT_SET_FIELD:
c2d936a4
BP
7185 mf = ofpact_get_SET_FIELD(a)->field;
7186 /* Require OXM_OF_VLAN_VID to have an existing VLAN header. */
aff49b8c 7187 if (!mf_are_prereqs_ok(mf, flow, NULL) ||
c2d936a4
BP
7188 (mf->id == MFF_VLAN_VID && !(flow->vlan_tci & htons(VLAN_CFI)))) {
7189 VLOG_WARN_RL(&rl, "set_field %s lacks correct prerequisities",
7190 mf->name);
7191 return OFPERR_OFPBAC_MATCH_INCONSISTENT;
7192 }
7193 /* Remember if we saw a vlan tag in the flow to aid translating to
7194 * OpenFlow 1.1 if need be. */
7195 ofpact_get_SET_FIELD(a)->flow_has_vlan =
7196 (flow->vlan_tci & htons(VLAN_CFI)) == htons(VLAN_CFI);
7197 if (mf->id == MFF_VLAN_TCI) {
7198 /* The set field may add or remove the vlan tag,
7199 * Mark the status temporarily. */
128684a6 7200 flow->vlan_tci = ofpact_get_SET_FIELD(a)->value->be16;
c2d936a4
BP
7201 }
7202 return 0;
e3f8f887 7203
bd85dac1 7204 case OFPACT_STACK_PUSH:
c2d936a4
BP
7205 return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow);
7206
bd85dac1 7207 case OFPACT_STACK_POP:
c2d936a4
BP
7208 return nxm_stack_pop_check(ofpact_get_STACK_POP(a), flow);
7209
7210 case OFPACT_SET_MPLS_LABEL:
7211 case OFPACT_SET_MPLS_TC:
7212 case OFPACT_SET_MPLS_TTL:
7213 case OFPACT_DEC_MPLS_TTL:
7214 if (!eth_type_mpls(flow->dl_type)) {
7215 inconsistent_match(usable_protocols);
7216 }
7217 return 0;
7218
d01c980f 7219 case OFPACT_SET_TUNNEL:
c2d936a4 7220 case OFPACT_SET_QUEUE:
d01c980f 7221 case OFPACT_POP_QUEUE:
d01c980f 7222 case OFPACT_RESUBMIT:
c2d936a4
BP
7223 return 0;
7224
7225 case OFPACT_FIN_TIMEOUT:
7226 if (flow->nw_proto != IPPROTO_TCP) {
7227 inconsistent_match(usable_protocols);
7228 }
7229 return 0;
7230
d01c980f 7231 case OFPACT_LEARN:
c2d936a4
BP
7232 return learn_check(ofpact_get_LEARN(a), flow);
7233
18080541
BP
7234 case OFPACT_CONJUNCTION:
7235 return 0;
7236
d01c980f 7237 case OFPACT_MULTIPATH:
c2d936a4
BP
7238 return multipath_check(ofpact_get_MULTIPATH(a), flow);
7239
d01c980f
BP
7240 case OFPACT_NOTE:
7241 case OFPACT_EXIT:
c2d936a4 7242 return 0;
d01c980f 7243
c2d936a4
BP
7244 case OFPACT_PUSH_MPLS:
7245 flow->dl_type = ofpact_get_PUSH_MPLS(a)->ethertype;
7246 /* The packet is now MPLS and the MPLS payload is opaque.
7247 * Thus nothing can be assumed about the network protocol.
7248 * Temporarily mark that we have no nw_proto. */
7249 flow->nw_proto = 0;
7250 return 0;
1e7db674 7251
c2d936a4
BP
7252 case OFPACT_POP_MPLS:
7253 if (!eth_type_mpls(flow->dl_type)) {
7254 inconsistent_match(usable_protocols);
7255 }
7256 flow->dl_type = ofpact_get_POP_MPLS(a)->ethertype;
7257 return 0;
1e7db674 7258
c2d936a4
BP
7259 case OFPACT_SAMPLE:
7260 return 0;
1e7db674 7261
7ae62a67
WT
7262 case OFPACT_CLONE: {
7263 struct ofpact_nest *on = ofpact_get_CLONE(a);
7264 return ofpacts_check(on->actions, ofpact_nest_get_action_len(on),
7265 flow, max_ports, table_id, n_tables,
7266 usable_protocols);
7267 }
7268
07659514
JS
7269 case OFPACT_CT: {
7270 struct ofpact_conntrack *oc = ofpact_get_CT(a);
7271
7272 if (!dl_type_is_ip_any(flow->dl_type)
8b6d097c 7273 || (flow->ct_state & CS_INVALID && oc->flags & NX_CT_F_COMMIT)
40c7b2fc
JS
7274 || (oc->alg == IPPORT_FTP && flow->nw_proto != IPPROTO_TCP)
7275 || (oc->alg == IPPORT_TFTP && flow->nw_proto != IPPROTO_UDP)) {
ed26e3ea
JR
7276 /* We can't downgrade to OF1.0 and expect inconsistent CT actions
7277 * be silently discarded. Instead, datapath flow install fails, so
7278 * it is better to flag inconsistent CT actions as hard errors. */
7279 return OFPERR_OFPBAC_MATCH_INCONSISTENT;
07659514
JS
7280 }
7281
7282 if (oc->zone_src.field) {
7283 return mf_check_src(&oc->zone_src, flow);
7284 }
8e53fe8c 7285
9f02d70c
JR
7286 return ofpacts_check(oc->actions, ofpact_ct_get_action_len(oc),
7287 flow, max_ports, table_id, n_tables,
7288 usable_protocols);
07659514
JS
7289 }
7290
72fe7578
BP
7291 case OFPACT_CT_CLEAR:
7292 return 0;
7293
9ac0aada
JR
7294 case OFPACT_NAT: {
7295 struct ofpact_nat *on = ofpact_get_NAT(a);
7296
7297 if (!dl_type_is_ip_any(flow->dl_type) ||
7298 (on->range_af == AF_INET && flow->dl_type != htons(ETH_TYPE_IP)) ||
7299 (on->range_af == AF_INET6
7300 && flow->dl_type != htons(ETH_TYPE_IPV6))) {
ed26e3ea 7301 return OFPERR_OFPBAC_MATCH_INCONSISTENT;
9ac0aada
JR
7302 }
7303 return 0;
7304 }
7305
c2d936a4
BP
7306 case OFPACT_CLEAR_ACTIONS:
7307 return 0;
1e7db674 7308
c2d936a4
BP
7309 case OFPACT_WRITE_ACTIONS: {
7310 /* Use a temporary copy of 'usable_protocols' because we can't check
7311 * consistency of an action set. */
7312 struct ofpact_nest *on = ofpact_get_WRITE_ACTIONS(a);
7313 enum ofputil_protocol p = *usable_protocols;
7314 return ofpacts_check(on->actions, ofpact_nest_get_action_len(on),
7315 flow, max_ports, table_id, n_tables, &p);
7316 }
1e7db674 7317
c2d936a4
BP
7318 case OFPACT_WRITE_METADATA:
7319 return 0;
1e7db674 7320
c2d936a4
BP
7321 case OFPACT_METER: {
7322 uint32_t mid = ofpact_get_METER(a)->meter_id;
7323 if (mid == 0 || mid > OFPM13_MAX) {
7324 return OFPERR_OFPMMFC_INVALID_METER;
7325 }
7326 return 0;
7327 }
1e7db674 7328
c2d936a4
BP
7329 case OFPACT_GOTO_TABLE: {
7330 uint8_t goto_table = ofpact_get_GOTO_TABLE(a)->table_id;
7331 if ((table_id != 255 && goto_table <= table_id)
7332 || (n_tables != 255 && goto_table >= n_tables)) {
8c87971e 7333 return OFPERR_OFPBIC_BAD_TABLE_ID;
c2d936a4
BP
7334 }
7335 return 0;
7336 }
1e7db674 7337
c2d936a4
BP
7338 case OFPACT_GROUP:
7339 return 0;
1e7db674 7340
e672ff9b
JR
7341 case OFPACT_UNROLL_XLATE:
7342 /* UNROLL is an internal action that should never be seen via
7343 * OpenFlow. */
7344 return OFPERR_OFPBAC_BAD_TYPE;
7345
d4abaff5
BP
7346 case OFPACT_DEBUG_RECIRC:
7347 return 0;
7348
c2d936a4
BP
7349 default:
7350 OVS_NOT_REACHED();
7351 }
7352}
1e7db674 7353
c2d936a4
BP
7354/* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are
7355 * appropriate for a packet with the prerequisites satisfied by 'flow' in a
7356 * switch with no more than 'max_ports' ports.
7357 *
7358 * If 'ofpacts' and 'flow' are inconsistent with one another, un-sets in
7359 * '*usable_protocols' the protocols that forbid the inconsistency. (An
7360 * example of an inconsistency between match and actions is a flow that does
7361 * not match on an MPLS Ethertype but has an action that pops an MPLS label.)
7362 *
7363 * May annotate ofpacts with information gathered from the 'flow'.
7364 *
7365 * May temporarily modify 'flow', but restores the changes before returning. */
7366enum ofperr
7367ofpacts_check(struct ofpact ofpacts[], size_t ofpacts_len,
7368 struct flow *flow, ofp_port_t max_ports,
7369 uint8_t table_id, uint8_t n_tables,
7370 enum ofputil_protocol *usable_protocols)
7371{
7372 struct ofpact *a;
7373 ovs_be16 dl_type = flow->dl_type;
7374 ovs_be16 vlan_tci = flow->vlan_tci;
7375 uint8_t nw_proto = flow->nw_proto;
7376 enum ofperr error = 0;
1e7db674 7377
c2d936a4
BP
7378 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
7379 error = ofpact_check__(usable_protocols, a, flow,
7380 max_ports, table_id, n_tables);
7381 if (error) {
1e7db674 7382 break;
c2d936a4
BP
7383 }
7384 }
7385 /* Restore fields that may have been modified. */
7386 flow->dl_type = dl_type;
7387 flow->vlan_tci = vlan_tci;
7388 flow->nw_proto = nw_proto;
7389 return error;
7390}
1e7db674 7391
c2d936a4
BP
7392/* Like ofpacts_check(), but reports inconsistencies as
7393 * OFPERR_OFPBAC_MATCH_INCONSISTENT rather than clearing bits. */
7394enum ofperr
7395ofpacts_check_consistency(struct ofpact ofpacts[], size_t ofpacts_len,
7396 struct flow *flow, ofp_port_t max_ports,
7397 uint8_t table_id, uint8_t n_tables,
7398 enum ofputil_protocol usable_protocols)
7399{
7400 enum ofputil_protocol p = usable_protocols;
7401 enum ofperr error;
1e7db674 7402
c2d936a4
BP
7403 error = ofpacts_check(ofpacts, ofpacts_len, flow, max_ports,
7404 table_id, n_tables, &p);
7405 return (error ? error
7406 : p != usable_protocols ? OFPERR_OFPBAC_MATCH_INCONSISTENT
7407 : 0);
7408}
097d4939 7409
28f5311f
JS
7410/* Returns the destination field that 'ofpact' would write to, or NULL
7411 * if the action would not write to an mf_field. */
7412const struct mf_field *
7413ofpact_get_mf_dst(const struct ofpact *ofpact)
8e53fe8c 7414{
28f5311f
JS
7415 if (ofpact->type == OFPACT_SET_FIELD) {
7416 const struct ofpact_set_field *orl;
8e53fe8c 7417
28f5311f 7418 orl = CONTAINER_OF(ofpact, struct ofpact_set_field, ofpact);
8e53fe8c 7419 return orl->field;
28f5311f
JS
7420 } else if (ofpact->type == OFPACT_REG_MOVE) {
7421 const struct ofpact_reg_move *orm;
8e53fe8c 7422
28f5311f 7423 orm = CONTAINER_OF(ofpact, struct ofpact_reg_move, ofpact);
8e53fe8c
JS
7424 return orm->dst.field;
7425 }
7426
7427 return NULL;
7428}
7429
7430static enum ofperr
7431unsupported_nesting(enum ofpact_type action, enum ofpact_type outer_action)
7432{
7433 VLOG_WARN("%s action doesn't support nested action %s",
7434 ofpact_name(outer_action), ofpact_name(action));
7435 return OFPERR_OFPBAC_BAD_ARGUMENT;
7436}
7437
7438static bool
7439field_requires_ct(enum mf_field_id field)
7440{
9daf2348 7441 return field == MFF_CT_MARK || field == MFF_CT_LABEL;
8e53fe8c
JS
7442}
7443
7444/* Apply nesting constraints for actions */
d824b5b7
JS
7445static enum ofperr
7446ofpacts_verify_nested(const struct ofpact *a, enum ofpact_type outer_action)
7447{
28f5311f 7448 const struct mf_field *field = ofpact_get_mf_dst(a);
8e53fe8c
JS
7449
7450 if (field && field_requires_ct(field->id) && outer_action != OFPACT_CT) {
7451 VLOG_WARN("cannot set CT fields outside of ct action");
7452 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
7453 }
9ac0aada
JR
7454 if (a->type == OFPACT_NAT) {
7455 if (outer_action != OFPACT_CT) {
7456 VLOG_WARN("Cannot have NAT action outside of \"ct\" action");
7457 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
7458 }
7459 return 0;
7460 }
8e53fe8c
JS
7461
7462 if (outer_action) {
7463 ovs_assert(outer_action == OFPACT_WRITE_ACTIONS
7464 || outer_action == OFPACT_CT);
7465
7466 if (outer_action == OFPACT_CT) {
7467 if (!field) {
7468 return unsupported_nesting(a->type, outer_action);
7469 } else if (!field_requires_ct(field->id)) {
7470 VLOG_WARN("%s action doesn't support nested modification "
7471 "of %s", ofpact_name(outer_action), field->name);
7472 return OFPERR_OFPBAC_BAD_ARGUMENT;
7473 }
7474 }
d824b5b7
JS
7475 }
7476
7477 return 0;
7478}
7479
18080541
BP
7480/* Verifies that the 'ofpacts_len' bytes of actions in 'ofpacts' are in the
7481 * appropriate order as defined by the OpenFlow spec and as required by Open
7482 * vSwitch.
7483 *
7484 * 'allowed_ovsinsts' is a bitmap of OVSINST_* values, in which 1-bits indicate
d824b5b7
JS
7485 * instructions that are allowed within 'ofpacts[]'.
7486 *
7487 * If 'outer_action' is not zero, it specifies that the actions are nested
7488 * within another action of type 'outer_action'. */
c2d936a4
BP
7489static enum ofperr
7490ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len,
d824b5b7 7491 uint32_t allowed_ovsinsts, enum ofpact_type outer_action)
c2d936a4
BP
7492{
7493 const struct ofpact *a;
7494 enum ovs_instruction_type inst;
097d4939 7495
c2d936a4
BP
7496 inst = OVSINST_OFPIT13_METER;
7497 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
7498 enum ovs_instruction_type next;
8e53fe8c 7499 enum ofperr error;
1e7db674 7500
18080541
BP
7501 if (a->type == OFPACT_CONJUNCTION) {
7502 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
f08e39dd
BP
7503 if (a->type != OFPACT_CONJUNCTION && a->type != OFPACT_NOTE) {
7504 VLOG_WARN("\"conjunction\" actions may be used along with "
7505 "\"note\" but not any other kind of action "
7506 "(such as the \"%s\" action used here)",
96775a1c 7507 ofpact_name(a->type));
18080541
BP
7508 return OFPERR_NXBAC_BAD_CONJUNCTION;
7509 }
7510 }
7511 return 0;
7512 }
7513
8e53fe8c
JS
7514 error = ofpacts_verify_nested(a, outer_action);
7515 if (error) {
7516 return error;
d824b5b7
JS
7517 }
7518
c2d936a4
BP
7519 next = ovs_instruction_type_from_ofpact_type(a->type);
7520 if (a > ofpacts
7521 && (inst == OVSINST_OFPIT11_APPLY_ACTIONS
7522 ? next < inst
7523 : next <= inst)) {
7524 const char *name = ovs_instruction_name_from_type(inst);
7525 const char *next_name = ovs_instruction_name_from_type(next);
1e7db674 7526
c2d936a4
BP
7527 if (next == inst) {
7528 VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
7529 "1.1+ compatibility", name);
7530 } else {
7531 VLOG_WARN("invalid instruction ordering: %s must appear "
7532 "before %s, for OpenFlow 1.1+ compatibility",
7533 next_name, name);
7534 }
7535 return OFPERR_OFPBAC_UNSUPPORTED_ORDER;
7536 }
7537 if (!((1u << next) & allowed_ovsinsts)) {
7538 const char *name = ovs_instruction_name_from_type(next);
1e7db674 7539
c2d936a4
BP
7540 VLOG_WARN("%s instruction not allowed here", name);
7541 return OFPERR_OFPBIC_UNSUP_INST;
1e7db674 7542 }
c2d936a4
BP
7543
7544 inst = next;
7545 }
7546
7547 return 0;
7548}
7549\f
7550/* Converting ofpacts to OpenFlow. */
7551
7552static void
7553encode_ofpact(const struct ofpact *a, enum ofp_version ofp_version,
7554 struct ofpbuf *out)
7555{
7556 switch (a->type) {
7557#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
7558 case OFPACT_##ENUM: \
355ead69
GS
7559 encode_##ENUM(ofpact_get_##ENUM(a), ofp_version, out); \
7560 return;
c2d936a4
BP
7561 OFPACTS
7562#undef OFPACT
7563 default:
7564 OVS_NOT_REACHED();
1e7db674 7565 }
e3f8f887
JR
7566}
7567
7568/* Converts the 'ofpacts_len' bytes of ofpacts in 'ofpacts' into OpenFlow
7569 * actions in 'openflow', appending the actions to any existing data in
d01c980f 7570 * 'openflow'. */
a07c15bc 7571size_t
e3f8f887
JR
7572ofpacts_put_openflow_actions(const struct ofpact ofpacts[], size_t ofpacts_len,
7573 struct ofpbuf *openflow,
7574 enum ofp_version ofp_version)
d01c980f
BP
7575{
7576 const struct ofpact *a;
6fd6ed71 7577 size_t start_size = openflow->size;
d01c980f
BP
7578
7579 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
c2d936a4 7580 encode_ofpact(a, ofp_version, openflow);
d01c980f 7581 }
6fd6ed71 7582 return openflow->size - start_size;
d01c980f
BP
7583}
7584
c2d936a4
BP
7585static enum ovs_instruction_type
7586ofpact_is_apply_actions(const struct ofpact *a)
d01c980f 7587{
c2d936a4
BP
7588 return (ovs_instruction_type_from_ofpact_type(a->type)
7589 == OVSINST_OFPIT11_APPLY_ACTIONS);
d01c980f 7590}
8dd54666
IY
7591
7592void
e3f8f887
JR
7593ofpacts_put_openflow_instructions(const struct ofpact ofpacts[],
7594 size_t ofpacts_len,
7595 struct ofpbuf *openflow,
7596 enum ofp_version ofp_version)
8dd54666 7597{
c2d936a4 7598 const struct ofpact *end = ofpact_end(ofpacts, ofpacts_len);
8dd54666
IY
7599 const struct ofpact *a;
7600
8f2cded4
BP
7601 if (ofp_version == OFP10_VERSION) {
7602 ofpacts_put_openflow_actions(ofpacts, ofpacts_len, openflow,
7603 ofp_version);
7604 return;
7605 }
e3f8f887 7606
c2d936a4
BP
7607 a = ofpacts;
7608 while (a < end) {
7609 if (ofpact_is_apply_actions(a)) {
6fd6ed71 7610 size_t ofs = openflow->size;
8dd54666
IY
7611
7612 instruction_put_OFPIT11_APPLY_ACTIONS(openflow);
c2d936a4
BP
7613 do {
7614 encode_ofpact(a, ofp_version, openflow);
7615 a = ofpact_next(a);
7616 } while (a < end && ofpact_is_apply_actions(a));
7fdb60a7 7617 ofpacts_update_instruction_actions(openflow, ofs);
c2d936a4
BP
7618 } else {
7619 encode_ofpact(a, ofp_version, openflow);
7620 a = ofpact_next(a);
8dd54666
IY
7621 }
7622 }
7623}
d01c980f 7624\f
08d1e234
BP
7625/* Sets of supported actions. */
7626
7627/* Two-way translation between OVS's internal "OFPACT_*" representation of
7628 * actions and the "OFPAT_*" representation used in some OpenFlow version.
7629 * (OFPAT_* numbering varies from one OpenFlow version to another, so a given
7630 * instance is specific to one OpenFlow version.) */
7631struct ofpact_map {
7632 enum ofpact_type ofpact; /* Internal name for action type. */
7633 int ofpat; /* OFPAT_* number from OpenFlow spec. */
7634};
7635
7636static const struct ofpact_map *
7637get_ofpact_map(enum ofp_version version)
7638{
7639 /* OpenFlow 1.0 actions. */
7640 static const struct ofpact_map of10[] = {
7641 { OFPACT_OUTPUT, 0 },
7642 { OFPACT_SET_VLAN_VID, 1 },
7643 { OFPACT_SET_VLAN_PCP, 2 },
7644 { OFPACT_STRIP_VLAN, 3 },
7645 { OFPACT_SET_ETH_SRC, 4 },
7646 { OFPACT_SET_ETH_DST, 5 },
7647 { OFPACT_SET_IPV4_SRC, 6 },
7648 { OFPACT_SET_IPV4_DST, 7 },
7649 { OFPACT_SET_IP_DSCP, 8 },
7650 { OFPACT_SET_L4_SRC_PORT, 9 },
7651 { OFPACT_SET_L4_DST_PORT, 10 },
7652 { OFPACT_ENQUEUE, 11 },
7653 { 0, -1 },
7654 };
7655
7656 /* OpenFlow 1.1 actions. */
7657 static const struct ofpact_map of11[] = {
7658 { OFPACT_OUTPUT, 0 },
7659 { OFPACT_SET_VLAN_VID, 1 },
7660 { OFPACT_SET_VLAN_PCP, 2 },
7661 { OFPACT_SET_ETH_SRC, 3 },
7662 { OFPACT_SET_ETH_DST, 4 },
7663 { OFPACT_SET_IPV4_SRC, 5 },
7664 { OFPACT_SET_IPV4_DST, 6 },
7665 { OFPACT_SET_IP_DSCP, 7 },
7666 { OFPACT_SET_IP_ECN, 8 },
7667 { OFPACT_SET_L4_SRC_PORT, 9 },
7668 { OFPACT_SET_L4_DST_PORT, 10 },
7669 /* OFPAT_COPY_TTL_OUT (11) not supported. */
7670 /* OFPAT_COPY_TTL_IN (12) not supported. */
7671 { OFPACT_SET_MPLS_LABEL, 13 },
7672 { OFPACT_SET_MPLS_TC, 14 },
7673 { OFPACT_SET_MPLS_TTL, 15 },
7674 { OFPACT_DEC_MPLS_TTL, 16 },
7675 { OFPACT_PUSH_VLAN, 17 },
7676 { OFPACT_STRIP_VLAN, 18 },
7677 { OFPACT_PUSH_MPLS, 19 },
7678 { OFPACT_POP_MPLS, 20 },
7679 { OFPACT_SET_QUEUE, 21 },
7680 { OFPACT_GROUP, 22 },
7681 { OFPACT_SET_IP_TTL, 23 },
7682 { OFPACT_DEC_TTL, 24 },
7683 { 0, -1 },
7684 };
7685
7686 /* OpenFlow 1.2, 1.3, and 1.4 actions. */
7687 static const struct ofpact_map of12[] = {
7688 { OFPACT_OUTPUT, 0 },
7689 /* OFPAT_COPY_TTL_OUT (11) not supported. */
7690 /* OFPAT_COPY_TTL_IN (12) not supported. */
7691 { OFPACT_SET_MPLS_TTL, 15 },
7692 { OFPACT_DEC_MPLS_TTL, 16 },
7693 { OFPACT_PUSH_VLAN, 17 },
7694 { OFPACT_STRIP_VLAN, 18 },
7695 { OFPACT_PUSH_MPLS, 19 },
7696 { OFPACT_POP_MPLS, 20 },
7697 { OFPACT_SET_QUEUE, 21 },
7698 { OFPACT_GROUP, 22 },
7699 { OFPACT_SET_IP_TTL, 23 },
7700 { OFPACT_DEC_TTL, 24 },
7701 { OFPACT_SET_FIELD, 25 },
7702 /* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
7703 /* OF1.3+ OFPAT_POP_PBB (27) not supported. */
7704 { 0, -1 },
7705 };
7706
7707 switch (version) {
7708 case OFP10_VERSION:
7709 return of10;
7710
7711 case OFP11_VERSION:
7712 return of11;
7713
7714 case OFP12_VERSION:
7715 case OFP13_VERSION:
7716 case OFP14_VERSION:
7717 case OFP15_VERSION:
b79d45a1 7718 case OFP16_VERSION:
08d1e234
BP
7719 default:
7720 return of12;
7721 }
7722}
7723
7724/* Converts 'ofpacts_bitmap', a bitmap whose bits correspond to OFPACT_*
7725 * values, into a bitmap of actions suitable for OpenFlow 'version', and
7726 * returns the result. */
7727ovs_be32
7728ofpact_bitmap_to_openflow(uint64_t ofpacts_bitmap, enum ofp_version version)
7729{
7730 uint32_t openflow_bitmap = 0;
7731 const struct ofpact_map *x;
7732
7733 for (x = get_ofpact_map(version); x->ofpat >= 0; x++) {
7734 if (ofpacts_bitmap & (UINT64_C(1) << x->ofpact)) {
7735 openflow_bitmap |= 1u << x->ofpat;
7736 }
7737 }
7738 return htonl(openflow_bitmap);
7739}
7740
7741/* Converts 'ofpat_bitmap', a bitmap of actions from an OpenFlow message with
7742 * the given 'version' into a bitmap whose bits correspond to OFPACT_* values,
7743 * and returns the result. */
7744uint64_t
7745ofpact_bitmap_from_openflow(ovs_be32 ofpat_bitmap, enum ofp_version version)
7746{
7747 uint64_t ofpact_bitmap = 0;
7748 const struct ofpact_map *x;
7749
7750 for (x = get_ofpact_map(version); x->ofpat >= 0; x++) {
7751 if (ofpat_bitmap & htonl(1u << x->ofpat)) {
7752 ofpact_bitmap |= UINT64_C(1) << x->ofpact;
7753 }
7754 }
7755 return ofpact_bitmap;
7756}
7757
7758/* Appends to 's' a string representation of the set of OFPACT_* represented
7759 * by 'ofpacts_bitmap'. */
7760void
7761ofpact_bitmap_format(uint64_t ofpacts_bitmap, struct ds *s)
7762{
7763 if (!ofpacts_bitmap) {
7764 ds_put_cstr(s, "<none>");
7765 } else {
7766 while (ofpacts_bitmap) {
7767 ds_put_format(s, "%s ",
7768 ofpact_name(rightmost_1bit_idx(ofpacts_bitmap)));
7769 ofpacts_bitmap = zero_rightmost_1bit(ofpacts_bitmap);
7770 }
7771 ds_chomp(s, ' ');
7772 }
7773}
7774\f
f25d0cf3
BP
7775/* Returns true if 'action' outputs to 'port', false otherwise. */
7776static bool
4e022ec0 7777ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
f25d0cf3
BP
7778{
7779 switch (ofpact->type) {
7780 case OFPACT_OUTPUT:
7781 return ofpact_get_OUTPUT(ofpact)->port == port;
7782 case OFPACT_ENQUEUE:
7783 return ofpact_get_ENQUEUE(ofpact)->port == port;
7784 case OFPACT_CONTROLLER:
7785 return port == OFPP_CONTROLLER;
7786
7787 case OFPACT_OUTPUT_REG:
aaca4fe0 7788 case OFPACT_OUTPUT_TRUNC:
f25d0cf3
BP
7789 case OFPACT_BUNDLE:
7790 case OFPACT_SET_VLAN_VID:
7791 case OFPACT_SET_VLAN_PCP:
7792 case OFPACT_STRIP_VLAN:
3e34fbdd 7793 case OFPACT_PUSH_VLAN:
f25d0cf3
BP
7794 case OFPACT_SET_ETH_SRC:
7795 case OFPACT_SET_ETH_DST:
7796 case OFPACT_SET_IPV4_SRC:
7797 case OFPACT_SET_IPV4_DST:
04f01c24 7798 case OFPACT_SET_IP_DSCP:
ff14eb7a 7799 case OFPACT_SET_IP_ECN:
0c20dbe4 7800 case OFPACT_SET_IP_TTL:
f25d0cf3
BP
7801 case OFPACT_SET_L4_SRC_PORT:
7802 case OFPACT_SET_L4_DST_PORT:
7803 case OFPACT_REG_MOVE:
b2dd70be 7804 case OFPACT_SET_FIELD:
bd85dac1
AZ
7805 case OFPACT_STACK_PUSH:
7806 case OFPACT_STACK_POP:
f25d0cf3 7807 case OFPACT_DEC_TTL:
097d4939
JR
7808 case OFPACT_SET_MPLS_LABEL:
7809 case OFPACT_SET_MPLS_TC:
0f3f3c3d 7810 case OFPACT_SET_MPLS_TTL:
b676167a 7811 case OFPACT_DEC_MPLS_TTL:
f25d0cf3 7812 case OFPACT_SET_TUNNEL:
4cceacb9 7813 case OFPACT_WRITE_METADATA:
f25d0cf3
BP
7814 case OFPACT_SET_QUEUE:
7815 case OFPACT_POP_QUEUE:
7816 case OFPACT_FIN_TIMEOUT:
7817 case OFPACT_RESUBMIT:
7818 case OFPACT_LEARN:
18080541 7819 case OFPACT_CONJUNCTION:
f25d0cf3 7820 case OFPACT_MULTIPATH:
f25d0cf3
BP
7821 case OFPACT_NOTE:
7822 case OFPACT_EXIT:
e672ff9b 7823 case OFPACT_UNROLL_XLATE:
b02475c5
SH
7824 case OFPACT_PUSH_MPLS:
7825 case OFPACT_POP_MPLS:
29089a54 7826 case OFPACT_SAMPLE:
b19e8793 7827 case OFPACT_CLEAR_ACTIONS:
7ae62a67 7828 case OFPACT_CLONE:
7fdb60a7 7829 case OFPACT_WRITE_ACTIONS:
8dd54666 7830 case OFPACT_GOTO_TABLE:
638a19b0 7831 case OFPACT_METER:
7395c052 7832 case OFPACT_GROUP:
d4abaff5 7833 case OFPACT_DEBUG_RECIRC:
07659514 7834 case OFPACT_CT:
72fe7578 7835 case OFPACT_CT_CLEAR:
9ac0aada 7836 case OFPACT_NAT:
f25d0cf3
BP
7837 default:
7838 return false;
7839 }
7840}
7841
7842/* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
7843 * to 'port', false otherwise. */
7844bool
7845ofpacts_output_to_port(const struct ofpact *ofpacts, size_t ofpacts_len,
4e022ec0 7846 ofp_port_t port)
c2d936a4
BP
7847{
7848 const struct ofpact *a;
f25d0cf3 7849
4f20179d 7850 OFPACT_FOR_EACH_FLATTENED (a, ofpacts, ofpacts_len) {
c2d936a4
BP
7851 if (ofpact_outputs_to_port(a, port)) {
7852 return true;
7853 }
7854 }
f25d0cf3 7855
c2d936a4
BP
7856 return false;
7857}
f25d0cf3 7858
c2d936a4
BP
7859/* Returns true if any action in the 'ofpacts_len' bytes of 'ofpacts' outputs
7860 * to 'group', false otherwise. */
7861bool
7862ofpacts_output_to_group(const struct ofpact *ofpacts, size_t ofpacts_len,
7863 uint32_t group_id)
7864{
7865 const struct ofpact *a;
b02475c5 7866
4f20179d 7867 OFPACT_FOR_EACH_FLATTENED (a, ofpacts, ofpacts_len) {
c2d936a4
BP
7868 if (a->type == OFPACT_GROUP
7869 && ofpact_get_GROUP(a)->group_id == group_id) {
7870 return true;
7871 }
7872 }
b02475c5 7873
c2d936a4
BP
7874 return false;
7875}
8dd54666 7876
c2d936a4
BP
7877bool
7878ofpacts_equal(const struct ofpact *a, size_t a_len,
7879 const struct ofpact *b, size_t b_len)
7880{
7881 return a_len == b_len && !memcmp(a, b, a_len);
7882}
29089a54 7883
c2d936a4
BP
7884/* Finds the OFPACT_METER action, if any, in the 'ofpacts_len' bytes of
7885 * 'ofpacts'. If found, returns its meter ID; if not, returns 0.
7886 *
7887 * This function relies on the order of 'ofpacts' being correct (as checked by
7888 * ofpacts_verify()). */
7889uint32_t
7890ofpacts_get_meter(const struct ofpact ofpacts[], size_t ofpacts_len)
7891{
7892 const struct ofpact *a;
7fdb60a7 7893
c2d936a4
BP
7894 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
7895 enum ovs_instruction_type inst;
b19e8793 7896
c2d936a4
BP
7897 inst = ovs_instruction_type_from_ofpact_type(a->type);
7898 if (a->type == OFPACT_METER) {
7899 return ofpact_get_METER(a)->meter_id;
7900 } else if (inst > OVSINST_OFPIT13_METER) {
7901 break;
4cceacb9 7902 }
c2d936a4 7903 }
638a19b0 7904
c2d936a4
BP
7905 return 0;
7906}
7907\f
7908/* Formatting ofpacts. */
7395c052 7909
c2d936a4
BP
7910static void
7911ofpact_format(const struct ofpact *a, struct ds *s)
7912{
7913 switch (a->type) {
7914#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
7915 case OFPACT_##ENUM: \
7916 format_##ENUM(ALIGNED_CAST(const struct STRUCT *, a), s); \
7917 break;
7918 OFPACTS
7919#undef OFPACT
7920 default:
7921 OVS_NOT_REACHED();
f25d0cf3
BP
7922 }
7923}
7924
7925/* Appends a string representing the 'ofpacts_len' bytes of ofpacts in
7926 * 'ofpacts' to 'string'. */
7927void
7928ofpacts_format(const struct ofpact *ofpacts, size_t ofpacts_len,
7929 struct ds *string)
7930{
f25d0cf3 7931 if (!ofpacts_len) {
b1c5bf1f 7932 ds_put_format(string, "%sdrop%s", colors.drop, colors.end);
f25d0cf3
BP
7933 } else {
7934 const struct ofpact *a;
7935
7936 OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
7937 if (a != ofpacts) {
b1c5bf1f 7938 ds_put_char(string, ',');
f25d0cf3 7939 }
8dd54666 7940
f25d0cf3
BP
7941 ofpact_format(a, string);
7942 }
7943 }
7944}
7945\f
7946/* Internal use by helpers. */
7947
ce058104 7948/* Implementation of ofpact_put_<ENUM>(). */
f25d0cf3
BP
7949void *
7950ofpact_put(struct ofpbuf *ofpacts, enum ofpact_type type, size_t len)
7951{
7952 struct ofpact *ofpact;
7953
6fd6ed71
PS
7954 ofpacts->header = ofpbuf_put_uninit(ofpacts, len);
7955 ofpact = ofpacts->header;
f25d0cf3
BP
7956 ofpact_init(ofpact, type, len);
7957 return ofpact;
7958}
7959
ce058104 7960/* Implementation of ofpact_init_<ENUM>(). */
f25d0cf3
BP
7961void
7962ofpact_init(struct ofpact *ofpact, enum ofpact_type type, size_t len)
7963{
7964 memset(ofpact, 0, len);
7965 ofpact->type = type;
c2d936a4 7966 ofpact->raw = -1;
f25d0cf3
BP
7967 ofpact->len = len;
7968}
ce058104
BP
7969
7970/* Implementation of ofpact_finish_<ENUM>().
7971 *
7972 * Finishes composing a variable-length action (begun using
2bd318de
BP
7973 * ofpact_put_<NAME>()), by padding the action to a multiple of OFPACT_ALIGNTO
7974 * bytes and updating its embedded length field. See the large comment near
ebe12cd3
JS
7975 * the end of ofp-actions.h for more information.
7976 *
7977 * May reallocate 'ofpacts'. Callers should consider updating their 'ofpact'
7978 * pointer to the return value of this function. */
7979void *
34abaa3d 7980ofpact_finish(struct ofpbuf *ofpacts, struct ofpact *ofpact)
f25d0cf3 7981{
5308056f
JS
7982 ptrdiff_t len;
7983
6fd6ed71 7984 ovs_assert(ofpact == ofpacts->header);
5308056f 7985 len = (char *) ofpbuf_tail(ofpacts) - (char *) ofpact;
847b5649 7986 ovs_assert(len > 0 && len <= UINT16_MAX);
5308056f 7987 ofpact->len = len;
2bd318de 7988 ofpbuf_padto(ofpacts, OFPACT_ALIGN(ofpacts->size));
ebe12cd3
JS
7989
7990 return ofpacts->header;
f25d0cf3 7991}
c2d936a4 7992\f
cab50449 7993static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
7994ofpact_parse(enum ofpact_type type, char *value, struct ofpbuf *ofpacts,
7995 enum ofputil_protocol *usable_protocols)
7996{
7997 switch (type) {
7998#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
7999 case OFPACT_##ENUM: \
8000 return parse_##ENUM(value, ofpacts, usable_protocols);
8001 OFPACTS
8002#undef OFPACT
8003 default:
8004 OVS_NOT_REACHED();
8005 }
8006}
8007
8008static bool
8009ofpact_type_from_name(const char *name, enum ofpact_type *type)
8010{
8011#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \
8012 if (!strcasecmp(name, NAME)) { \
8013 *type = OFPACT_##ENUM; \
8014 return true; \
8015 }
8016 OFPACTS
8017#undef OFPACT
8018
8019 return false;
8020}
8021
8022/* Parses 'str' as a series of instructions, and appends them to 'ofpacts'.
8023 *
8024 * Returns NULL if successful, otherwise a malloc()'d string describing the
d824b5b7
JS
8025 * error. The caller is responsible for freeing the returned string.
8026 *
8027 * If 'outer_action' is specified, indicates that the actions being parsed
8028 * are nested within another action of the type specified in 'outer_action'. */
cab50449 8029static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
8030ofpacts_parse__(char *str, struct ofpbuf *ofpacts,
8031 enum ofputil_protocol *usable_protocols,
d824b5b7 8032 bool allow_instructions, enum ofpact_type outer_action)
c2d936a4
BP
8033{
8034 int prev_inst = -1;
8035 enum ofperr retval;
8036 char *key, *value;
8037 bool drop = false;
8038 char *pos;
8039
8040 pos = str;
8041 while (ofputil_parse_key_value(&pos, &key, &value)) {
8042 enum ovs_instruction_type inst = OVSINST_OFPIT11_APPLY_ACTIONS;
8043 enum ofpact_type type;
8044 char *error = NULL;
8045 ofp_port_t port;
8046
8047 if (ofpact_type_from_name(key, &type)) {
8048 error = ofpact_parse(type, value, ofpacts, usable_protocols);
8049 inst = ovs_instruction_type_from_ofpact_type(type);
8050 } else if (!strcasecmp(key, "mod_vlan_vid")) {
8051 error = parse_set_vlan_vid(value, ofpacts, true);
8052 } else if (!strcasecmp(key, "mod_vlan_pcp")) {
8053 error = parse_set_vlan_pcp(value, ofpacts, true);
8054 } else if (!strcasecmp(key, "set_nw_ttl")) {
8055 error = parse_SET_IP_TTL(value, ofpacts, usable_protocols);
8056 } else if (!strcasecmp(key, "pop_vlan")) {
8057 error = parse_pop_vlan(ofpacts);
8058 } else if (!strcasecmp(key, "set_tunnel64")) {
8059 error = parse_set_tunnel(value, ofpacts,
8060 NXAST_RAW_SET_TUNNEL64);
7eb4b1f1
BP
8061 } else if (!strcasecmp(key, "load")) {
8062 error = parse_reg_load(value, ofpacts);
c2d936a4
BP
8063 } else if (!strcasecmp(key, "bundle_load")) {
8064 error = parse_bundle_load(value, ofpacts);
8065 } else if (!strcasecmp(key, "drop")) {
8066 drop = true;
8067 } else if (!strcasecmp(key, "apply_actions")) {
8068 return xstrdup("apply_actions is the default instruction");
8069 } else if (ofputil_port_from_string(key, &port)) {
8070 ofpact_put_OUTPUT(ofpacts)->port = port;
8071 } else {
8072 return xasprintf("unknown action %s", key);
8073 }
8074 if (error) {
8075 return error;
8076 }
8077
8078 if (inst != OVSINST_OFPIT11_APPLY_ACTIONS) {
8079 if (!allow_instructions) {
8080 return xasprintf("only actions are allowed here (not "
8081 "instruction %s)",
8082 ovs_instruction_name_from_type(inst));
8083 }
8084 if (inst == prev_inst) {
8085 return xasprintf("instruction %s may be specified only once",
8086 ovs_instruction_name_from_type(inst));
8087 }
8088 }
8089 if (prev_inst != -1 && inst < prev_inst) {
8090 return xasprintf("instruction %s must be specified before %s",
8091 ovs_instruction_name_from_type(inst),
8092 ovs_instruction_name_from_type(prev_inst));
8093 }
8094 prev_inst = inst;
8095 }
c2d936a4 8096
6fd6ed71 8097 if (drop && ofpacts->size) {
c2d936a4
BP
8098 return xstrdup("\"drop\" must not be accompanied by any other action "
8099 "or instruction");
8100 }
8101
6fd6ed71 8102 retval = ofpacts_verify(ofpacts->data, ofpacts->size,
c2d936a4
BP
8103 (allow_instructions
8104 ? (1u << N_OVS_INSTRUCTIONS) - 1
d824b5b7
JS
8105 : 1u << OVSINST_OFPIT11_APPLY_ACTIONS),
8106 outer_action);
c2d936a4
BP
8107 if (retval) {
8108 return xstrdup("Incorrect instruction ordering");
8109 }
8110
8111 return NULL;
8112}
8113
cab50449 8114static char * OVS_WARN_UNUSED_RESULT
c2d936a4 8115ofpacts_parse(char *str, struct ofpbuf *ofpacts,
d824b5b7
JS
8116 enum ofputil_protocol *usable_protocols, bool allow_instructions,
8117 enum ofpact_type outer_action)
c2d936a4 8118{
6fd6ed71 8119 uint32_t orig_size = ofpacts->size;
c2d936a4 8120 char *error = ofpacts_parse__(str, ofpacts, usable_protocols,
d824b5b7 8121 allow_instructions, outer_action);
c2d936a4 8122 if (error) {
6fd6ed71 8123 ofpacts->size = orig_size;
c2d936a4
BP
8124 }
8125 return error;
8126}
8127
cab50449 8128static char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
8129ofpacts_parse_copy(const char *s_, struct ofpbuf *ofpacts,
8130 enum ofputil_protocol *usable_protocols,
d824b5b7 8131 bool allow_instructions, enum ofpact_type outer_action)
c2d936a4
BP
8132{
8133 char *error, *s;
8134
8135 *usable_protocols = OFPUTIL_P_ANY;
8136
8137 s = xstrdup(s_);
d824b5b7
JS
8138 error = ofpacts_parse(s, ofpacts, usable_protocols, allow_instructions,
8139 outer_action);
c2d936a4
BP
8140 free(s);
8141
8142 return error;
8143}
8144
8145/* Parses 's' as a set of OpenFlow actions and appends the actions to
d824b5b7
JS
8146 * 'ofpacts'. 'outer_action', if nonzero, specifies that 's' contains actions
8147 * that are nested within the action of type 'outer_action'.
c2d936a4
BP
8148 *
8149 * Returns NULL if successful, otherwise a malloc()'d string describing the
8150 * error. The caller is responsible for freeing the returned string. */
cab50449 8151char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
8152ofpacts_parse_actions(const char *s, struct ofpbuf *ofpacts,
8153 enum ofputil_protocol *usable_protocols)
8154{
d824b5b7 8155 return ofpacts_parse_copy(s, ofpacts, usable_protocols, false, 0);
c2d936a4
BP
8156}
8157
8158/* Parses 's' as a set of OpenFlow instructions and appends the instructions to
8159 * 'ofpacts'.
8160 *
8161 * Returns NULL if successful, otherwise a malloc()'d string describing the
8162 * error. The caller is responsible for freeing the returned string. */
cab50449 8163char * OVS_WARN_UNUSED_RESULT
c2d936a4
BP
8164ofpacts_parse_instructions(const char *s, struct ofpbuf *ofpacts,
8165 enum ofputil_protocol *usable_protocols)
8166{
d824b5b7 8167 return ofpacts_parse_copy(s, ofpacts, usable_protocols, true, 0);
c2d936a4 8168}
08d1e234
BP
8169
8170const char *
8171ofpact_name(enum ofpact_type type)
8172{
8173 switch (type) {
8174#define OFPACT(ENUM, STRUCT, MEMBER, NAME) case OFPACT_##ENUM: return NAME;
8175 OFPACTS
8176#undef OFPACT
8177 }
8178 return "<unknown>";
8179}
c2d936a4
BP
8180\f
8181/* Low-level action decoding and encoding functions. */
8182
8183/* Everything needed to identify a particular OpenFlow action. */
8184struct ofpact_hdrs {
8185 uint32_t vendor; /* 0 if standard, otherwise a vendor code. */
8186 uint16_t type; /* Type if standard, otherwise subtype. */
8187 uint8_t ofp_version; /* From ofp_header. */
8188};
8189
8190/* Information about a particular OpenFlow action. */
8191struct ofpact_raw_instance {
8192 /* The action's identity. */
8193 struct ofpact_hdrs hdrs;
8194 enum ofp_raw_action_type raw;
8195
8196 /* Looking up the action. */
8197 struct hmap_node decode_node; /* Based on 'hdrs'. */
8198 struct hmap_node encode_node; /* Based on 'raw' + 'hdrs.ofp_version'. */
8199
8200 /* The action's encoded size.
8201 *
8202 * If this action is fixed-length, 'min_length' == 'max_length'.
8203 * If it is variable length, then 'max_length' is ROUND_DOWN(UINT16_MAX,
8204 * OFP_ACTION_ALIGN) == 65528. */
8205 unsigned short int min_length;
8206 unsigned short int max_length;
8207
8208 /* For actions with a simple integer numeric argument, 'arg_ofs' is the
8209 * offset of that argument from the beginning of the action and 'arg_len'
8210 * its length, both in bytes.
8211 *
8212 * For actions that take other forms, these are both zero. */
8213 unsigned short int arg_ofs;
8214 unsigned short int arg_len;
8215
8216 /* The name of the action, e.g. "OFPAT_OUTPUT" or "NXAST_RESUBMIT". */
8217 const char *name;
8218
8219 /* If this action is deprecated, a human-readable string with a brief
8220 * explanation. */
8221 const char *deprecation;
8222};
8223
8224/* Action header. */
8225struct ofp_action_header {
8226 /* The meaning of other values of 'type' generally depends on the OpenFlow
8227 * version (see enum ofp_raw_action_type).
8228 *
8229 * Across all OpenFlow versions, OFPAT_VENDOR indicates that 'vendor'
8230 * designates an OpenFlow vendor ID and that the remainder of the action
8231 * structure has a vendor-defined meaning.
8232 */
8233#define OFPAT_VENDOR 0xffff
8234 ovs_be16 type;
8235
8236 /* Always a multiple of 8. */
8237 ovs_be16 len;
8238
8239 /* For type == OFPAT_VENDOR only, this is a vendor ID, e.g. NX_VENDOR_ID or
8240 * ONF_VENDOR_ID. Other 'type's use this space for some other purpose. */
8241 ovs_be32 vendor;
8242};
8243OFP_ASSERT(sizeof(struct ofp_action_header) == 8);
8244
c2d936a4
BP
8245static bool
8246ofpact_hdrs_equal(const struct ofpact_hdrs *a,
8247 const struct ofpact_hdrs *b)
8248{
8249 return (a->vendor == b->vendor
8250 && a->type == b->type
8251 && a->ofp_version == b->ofp_version);
8252}
8253
8254static uint32_t
8255ofpact_hdrs_hash(const struct ofpact_hdrs *hdrs)
8256{
8257 return hash_2words(hdrs->vendor, (hdrs->type << 16) | hdrs->ofp_version);
8258}
8259
8260#include "ofp-actions.inc2"
8261
8262static struct hmap *
8263ofpact_decode_hmap(void)
8264{
8265 static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
8266 static struct hmap hmap;
8267
8268 if (ovsthread_once_start(&once)) {
8269 struct ofpact_raw_instance *inst;
8270
8271 hmap_init(&hmap);
8272 for (inst = all_raw_instances;
8273 inst < &all_raw_instances[ARRAY_SIZE(all_raw_instances)];
8274 inst++) {
8275 hmap_insert(&hmap, &inst->decode_node,
8276 ofpact_hdrs_hash(&inst->hdrs));
8277 }
8278 ovsthread_once_done(&once);
8279 }
8280 return &hmap;
8281}
8282
8283static struct hmap *
8284ofpact_encode_hmap(void)
8285{
8286 static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
8287 static struct hmap hmap;
8288
8289 if (ovsthread_once_start(&once)) {
8290 struct ofpact_raw_instance *inst;
8291
8292 hmap_init(&hmap);
8293 for (inst = all_raw_instances;
8294 inst < &all_raw_instances[ARRAY_SIZE(all_raw_instances)];
8295 inst++) {
8296 hmap_insert(&hmap, &inst->encode_node,
8297 hash_2words(inst->raw, inst->hdrs.ofp_version));
8298 }
8299 ovsthread_once_done(&once);
8300 }
8301 return &hmap;
8302}
8303
8304static enum ofperr
8305ofpact_decode_raw(enum ofp_version ofp_version,
8306 const struct ofp_action_header *oah, size_t length,
8307 const struct ofpact_raw_instance **instp)
8308{
8309 const struct ofpact_raw_instance *inst;
8310 struct ofpact_hdrs hdrs;
8311
8312 *instp = NULL;
8313 if (length < sizeof *oah) {
8314 return OFPERR_OFPBAC_BAD_LEN;
8315 }
8316
8317 /* Get base action type. */
8318 if (oah->type == htons(OFPAT_VENDOR)) {
8319 /* Get vendor. */
8320 hdrs.vendor = ntohl(oah->vendor);
232c1e12
BP
8321 if (hdrs.vendor == NX_VENDOR_ID || hdrs.vendor == ONF_VENDOR_ID) {
8322 /* Get extension subtype. */
8323 const struct ext_action_header *nah;
c2d936a4 8324
232c1e12 8325 nah = ALIGNED_CAST(const struct ext_action_header *, oah);
c2d936a4
BP
8326 if (length < sizeof *nah) {
8327 return OFPERR_OFPBAC_BAD_LEN;
8328 }
8329 hdrs.type = ntohs(nah->subtype);
8330 } else {
8331 VLOG_WARN_RL(&rl, "OpenFlow action has unknown vendor %#"PRIx32,
8332 hdrs.vendor);
8333 return OFPERR_OFPBAC_BAD_VENDOR;
8334 }
8335 } else {
8336 hdrs.vendor = 0;
8337 hdrs.type = ntohs(oah->type);
8338 }
8339
8340 hdrs.ofp_version = ofp_version;
8341 HMAP_FOR_EACH_WITH_HASH (inst, decode_node, ofpact_hdrs_hash(&hdrs),
8342 ofpact_decode_hmap()) {
8343 if (ofpact_hdrs_equal(&hdrs, &inst->hdrs)) {
8344 *instp = inst;
8345 return 0;
8346 }
8347 }
8348
8349 return (hdrs.vendor
8350 ? OFPERR_OFPBAC_BAD_VENDOR_TYPE
8351 : OFPERR_OFPBAC_BAD_TYPE);
8352}
8353
8354static enum ofperr
8355ofpact_pull_raw(struct ofpbuf *buf, enum ofp_version ofp_version,
8356 enum ofp_raw_action_type *raw, uint64_t *arg)
8357{
6fd6ed71 8358 const struct ofp_action_header *oah = buf->data;
c2d936a4
BP
8359 const struct ofpact_raw_instance *action;
8360 unsigned int length;
8361 enum ofperr error;
8362
8363 *raw = *arg = 0;
6fd6ed71 8364 error = ofpact_decode_raw(ofp_version, oah, buf->size, &action);
c2d936a4
BP
8365 if (error) {
8366 return error;
8367 }
8368
8369 if (action->deprecation) {
8370 VLOG_INFO_RL(&rl, "%s is deprecated in %s (%s)",
8371 action->name, ofputil_version_to_string(ofp_version),
8372 action->deprecation);
8373 }
8374
8375 length = ntohs(oah->len);
6fd6ed71 8376 if (length > buf->size) {
b153b990 8377 VLOG_WARN_RL(&rl, "OpenFlow action %s length %u exceeds action buffer "
6fd6ed71 8378 "length %"PRIu32, action->name, length, buf->size);
b153b990
BP
8379 return OFPERR_OFPBAC_BAD_LEN;
8380 }
c2d936a4
BP
8381 if (length < action->min_length || length > action->max_length) {
8382 VLOG_WARN_RL(&rl, "OpenFlow action %s length %u not in valid range "
8383 "[%hu,%hu]", action->name, length,
8384 action->min_length, action->max_length);
8385 return OFPERR_OFPBAC_BAD_LEN;
8386 }
8387 if (length % 8) {
8388 VLOG_WARN_RL(&rl, "OpenFlow action %s length %u is not a multiple "
8389 "of 8", action->name, length);
8390 return OFPERR_OFPBAC_BAD_LEN;
8391 }
8392
8393 *raw = action->raw;
8394 *arg = 0;
8395 if (action->arg_len) {
8396 const uint8_t *p;
8397 int i;
8398
8399 p = ofpbuf_at_assert(buf, action->arg_ofs, action->arg_len);
8400 for (i = 0; i < action->arg_len; i++) {
8401 *arg = (*arg << 8) | p[i];
8402 }
8403 }
8404
8405 ofpbuf_pull(buf, length);
8406
8407 return 0;
8408}
8409
8410static const struct ofpact_raw_instance *
8411ofpact_raw_lookup(enum ofp_version ofp_version, enum ofp_raw_action_type raw)
8412{
8413 const struct ofpact_raw_instance *inst;
8414
8415 HMAP_FOR_EACH_WITH_HASH (inst, encode_node, hash_2words(raw, ofp_version),
8416 ofpact_encode_hmap()) {
8417 if (inst->raw == raw && inst->hdrs.ofp_version == ofp_version) {
8418 return inst;
8419 }
8420 }
8421 OVS_NOT_REACHED();
8422}
8423
8424static void *
8425ofpact_put_raw(struct ofpbuf *buf, enum ofp_version ofp_version,
8426 enum ofp_raw_action_type raw, uint64_t arg)
8427{
8428 const struct ofpact_raw_instance *inst;
8429 struct ofp_action_header *oah;
8430 const struct ofpact_hdrs *hdrs;
8431
8432 inst = ofpact_raw_lookup(ofp_version, raw);
8433 hdrs = &inst->hdrs;
8434
8435 oah = ofpbuf_put_zeros(buf, inst->min_length);
8436 oah->type = htons(hdrs->vendor ? OFPAT_VENDOR : hdrs->type);
8437 oah->len = htons(inst->min_length);
8438 oah->vendor = htonl(hdrs->vendor);
8439
8440 switch (hdrs->vendor) {
8441 case 0:
8442 break;
8443
232c1e12
BP
8444 case NX_VENDOR_ID:
8445 case ONF_VENDOR_ID: {
8446 struct ext_action_header *nah = (struct ext_action_header *) oah;
c2d936a4
BP
8447 nah->subtype = htons(hdrs->type);
8448 break;
8449 }
8450
8451 default:
8452 OVS_NOT_REACHED();
8453 }
8454
8455 if (inst->arg_len) {
8456 uint8_t *p = (uint8_t *) oah + inst->arg_ofs + inst->arg_len;
8457 int i;
8458
8459 for (i = 0; i < inst->arg_len; i++) {
8460 *--p = arg;
8461 arg >>= 8;
8462 }
8463 } else {
8464 ovs_assert(!arg);
8465 }
8466
8467 return oah;
8468}
178742f9
BP
8469
8470static void
8471pad_ofpat(struct ofpbuf *openflow, size_t start_ofs)
8472{
8473 struct ofp_action_header *oah;
8474
9ac0aada
JR
8475 ofpbuf_put_zeros(openflow, PAD_SIZE(openflow->size - start_ofs,
8476 OFP_ACTION_ALIGN));
178742f9
BP
8477
8478 oah = ofpbuf_at_assert(openflow, start_ofs, sizeof *oah);
6fd6ed71 8479 oah->len = htons(openflow->size - start_ofs);
178742f9
BP
8480}
8481