]> git.proxmox.com Git - mirror_ovs.git/blame - lib/nx-match.c
bridge: Relax the whitelist format for punix path.
[mirror_ovs.git] / lib / nx-match.c
CommitLineData
09246b99 1/*
18080541 2 * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
09246b99
BP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
18
19#include "nx-match.h"
20
685a51a5
JP
21#include <netinet/icmp6.h>
22
09246b99
BP
23#include "classifier.h"
24#include "dynamic-string.h"
178742f9 25#include "hmap.h"
6a885fd0 26#include "meta-flow.h"
f25d0cf3 27#include "ofp-actions.h"
90bf1e07 28#include "ofp-errors.h"
09246b99
BP
29#include "ofp-util.h"
30#include "ofpbuf.h"
31#include "openflow/nicira-ext.h"
32#include "packets.h"
178742f9 33#include "shash.h"
9558d2a5 34#include "tun-metadata.h"
09246b99 35#include "unaligned.h"
ddc4f8e2 36#include "util.h"
e6211adc 37#include "openvswitch/vlog.h"
09246b99
BP
38
39VLOG_DEFINE_THIS_MODULE(nx_match);
40
508a9338
BP
41/* OXM headers.
42 *
43 *
44 * Standard OXM/NXM
45 * ================
46 *
47 * The header is 32 bits long. It looks like this:
48 *
49 * |31 16 15 9| 8 7 0
50 * +----------------------------------+---------------+--+------------------+
51 * | oxm_class | oxm_field |hm| oxm_length |
52 * +----------------------------------+---------------+--+------------------+
53 *
54 * where hm stands for oxm_hasmask. It is followed by oxm_length bytes of
55 * payload. When oxm_hasmask is 0, the payload is the value of the field
56 * identified by the header; when oxm_hasmask is 1, the payload is a value for
57 * the field followed by a mask of equal length.
58 *
59 * Internally, we represent a standard OXM header as a 64-bit integer with the
60 * above information in the most-significant bits.
61 *
62 *
63 * Experimenter OXM
64 * ================
65 *
66 * The header is 64 bits long. It looks like the diagram above except that a
67 * 32-bit experimenter ID, which we call oxm_vendor and which identifies a
68 * vendor, is inserted just before the payload. Experimenter OXMs are
69 * identified by an all-1-bits oxm_class (OFPXMC12_EXPERIMENTER). The
70 * oxm_length value *includes* the experimenter ID, so that the real payload is
71 * only oxm_length - 4 bytes long.
72 *
73 * Internally, we represent an experimenter OXM header as a 64-bit integer with
74 * the standard header in the upper 32 bits and the experimenter ID in the
75 * lower 32 bits. (It would be more convenient to swap the positions of the
76 * two 32-bit words, but this would be more error-prone because experimenter
77 * OXMs are very rarely used, so accidentally passing one through a 32-bit type
78 * somewhere in the OVS code would be hard to find.)
79 */
80
178742f9
BP
81/*
82 * OXM Class IDs.
83 * The high order bit differentiate reserved classes from member classes.
84 * Classes 0x0000 to 0x7FFF are member classes, allocated by ONF.
85 * Classes 0x8000 to 0xFFFE are reserved classes, reserved for standardisation.
86 */
87enum ofp12_oxm_class {
88 OFPXMC12_NXM_0 = 0x0000, /* Backward compatibility with NXM */
89 OFPXMC12_NXM_1 = 0x0001, /* Backward compatibility with NXM */
90 OFPXMC12_OPENFLOW_BASIC = 0x8000, /* Basic class for OpenFlow */
91 OFPXMC15_PACKET_REGS = 0x8001, /* Packet registers (pipeline fields). */
92 OFPXMC12_EXPERIMENTER = 0xffff, /* Experimenter class */
93};
94
508a9338
BP
95/* Functions for extracting raw field values from OXM/NXM headers. */
96static uint32_t nxm_vendor(uint64_t header) { return header; }
97static int nxm_class(uint64_t header) { return header >> 48; }
98static int nxm_field(uint64_t header) { return (header >> 41) & 0x7f; }
99static bool nxm_hasmask(uint64_t header) { return (header >> 40) & 1; }
100static int nxm_length(uint64_t header) { return (header >> 32) & 0xff; }
899bb63d 101static uint64_t nxm_no_len(uint64_t header) { return header & 0xffffff80ffffffffULL; }
508a9338
BP
102
103static bool
104is_experimenter_oxm(uint64_t header)
105{
106 return nxm_class(header) == OFPXMC12_EXPERIMENTER;
107}
108
109/* The OXM header "length" field is somewhat tricky:
110 *
111 * - For a standard OXM header, the length is the number of bytes of the
112 * payload, and the payload consists of just the value (and mask, if
113 * present).
114 *
115 * - For an experimenter OXM header, the length is the number of bytes in
116 * the payload plus 4 (the length of the experimenter ID). That is, the
117 * experimenter ID is included in oxm_length.
118 *
119 * This function returns the length of the experimenter ID field in 'header'.
120 * That is, for an experimenter OXM (when an experimenter ID is present), it
121 * returns 4, and for a standard OXM (when no experimenter ID is present), it
122 * returns 0. */
123static int
124nxm_experimenter_len(uint64_t header)
125{
126 return is_experimenter_oxm(header) ? 4 : 0;
127}
128
129/* Returns the number of bytes that follow the header for an NXM/OXM entry
130 * with the given 'header'. */
131static int
132nxm_payload_len(uint64_t header)
133{
134 return nxm_length(header) - nxm_experimenter_len(header);
135}
136
137/* Returns the number of bytes in the header for an NXM/OXM entry with the
138 * given 'header'. */
139static int
140nxm_header_len(uint64_t header)
141{
142 return 4 + nxm_experimenter_len(header);
143}
178742f9 144
508a9338
BP
145#define NXM_HEADER(VENDOR, CLASS, FIELD, HASMASK, LENGTH) \
146 (((uint64_t) (CLASS) << 48) | \
147 ((uint64_t) (FIELD) << 41) | \
148 ((uint64_t) (HASMASK) << 40) | \
149 ((uint64_t) (LENGTH) << 32) | \
150 (VENDOR))
178742f9 151
508a9338
BP
152#define NXM_HEADER_FMT "%#"PRIx32":%d:%d:%d:%d"
153#define NXM_HEADER_ARGS(HEADER) \
154 nxm_vendor(HEADER), nxm_class(HEADER), nxm_field(HEADER), \
178742f9
BP
155 nxm_hasmask(HEADER), nxm_length(HEADER)
156
157/* Functions for turning the "hasmask" bit on or off. (This also requires
158 * adjusting the length.) */
508a9338
BP
159static uint64_t
160nxm_make_exact_header(uint64_t header)
178742f9 161{
508a9338
BP
162 int new_len = nxm_payload_len(header) / 2 + nxm_experimenter_len(header);
163 return NXM_HEADER(nxm_vendor(header), nxm_class(header),
164 nxm_field(header), 0, new_len);
178742f9 165}
508a9338
BP
166static uint64_t
167nxm_make_wild_header(uint64_t header)
178742f9 168{
508a9338
BP
169 int new_len = nxm_payload_len(header) * 2 + nxm_experimenter_len(header);
170 return NXM_HEADER(nxm_vendor(header), nxm_class(header),
171 nxm_field(header), 1, new_len);
178742f9
BP
172}
173
174/* Flow cookie.
175 *
176 * This may be used to gain the OpenFlow 1.1-like ability to restrict
177 * certain NXM-based Flow Mod and Flow Stats Request messages to flows
178 * with specific cookies. See the "nx_flow_mod" and "nx_flow_stats_request"
179 * structure definitions for more details. This match is otherwise not
180 * allowed. */
508a9338 181#define NXM_NX_COOKIE NXM_HEADER (0, 0x0001, 30, 0, 8)
178742f9
BP
182#define NXM_NX_COOKIE_W nxm_make_wild_header(NXM_NX_COOKIE)
183
184struct nxm_field {
508a9338 185 uint64_t header;
178742f9
BP
186 enum ofp_version version;
187 const char *name; /* e.g. "NXM_OF_IN_PORT". */
188
189 enum mf_field_id id;
190};
191
508a9338 192static const struct nxm_field *nxm_field_by_header(uint64_t header);
178742f9 193static const struct nxm_field *nxm_field_by_name(const char *name, size_t len);
e6556fe3
BP
194static const struct nxm_field *nxm_field_by_mf_id(enum mf_field_id,
195 enum ofp_version);
178742f9 196
508a9338 197static void nx_put_header__(struct ofpbuf *, uint64_t header, bool masked);
dc3eb953
JG
198static void nx_put_header_len(struct ofpbuf *, enum mf_field_id field,
199 enum ofp_version version, bool masked,
200 size_t n_bytes);
f8047558 201
09246b99
BP
202/* Rate limit for nx_match parse errors. These always indicate a bug in the
203 * peer and so there's not much point in showing a lot of them. */
204static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
205
178742f9
BP
206static const struct nxm_field *
207mf_parse_subfield_name(const char *name, int name_len, bool *wild);
208
178742f9
BP
209/* Returns the preferred OXM header to use for field 'id' in OpenFlow version
210 * 'version'. Specify 0 for 'version' if an NXM legacy header should be
211 * preferred over any standardized OXM header. Returns 0 if field 'id' cannot
212 * be expressed in NXM or OXM. */
508a9338 213static uint64_t
178742f9
BP
214mf_oxm_header(enum mf_field_id id, enum ofp_version version)
215{
e6556fe3 216 const struct nxm_field *f = nxm_field_by_mf_id(id, version);
178742f9
BP
217 return f ? f->header : 0;
218}
219
508a9338
BP
220/* Returns the 32-bit OXM or NXM header to use for field 'id', preferring an
221 * NXM legacy header over any standardized OXM header. Returns 0 if field 'id'
222 * cannot be expressed with a 32-bit NXM or OXM header.
223 *
224 * Whenever possible, use nx_pull_header() instead of this function, because
225 * this function cannot support 64-bit experimenter OXM headers. */
226uint32_t
227mf_nxm_header(enum mf_field_id id)
228{
229 uint64_t oxm = mf_oxm_header(id, 0);
230 return is_experimenter_oxm(oxm) ? 0 : oxm >> 32;
231}
232
233static const struct mf_field *
234mf_from_oxm_header(uint64_t header)
235{
236 const struct nxm_field *f = nxm_field_by_header(header);
237 return f ? mf_from_id(f->id) : NULL;
238}
239
178742f9
BP
240/* Returns the "struct mf_field" that corresponds to NXM or OXM header
241 * 'header', or NULL if 'header' doesn't correspond to any known field. */
242const struct mf_field *
243mf_from_nxm_header(uint32_t header)
244{
508a9338 245 return mf_from_oxm_header((uint64_t) header << 32);
178742f9
BP
246}
247
09246b99
BP
248/* Returns the width of the data for a field with the given 'header', in
249 * bytes. */
178742f9 250static int
508a9338 251nxm_field_bytes(uint64_t header)
09246b99 252{
508a9338 253 unsigned int length = nxm_payload_len(header);
178742f9 254 return nxm_hasmask(header) ? length / 2 : length;
09246b99 255}
e6556fe3 256\f
6a885fd0 257/* nx_pull_match() and helpers. */
09246b99 258
178742f9
BP
259/* Given NXM/OXM value 'value' and mask 'mask' associated with 'header', checks
260 * for any 1-bit in the value where there is a 0-bit in the mask. Returns 0 if
261 * none, otherwise an error code. */
262static bool
508a9338 263is_mask_consistent(uint64_t header, const uint8_t *value, const uint8_t *mask)
09246b99 264{
178742f9
BP
265 unsigned int width = nxm_field_bytes(header);
266 unsigned int i;
09246b99 267
178742f9
BP
268 for (i = 0; i < width; i++) {
269 if (value[i] & ~mask[i]) {
270 if (!VLOG_DROP_WARN(&rl)) {
271 VLOG_WARN_RL(&rl, "Rejecting NXM/OXM entry "NXM_HEADER_FMT " "
272 "with 1-bits in value for bits wildcarded by the "
273 "mask.", NXM_HEADER_ARGS(header));
274 }
275 return false;
09246b99 276 }
09246b99 277 }
178742f9
BP
278 return true;
279}
09246b99 280
178742f9 281static bool
508a9338 282is_cookie_pseudoheader(uint64_t header)
178742f9
BP
283{
284 return header == NXM_NX_COOKIE || header == NXM_NX_COOKIE_W;
285}
286
287static enum ofperr
508a9338 288nx_pull_header__(struct ofpbuf *b, bool allow_cookie, uint64_t *header,
178742f9
BP
289 const struct mf_field **field)
290{
6fd6ed71 291 if (b->size < 4) {
508a9338 292 goto bad_len;
09246b99 293 }
508a9338 294
6fd6ed71 295 *header = ((uint64_t) ntohl(get_unaligned_be32(b->data))) << 32;
508a9338 296 if (is_experimenter_oxm(*header)) {
6fd6ed71 297 if (b->size < 8) {
508a9338
BP
298 goto bad_len;
299 }
6fd6ed71 300 *header = ntohll(get_unaligned_be64(b->data));
508a9338
BP
301 }
302 if (nxm_length(*header) <= nxm_experimenter_len(*header)) {
303 VLOG_WARN_RL(&rl, "OXM header "NXM_HEADER_FMT" has invalid length %d "
304 "(minimum is %d)",
305 NXM_HEADER_ARGS(*header), nxm_length(*header),
306 nxm_header_len(*header) + 1);
178742f9
BP
307 goto error;
308 }
508a9338
BP
309 ofpbuf_pull(b, nxm_header_len(*header));
310
178742f9 311 if (field) {
508a9338 312 *field = mf_from_oxm_header(*header);
178742f9
BP
313 if (!*field && !(allow_cookie && is_cookie_pseudoheader(*header))) {
314 VLOG_DBG_RL(&rl, "OXM header "NXM_HEADER_FMT" is unknown",
315 NXM_HEADER_ARGS(*header));
316 return OFPERR_OFPBMC_BAD_FIELD;
317 }
09246b99
BP
318 }
319
178742f9
BP
320 return 0;
321
508a9338
BP
322bad_len:
323 VLOG_DBG_RL(&rl, "encountered partial (%"PRIu32"-byte) OXM entry",
6fd6ed71 324 b->size);
178742f9
BP
325error:
326 *header = 0;
38221f4e
BP
327 if (field) {
328 *field = NULL;
329 }
178742f9 330 return OFPERR_OFPBMC_BAD_LEN;
09246b99
BP
331}
332
11b8d049
JG
333static void
334copy_entry_value(const struct mf_field *field, union mf_value *value,
335 const uint8_t *payload, int width)
336{
337 int copy_len;
338 void *copy_dst;
339
340 copy_dst = value;
341 copy_len = MIN(width, field ? field->n_bytes : sizeof *value);
342
343 if (field && field->variable_len) {
344 memset(value, 0, field->n_bytes);
345 copy_dst = &value->u8 + field->n_bytes - copy_len;
346 }
347
348 memcpy(copy_dst, payload, copy_len);
349}
350
3947cc76 351static enum ofperr
508a9338 352nx_pull_entry__(struct ofpbuf *b, bool allow_cookie, uint64_t *header,
11b8d049 353 const struct mf_field **field_,
178742f9 354 union mf_value *value, union mf_value *mask)
e1cfc4e4 355{
11b8d049 356 const struct mf_field *field;
178742f9
BP
357 enum ofperr header_error;
358 unsigned int payload_len;
359 const uint8_t *payload;
360 int width;
e1cfc4e4 361
11b8d049 362 header_error = nx_pull_header__(b, allow_cookie, header, &field);
178742f9
BP
363 if (header_error && header_error != OFPERR_OFPBMC_BAD_FIELD) {
364 return header_error;
365 }
366
508a9338 367 payload_len = nxm_payload_len(*header);
178742f9
BP
368 payload = ofpbuf_try_pull(b, payload_len);
369 if (!payload) {
370 VLOG_DBG_RL(&rl, "OXM header "NXM_HEADER_FMT" calls for %u-byte "
371 "payload but only %"PRIu32" bytes follow OXM header",
6fd6ed71 372 NXM_HEADER_ARGS(*header), payload_len, b->size);
178742f9
BP
373 return OFPERR_OFPBMC_BAD_LEN;
374 }
375
376 width = nxm_field_bytes(*header);
377 if (nxm_hasmask(*header)
378 && !is_mask_consistent(*header, payload, payload + width)) {
379 return OFPERR_OFPBMC_BAD_WILDCARDS;
380 }
381
11b8d049
JG
382 copy_entry_value(field, value, payload, width);
383
178742f9
BP
384 if (mask) {
385 if (nxm_hasmask(*header)) {
11b8d049 386 copy_entry_value(field, mask, payload + width, width);
178742f9 387 } else {
11b8d049 388 memset(mask, 0xff, sizeof *mask);
178742f9
BP
389 }
390 } else if (nxm_hasmask(*header)) {
391 VLOG_DBG_RL(&rl, "OXM header "NXM_HEADER_FMT" includes mask but "
392 "masked OXMs are not allowed here",
393 NXM_HEADER_ARGS(*header));
394 return OFPERR_OFPBMC_BAD_MASK;
395 }
396
11b8d049
JG
397 if (field_) {
398 *field_ = field;
399 return header_error;
400 }
401
402 return 0;
178742f9
BP
403}
404
405/* Attempts to pull an NXM or OXM header, value, and mask (if present) from the
406 * beginning of 'b'. If successful, stores a pointer to the "struct mf_field"
407 * corresponding to the pulled header in '*field', the value into '*value',
408 * and the mask into '*mask', and returns 0. On error, returns an OpenFlow
409 * error; in this case, some bytes might have been pulled off 'b' anyhow, and
410 * the output parameters might have been modified.
411 *
412 * If a NULL 'mask' is supplied, masked OXM or NXM entries are treated as
413 * errors (with OFPERR_OFPBMC_BAD_MASK).
414 */
415enum ofperr
416nx_pull_entry(struct ofpbuf *b, const struct mf_field **field,
417 union mf_value *value, union mf_value *mask)
418{
508a9338 419 uint64_t header;
178742f9
BP
420
421 return nx_pull_entry__(b, false, &header, field, value, mask);
422}
423
424/* Attempts to pull an NXM or OXM header from the beginning of 'b'. If
425 * successful, stores a pointer to the "struct mf_field" corresponding to the
426 * pulled header in '*field', stores the header's hasmask bit in '*masked'
427 * (true if hasmask=1, false if hasmask=0), and returns 0. On error, returns
428 * an OpenFlow error; in this case, some bytes might have been pulled off 'b'
429 * anyhow, and the output parameters might have been modified.
430 *
431 * If NULL 'masked' is supplied, masked OXM or NXM headers are treated as
432 * errors (with OFPERR_OFPBMC_BAD_MASK).
433 */
434enum ofperr
435nx_pull_header(struct ofpbuf *b, const struct mf_field **field, bool *masked)
436{
437 enum ofperr error;
508a9338 438 uint64_t header;
178742f9
BP
439
440 error = nx_pull_header__(b, false, &header, field);
441 if (masked) {
442 *masked = !error && nxm_hasmask(header);
443 } else if (!error && nxm_hasmask(header)) {
444 error = OFPERR_OFPBMC_BAD_MASK;
445 }
446 return error;
447}
448
449static enum ofperr
450nx_pull_match_entry(struct ofpbuf *b, bool allow_cookie,
451 const struct mf_field **field,
452 union mf_value *value, union mf_value *mask)
453{
454 enum ofperr error;
508a9338 455 uint64_t header;
178742f9
BP
456
457 error = nx_pull_entry__(b, allow_cookie, &header, field, value, mask);
458 if (error) {
459 return error;
460 }
461 if (field && *field) {
462 if (!mf_is_mask_valid(*field, mask)) {
463 VLOG_DBG_RL(&rl, "bad mask for field %s", (*field)->name);
464 return OFPERR_OFPBMC_BAD_MASK;
465 }
466 if (!mf_is_value_valid(*field, value)) {
467 VLOG_DBG_RL(&rl, "bad value for field %s", (*field)->name);
468 return OFPERR_OFPBMC_BAD_VALUE;
e1cfc4e4
BP
469 }
470 }
3947cc76 471 return 0;
e1cfc4e4
BP
472}
473
90bf1e07 474static enum ofperr
7623f4dd 475nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict,
81a76618 476 struct match *match, ovs_be64 *cookie, ovs_be64 *cookie_mask)
09246b99 477{
178742f9 478 struct ofpbuf b;
09246b99 479
cb22974d 480 ovs_assert((cookie != NULL) == (cookie_mask != NULL));
e729e793 481
81a76618 482 match_init_catchall(match);
a3a0c29e
BP
483 if (cookie) {
484 *cookie = *cookie_mask = htonll(0);
485 }
a3a0c29e 486
178742f9 487 ofpbuf_use_const(&b, p, match_len);
6fd6ed71
PS
488 while (b.size) {
489 const uint8_t *pos = b.data;
178742f9
BP
490 const struct mf_field *field;
491 union mf_value value;
492 union mf_value mask;
90bf1e07 493 enum ofperr error;
09246b99 494
178742f9
BP
495 error = nx_pull_match_entry(&b, cookie != NULL, &field, &value, &mask);
496 if (error) {
497 if (error == OFPERR_OFPBMC_BAD_FIELD && !strict) {
498 continue;
499 }
500 } else if (!field) {
501 if (!cookie) {
2e0525bc 502 error = OFPERR_OFPBMC_BAD_FIELD;
178742f9
BP
503 } else if (*cookie_mask) {
504 error = OFPERR_OFPBMC_DUP_FIELD;
102ce766 505 } else {
178742f9
BP
506 *cookie = value.be64;
507 *cookie_mask = mask.be64;
102ce766 508 }
178742f9 509 } else if (!mf_are_prereqs_ok(field, &match->flow)) {
2e0525bc 510 error = OFPERR_OFPBMC_BAD_PREREQ;
178742f9 511 } else if (!mf_is_all_wild(field, &match->wc)) {
2e0525bc 512 error = OFPERR_OFPBMC_DUP_FIELD;
72333065 513 } else {
178742f9 514 mf_set(field, &value, &mask, match);
e729e793
JP
515 }
516
09246b99 517 if (error) {
178742f9
BP
518 VLOG_DBG_RL(&rl, "error parsing OXM at offset %"PRIdPTR" "
519 "within match (%s)", pos -
520 p, ofperr_to_string(error));
09246b99
BP
521 return error;
522 }
09246b99
BP
523 }
524
178742f9 525 return 0;
09246b99 526}
102ce766 527
7623f4dd
SH
528static enum ofperr
529nx_pull_match__(struct ofpbuf *b, unsigned int match_len, bool strict,
81a76618 530 struct match *match,
7623f4dd
SH
531 ovs_be64 *cookie, ovs_be64 *cookie_mask)
532{
533 uint8_t *p = NULL;
534
535 if (match_len) {
536 p = ofpbuf_try_pull(b, ROUND_UP(match_len, 8));
537 if (!p) {
538 VLOG_DBG_RL(&rl, "nx_match length %u, rounded up to a "
539 "multiple of 8, is longer than space in message (max "
6fd6ed71 540 "length %"PRIu32")", match_len, b->size);
7623f4dd
SH
541 return OFPERR_OFPBMC_BAD_LEN;
542 }
543 }
544
81a76618 545 return nx_pull_raw(p, match_len, strict, match, cookie, cookie_mask);
7623f4dd
SH
546}
547
102ce766 548/* Parses the nx_match formatted match description in 'b' with length
81a76618
BP
549 * 'match_len'. Stores the results in 'match'. If 'cookie' and 'cookie_mask'
550 * are valid pointers, then stores the cookie and mask in them if 'b' contains
551 * a "NXM_NX_COOKIE*" match. Otherwise, stores 0 in both.
102ce766 552 *
81a76618 553 * Fails with an error upon encountering an unknown NXM header.
102ce766
EJ
554 *
555 * Returns 0 if successful, otherwise an OpenFlow error code. */
90bf1e07 556enum ofperr
81a76618 557nx_pull_match(struct ofpbuf *b, unsigned int match_len, struct match *match,
102ce766
EJ
558 ovs_be64 *cookie, ovs_be64 *cookie_mask)
559{
81a76618 560 return nx_pull_match__(b, match_len, true, match, cookie, cookie_mask);
102ce766
EJ
561}
562
81a76618
BP
563/* Behaves the same as nx_pull_match(), but skips over unknown NXM headers,
564 * instead of failing with an error. */
90bf1e07 565enum ofperr
102ce766 566nx_pull_match_loose(struct ofpbuf *b, unsigned int match_len,
81a76618 567 struct match *match,
102ce766
EJ
568 ovs_be64 *cookie, ovs_be64 *cookie_mask)
569{
81a76618 570 return nx_pull_match__(b, match_len, false, match, cookie, cookie_mask);
102ce766 571}
7623f4dd
SH
572
573static enum ofperr
81a76618 574oxm_pull_match__(struct ofpbuf *b, bool strict, struct match *match)
7623f4dd 575{
6fd6ed71 576 struct ofp11_match_header *omh = b->data;
7623f4dd
SH
577 uint8_t *p;
578 uint16_t match_len;
579
6fd6ed71 580 if (b->size < sizeof *omh) {
7623f4dd
SH
581 return OFPERR_OFPBMC_BAD_LEN;
582 }
583
584 match_len = ntohs(omh->length);
585 if (match_len < sizeof *omh) {
586 return OFPERR_OFPBMC_BAD_LEN;
587 }
588
589 if (omh->type != htons(OFPMT_OXM)) {
590 return OFPERR_OFPBMC_BAD_TYPE;
591 }
592
593 p = ofpbuf_try_pull(b, ROUND_UP(match_len, 8));
594 if (!p) {
595 VLOG_DBG_RL(&rl, "oxm length %u, rounded up to a "
596 "multiple of 8, is longer than space in message (max "
6fd6ed71 597 "length %"PRIu32")", match_len, b->size);
7623f4dd
SH
598 return OFPERR_OFPBMC_BAD_LEN;
599 }
600
601 return nx_pull_raw(p + sizeof *omh, match_len - sizeof *omh,
81a76618 602 strict, match, NULL, NULL);
7623f4dd
SH
603}
604
aa0667bc
YT
605/* Parses the oxm formatted match description preceded by a struct
606 * ofp11_match_header in 'b'. Stores the result in 'match'.
7623f4dd
SH
607 *
608 * Fails with an error when encountering unknown OXM headers.
609 *
610 * Returns 0 if successful, otherwise an OpenFlow error code. */
611enum ofperr
81a76618 612oxm_pull_match(struct ofpbuf *b, struct match *match)
7623f4dd 613{
81a76618 614 return oxm_pull_match__(b, true, match);
7623f4dd
SH
615}
616
617/* Behaves the same as oxm_pull_match() with one exception. Skips over unknown
aa0667bc 618 * OXM headers instead of failing with an error when they are encountered. */
7623f4dd 619enum ofperr
81a76618 620oxm_pull_match_loose(struct ofpbuf *b, struct match *match)
7623f4dd 621{
81a76618 622 return oxm_pull_match__(b, false, match);
7623f4dd 623}
bc65c25a
SH
624
625/* Verify an array of OXM TLVs treating value of each TLV as a mask,
626 * disallowing masks in each TLV and ignoring pre-requisites. */
627enum ofperr
628oxm_pull_field_array(const void *fields_data, size_t fields_len,
629 struct field_array *fa)
630{
631 struct ofpbuf b;
632
633 ofpbuf_use_const(&b, fields_data, fields_len);
634 while (b.size) {
635 const uint8_t *pos = b.data;
636 const struct mf_field *field;
637 union mf_value value;
638 enum ofperr error;
639 uint64_t header;
640
641 error = nx_pull_entry__(&b, false, &header, &field, &value, NULL);
642 if (error) {
643 VLOG_DBG_RL(&rl, "error pulling field array field");
644 return error;
645 } else if (!field) {
646 VLOG_DBG_RL(&rl, "unknown field array field");
647 error = OFPERR_OFPBMC_BAD_FIELD;
648 } else if (bitmap_is_set(fa->used.bm, field->id)) {
649 VLOG_DBG_RL(&rl, "duplicate field array field '%s'", field->name);
650 error = OFPERR_OFPBMC_DUP_FIELD;
651 } else if (!mf_is_mask_valid(field, &value)) {
652 VLOG_DBG_RL(&rl, "bad mask in field array field '%s'", field->name);
653 return OFPERR_OFPBMC_BAD_MASK;
654 } else {
655 field_array_set(field->id, &value, fa);
656 }
657
658 if (error) {
659 const uint8_t *start = fields_data;
660
661 VLOG_DBG_RL(&rl, "error parsing OXM at offset %"PRIdPTR" "
662 "within field array (%s)", pos - start,
663 ofperr_to_string(error));
664 return error;
665 }
666 }
667
668 return 0;
669}
09246b99
BP
670\f
671/* nx_put_match() and helpers.
672 *
673 * 'put' functions whose names end in 'w' add a wildcarded field.
674 * 'put' functions whose names end in 'm' add a field that might be wildcarded.
675 * Other 'put' functions add exact-match fields.
676 */
677
678static void
f8047558
BP
679nxm_put_unmasked(struct ofpbuf *b, enum mf_field_id field,
680 enum ofp_version version, const void *value, size_t n_bytes)
09246b99 681{
dc3eb953 682 nx_put_header_len(b, field, version, false, n_bytes);
f8047558 683 ofpbuf_put(b, value, n_bytes);
09246b99
BP
684}
685
9558d2a5 686void
f8047558
BP
687nxm_put(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
688 const void *value, const void *mask, size_t n_bytes)
66642cb4 689{
f8047558
BP
690 if (!is_all_zeros(mask, n_bytes)) {
691 bool masked = !is_all_ones(mask, n_bytes);
dc3eb953 692 nx_put_header_len(b, field, version, masked, n_bytes);
f8047558
BP
693 ofpbuf_put(b, value, n_bytes);
694 if (masked) {
695 ofpbuf_put(b, mask, n_bytes);
696 }
66642cb4
BP
697 }
698}
699
09246b99 700static void
f8047558
BP
701nxm_put_8m(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
702 uint8_t value, uint8_t mask)
09246b99 703{
f8047558 704 nxm_put(b, field, version, &value, &mask, sizeof value);
09246b99
BP
705}
706
707static void
f8047558
BP
708nxm_put_8(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
709 uint8_t value)
09246b99 710{
f8047558 711 nxm_put_unmasked(b, field, version, &value, sizeof value);
09246b99
BP
712}
713
714static void
f8047558
BP
715nxm_put_16m(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
716 ovs_be16 value, ovs_be16 mask)
09246b99 717{
f8047558 718 nxm_put(b, field, version, &value, &mask, sizeof value);
09246b99
BP
719}
720
721static void
f8047558
BP
722nxm_put_16(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
723 ovs_be16 value)
09246b99 724{
f8047558 725 nxm_put_unmasked(b, field, version, &value, sizeof value);
09246b99
BP
726}
727
8368c090 728static void
f8047558
BP
729nxm_put_32m(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
730 ovs_be32 value, ovs_be32 mask)
8368c090 731{
f8047558 732 nxm_put(b, field, version, &value, &mask, sizeof value);
8368c090
BP
733}
734
735static void
f8047558
BP
736nxm_put_32(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
737 ovs_be32 value)
8368c090 738{
f8047558 739 nxm_put_unmasked(b, field, version, &value, sizeof value);
8368c090
BP
740}
741
09246b99 742static void
f8047558
BP
743nxm_put_64m(struct ofpbuf *b, enum mf_field_id field, enum ofp_version version,
744 ovs_be64 value, ovs_be64 mask)
09246b99 745{
f8047558 746 nxm_put(b, field, version, &value, &mask, sizeof value);
09246b99
BP
747}
748
1e37a2d7 749static void
f8047558
BP
750nxm_put_eth_masked(struct ofpbuf *b,
751 enum mf_field_id field, enum ofp_version version,
74ff3298 752 const struct eth_addr value, const struct eth_addr mask)
1e37a2d7 753{
74ff3298 754 nxm_put(b, field, version, value.ea, mask.ea, ETH_ADDR_LEN);
1e37a2d7
BP
755}
756
d31f1109 757static void
f8047558
BP
758nxm_put_ipv6(struct ofpbuf *b,
759 enum mf_field_id field, enum ofp_version version,
d31f1109
JP
760 const struct in6_addr *value, const struct in6_addr *mask)
761{
f8047558
BP
762 nxm_put(b, field, version, value->s6_addr, mask->s6_addr,
763 sizeof value->s6_addr);
d31f1109
JP
764}
765
7257b535 766static void
f8047558
BP
767nxm_put_frag(struct ofpbuf *b, const struct match *match,
768 enum ofp_version version)
7257b535 769{
f8047558
BP
770 uint8_t nw_frag = match->flow.nw_frag & FLOW_NW_FRAG_MASK;
771 uint8_t nw_frag_mask = match->wc.masks.nw_frag & FLOW_NW_FRAG_MASK;
7257b535 772
f8047558
BP
773 nxm_put_8m(b, MFF_IP_FRAG, version, nw_frag,
774 nw_frag_mask == FLOW_NW_FRAG_MASK ? UINT8_MAX : nw_frag_mask);
7257b535
BP
775}
776
5e10215d
BP
777/* Appends to 'b' a set of OXM or NXM matches for the IPv4 or IPv6 fields in
778 * 'match'. */
8e7082b0 779static void
9d84066c 780nxm_put_ip(struct ofpbuf *b, const struct match *match, enum ofp_version oxm)
8e7082b0 781{
81a76618 782 const struct flow *flow = &match->flow;
8e7082b0 783
5e10215d 784 if (flow->dl_type == htons(ETH_TYPE_IP)) {
f8047558 785 nxm_put_32m(b, MFF_IPV4_SRC, oxm,
5e10215d 786 flow->nw_src, match->wc.masks.nw_src);
f8047558 787 nxm_put_32m(b, MFF_IPV4_DST, oxm,
5e10215d
BP
788 flow->nw_dst, match->wc.masks.nw_dst);
789 } else {
f8047558 790 nxm_put_ipv6(b, MFF_IPV6_SRC, oxm,
5e10215d 791 &flow->ipv6_src, &match->wc.masks.ipv6_src);
f8047558 792 nxm_put_ipv6(b, MFF_IPV6_DST, oxm,
5e10215d
BP
793 &flow->ipv6_dst, &match->wc.masks.ipv6_dst);
794 }
795
21119b3e 796 nxm_put_frag(b, match, oxm);
8e7082b0 797
81a76618 798 if (match->wc.masks.nw_tos & IP_DSCP_MASK) {
1638b906 799 if (oxm) {
f8047558 800 nxm_put_8(b, MFF_IP_DSCP_SHIFTED, oxm,
9d84066c 801 flow->nw_tos >> 2);
1638b906 802 } else {
f8047558 803 nxm_put_8(b, MFF_IP_DSCP, oxm,
9d84066c 804 flow->nw_tos & IP_DSCP_MASK);
1638b906 805 }
8e7082b0
BP
806 }
807
81a76618 808 if (match->wc.masks.nw_tos & IP_ECN_MASK) {
f8047558 809 nxm_put_8(b, MFF_IP_ECN, oxm,
b5ae8913 810 flow->nw_tos & IP_ECN_MASK);
8e7082b0
BP
811 }
812
81a76618 813 if (!oxm && match->wc.masks.nw_ttl) {
f8047558 814 nxm_put_8(b, MFF_IP_TTL, oxm, flow->nw_ttl);
8e7082b0
BP
815 }
816
f8047558 817 nxm_put_32m(b, MFF_IPV6_LABEL, oxm,
5e10215d
BP
818 flow->ipv6_label, match->wc.masks.ipv6_label);
819
81a76618 820 if (match->wc.masks.nw_proto) {
f8047558 821 nxm_put_8(b, MFF_IP_PROTO, oxm, flow->nw_proto);
8e7082b0
BP
822
823 if (flow->nw_proto == IPPROTO_TCP) {
f8047558 824 nxm_put_16m(b, MFF_TCP_SRC, oxm,
81a76618 825 flow->tp_src, match->wc.masks.tp_src);
f8047558 826 nxm_put_16m(b, MFF_TCP_DST, oxm,
81a76618 827 flow->tp_dst, match->wc.masks.tp_dst);
f8047558 828 nxm_put_16m(b, MFF_TCP_FLAGS, oxm,
dc235f7f 829 flow->tcp_flags, match->wc.masks.tcp_flags);
8e7082b0 830 } else if (flow->nw_proto == IPPROTO_UDP) {
f8047558 831 nxm_put_16m(b, MFF_UDP_SRC, oxm,
81a76618 832 flow->tp_src, match->wc.masks.tp_src);
f8047558 833 nxm_put_16m(b, MFF_UDP_DST, oxm,
81a76618 834 flow->tp_dst, match->wc.masks.tp_dst);
0d56eaf2 835 } else if (flow->nw_proto == IPPROTO_SCTP) {
f8047558 836 nxm_put_16m(b, MFF_SCTP_SRC, oxm, flow->tp_src,
0d56eaf2 837 match->wc.masks.tp_src);
f8047558 838 nxm_put_16m(b, MFF_SCTP_DST, oxm, flow->tp_dst,
0d56eaf2 839 match->wc.masks.tp_dst);
5e10215d
BP
840 } else if (is_icmpv4(flow)) {
841 if (match->wc.masks.tp_src) {
f8047558 842 nxm_put_8(b, MFF_ICMPV4_TYPE, oxm,
5e10215d
BP
843 ntohs(flow->tp_src));
844 }
845 if (match->wc.masks.tp_dst) {
f8047558 846 nxm_put_8(b, MFF_ICMPV4_CODE, oxm,
5e10215d
BP
847 ntohs(flow->tp_dst));
848 }
849 } else if (is_icmpv6(flow)) {
81a76618 850 if (match->wc.masks.tp_src) {
f8047558 851 nxm_put_8(b, MFF_ICMPV6_TYPE, oxm,
5e10215d 852 ntohs(flow->tp_src));
8e7082b0 853 }
81a76618 854 if (match->wc.masks.tp_dst) {
f8047558 855 nxm_put_8(b, MFF_ICMPV6_CODE, oxm,
5e10215d
BP
856 ntohs(flow->tp_dst));
857 }
858 if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) ||
859 flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) {
f8047558 860 nxm_put_ipv6(b, MFF_ND_TARGET, oxm,
5e10215d
BP
861 &flow->nd_target, &match->wc.masks.nd_target);
862 if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) {
f8047558 863 nxm_put_eth_masked(b, MFF_ND_SLL, oxm,
5e10215d
BP
864 flow->arp_sha, match->wc.masks.arp_sha);
865 }
866 if (flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) {
f8047558 867 nxm_put_eth_masked(b, MFF_ND_TLL, oxm,
5e10215d
BP
868 flow->arp_tha, match->wc.masks.arp_tha);
869 }
8e7082b0
BP
870 }
871 }
872 }
873}
874
81a76618 875/* Appends to 'b' the nx_match format that expresses 'match'. For Flow Mod and
7623f4dd
SH
876 * Flow Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
877 * Otherwise, 'cookie_mask' should be zero.
4d0ed519 878 *
9d84066c
BP
879 * Specify 'oxm' as 0 to express the match in NXM format; otherwise, specify
880 * 'oxm' as the OpenFlow version number for the OXM format to use.
881 *
4d0ed519
BP
882 * This function can cause 'b''s data to be reallocated.
883 *
884 * Returns the number of bytes appended to 'b', excluding padding.
885 *
81a76618 886 * If 'match' is a catch-all rule that matches every packet, then this function
4d0ed519 887 * appends nothing to 'b' and returns 0. */
7623f4dd 888static int
9d84066c 889nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
7623f4dd 890 ovs_be64 cookie, ovs_be64 cookie_mask)
09246b99 891{
81a76618 892 const struct flow *flow = &match->flow;
6fd6ed71 893 const size_t start_len = b->size;
09246b99 894 int match_len;
b6c9e612 895 int i;
09246b99 896
b666962b 897 BUILD_ASSERT_DECL(FLOW_WC_SEQ == 33);
a877206f 898
09246b99 899 /* Metadata. */
a79f29f2 900 if (match->wc.masks.dp_hash) {
f8047558 901 nxm_put_32m(b, MFF_DP_HASH, oxm,
447b6582 902 htonl(flow->dp_hash), htonl(match->wc.masks.dp_hash));
a79f29f2
AZ
903 }
904
905 if (match->wc.masks.recirc_id) {
f8047558 906 nxm_put_32(b, MFF_RECIRC_ID, oxm, htonl(flow->recirc_id));
a79f29f2
AZ
907 }
908
18080541
BP
909 if (match->wc.masks.conj_id) {
910 nxm_put_32(b, MFF_CONJ_ID, oxm, htonl(flow->conj_id));
911 }
912
4e022ec0
AW
913 if (match->wc.masks.in_port.ofp_port) {
914 ofp_port_t in_port = flow->in_port.ofp_port;
b5ae8913 915 if (oxm) {
f8047558 916 nxm_put_32(b, MFF_IN_PORT_OXM, oxm,
9d84066c 917 ofputil_port_to_ofp11(in_port));
b5ae8913 918 } else {
f8047558 919 nxm_put_16(b, MFF_IN_PORT, oxm,
9d84066c 920 htons(ofp_to_u16(in_port)));
b5ae8913 921 }
09246b99 922 }
c61f3870
BP
923 if (match->wc.masks.actset_output) {
924 nxm_put_32(b, MFF_ACTSET_OUTPUT, oxm,
925 ofputil_port_to_ofp11(flow->actset_output));
926 }
09246b99
BP
927
928 /* Ethernet. */
f8047558 929 nxm_put_eth_masked(b, MFF_ETH_SRC, oxm,
81a76618 930 flow->dl_src, match->wc.masks.dl_src);
f8047558 931 nxm_put_eth_masked(b, MFF_ETH_DST, oxm,
81a76618 932 flow->dl_dst, match->wc.masks.dl_dst);
f8047558 933 nxm_put_16m(b, MFF_ETH_TYPE, oxm,
e2170cff 934 ofputil_dl_type_to_openflow(flow->dl_type),
81a76618 935 match->wc.masks.dl_type);
09246b99 936
95f61ba8
SH
937 /* 802.1Q. */
938 if (oxm) {
26720e24
BP
939 ovs_be16 VID_CFI_MASK = htons(VLAN_VID_MASK | VLAN_CFI);
940 ovs_be16 vid = flow->vlan_tci & VID_CFI_MASK;
81a76618 941 ovs_be16 mask = match->wc.masks.vlan_tci & VID_CFI_MASK;
95f61ba8
SH
942
943 if (mask == htons(VLAN_VID_MASK | VLAN_CFI)) {
f8047558 944 nxm_put_16(b, MFF_VLAN_VID, oxm, vid);
95f61ba8 945 } else if (mask) {
f8047558 946 nxm_put_16m(b, MFF_VLAN_VID, oxm, vid, mask);
95f61ba8
SH
947 }
948
81a76618 949 if (vid && vlan_tci_to_pcp(match->wc.masks.vlan_tci)) {
f8047558 950 nxm_put_8(b, MFF_VLAN_PCP, oxm,
9d84066c 951 vlan_tci_to_pcp(flow->vlan_tci));
95f61ba8
SH
952 }
953
954 } else {
f8047558 955 nxm_put_16m(b, MFF_VLAN_TCI, oxm, flow->vlan_tci,
81a76618 956 match->wc.masks.vlan_tci);
95f61ba8 957 }
09246b99 958
b02475c5
SH
959 /* MPLS. */
960 if (eth_type_mpls(flow->dl_type)) {
8bfd0fda 961 if (match->wc.masks.mpls_lse[0] & htonl(MPLS_TC_MASK)) {
f8047558 962 nxm_put_8(b, MFF_MPLS_TC, oxm,
9d84066c 963 mpls_lse_to_tc(flow->mpls_lse[0]));
b02475c5
SH
964 }
965
8bfd0fda 966 if (match->wc.masks.mpls_lse[0] & htonl(MPLS_BOS_MASK)) {
f8047558 967 nxm_put_8(b, MFF_MPLS_BOS, oxm,
9d84066c 968 mpls_lse_to_bos(flow->mpls_lse[0]));
b02475c5
SH
969 }
970
8bfd0fda 971 if (match->wc.masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK)) {
f8047558 972 nxm_put_32(b, MFF_MPLS_LABEL, oxm,
8bfd0fda 973 htonl(mpls_lse_to_label(flow->mpls_lse[0])));
b02475c5
SH
974 }
975 }
976
66642cb4 977 /* L3. */
5e10215d
BP
978 if (is_ip_any(flow)) {
979 nxm_put_ip(b, match, oxm);
8087f5ff
MM
980 } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
981 flow->dl_type == htons(ETH_TYPE_RARP)) {
09246b99 982 /* ARP. */
81a76618 983 if (match->wc.masks.nw_proto) {
f8047558 984 nxm_put_16(b, MFF_ARP_OP, oxm,
b5ae8913 985 htons(flow->nw_proto));
09246b99 986 }
f8047558 987 nxm_put_32m(b, MFF_ARP_SPA, oxm,
81a76618 988 flow->nw_src, match->wc.masks.nw_src);
f8047558 989 nxm_put_32m(b, MFF_ARP_TPA, oxm,
81a76618 990 flow->nw_dst, match->wc.masks.nw_dst);
f8047558 991 nxm_put_eth_masked(b, MFF_ARP_SHA, oxm,
81a76618 992 flow->arp_sha, match->wc.masks.arp_sha);
f8047558 993 nxm_put_eth_masked(b, MFF_ARP_THA, oxm,
81a76618 994 flow->arp_tha, match->wc.masks.arp_tha);
09246b99
BP
995 }
996
997 /* Tunnel ID. */
f8047558 998 nxm_put_64m(b, MFF_TUN_ID, oxm,
0ad90c84
JR
999 flow->tunnel.tun_id, match->wc.masks.tunnel.tun_id);
1000
1001 /* Other tunnel metadata. */
b666962b
JG
1002 nxm_put_16m(b, MFF_TUN_FLAGS, oxm,
1003 htons(flow->tunnel.flags), htons(match->wc.masks.tunnel.flags));
f8047558 1004 nxm_put_32m(b, MFF_TUN_SRC, oxm,
0ad90c84 1005 flow->tunnel.ip_src, match->wc.masks.tunnel.ip_src);
f8047558 1006 nxm_put_32m(b, MFF_TUN_DST, oxm,
0ad90c84 1007 flow->tunnel.ip_dst, match->wc.masks.tunnel.ip_dst);
ac6073e3
MC
1008 nxm_put_16m(b, MFF_TUN_GBP_ID, oxm,
1009 flow->tunnel.gbp_id, match->wc.masks.tunnel.gbp_id);
1010 nxm_put_8m(b, MFF_TUN_GBP_FLAGS, oxm,
1011 flow->tunnel.gbp_flags, match->wc.masks.tunnel.gbp_flags);
9558d2a5 1012 tun_metadata_to_nx_match(b, oxm, match);
09246b99 1013
b6c9e612 1014 /* Registers. */
a678b23e
BP
1015 if (oxm < OFP15_VERSION) {
1016 for (i = 0; i < FLOW_N_REGS; i++) {
f8047558 1017 nxm_put_32m(b, MFF_REG0 + i, oxm,
a678b23e
BP
1018 htonl(flow->regs[i]), htonl(match->wc.masks.regs[i]));
1019 }
1020 } else {
1021 for (i = 0; i < FLOW_N_XREGS; i++) {
f8047558 1022 nxm_put_64m(b, MFF_XREG0 + i, oxm,
a678b23e
BP
1023 htonll(flow_get_xreg(flow, i)),
1024 htonll(flow_get_xreg(&match->wc.masks, i)));
1025 }
b6c9e612
BP
1026 }
1027
ac923e91 1028 /* Mark. */
f8047558 1029 nxm_put_32m(b, MFF_PKT_MARK, oxm, htonl(flow->pkt_mark),
ac923e91
JG
1030 htonl(match->wc.masks.pkt_mark));
1031
969fc56c 1032 /* OpenFlow 1.1+ Metadata. */
f8047558 1033 nxm_put_64m(b, MFF_METADATA, oxm,
9d84066c 1034 flow->metadata, match->wc.masks.metadata);
969fc56c 1035
e729e793 1036 /* Cookie. */
f8047558
BP
1037 if (cookie_mask) {
1038 bool masked = cookie_mask != OVS_BE64_MAX;
1039
1040 cookie &= cookie_mask;
1041 nx_put_header__(b, NXM_NX_COOKIE, masked);
1042 ofpbuf_put(b, &cookie, sizeof cookie);
1043 if (masked) {
1044 ofpbuf_put(b, &cookie_mask, sizeof cookie_mask);
1045 }
1046 }
e729e793 1047
6fd6ed71 1048 match_len = b->size - start_len;
7623f4dd
SH
1049 return match_len;
1050}
1051
81a76618 1052/* Appends to 'b' the nx_match format that expresses 'match', plus enough zero
7623f4dd
SH
1053 * bytes to pad the nx_match out to a multiple of 8. For Flow Mod and Flow
1054 * Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
1055 * Otherwise, 'cookie_mask' should be zero.
1056 *
1057 * This function can cause 'b''s data to be reallocated.
1058 *
1059 * Returns the number of bytes appended to 'b', excluding padding. The return
1060 * value can be zero if it appended nothing at all to 'b' (which happens if
1061 * 'cr' is a catch-all rule that matches every packet). */
1062int
81a76618 1063nx_put_match(struct ofpbuf *b, const struct match *match,
7623f4dd
SH
1064 ovs_be64 cookie, ovs_be64 cookie_mask)
1065{
9d84066c 1066 int match_len = nx_put_raw(b, 0, match, cookie, cookie_mask);
7623f4dd 1067
f6e984d7 1068 ofpbuf_put_zeros(b, PAD_SIZE(match_len, 8));
7623f4dd
SH
1069 return match_len;
1070}
1071
9d84066c 1072/* Appends to 'b' an struct ofp11_match_header followed by the OXM format that
81a76618
BP
1073 * expresses 'cr', plus enough zero bytes to pad the data appended out to a
1074 * multiple of 8.
7623f4dd 1075 *
9d84066c
BP
1076 * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow
1077 * version in use as 'version'.
1078 *
7623f4dd
SH
1079 * This function can cause 'b''s data to be reallocated.
1080 *
1081 * Returns the number of bytes appended to 'b', excluding the padding. Never
1082 * returns zero. */
1083int
9d84066c
BP
1084oxm_put_match(struct ofpbuf *b, const struct match *match,
1085 enum ofp_version version)
7623f4dd
SH
1086{
1087 int match_len;
1088 struct ofp11_match_header *omh;
6fd6ed71 1089 size_t start_len = b->size;
7623f4dd
SH
1090 ovs_be64 cookie = htonll(0), cookie_mask = htonll(0);
1091
1092 ofpbuf_put_uninit(b, sizeof *omh);
9d84066c
BP
1093 match_len = (nx_put_raw(b, version, match, cookie, cookie_mask)
1094 + sizeof *omh);
f6e984d7 1095 ofpbuf_put_zeros(b, PAD_SIZE(match_len, 8));
7623f4dd 1096
db5a1019 1097 omh = ofpbuf_at(b, start_len, sizeof *omh);
7623f4dd
SH
1098 omh->type = htons(OFPMT_OXM);
1099 omh->length = htons(match_len);
1100
09246b99
BP
1101 return match_len;
1102}
178742f9 1103
53eb84a5
SH
1104/* Appends to 'b' the nx_match format that expresses the tlv corresponding
1105 * to 'id'. If mask is not all-ones then it is also formated as the value
1106 * of the tlv. */
1107static void
1108nx_format_mask_tlv(struct ds *ds, enum mf_field_id id,
1109 const union mf_value *mask)
1110{
1111 const struct mf_field *mf = mf_from_id(id);
1112
1113 ds_put_format(ds, "%s", mf->name);
1114
1115 if (!is_all_ones(mask, mf->n_bytes)) {
1116 ds_put_char(ds, '=');
1117 mf_format(mf, mask, NULL, ds);
1118 }
1119
1120 ds_put_char(ds, ',');
1121}
1122
1123/* Appends a string representation of 'fa_' to 'ds'.
1124 * The TLVS value of 'fa_' is treated as a mask and
1125 * only the name of fields is formated if it is all ones. */
1126void
1127oxm_format_field_array(struct ds *ds, const struct field_array *fa)
1128{
1129 size_t start_len = ds->length;
1130 int i;
1131
1132 for (i = 0; i < MFF_N_IDS; i++) {
1133 if (bitmap_is_set(fa->used.bm, i)) {
1134 nx_format_mask_tlv(ds, i, &fa->value[i]);
1135 }
1136 }
1137
1138 if (ds->length > start_len) {
1139 ds_chomp(ds, ',');
1140 }
1141}
1142
1143/* Appends to 'b' a series of OXM TLVs corresponding to the series
1144 * of enum mf_field_id and value tuples in 'fa_'.
1145 *
1146 * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow
1147 * version in use as 'version'.
1148 *
1149 * This function can cause 'b''s data to be reallocated.
1150 *
1151 * Returns the number of bytes appended to 'b'. May return zero. */
1152int
1153oxm_put_field_array(struct ofpbuf *b, const struct field_array *fa,
1154 enum ofp_version version)
1155{
1156 size_t start_len = b->size;
1157 int i;
1158
1159 /* Field arrays are only used with the group selection method
d5651b84 1160 * property and group properties are only available in OpenFlow 1.5+.
53eb84a5
SH
1161 * So the following assertion should never fail.
1162 *
1163 * If support for older OpenFlow versions is desired then some care
1164 * will need to be taken of different TLVs that handle the same
1165 * flow fields. In particular:
1166 * - VLAN_TCI, VLAN_VID and MFF_VLAN_PCP
1167 * - IP_DSCP_MASK and DSCP_SHIFTED
1168 * - REGS and XREGS
1169 */
1170 ovs_assert(version >= OFP15_VERSION);
1171
1172 for (i = 0; i < MFF_N_IDS; i++) {
1173 if (bitmap_is_set(fa->used.bm, i)) {
4ede8c79
JG
1174 int len = mf_field_len(mf_from_id(i), &fa->value[i], NULL);
1175 nxm_put_unmasked(b, i, version,
1176 &fa->value[i].u8 + mf_from_id(i)->n_bytes - len,
1177 len);
53eb84a5
SH
1178 }
1179 }
1180
1181 return b->size - start_len;
1182}
1183
f8047558 1184static void
508a9338 1185nx_put_header__(struct ofpbuf *b, uint64_t header, bool masked)
f8047558 1186{
508a9338
BP
1187 uint64_t masked_header = masked ? nxm_make_wild_header(header) : header;
1188 ovs_be64 network_header = htonll(masked_header);
f8047558 1189
508a9338 1190 ofpbuf_put(b, &network_header, nxm_header_len(header));
f8047558
BP
1191}
1192
178742f9
BP
1193void
1194nx_put_header(struct ofpbuf *b, enum mf_field_id field,
1195 enum ofp_version version, bool masked)
1196{
f8047558 1197 nx_put_header__(b, mf_oxm_header(field, version), masked);
178742f9
BP
1198}
1199
dc3eb953
JG
1200static void
1201nx_put_header_len(struct ofpbuf *b, enum mf_field_id field,
1202 enum ofp_version version, bool masked, size_t n_bytes)
1203{
1204 uint64_t header = mf_oxm_header(field, version);
1205
1206 header = NXM_HEADER(nxm_vendor(header), nxm_class(header),
1207 nxm_field(header), false,
1208 nxm_experimenter_len(header) + n_bytes);
1209
1210 nx_put_header__(b, header, masked);
1211}
1212
178742f9
BP
1213void
1214nx_put_entry(struct ofpbuf *b,
1215 enum mf_field_id field, enum ofp_version version,
1216 const union mf_value *value, const union mf_value *mask)
1217{
4ede8c79
JG
1218 const struct mf_field *mf = mf_from_id(field);
1219 bool masked = mask && !is_all_ones(mask, mf->n_bytes);
1220 int len, offset;
178742f9 1221
4ede8c79
JG
1222 len = mf_field_len(mf, value, mask);
1223 offset = mf->n_bytes - len;
1224
1225 nx_put_header_len(b, field, version, masked, len);
1226 ofpbuf_put(b, &value->u8 + offset, len);
178742f9 1227 if (masked) {
4ede8c79 1228 ofpbuf_put(b, &mask->u8 + offset, len);
178742f9
BP
1229 }
1230}
09246b99
BP
1231\f
1232/* nx_match_to_string() and helpers. */
1233
508a9338 1234static void format_nxm_field_name(struct ds *, uint64_t header);
f393f81e 1235
09246b99
BP
1236char *
1237nx_match_to_string(const uint8_t *p, unsigned int match_len)
1238{
178742f9 1239 struct ofpbuf b;
09246b99
BP
1240 struct ds s;
1241
1242 if (!match_len) {
1243 return xstrdup("<any>");
1244 }
1245
178742f9 1246 ofpbuf_use_const(&b, p, match_len);
09246b99 1247 ds_init(&s);
6fd6ed71 1248 while (b.size) {
178742f9
BP
1249 union mf_value value;
1250 union mf_value mask;
1251 enum ofperr error;
508a9338 1252 uint64_t header;
178742f9
BP
1253 int value_len;
1254
1255 error = nx_pull_entry__(&b, true, &header, NULL, &value, &mask);
1256 if (error) {
1257 break;
1258 }
1259 value_len = MIN(sizeof value, nxm_field_bytes(header));
09246b99
BP
1260
1261 if (s.length) {
1262 ds_put_cstr(&s, ", ");
1263 }
1264
f393f81e 1265 format_nxm_field_name(&s, header);
09246b99
BP
1266 ds_put_char(&s, '(');
1267
178742f9
BP
1268 for (int i = 0; i < value_len; i++) {
1269 ds_put_format(&s, "%02x", ((const uint8_t *) &value)[i]);
09246b99 1270 }
178742f9 1271 if (nxm_hasmask(header)) {
09246b99 1272 ds_put_char(&s, '/');
178742f9
BP
1273 for (int i = 0; i < value_len; i++) {
1274 ds_put_format(&s, "%02x", ((const uint8_t *) &mask)[i]);
09246b99
BP
1275 }
1276 }
1277 ds_put_char(&s, ')');
09246b99
BP
1278 }
1279
6fd6ed71 1280 if (b.size) {
09246b99
BP
1281 if (s.length) {
1282 ds_put_cstr(&s, ", ");
1283 }
1284
6fd6ed71 1285 ds_put_format(&s, "<%u invalid bytes>", b.size);
09246b99
BP
1286 }
1287
1288 return ds_steal_cstr(&s);
1289}
1290
7623f4dd 1291char *
db5a1019 1292oxm_match_to_string(const struct ofpbuf *p, unsigned int match_len)
7623f4dd 1293{
6fd6ed71 1294 const struct ofp11_match_header *omh = p->data;
7623f4dd
SH
1295 uint16_t match_len_;
1296 struct ds s;
1297
1298 ds_init(&s);
1299
1300 if (match_len < sizeof *omh) {
1301 ds_put_format(&s, "<match too short: %u>", match_len);
1302 goto err;
1303 }
1304
1305 if (omh->type != htons(OFPMT_OXM)) {
1306 ds_put_format(&s, "<bad match type field: %u>", ntohs(omh->type));
1307 goto err;
1308 }
1309
1310 match_len_ = ntohs(omh->length);
1311 if (match_len_ < sizeof *omh) {
1312 ds_put_format(&s, "<match length field too short: %u>", match_len_);
1313 goto err;
1314 }
1315
1316 if (match_len_ != match_len) {
1317 ds_put_format(&s, "<match length field incorrect: %u != %u>",
1318 match_len_, match_len);
1319 goto err;
1320 }
1321
db5a1019
AW
1322 return nx_match_to_string(ofpbuf_at(p, sizeof *omh, 0),
1323 match_len - sizeof *omh);
7623f4dd
SH
1324
1325err:
1326 return ds_steal_cstr(&s);
1327}
1328
178742f9
BP
1329void
1330nx_format_field_name(enum mf_field_id id, enum ofp_version version,
1331 struct ds *s)
1332{
1333 format_nxm_field_name(s, mf_oxm_header(id, version));
1334}
1335
f393f81e 1336static void
508a9338 1337format_nxm_field_name(struct ds *s, uint64_t header)
f393f81e 1338{
178742f9
BP
1339 const struct nxm_field *f = nxm_field_by_header(header);
1340 if (f) {
1341 ds_put_cstr(s, f->name);
1342 if (nxm_hasmask(header)) {
28da1f8f
BP
1343 ds_put_cstr(s, "_W");
1344 }
e729e793
JP
1345 } else if (header == NXM_NX_COOKIE) {
1346 ds_put_cstr(s, "NXM_NX_COOKIE");
1347 } else if (header == NXM_NX_COOKIE_W) {
1348 ds_put_cstr(s, "NXM_NX_COOKIE_W");
f393f81e 1349 } else {
c8058af7 1350 ds_put_format(s, "%d:%d", nxm_class(header), nxm_field(header));
f393f81e
BP
1351 }
1352}
1353
178742f9
BP
1354static bool
1355streq_len(const char *a, size_t a_len, const char *b)
1356{
1357 return strlen(b) == a_len && !memcmp(a, b, a_len);
1358}
1359
508a9338 1360static uint64_t
558d80cb 1361parse_nxm_field_name(const char *name, int name_len)
09246b99 1362{
178742f9 1363 const struct nxm_field *f;
28da1f8f 1364 bool wild;
28da1f8f 1365
178742f9
BP
1366 f = mf_parse_subfield_name(name, name_len, &wild);
1367 if (f) {
b5ae8913 1368 if (!wild) {
178742f9
BP
1369 return f->header;
1370 } else if (mf_from_id(f->id)->maskable != MFM_NONE) {
1371 return nxm_make_wild_header(f->header);
09246b99
BP
1372 }
1373 }
1374
178742f9
BP
1375 if (streq_len(name, name_len, "NXM_NX_COOKIE")) {
1376 return NXM_NX_COOKIE;
1377 } else if (streq_len(name, name_len, "NXM_NX_COOKIE_W")) {
1378 return NXM_NX_COOKIE_W;
e729e793
JP
1379 }
1380
508a9338 1381 /* Check whether it's a field header value as hex.
558d80cb
BP
1382 * (This isn't ordinarily useful except for testing error behavior.) */
1383 if (name_len == 8) {
508a9338 1384 uint64_t header;
0429d959
BP
1385 bool ok;
1386
508a9338 1387 header = hexits_value(name, name_len, &ok) << 32;
0429d959 1388 if (ok) {
558d80cb
BP
1389 return header;
1390 }
508a9338
BP
1391 } else if (name_len == 16) {
1392 uint64_t header;
1393 bool ok;
1394
1395 header = hexits_value(name, name_len, &ok);
1396 if (ok && is_experimenter_oxm(header)) {
1397 return header;
1398 }
558d80cb
BP
1399 }
1400
1401 return 0;
09246b99 1402}
09246b99
BP
1403\f
1404/* nx_match_from_string(). */
1405
7623f4dd
SH
1406static int
1407nx_match_from_string_raw(const char *s, struct ofpbuf *b)
09246b99
BP
1408{
1409 const char *full_s = s;
6fd6ed71 1410 const size_t start_len = b->size;
09246b99
BP
1411
1412 if (!strcmp(s, "<any>")) {
6fd6ed71 1413 /* Ensure that 'b->data' isn't actually null. */
09246b99
BP
1414 ofpbuf_prealloc_tailroom(b, 1);
1415 return 0;
1416 }
1417
1418 for (s += strspn(s, ", "); *s; s += strspn(s, ", ")) {
558d80cb 1419 const char *name;
508a9338 1420 uint64_t header;
00fe22f8
JG
1421 ovs_be64 nw_header;
1422 ovs_be64 *header_ptr;
09246b99 1423 int name_len;
78090f63 1424 size_t n;
09246b99 1425
558d80cb 1426 name = s;
09246b99
BP
1427 name_len = strcspn(s, "(");
1428 if (s[name_len] != '(') {
1429 ovs_fatal(0, "%s: missing ( at end of nx_match", full_s);
1430 }
1431
558d80cb
BP
1432 header = parse_nxm_field_name(name, name_len);
1433 if (!header) {
09246b99
BP
1434 ovs_fatal(0, "%s: unknown field `%.*s'", full_s, name_len, s);
1435 }
1436
1437 s += name_len + 1;
1438
00fe22f8 1439 header_ptr = ofpbuf_put_uninit(b, nxm_header_len(header));
78090f63
BP
1440 s = ofpbuf_put_hex(b, s, &n);
1441 if (n != nxm_field_bytes(header)) {
00fe22f8
JG
1442 const struct mf_field *field = mf_from_oxm_header(header);
1443
1444 if (field && field->variable_len) {
1445 if (n <= field->n_bytes) {
1446 int len = (nxm_hasmask(header) ? n * 2 : n) +
1447 nxm_experimenter_len(header);
1448
1449 header = NXM_HEADER(nxm_vendor(header), nxm_class(header),
1450 nxm_field(header),
1451 nxm_hasmask(header) ? 1 : 0, len);
1452 } else {
1453 ovs_fatal(0, "expected to read at most %d bytes but got "
1454 "%"PRIuSIZE, field->n_bytes, n);
1455 }
1456 } else {
1457 ovs_fatal(0, "expected to read %d bytes but got %"PRIuSIZE,
1458 nxm_field_bytes(header), n);
1459 }
78090f63 1460 }
00fe22f8
JG
1461 nw_header = htonll(header);
1462 memcpy(header_ptr, &nw_header, nxm_header_len(header));
1463
178742f9 1464 if (nxm_hasmask(header)) {
09246b99
BP
1465 s += strspn(s, " ");
1466 if (*s != '/') {
558d80cb
BP
1467 ovs_fatal(0, "%s: missing / in masked field %.*s",
1468 full_s, name_len, name);
09246b99 1469 }
78090f63
BP
1470 s = ofpbuf_put_hex(b, s + 1, &n);
1471 if (n != nxm_field_bytes(header)) {
1472 ovs_fatal(0, "%.2s: hex digits expected", s);
1473 }
09246b99
BP
1474 }
1475
1476 s += strspn(s, " ");
1477 if (*s != ')') {
558d80cb
BP
1478 ovs_fatal(0, "%s: missing ) following field %.*s",
1479 full_s, name_len, name);
09246b99
BP
1480 }
1481 s++;
1482 }
1483
6fd6ed71 1484 return b->size - start_len;
7623f4dd
SH
1485}
1486
1487int
1488nx_match_from_string(const char *s, struct ofpbuf *b)
1489{
1490 int match_len = nx_match_from_string_raw(s, b);
f6e984d7 1491 ofpbuf_put_zeros(b, PAD_SIZE(match_len, 8));
7623f4dd
SH
1492 return match_len;
1493}
1494
1495int
1496oxm_match_from_string(const char *s, struct ofpbuf *b)
1497{
1498 int match_len;
1499 struct ofp11_match_header *omh;
6fd6ed71 1500 size_t start_len = b->size;
7623f4dd
SH
1501
1502 ofpbuf_put_uninit(b, sizeof *omh);
1503 match_len = nx_match_from_string_raw(s, b) + sizeof *omh;
f6e984d7 1504 ofpbuf_put_zeros(b, PAD_SIZE(match_len, 8));
7623f4dd 1505
db5a1019 1506 omh = ofpbuf_at(b, start_len, sizeof *omh);
7623f4dd
SH
1507 omh->type = htons(OFPMT_OXM);
1508 omh->length = htons(match_len);
1509
09246b99
BP
1510 return match_len;
1511}
b6c9e612 1512\f
bdda5aca
BP
1513/* Parses 's' as a "move" action, in the form described in ovs-ofctl(8), into
1514 * '*move'.
1515 *
1516 * Returns NULL if successful, otherwise a malloc()'d string describing the
1517 * error. The caller is responsible for freeing the returned string. */
cab50449 1518char * OVS_WARN_UNUSED_RESULT
f25d0cf3 1519nxm_parse_reg_move(struct ofpact_reg_move *move, const char *s)
f393f81e
BP
1520{
1521 const char *full_s = s;
bdda5aca 1522 char *error;
f393f81e 1523
bdda5aca
BP
1524 error = mf_parse_subfield__(&move->src, &s);
1525 if (error) {
1526 return error;
1527 }
f393f81e 1528 if (strncmp(s, "->", 2)) {
bdda5aca 1529 return xasprintf("%s: missing `->' following source", full_s);
f393f81e
BP
1530 }
1531 s += 2;
bdda5aca
BP
1532 error = mf_parse_subfield(&move->dst, s);
1533 if (error) {
1534 return error;
f393f81e
BP
1535 }
1536
f25d0cf3 1537 if (move->src.n_bits != move->dst.n_bits) {
bdda5aca
BP
1538 return xasprintf("%s: source field is %d bits wide but destination is "
1539 "%d bits wide", full_s,
1540 move->src.n_bits, move->dst.n_bits);
f393f81e 1541 }
bdda5aca 1542 return NULL;
f393f81e 1543}
f393f81e 1544\f
7eb4b1f1 1545/* nxm_format_reg_move(). */
f393f81e 1546
f393f81e 1547void
f25d0cf3 1548nxm_format_reg_move(const struct ofpact_reg_move *move, struct ds *s)
f393f81e 1549{
f393f81e 1550 ds_put_format(s, "move:");
f25d0cf3 1551 mf_format_subfield(&move->src, s);
f393f81e 1552 ds_put_cstr(s, "->");
f25d0cf3 1553 mf_format_subfield(&move->dst, s);
f393f81e
BP
1554}
1555
f25d0cf3
BP
1556\f
1557enum ofperr
f25d0cf3 1558nxm_reg_move_check(const struct ofpact_reg_move *move, const struct flow *flow)
43edca57 1559{
90bf1e07 1560 enum ofperr error;
43edca57 1561
f25d0cf3 1562 error = mf_check_src(&move->src, flow);
43edca57
EJ
1563 if (error) {
1564 return error;
b6c9e612
BP
1565 }
1566
b8778a0d 1567 return mf_check_dst(&move->dst, flow);
f25d0cf3 1568}
f25d0cf3 1569\f
7eb4b1f1 1570/* nxm_execute_reg_move(). */
b6c9e612
BP
1571
1572void
f25d0cf3 1573nxm_execute_reg_move(const struct ofpact_reg_move *move,
bcd2633a 1574 struct flow *flow, struct flow_wildcards *wc)
b6c9e612 1575{
f25d0cf3
BP
1576 union mf_value src_value;
1577 union mf_value dst_value;
816fd533 1578
5e2e998a
JR
1579 mf_mask_field_and_prereqs(move->dst.field, wc);
1580 mf_mask_field_and_prereqs(move->src.field, wc);
bcd2633a 1581
b8778a0d
JR
1582 /* A flow may wildcard nw_frag. Do nothing if setting a transport
1583 * header field on a packet that does not have them. */
1584 if (mf_are_prereqs_ok(move->dst.field, flow)
1585 && mf_are_prereqs_ok(move->src.field, flow)) {
1586
1587 mf_get_value(move->dst.field, flow, &dst_value);
1588 mf_get_value(move->src.field, flow, &src_value);
1589 bitwise_copy(&src_value, move->src.field->n_bytes, move->src.ofs,
1590 &dst_value, move->dst.field->n_bytes, move->dst.ofs,
1591 move->src.n_bits);
1592 mf_set_flow_value(move->dst.field, &dst_value, flow);
1593 }
43edca57 1594}
b6c9e612 1595
816fd533 1596void
f25d0cf3 1597nxm_reg_load(const struct mf_subfield *dst, uint64_t src_data,
f74e7df7 1598 struct flow *flow, struct flow_wildcards *wc)
816fd533 1599{
9bab681f 1600 union mf_subvalue src_subvalue;
f74e7df7 1601 union mf_subvalue mask_value;
9bab681f 1602 ovs_be64 src_data_be = htonll(src_data);
f25d0cf3 1603
f74e7df7
JP
1604 memset(&mask_value, 0xff, sizeof mask_value);
1605 mf_write_subfield_flow(dst, &mask_value, &wc->masks);
1606
9bab681f
IY
1607 bitwise_copy(&src_data_be, sizeof src_data_be, 0,
1608 &src_subvalue, sizeof src_subvalue, 0,
1609 sizeof src_data_be * 8);
1610 mf_write_subfield_flow(dst, &src_subvalue, flow);
b6c9e612 1611}
bd85dac1
AZ
1612\f
1613/* nxm_parse_stack_action, works for both push() and pop(). */
bdda5aca
BP
1614
1615/* Parses 's' as a "push" or "pop" action, in the form described in
1616 * ovs-ofctl(8), into '*stack_action'.
1617 *
1618 * Returns NULL if successful, otherwise a malloc()'d string describing the
1619 * error. The caller is responsible for freeing the returned string. */
cab50449 1620char * OVS_WARN_UNUSED_RESULT
bd85dac1
AZ
1621nxm_parse_stack_action(struct ofpact_stack *stack_action, const char *s)
1622{
bdda5aca
BP
1623 char *error;
1624
1625 error = mf_parse_subfield__(&stack_action->subfield, &s);
1626 if (error) {
1627 return error;
1628 }
1629
bd85dac1 1630 if (*s != '\0') {
bdda5aca 1631 return xasprintf("%s: trailing garbage following push or pop", s);
bd85dac1 1632 }
bdda5aca
BP
1633
1634 return NULL;
bd85dac1
AZ
1635}
1636
1637void
1638nxm_format_stack_push(const struct ofpact_stack *push, struct ds *s)
1639{
1640 ds_put_cstr(s, "push:");
1641 mf_format_subfield(&push->subfield, s);
1642}
1643
1644void
1645nxm_format_stack_pop(const struct ofpact_stack *pop, struct ds *s)
1646{
1647 ds_put_cstr(s, "pop:");
1648 mf_format_subfield(&pop->subfield, s);
1649}
1650
bd85dac1
AZ
1651enum ofperr
1652nxm_stack_push_check(const struct ofpact_stack *push,
1653 const struct flow *flow)
1654{
1655 return mf_check_src(&push->subfield, flow);
1656}
1657
1658enum ofperr
1659nxm_stack_pop_check(const struct ofpact_stack *pop,
1660 const struct flow *flow)
1661{
1662 return mf_check_dst(&pop->subfield, flow);
1663}
1664
bd85dac1
AZ
1665/* nxm_execute_stack_push(), nxm_execute_stack_pop(). */
1666static void
1667nx_stack_push(struct ofpbuf *stack, union mf_subvalue *v)
1668{
1669 ofpbuf_put(stack, v, sizeof *v);
1670}
1671
1672static union mf_subvalue *
1673nx_stack_pop(struct ofpbuf *stack)
1674{
1675 union mf_subvalue *v = NULL;
1676
6fd6ed71 1677 if (stack->size) {
1f317cb5 1678
6fd6ed71 1679 stack->size -= sizeof *v;
bd85dac1
AZ
1680 v = (union mf_subvalue *) ofpbuf_tail(stack);
1681 }
1682
1683 return v;
1684}
1685
1686void
1687nxm_execute_stack_push(const struct ofpact_stack *push,
bcd2633a
JP
1688 const struct flow *flow, struct flow_wildcards *wc,
1689 struct ofpbuf *stack)
bd85dac1 1690{
bcd2633a 1691 union mf_subvalue mask_value;
bd85dac1
AZ
1692 union mf_subvalue dst_value;
1693
bcd2633a
JP
1694 memset(&mask_value, 0xff, sizeof mask_value);
1695 mf_write_subfield_flow(&push->subfield, &mask_value, &wc->masks);
1696
bd85dac1
AZ
1697 mf_read_subfield(&push->subfield, flow, &dst_value);
1698 nx_stack_push(stack, &dst_value);
1699}
1700
1701void
1702nxm_execute_stack_pop(const struct ofpact_stack *pop,
f74e7df7
JP
1703 struct flow *flow, struct flow_wildcards *wc,
1704 struct ofpbuf *stack)
bd85dac1
AZ
1705{
1706 union mf_subvalue *src_value;
1707
1708 src_value = nx_stack_pop(stack);
1709
1710 /* Only pop if stack is not empty. Otherwise, give warning. */
1711 if (src_value) {
f74e7df7
JP
1712 union mf_subvalue mask_value;
1713
1714 memset(&mask_value, 0xff, sizeof mask_value);
1715 mf_write_subfield_flow(&pop->subfield, &mask_value, &wc->masks);
bd85dac1
AZ
1716 mf_write_subfield_flow(&pop->subfield, src_value, flow);
1717 } else {
1718 if (!VLOG_DROP_WARN(&rl)) {
1719 char *flow_str = flow_to_string(flow);
1774d762 1720 VLOG_WARN_RL(&rl, "Failed to pop from an empty stack. On flow\n"
bd85dac1
AZ
1721 " %s", flow_str);
1722 free(flow_str);
1723 }
1724 }
1725}
178742f9
BP
1726\f
1727/* Formats 'sf' into 's' in a format normally acceptable to
1728 * mf_parse_subfield(). (It won't be acceptable if sf->field is NULL or if
1729 * sf->field has no NXM name.) */
1730void
1731mf_format_subfield(const struct mf_subfield *sf, struct ds *s)
1732{
1733 if (!sf->field) {
1734 ds_put_cstr(s, "<unknown>");
1735 } else {
e6556fe3 1736 const struct nxm_field *f = nxm_field_by_mf_id(sf->field->id, 0);
178742f9
BP
1737 ds_put_cstr(s, f ? f->name : sf->field->name);
1738 }
1739
1740 if (sf->field && sf->ofs == 0 && sf->n_bits == sf->field->n_bits) {
1741 ds_put_cstr(s, "[]");
1742 } else if (sf->n_bits == 1) {
1743 ds_put_format(s, "[%d]", sf->ofs);
1744 } else {
1745 ds_put_format(s, "[%d..%d]", sf->ofs, sf->ofs + sf->n_bits - 1);
1746 }
1747}
1748
1749static const struct nxm_field *
1750mf_parse_subfield_name(const char *name, int name_len, bool *wild)
1751{
1752 *wild = name_len > 2 && !memcmp(&name[name_len - 2], "_W", 2);
1753 if (*wild) {
1754 name_len -= 2;
1755 }
1756
1757 return nxm_field_by_name(name, name_len);
1758}
1759
1760/* Parses a subfield from the beginning of '*sp' into 'sf'. If successful,
1761 * returns NULL and advances '*sp' to the first byte following the parsed
1762 * string. On failure, returns a malloc()'d error message, does not modify
1763 * '*sp', and does not properly initialize 'sf'.
1764 *
1765 * The syntax parsed from '*sp' takes the form "header[start..end]" where
1766 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1767 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1768 * may both be omitted (the [] are still required) to indicate an entire
1769 * field. */
cab50449 1770char * OVS_WARN_UNUSED_RESULT
178742f9
BP
1771mf_parse_subfield__(struct mf_subfield *sf, const char **sp)
1772{
1773 const struct mf_field *field;
1774 const struct nxm_field *f;
1775 const char *name;
1776 int start, end;
1777 const char *s;
1778 int name_len;
1779 bool wild;
1780
1781 s = *sp;
1782 name = s;
1783 name_len = strcspn(s, "[");
1784 if (s[name_len] != '[') {
1785 return xasprintf("%s: missing [ looking for field name", *sp);
1786 }
1787
1788 f = mf_parse_subfield_name(name, name_len, &wild);
1789 if (!f) {
1790 return xasprintf("%s: unknown field `%.*s'", *sp, name_len, s);
1791 }
1792 field = mf_from_id(f->id);
1793
1794 s += name_len;
1795 if (ovs_scan(s, "[%d..%d]", &start, &end)) {
1796 /* Nothing to do. */
1797 } else if (ovs_scan(s, "[%d]", &start)) {
1798 end = start;
1799 } else if (!strncmp(s, "[]", 2)) {
1800 start = 0;
1801 end = field->n_bits - 1;
1802 } else {
1803 return xasprintf("%s: syntax error expecting [] or [<bit>] or "
1804 "[<start>..<end>]", *sp);
1805 }
1806 s = strchr(s, ']') + 1;
1807
1808 if (start > end) {
1809 return xasprintf("%s: starting bit %d is after ending bit %d",
1810 *sp, start, end);
1811 } else if (start >= field->n_bits) {
1812 return xasprintf("%s: starting bit %d is not valid because field is "
1813 "only %d bits wide", *sp, start, field->n_bits);
1814 } else if (end >= field->n_bits){
1815 return xasprintf("%s: ending bit %d is not valid because field is "
1816 "only %d bits wide", *sp, end, field->n_bits);
1817 }
1818
1819 sf->field = field;
1820 sf->ofs = start;
1821 sf->n_bits = end - start + 1;
1822
1823 *sp = s;
1824 return NULL;
1825}
1826
1827/* Parses a subfield from the entirety of 's' into 'sf'. Returns NULL if
1828 * successful, otherwise a malloc()'d string describing the error. The caller
1829 * is responsible for freeing the returned string.
1830 *
1831 * The syntax parsed from 's' takes the form "header[start..end]" where
1832 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1833 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1834 * may both be omitted (the [] are still required) to indicate an entire
1835 * field. */
cab50449 1836char * OVS_WARN_UNUSED_RESULT
178742f9
BP
1837mf_parse_subfield(struct mf_subfield *sf, const char *s)
1838{
1839 char *error = mf_parse_subfield__(sf, &s);
1840 if (!error && s[0]) {
1841 error = xstrdup("unexpected input following field syntax");
1842 }
1843 return error;
1844}
1845\f
1846/* Returns an bitmap in which each bit corresponds to the like-numbered field
1847 * in the OFPXMC12_OPENFLOW_BASIC OXM class, in which the bit values are taken
1848 * from the 'fields' bitmap. Only fields defined in OpenFlow 'version' are
1849 * considered.
1850 *
1851 * This is useful for encoding OpenFlow 1.2 table stats messages. */
1852ovs_be64
1853oxm_bitmap_from_mf_bitmap(const struct mf_bitmap *fields,
1854 enum ofp_version version)
1855{
1856 uint64_t oxm_bitmap = 0;
1857 int i;
1858
1859 BITMAP_FOR_EACH_1 (i, MFF_N_IDS, fields->bm) {
508a9338 1860 uint64_t oxm = mf_oxm_header(i, version);
c8058af7 1861 uint32_t class = nxm_class(oxm);
178742f9
BP
1862 int field = nxm_field(oxm);
1863
c8058af7 1864 if (class == OFPXMC12_OPENFLOW_BASIC && field < 64) {
178742f9
BP
1865 oxm_bitmap |= UINT64_C(1) << field;
1866 }
1867 }
1868 return htonll(oxm_bitmap);
1869}
1870
1871/* Opposite conversion from oxm_bitmap_from_mf_bitmap().
1872 *
1873 * This is useful for decoding OpenFlow 1.2 table stats messages. */
1874struct mf_bitmap
1875oxm_bitmap_to_mf_bitmap(ovs_be64 oxm_bitmap, enum ofp_version version)
1876{
1877 struct mf_bitmap fields = MF_BITMAP_INITIALIZER;
1878
1879 for (enum mf_field_id id = 0; id < MFF_N_IDS; id++) {
e6556fe3
BP
1880 uint64_t oxm = mf_oxm_header(id, version);
1881 if (oxm && version >= nxm_field_by_header(oxm)->version) {
c8058af7 1882 uint32_t class = nxm_class(oxm);
178742f9
BP
1883 int field = nxm_field(oxm);
1884
c8058af7 1885 if (class == OFPXMC12_OPENFLOW_BASIC
178742f9
BP
1886 && field < 64
1887 && oxm_bitmap & htonll(UINT64_C(1) << field)) {
1888 bitmap_set1(fields.bm, id);
1889 }
1890 }
1891 }
1892 return fields;
1893}
1894
1895/* Returns a bitmap of fields that can be encoded in OXM and that can be
1896 * modified with a "set_field" action. */
1897struct mf_bitmap
1898oxm_writable_fields(void)
1899{
1900 struct mf_bitmap b = MF_BITMAP_INITIALIZER;
1901 int i;
1902
1903 for (i = 0; i < MFF_N_IDS; i++) {
1904 if (mf_oxm_header(i, 0) && mf_from_id(i)->writable) {
1905 bitmap_set1(b.bm, i);
1906 }
1907 }
1908 return b;
1909}
1910
1911/* Returns a bitmap of fields that can be encoded in OXM and that can be
1912 * matched in a flow table. */
1913struct mf_bitmap
1914oxm_matchable_fields(void)
1915{
1916 struct mf_bitmap b = MF_BITMAP_INITIALIZER;
1917 int i;
1918
1919 for (i = 0; i < MFF_N_IDS; i++) {
1920 if (mf_oxm_header(i, 0)) {
1921 bitmap_set1(b.bm, i);
1922 }
1923 }
1924 return b;
1925}
1926
1927/* Returns a bitmap of fields that can be encoded in OXM and that can be
1928 * matched in a flow table with an arbitrary bitmask. */
1929struct mf_bitmap
1930oxm_maskable_fields(void)
1931{
1932 struct mf_bitmap b = MF_BITMAP_INITIALIZER;
1933 int i;
1934
1935 for (i = 0; i < MFF_N_IDS; i++) {
1936 if (mf_oxm_header(i, 0) && mf_from_id(i)->maskable == MFM_FULLY) {
1937 bitmap_set1(b.bm, i);
1938 }
1939 }
1940 return b;
1941}
1942\f
1943struct nxm_field_index {
e6556fe3
BP
1944 struct hmap_node header_node; /* In nxm_header_map. */
1945 struct hmap_node name_node; /* In nxm_name_map. */
ca6ba700 1946 struct ovs_list mf_node; /* In mf_mf_map[nf.id]. */
e6556fe3 1947 const struct nxm_field nf;
178742f9
BP
1948};
1949
1950#include "nx-match.inc"
1951
1952static struct hmap nxm_header_map;
1953static struct hmap nxm_name_map;
ca6ba700 1954static struct ovs_list nxm_mf_map[MFF_N_IDS];
178742f9
BP
1955
1956static void
1957nxm_init(void)
1958{
1959 static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
1960 if (ovsthread_once_start(&once)) {
1961 hmap_init(&nxm_header_map);
1962 hmap_init(&nxm_name_map);
e6556fe3
BP
1963 for (int i = 0; i < MFF_N_IDS; i++) {
1964 list_init(&nxm_mf_map[i]);
1965 }
178742f9
BP
1966 for (struct nxm_field_index *nfi = all_nxm_fields;
1967 nfi < &all_nxm_fields[ARRAY_SIZE(all_nxm_fields)]; nfi++) {
1968 hmap_insert(&nxm_header_map, &nfi->header_node,
899bb63d 1969 hash_uint64(nxm_no_len(nfi->nf.header)));
178742f9
BP
1970 hmap_insert(&nxm_name_map, &nfi->name_node,
1971 hash_string(nfi->nf.name, 0));
e6556fe3 1972 list_push_back(&nxm_mf_map[nfi->nf.id], &nfi->mf_node);
178742f9
BP
1973 }
1974 ovsthread_once_done(&once);
1975 }
1976}
1977
1978static const struct nxm_field *
508a9338 1979nxm_field_by_header(uint64_t header)
178742f9
BP
1980{
1981 const struct nxm_field_index *nfi;
899bb63d 1982 uint64_t header_no_len;
178742f9
BP
1983
1984 nxm_init();
1985 if (nxm_hasmask(header)) {
1986 header = nxm_make_exact_header(header);
1987 }
1988
899bb63d
JG
1989 header_no_len = nxm_no_len(header);
1990
1991 HMAP_FOR_EACH_IN_BUCKET (nfi, header_node, hash_uint64(header_no_len),
178742f9 1992 &nxm_header_map) {
899bb63d
JG
1993 if (header_no_len == nxm_no_len(nfi->nf.header)) {
1994 if (nxm_length(header) == nxm_length(nfi->nf.header) ||
1995 mf_from_id(nfi->nf.id)->variable_len) {
1996 return &nfi->nf;
1997 } else {
1998 return NULL;
1999 }
178742f9
BP
2000 }
2001 }
2002 return NULL;
2003}
2004
2005static const struct nxm_field *
2006nxm_field_by_name(const char *name, size_t len)
2007{
2008 const struct nxm_field_index *nfi;
2009
2010 nxm_init();
2011 HMAP_FOR_EACH_WITH_HASH (nfi, name_node, hash_bytes(name, len, 0),
2012 &nxm_name_map) {
2013 if (strlen(nfi->nf.name) == len && !memcmp(nfi->nf.name, name, len)) {
2014 return &nfi->nf;
2015 }
2016 }
2017 return NULL;
2018}
2019
2020static const struct nxm_field *
e6556fe3 2021nxm_field_by_mf_id(enum mf_field_id id, enum ofp_version version)
178742f9 2022{
e6556fe3
BP
2023 const struct nxm_field_index *nfi;
2024 const struct nxm_field *f;
178742f9 2025
178742f9 2026 nxm_init();
178742f9 2027
e6556fe3
BP
2028 f = NULL;
2029 LIST_FOR_EACH (nfi, mf_node, &nxm_mf_map[id]) {
2030 if (!f || version >= nfi->nf.version) {
2031 f = &nfi->nf;
2032 }
2033 }
2034 return f;
2035}