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