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