2 * Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <netinet/icmp6.h>
23 #include "classifier.h"
24 #include "dynamic-string.h"
26 #include "meta-flow.h"
27 #include "ofp-actions.h"
28 #include "ofp-errors.h"
31 #include "openflow/nicira-ext.h"
34 #include "unaligned.h"
36 #include "openvswitch/vlog.h"
38 VLOG_DEFINE_THIS_MODULE(nx_match
);
46 * The header is 32 bits long. It looks like this:
49 * +----------------------------------+---------------+--+------------------+
50 * | oxm_class | oxm_field |hm| oxm_length |
51 * +----------------------------------+---------------+--+------------------+
53 * where hm stands for oxm_hasmask. It is followed by oxm_length bytes of
54 * payload. When oxm_hasmask is 0, the payload is the value of the field
55 * identified by the header; when oxm_hasmask is 1, the payload is a value for
56 * the field followed by a mask of equal length.
58 * Internally, we represent a standard OXM header as a 64-bit integer with the
59 * above information in the most-significant bits.
65 * The header is 64 bits long. It looks like the diagram above except that a
66 * 32-bit experimenter ID, which we call oxm_vendor and which identifies a
67 * vendor, is inserted just before the payload. Experimenter OXMs are
68 * identified by an all-1-bits oxm_class (OFPXMC12_EXPERIMENTER). The
69 * oxm_length value *includes* the experimenter ID, so that the real payload is
70 * only oxm_length - 4 bytes long.
72 * Internally, we represent an experimenter OXM header as a 64-bit integer with
73 * the standard header in the upper 32 bits and the experimenter ID in the
74 * lower 32 bits. (It would be more convenient to swap the positions of the
75 * two 32-bit words, but this would be more error-prone because experimenter
76 * OXMs are very rarely used, so accidentally passing one through a 32-bit type
77 * somewhere in the OVS code would be hard to find.)
82 * The high order bit differentiate reserved classes from member classes.
83 * Classes 0x0000 to 0x7FFF are member classes, allocated by ONF.
84 * Classes 0x8000 to 0xFFFE are reserved classes, reserved for standardisation.
86 enum ofp12_oxm_class
{
87 OFPXMC12_NXM_0
= 0x0000, /* Backward compatibility with NXM */
88 OFPXMC12_NXM_1
= 0x0001, /* Backward compatibility with NXM */
89 OFPXMC12_OPENFLOW_BASIC
= 0x8000, /* Basic class for OpenFlow */
90 OFPXMC15_PACKET_REGS
= 0x8001, /* Packet registers (pipeline fields). */
91 OFPXMC12_EXPERIMENTER
= 0xffff, /* Experimenter class */
94 /* Functions for extracting raw field values from OXM/NXM headers. */
95 static uint32_t nxm_vendor(uint64_t header
) { return header
; }
96 static int nxm_class(uint64_t header
) { return header
>> 48; }
97 static int nxm_field(uint64_t header
) { return (header
>> 41) & 0x7f; }
98 static bool nxm_hasmask(uint64_t header
) { return (header
>> 40) & 1; }
99 static int nxm_length(uint64_t header
) { return (header
>> 32) & 0xff; }
100 static uint64_t nxm_no_len(uint64_t header
) { return header
& 0xffffff80ffffffffULL
; }
103 is_experimenter_oxm(uint64_t header
)
105 return nxm_class(header
) == OFPXMC12_EXPERIMENTER
;
108 /* The OXM header "length" field is somewhat tricky:
110 * - For a standard OXM header, the length is the number of bytes of the
111 * payload, and the payload consists of just the value (and mask, if
114 * - For an experimenter OXM header, the length is the number of bytes in
115 * the payload plus 4 (the length of the experimenter ID). That is, the
116 * experimenter ID is included in oxm_length.
118 * This function returns the length of the experimenter ID field in 'header'.
119 * That is, for an experimenter OXM (when an experimenter ID is present), it
120 * returns 4, and for a standard OXM (when no experimenter ID is present), it
123 nxm_experimenter_len(uint64_t header
)
125 return is_experimenter_oxm(header
) ? 4 : 0;
128 /* Returns the number of bytes that follow the header for an NXM/OXM entry
129 * with the given 'header'. */
131 nxm_payload_len(uint64_t header
)
133 return nxm_length(header
) - nxm_experimenter_len(header
);
136 /* Returns the number of bytes in the header for an NXM/OXM entry with the
139 nxm_header_len(uint64_t header
)
141 return 4 + nxm_experimenter_len(header
);
144 #define NXM_HEADER(VENDOR, CLASS, FIELD, HASMASK, LENGTH) \
145 (((uint64_t) (CLASS) << 48) | \
146 ((uint64_t) (FIELD) << 41) | \
147 ((uint64_t) (HASMASK) << 40) | \
148 ((uint64_t) (LENGTH) << 32) | \
151 #define NXM_HEADER_FMT "%#"PRIx32":%d:%d:%d:%d"
152 #define NXM_HEADER_ARGS(HEADER) \
153 nxm_vendor(HEADER), nxm_class(HEADER), nxm_field(HEADER), \
154 nxm_hasmask(HEADER), nxm_length(HEADER)
156 /* Functions for turning the "hasmask" bit on or off. (This also requires
157 * adjusting the length.) */
159 nxm_make_exact_header(uint64_t header
)
161 int new_len
= nxm_payload_len(header
) / 2 + nxm_experimenter_len(header
);
162 return NXM_HEADER(nxm_vendor(header
), nxm_class(header
),
163 nxm_field(header
), 0, new_len
);
166 nxm_make_wild_header(uint64_t header
)
168 int new_len
= nxm_payload_len(header
) * 2 + nxm_experimenter_len(header
);
169 return NXM_HEADER(nxm_vendor(header
), nxm_class(header
),
170 nxm_field(header
), 1, new_len
);
175 * This may be used to gain the OpenFlow 1.1-like ability to restrict
176 * certain NXM-based Flow Mod and Flow Stats Request messages to flows
177 * with specific cookies. See the "nx_flow_mod" and "nx_flow_stats_request"
178 * structure definitions for more details. This match is otherwise not
180 #define NXM_NX_COOKIE NXM_HEADER (0, 0x0001, 30, 0, 8)
181 #define NXM_NX_COOKIE_W nxm_make_wild_header(NXM_NX_COOKIE)
185 enum ofp_version version
;
186 const char *name
; /* e.g. "NXM_OF_IN_PORT". */
191 static const struct nxm_field
*nxm_field_by_header(uint64_t header
);
192 static const struct nxm_field
*nxm_field_by_name(const char *name
, size_t len
);
193 static const struct nxm_field
*nxm_field_by_mf_id(enum mf_field_id
,
196 static void nx_put_header__(struct ofpbuf
*, uint64_t header
, bool masked
);
198 /* Rate limit for nx_match parse errors. These always indicate a bug in the
199 * peer and so there's not much point in showing a lot of them. */
200 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
202 static const struct nxm_field
*
203 mf_parse_subfield_name(const char *name
, int name_len
, bool *wild
);
205 /* Returns the preferred OXM header to use for field 'id' in OpenFlow version
206 * 'version'. Specify 0 for 'version' if an NXM legacy header should be
207 * preferred over any standardized OXM header. Returns 0 if field 'id' cannot
208 * be expressed in NXM or OXM. */
210 mf_oxm_header(enum mf_field_id id
, enum ofp_version version
)
212 const struct nxm_field
*f
= nxm_field_by_mf_id(id
, version
);
213 return f
? f
->header
: 0;
216 /* Returns the 32-bit OXM or NXM header to use for field 'id', preferring an
217 * NXM legacy header over any standardized OXM header. Returns 0 if field 'id'
218 * cannot be expressed with a 32-bit NXM or OXM header.
220 * Whenever possible, use nx_pull_header() instead of this function, because
221 * this function cannot support 64-bit experimenter OXM headers. */
223 mf_nxm_header(enum mf_field_id id
)
225 uint64_t oxm
= mf_oxm_header(id
, 0);
226 return is_experimenter_oxm(oxm
) ? 0 : oxm
>> 32;
229 static const struct mf_field
*
230 mf_from_oxm_header(uint64_t header
)
232 const struct nxm_field
*f
= nxm_field_by_header(header
);
233 return f
? mf_from_id(f
->id
) : NULL
;
236 /* Returns the "struct mf_field" that corresponds to NXM or OXM header
237 * 'header', or NULL if 'header' doesn't correspond to any known field. */
238 const struct mf_field
*
239 mf_from_nxm_header(uint32_t header
)
241 return mf_from_oxm_header((uint64_t) header
<< 32);
244 /* Returns the width of the data for a field with the given 'header', in
247 nxm_field_bytes(uint64_t header
)
249 unsigned int length
= nxm_payload_len(header
);
250 return nxm_hasmask(header
) ? length
/ 2 : length
;
253 /* nx_pull_match() and helpers. */
255 /* Given NXM/OXM value 'value' and mask 'mask' associated with 'header', checks
256 * for any 1-bit in the value where there is a 0-bit in the mask. Returns 0 if
257 * none, otherwise an error code. */
259 is_mask_consistent(uint64_t header
, const uint8_t *value
, const uint8_t *mask
)
261 unsigned int width
= nxm_field_bytes(header
);
264 for (i
= 0; i
< width
; i
++) {
265 if (value
[i
] & ~mask
[i
]) {
266 if (!VLOG_DROP_WARN(&rl
)) {
267 VLOG_WARN_RL(&rl
, "Rejecting NXM/OXM entry "NXM_HEADER_FMT
" "
268 "with 1-bits in value for bits wildcarded by the "
269 "mask.", NXM_HEADER_ARGS(header
));
278 is_cookie_pseudoheader(uint64_t header
)
280 return header
== NXM_NX_COOKIE
|| header
== NXM_NX_COOKIE_W
;
284 nx_pull_header__(struct ofpbuf
*b
, bool allow_cookie
, uint64_t *header
,
285 const struct mf_field
**field
)
291 *header
= ((uint64_t) ntohl(get_unaligned_be32(b
->data
))) << 32;
292 if (is_experimenter_oxm(*header
)) {
296 *header
= ntohll(get_unaligned_be64(b
->data
));
298 if (nxm_length(*header
) <= nxm_experimenter_len(*header
)) {
299 VLOG_WARN_RL(&rl
, "OXM header "NXM_HEADER_FMT
" has invalid length %d "
301 NXM_HEADER_ARGS(*header
), nxm_length(*header
),
302 nxm_header_len(*header
) + 1);
305 ofpbuf_pull(b
, nxm_header_len(*header
));
308 *field
= mf_from_oxm_header(*header
);
309 if (!*field
&& !(allow_cookie
&& is_cookie_pseudoheader(*header
))) {
310 VLOG_DBG_RL(&rl
, "OXM header "NXM_HEADER_FMT
" is unknown",
311 NXM_HEADER_ARGS(*header
));
312 return OFPERR_OFPBMC_BAD_FIELD
;
319 VLOG_DBG_RL(&rl
, "encountered partial (%"PRIu32
"-byte) OXM entry",
326 return OFPERR_OFPBMC_BAD_LEN
;
330 copy_entry_value(const struct mf_field
*field
, union mf_value
*value
,
331 const uint8_t *payload
, int width
)
337 copy_len
= MIN(width
, field
? field
->n_bytes
: sizeof *value
);
339 if (field
&& field
->variable_len
) {
340 memset(value
, 0, field
->n_bytes
);
341 copy_dst
= &value
->u8
+ field
->n_bytes
- copy_len
;
344 memcpy(copy_dst
, payload
, copy_len
);
348 nx_pull_entry__(struct ofpbuf
*b
, bool allow_cookie
, uint64_t *header
,
349 const struct mf_field
**field_
,
350 union mf_value
*value
, union mf_value
*mask
)
352 const struct mf_field
*field
;
353 enum ofperr header_error
;
354 unsigned int payload_len
;
355 const uint8_t *payload
;
358 header_error
= nx_pull_header__(b
, allow_cookie
, header
, &field
);
359 if (header_error
&& header_error
!= OFPERR_OFPBMC_BAD_FIELD
) {
363 payload_len
= nxm_payload_len(*header
);
364 payload
= ofpbuf_try_pull(b
, payload_len
);
366 VLOG_DBG_RL(&rl
, "OXM header "NXM_HEADER_FMT
" calls for %u-byte "
367 "payload but only %"PRIu32
" bytes follow OXM header",
368 NXM_HEADER_ARGS(*header
), payload_len
, b
->size
);
369 return OFPERR_OFPBMC_BAD_LEN
;
372 width
= nxm_field_bytes(*header
);
373 if (nxm_hasmask(*header
)
374 && !is_mask_consistent(*header
, payload
, payload
+ width
)) {
375 return OFPERR_OFPBMC_BAD_WILDCARDS
;
378 copy_entry_value(field
, value
, payload
, width
);
381 if (nxm_hasmask(*header
)) {
382 copy_entry_value(field
, mask
, payload
+ width
, width
);
384 memset(mask
, 0xff, sizeof *mask
);
386 } else if (nxm_hasmask(*header
)) {
387 VLOG_DBG_RL(&rl
, "OXM header "NXM_HEADER_FMT
" includes mask but "
388 "masked OXMs are not allowed here",
389 NXM_HEADER_ARGS(*header
));
390 return OFPERR_OFPBMC_BAD_MASK
;
401 /* Attempts to pull an NXM or OXM header, value, and mask (if present) from the
402 * beginning of 'b'. If successful, stores a pointer to the "struct mf_field"
403 * corresponding to the pulled header in '*field', the value into '*value',
404 * and the mask into '*mask', and returns 0. On error, returns an OpenFlow
405 * error; in this case, some bytes might have been pulled off 'b' anyhow, and
406 * the output parameters might have been modified.
408 * If a NULL 'mask' is supplied, masked OXM or NXM entries are treated as
409 * errors (with OFPERR_OFPBMC_BAD_MASK).
412 nx_pull_entry(struct ofpbuf
*b
, const struct mf_field
**field
,
413 union mf_value
*value
, union mf_value
*mask
)
417 return nx_pull_entry__(b
, false, &header
, field
, value
, mask
);
420 /* Attempts to pull an NXM or OXM header from the beginning of 'b'. If
421 * successful, stores a pointer to the "struct mf_field" corresponding to the
422 * pulled header in '*field', stores the header's hasmask bit in '*masked'
423 * (true if hasmask=1, false if hasmask=0), and returns 0. On error, returns
424 * an OpenFlow error; in this case, some bytes might have been pulled off 'b'
425 * anyhow, and the output parameters might have been modified.
427 * If NULL 'masked' is supplied, masked OXM or NXM headers are treated as
428 * errors (with OFPERR_OFPBMC_BAD_MASK).
431 nx_pull_header(struct ofpbuf
*b
, const struct mf_field
**field
, bool *masked
)
436 error
= nx_pull_header__(b
, false, &header
, field
);
438 *masked
= !error
&& nxm_hasmask(header
);
439 } else if (!error
&& nxm_hasmask(header
)) {
440 error
= OFPERR_OFPBMC_BAD_MASK
;
446 nx_pull_match_entry(struct ofpbuf
*b
, bool allow_cookie
,
447 const struct mf_field
**field
,
448 union mf_value
*value
, union mf_value
*mask
)
453 error
= nx_pull_entry__(b
, allow_cookie
, &header
, field
, value
, mask
);
457 if (field
&& *field
) {
458 if (!mf_is_mask_valid(*field
, mask
)) {
459 VLOG_DBG_RL(&rl
, "bad mask for field %s", (*field
)->name
);
460 return OFPERR_OFPBMC_BAD_MASK
;
462 if (!mf_is_value_valid(*field
, value
)) {
463 VLOG_DBG_RL(&rl
, "bad value for field %s", (*field
)->name
);
464 return OFPERR_OFPBMC_BAD_VALUE
;
471 nx_pull_raw(const uint8_t *p
, unsigned int match_len
, bool strict
,
472 struct match
*match
, ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
476 ovs_assert((cookie
!= NULL
) == (cookie_mask
!= NULL
));
478 match_init_catchall(match
);
480 *cookie
= *cookie_mask
= htonll(0);
483 ofpbuf_use_const(&b
, p
, match_len
);
485 const uint8_t *pos
= b
.data
;
486 const struct mf_field
*field
;
487 union mf_value value
;
491 error
= nx_pull_match_entry(&b
, cookie
!= NULL
, &field
, &value
, &mask
);
493 if (error
== OFPERR_OFPBMC_BAD_FIELD
&& !strict
) {
498 error
= OFPERR_OFPBMC_BAD_FIELD
;
499 } else if (*cookie_mask
) {
500 error
= OFPERR_OFPBMC_DUP_FIELD
;
502 *cookie
= value
.be64
;
503 *cookie_mask
= mask
.be64
;
505 } else if (!mf_are_prereqs_ok(field
, &match
->flow
)) {
506 error
= OFPERR_OFPBMC_BAD_PREREQ
;
507 } else if (!mf_is_all_wild(field
, &match
->wc
)) {
508 error
= OFPERR_OFPBMC_DUP_FIELD
;
510 mf_set(field
, &value
, &mask
, match
);
514 VLOG_DBG_RL(&rl
, "error parsing OXM at offset %"PRIdPTR
" "
515 "within match (%s)", pos
-
516 p
, ofperr_to_string(error
));
525 nx_pull_match__(struct ofpbuf
*b
, unsigned int match_len
, bool strict
,
527 ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
532 p
= ofpbuf_try_pull(b
, ROUND_UP(match_len
, 8));
534 VLOG_DBG_RL(&rl
, "nx_match length %u, rounded up to a "
535 "multiple of 8, is longer than space in message (max "
536 "length %"PRIu32
")", match_len
, b
->size
);
537 return OFPERR_OFPBMC_BAD_LEN
;
541 return nx_pull_raw(p
, match_len
, strict
, match
, cookie
, cookie_mask
);
544 /* Parses the nx_match formatted match description in 'b' with length
545 * 'match_len'. Stores the results in 'match'. If 'cookie' and 'cookie_mask'
546 * are valid pointers, then stores the cookie and mask in them if 'b' contains
547 * a "NXM_NX_COOKIE*" match. Otherwise, stores 0 in both.
549 * Fails with an error upon encountering an unknown NXM header.
551 * Returns 0 if successful, otherwise an OpenFlow error code. */
553 nx_pull_match(struct ofpbuf
*b
, unsigned int match_len
, struct match
*match
,
554 ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
556 return nx_pull_match__(b
, match_len
, true, match
, cookie
, cookie_mask
);
559 /* Behaves the same as nx_pull_match(), but skips over unknown NXM headers,
560 * instead of failing with an error. */
562 nx_pull_match_loose(struct ofpbuf
*b
, unsigned int match_len
,
564 ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
566 return nx_pull_match__(b
, match_len
, false, match
, cookie
, cookie_mask
);
570 oxm_pull_match__(struct ofpbuf
*b
, bool strict
, struct match
*match
)
572 struct ofp11_match_header
*omh
= b
->data
;
576 if (b
->size
< sizeof *omh
) {
577 return OFPERR_OFPBMC_BAD_LEN
;
580 match_len
= ntohs(omh
->length
);
581 if (match_len
< sizeof *omh
) {
582 return OFPERR_OFPBMC_BAD_LEN
;
585 if (omh
->type
!= htons(OFPMT_OXM
)) {
586 return OFPERR_OFPBMC_BAD_TYPE
;
589 p
= ofpbuf_try_pull(b
, ROUND_UP(match_len
, 8));
591 VLOG_DBG_RL(&rl
, "oxm length %u, rounded up to a "
592 "multiple of 8, is longer than space in message (max "
593 "length %"PRIu32
")", match_len
, b
->size
);
594 return OFPERR_OFPBMC_BAD_LEN
;
597 return nx_pull_raw(p
+ sizeof *omh
, match_len
- sizeof *omh
,
598 strict
, match
, NULL
, NULL
);
601 /* Parses the oxm formatted match description preceded by a struct
602 * ofp11_match_header in 'b'. Stores the result in 'match'.
604 * Fails with an error when encountering unknown OXM headers.
606 * Returns 0 if successful, otherwise an OpenFlow error code. */
608 oxm_pull_match(struct ofpbuf
*b
, struct match
*match
)
610 return oxm_pull_match__(b
, true, match
);
613 /* Behaves the same as oxm_pull_match() with one exception. Skips over unknown
614 * OXM headers instead of failing with an error when they are encountered. */
616 oxm_pull_match_loose(struct ofpbuf
*b
, struct match
*match
)
618 return oxm_pull_match__(b
, false, match
);
621 /* Verify an array of OXM TLVs treating value of each TLV as a mask,
622 * disallowing masks in each TLV and ignoring pre-requisites. */
624 oxm_pull_field_array(const void *fields_data
, size_t fields_len
,
625 struct field_array
*fa
)
629 ofpbuf_use_const(&b
, fields_data
, fields_len
);
631 const uint8_t *pos
= b
.data
;
632 const struct mf_field
*field
;
633 union mf_value value
;
637 error
= nx_pull_entry__(&b
, false, &header
, &field
, &value
, NULL
);
639 VLOG_DBG_RL(&rl
, "error pulling field array field");
642 VLOG_DBG_RL(&rl
, "unknown field array field");
643 error
= OFPERR_OFPBMC_BAD_FIELD
;
644 } else if (bitmap_is_set(fa
->used
.bm
, field
->id
)) {
645 VLOG_DBG_RL(&rl
, "duplicate field array field '%s'", field
->name
);
646 error
= OFPERR_OFPBMC_DUP_FIELD
;
647 } else if (!mf_is_mask_valid(field
, &value
)) {
648 VLOG_DBG_RL(&rl
, "bad mask in field array field '%s'", field
->name
);
649 return OFPERR_OFPBMC_BAD_MASK
;
651 field_array_set(field
->id
, &value
, fa
);
655 const uint8_t *start
= fields_data
;
657 VLOG_DBG_RL(&rl
, "error parsing OXM at offset %"PRIdPTR
" "
658 "within field array (%s)", pos
- start
,
659 ofperr_to_string(error
));
667 /* nx_put_match() and helpers.
669 * 'put' functions whose names end in 'w' add a wildcarded field.
670 * 'put' functions whose names end in 'm' add a field that might be wildcarded.
671 * Other 'put' functions add exact-match fields.
675 nxm_put_unmasked(struct ofpbuf
*b
, enum mf_field_id field
,
676 enum ofp_version version
, const void *value
, size_t n_bytes
)
678 nx_put_header(b
, field
, version
, false);
679 ofpbuf_put(b
, value
, n_bytes
);
683 nxm_put(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
684 const void *value
, const void *mask
, size_t n_bytes
)
686 if (!is_all_zeros(mask
, n_bytes
)) {
687 bool masked
= !is_all_ones(mask
, n_bytes
);
688 nx_put_header(b
, field
, version
, masked
);
689 ofpbuf_put(b
, value
, n_bytes
);
691 ofpbuf_put(b
, mask
, n_bytes
);
697 nxm_put_8m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
698 uint8_t value
, uint8_t mask
)
700 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
704 nxm_put_8(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
707 nxm_put_unmasked(b
, field
, version
, &value
, sizeof value
);
711 nxm_put_16m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
712 ovs_be16 value
, ovs_be16 mask
)
714 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
718 nxm_put_16(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
721 nxm_put_unmasked(b
, field
, version
, &value
, sizeof value
);
725 nxm_put_32m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
726 ovs_be32 value
, ovs_be32 mask
)
728 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
732 nxm_put_32(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
735 nxm_put_unmasked(b
, field
, version
, &value
, sizeof value
);
739 nxm_put_64m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
740 ovs_be64 value
, ovs_be64 mask
)
742 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
746 nxm_put_eth_masked(struct ofpbuf
*b
,
747 enum mf_field_id field
, enum ofp_version version
,
748 const uint8_t value
[ETH_ADDR_LEN
],
749 const uint8_t mask
[ETH_ADDR_LEN
])
751 nxm_put(b
, field
, version
, value
, mask
, ETH_ADDR_LEN
);
755 nxm_put_ipv6(struct ofpbuf
*b
,
756 enum mf_field_id field
, enum ofp_version version
,
757 const struct in6_addr
*value
, const struct in6_addr
*mask
)
759 nxm_put(b
, field
, version
, value
->s6_addr
, mask
->s6_addr
,
760 sizeof value
->s6_addr
);
764 nxm_put_frag(struct ofpbuf
*b
, const struct match
*match
,
765 enum ofp_version version
)
767 uint8_t nw_frag
= match
->flow
.nw_frag
& FLOW_NW_FRAG_MASK
;
768 uint8_t nw_frag_mask
= match
->wc
.masks
.nw_frag
& FLOW_NW_FRAG_MASK
;
770 nxm_put_8m(b
, MFF_IP_FRAG
, version
, nw_frag
,
771 nw_frag_mask
== FLOW_NW_FRAG_MASK
? UINT8_MAX
: nw_frag_mask
);
774 /* Appends to 'b' a set of OXM or NXM matches for the IPv4 or IPv6 fields in
777 nxm_put_ip(struct ofpbuf
*b
, const struct match
*match
, enum ofp_version oxm
)
779 const struct flow
*flow
= &match
->flow
;
781 if (flow
->dl_type
== htons(ETH_TYPE_IP
)) {
782 nxm_put_32m(b
, MFF_IPV4_SRC
, oxm
,
783 flow
->nw_src
, match
->wc
.masks
.nw_src
);
784 nxm_put_32m(b
, MFF_IPV4_DST
, oxm
,
785 flow
->nw_dst
, match
->wc
.masks
.nw_dst
);
787 nxm_put_ipv6(b
, MFF_IPV6_SRC
, oxm
,
788 &flow
->ipv6_src
, &match
->wc
.masks
.ipv6_src
);
789 nxm_put_ipv6(b
, MFF_IPV6_DST
, oxm
,
790 &flow
->ipv6_dst
, &match
->wc
.masks
.ipv6_dst
);
793 nxm_put_frag(b
, match
, oxm
);
795 if (match
->wc
.masks
.nw_tos
& IP_DSCP_MASK
) {
797 nxm_put_8(b
, MFF_IP_DSCP_SHIFTED
, oxm
,
800 nxm_put_8(b
, MFF_IP_DSCP
, oxm
,
801 flow
->nw_tos
& IP_DSCP_MASK
);
805 if (match
->wc
.masks
.nw_tos
& IP_ECN_MASK
) {
806 nxm_put_8(b
, MFF_IP_ECN
, oxm
,
807 flow
->nw_tos
& IP_ECN_MASK
);
810 if (!oxm
&& match
->wc
.masks
.nw_ttl
) {
811 nxm_put_8(b
, MFF_IP_TTL
, oxm
, flow
->nw_ttl
);
814 nxm_put_32m(b
, MFF_IPV6_LABEL
, oxm
,
815 flow
->ipv6_label
, match
->wc
.masks
.ipv6_label
);
817 if (match
->wc
.masks
.nw_proto
) {
818 nxm_put_8(b
, MFF_IP_PROTO
, oxm
, flow
->nw_proto
);
820 if (flow
->nw_proto
== IPPROTO_TCP
) {
821 nxm_put_16m(b
, MFF_TCP_SRC
, oxm
,
822 flow
->tp_src
, match
->wc
.masks
.tp_src
);
823 nxm_put_16m(b
, MFF_TCP_DST
, oxm
,
824 flow
->tp_dst
, match
->wc
.masks
.tp_dst
);
825 nxm_put_16m(b
, MFF_TCP_FLAGS
, oxm
,
826 flow
->tcp_flags
, match
->wc
.masks
.tcp_flags
);
827 } else if (flow
->nw_proto
== IPPROTO_UDP
) {
828 nxm_put_16m(b
, MFF_UDP_SRC
, oxm
,
829 flow
->tp_src
, match
->wc
.masks
.tp_src
);
830 nxm_put_16m(b
, MFF_UDP_DST
, oxm
,
831 flow
->tp_dst
, match
->wc
.masks
.tp_dst
);
832 } else if (flow
->nw_proto
== IPPROTO_SCTP
) {
833 nxm_put_16m(b
, MFF_SCTP_SRC
, oxm
, flow
->tp_src
,
834 match
->wc
.masks
.tp_src
);
835 nxm_put_16m(b
, MFF_SCTP_DST
, oxm
, flow
->tp_dst
,
836 match
->wc
.masks
.tp_dst
);
837 } else if (is_icmpv4(flow
)) {
838 if (match
->wc
.masks
.tp_src
) {
839 nxm_put_8(b
, MFF_ICMPV4_TYPE
, oxm
,
840 ntohs(flow
->tp_src
));
842 if (match
->wc
.masks
.tp_dst
) {
843 nxm_put_8(b
, MFF_ICMPV4_CODE
, oxm
,
844 ntohs(flow
->tp_dst
));
846 } else if (is_icmpv6(flow
)) {
847 if (match
->wc
.masks
.tp_src
) {
848 nxm_put_8(b
, MFF_ICMPV6_TYPE
, oxm
,
849 ntohs(flow
->tp_src
));
851 if (match
->wc
.masks
.tp_dst
) {
852 nxm_put_8(b
, MFF_ICMPV6_CODE
, oxm
,
853 ntohs(flow
->tp_dst
));
855 if (flow
->tp_src
== htons(ND_NEIGHBOR_SOLICIT
) ||
856 flow
->tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
857 nxm_put_ipv6(b
, MFF_ND_TARGET
, oxm
,
858 &flow
->nd_target
, &match
->wc
.masks
.nd_target
);
859 if (flow
->tp_src
== htons(ND_NEIGHBOR_SOLICIT
)) {
860 nxm_put_eth_masked(b
, MFF_ND_SLL
, oxm
,
861 flow
->arp_sha
, match
->wc
.masks
.arp_sha
);
863 if (flow
->tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
864 nxm_put_eth_masked(b
, MFF_ND_TLL
, oxm
,
865 flow
->arp_tha
, match
->wc
.masks
.arp_tha
);
872 /* Appends to 'b' the nx_match format that expresses 'match'. For Flow Mod and
873 * Flow Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
874 * Otherwise, 'cookie_mask' should be zero.
876 * Specify 'oxm' as 0 to express the match in NXM format; otherwise, specify
877 * 'oxm' as the OpenFlow version number for the OXM format to use.
879 * This function can cause 'b''s data to be reallocated.
881 * Returns the number of bytes appended to 'b', excluding padding.
883 * If 'match' is a catch-all rule that matches every packet, then this function
884 * appends nothing to 'b' and returns 0. */
886 nx_put_raw(struct ofpbuf
*b
, enum ofp_version oxm
, const struct match
*match
,
887 ovs_be64 cookie
, ovs_be64 cookie_mask
)
889 const struct flow
*flow
= &match
->flow
;
890 const size_t start_len
= b
->size
;
894 BUILD_ASSERT_DECL(FLOW_WC_SEQ
== 31);
897 if (match
->wc
.masks
.dp_hash
) {
898 nxm_put_32m(b
, MFF_DP_HASH
, oxm
,
899 htonl(flow
->dp_hash
), htonl(match
->wc
.masks
.dp_hash
));
902 if (match
->wc
.masks
.recirc_id
) {
903 nxm_put_32(b
, MFF_RECIRC_ID
, oxm
, htonl(flow
->recirc_id
));
906 if (match
->wc
.masks
.conj_id
) {
907 nxm_put_32(b
, MFF_CONJ_ID
, oxm
, htonl(flow
->conj_id
));
910 if (match
->wc
.masks
.in_port
.ofp_port
) {
911 ofp_port_t in_port
= flow
->in_port
.ofp_port
;
913 nxm_put_32(b
, MFF_IN_PORT_OXM
, oxm
,
914 ofputil_port_to_ofp11(in_port
));
916 nxm_put_16(b
, MFF_IN_PORT
, oxm
,
917 htons(ofp_to_u16(in_port
)));
920 if (match
->wc
.masks
.actset_output
) {
921 nxm_put_32(b
, MFF_ACTSET_OUTPUT
, oxm
,
922 ofputil_port_to_ofp11(flow
->actset_output
));
926 nxm_put_eth_masked(b
, MFF_ETH_SRC
, oxm
,
927 flow
->dl_src
, match
->wc
.masks
.dl_src
);
928 nxm_put_eth_masked(b
, MFF_ETH_DST
, oxm
,
929 flow
->dl_dst
, match
->wc
.masks
.dl_dst
);
930 nxm_put_16m(b
, MFF_ETH_TYPE
, oxm
,
931 ofputil_dl_type_to_openflow(flow
->dl_type
),
932 match
->wc
.masks
.dl_type
);
936 ovs_be16 VID_CFI_MASK
= htons(VLAN_VID_MASK
| VLAN_CFI
);
937 ovs_be16 vid
= flow
->vlan_tci
& VID_CFI_MASK
;
938 ovs_be16 mask
= match
->wc
.masks
.vlan_tci
& VID_CFI_MASK
;
940 if (mask
== htons(VLAN_VID_MASK
| VLAN_CFI
)) {
941 nxm_put_16(b
, MFF_VLAN_VID
, oxm
, vid
);
943 nxm_put_16m(b
, MFF_VLAN_VID
, oxm
, vid
, mask
);
946 if (vid
&& vlan_tci_to_pcp(match
->wc
.masks
.vlan_tci
)) {
947 nxm_put_8(b
, MFF_VLAN_PCP
, oxm
,
948 vlan_tci_to_pcp(flow
->vlan_tci
));
952 nxm_put_16m(b
, MFF_VLAN_TCI
, oxm
, flow
->vlan_tci
,
953 match
->wc
.masks
.vlan_tci
);
957 if (eth_type_mpls(flow
->dl_type
)) {
958 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_TC_MASK
)) {
959 nxm_put_8(b
, MFF_MPLS_TC
, oxm
,
960 mpls_lse_to_tc(flow
->mpls_lse
[0]));
963 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_BOS_MASK
)) {
964 nxm_put_8(b
, MFF_MPLS_BOS
, oxm
,
965 mpls_lse_to_bos(flow
->mpls_lse
[0]));
968 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_LABEL_MASK
)) {
969 nxm_put_32(b
, MFF_MPLS_LABEL
, oxm
,
970 htonl(mpls_lse_to_label(flow
->mpls_lse
[0])));
975 if (is_ip_any(flow
)) {
976 nxm_put_ip(b
, match
, oxm
);
977 } else if (flow
->dl_type
== htons(ETH_TYPE_ARP
) ||
978 flow
->dl_type
== htons(ETH_TYPE_RARP
)) {
980 if (match
->wc
.masks
.nw_proto
) {
981 nxm_put_16(b
, MFF_ARP_OP
, oxm
,
982 htons(flow
->nw_proto
));
984 nxm_put_32m(b
, MFF_ARP_SPA
, oxm
,
985 flow
->nw_src
, match
->wc
.masks
.nw_src
);
986 nxm_put_32m(b
, MFF_ARP_TPA
, oxm
,
987 flow
->nw_dst
, match
->wc
.masks
.nw_dst
);
988 nxm_put_eth_masked(b
, MFF_ARP_SHA
, oxm
,
989 flow
->arp_sha
, match
->wc
.masks
.arp_sha
);
990 nxm_put_eth_masked(b
, MFF_ARP_THA
, oxm
,
991 flow
->arp_tha
, match
->wc
.masks
.arp_tha
);
995 nxm_put_64m(b
, MFF_TUN_ID
, oxm
,
996 flow
->tunnel
.tun_id
, match
->wc
.masks
.tunnel
.tun_id
);
998 /* Other tunnel metadata. */
999 nxm_put_32m(b
, MFF_TUN_SRC
, oxm
,
1000 flow
->tunnel
.ip_src
, match
->wc
.masks
.tunnel
.ip_src
);
1001 nxm_put_32m(b
, MFF_TUN_DST
, oxm
,
1002 flow
->tunnel
.ip_dst
, match
->wc
.masks
.tunnel
.ip_dst
);
1003 nxm_put_16m(b
, MFF_TUN_GBP_ID
, oxm
,
1004 flow
->tunnel
.gbp_id
, match
->wc
.masks
.tunnel
.gbp_id
);
1005 nxm_put_8m(b
, MFF_TUN_GBP_FLAGS
, oxm
,
1006 flow
->tunnel
.gbp_flags
, match
->wc
.masks
.tunnel
.gbp_flags
);
1009 if (oxm
< OFP15_VERSION
) {
1010 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
1011 nxm_put_32m(b
, MFF_REG0
+ i
, oxm
,
1012 htonl(flow
->regs
[i
]), htonl(match
->wc
.masks
.regs
[i
]));
1015 for (i
= 0; i
< FLOW_N_XREGS
; i
++) {
1016 nxm_put_64m(b
, MFF_XREG0
+ i
, oxm
,
1017 htonll(flow_get_xreg(flow
, i
)),
1018 htonll(flow_get_xreg(&match
->wc
.masks
, i
)));
1023 nxm_put_32m(b
, MFF_PKT_MARK
, oxm
, htonl(flow
->pkt_mark
),
1024 htonl(match
->wc
.masks
.pkt_mark
));
1026 /* OpenFlow 1.1+ Metadata. */
1027 nxm_put_64m(b
, MFF_METADATA
, oxm
,
1028 flow
->metadata
, match
->wc
.masks
.metadata
);
1032 bool masked
= cookie_mask
!= OVS_BE64_MAX
;
1034 cookie
&= cookie_mask
;
1035 nx_put_header__(b
, NXM_NX_COOKIE
, masked
);
1036 ofpbuf_put(b
, &cookie
, sizeof cookie
);
1038 ofpbuf_put(b
, &cookie_mask
, sizeof cookie_mask
);
1042 match_len
= b
->size
- start_len
;
1046 /* Appends to 'b' the nx_match format that expresses 'match', plus enough zero
1047 * bytes to pad the nx_match out to a multiple of 8. For Flow Mod and Flow
1048 * Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
1049 * Otherwise, 'cookie_mask' should be zero.
1051 * This function can cause 'b''s data to be reallocated.
1053 * Returns the number of bytes appended to 'b', excluding padding. The return
1054 * value can be zero if it appended nothing at all to 'b' (which happens if
1055 * 'cr' is a catch-all rule that matches every packet). */
1057 nx_put_match(struct ofpbuf
*b
, const struct match
*match
,
1058 ovs_be64 cookie
, ovs_be64 cookie_mask
)
1060 int match_len
= nx_put_raw(b
, 0, match
, cookie
, cookie_mask
);
1062 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1066 /* Appends to 'b' an struct ofp11_match_header followed by the OXM format that
1067 * expresses 'cr', plus enough zero bytes to pad the data appended out to a
1070 * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow
1071 * version in use as 'version'.
1073 * This function can cause 'b''s data to be reallocated.
1075 * Returns the number of bytes appended to 'b', excluding the padding. Never
1078 oxm_put_match(struct ofpbuf
*b
, const struct match
*match
,
1079 enum ofp_version version
)
1082 struct ofp11_match_header
*omh
;
1083 size_t start_len
= b
->size
;
1084 ovs_be64 cookie
= htonll(0), cookie_mask
= htonll(0);
1086 ofpbuf_put_uninit(b
, sizeof *omh
);
1087 match_len
= (nx_put_raw(b
, version
, match
, cookie
, cookie_mask
)
1089 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1091 omh
= ofpbuf_at(b
, start_len
, sizeof *omh
);
1092 omh
->type
= htons(OFPMT_OXM
);
1093 omh
->length
= htons(match_len
);
1098 /* Appends to 'b' the nx_match format that expresses the tlv corresponding
1099 * to 'id'. If mask is not all-ones then it is also formated as the value
1102 nx_format_mask_tlv(struct ds
*ds
, enum mf_field_id id
,
1103 const union mf_value
*mask
)
1105 const struct mf_field
*mf
= mf_from_id(id
);
1107 ds_put_format(ds
, "%s", mf
->name
);
1109 if (!is_all_ones(mask
, mf
->n_bytes
)) {
1110 ds_put_char(ds
, '=');
1111 mf_format(mf
, mask
, NULL
, ds
);
1114 ds_put_char(ds
, ',');
1117 /* Appends a string representation of 'fa_' to 'ds'.
1118 * The TLVS value of 'fa_' is treated as a mask and
1119 * only the name of fields is formated if it is all ones. */
1121 oxm_format_field_array(struct ds
*ds
, const struct field_array
*fa
)
1123 size_t start_len
= ds
->length
;
1126 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1127 if (bitmap_is_set(fa
->used
.bm
, i
)) {
1128 nx_format_mask_tlv(ds
, i
, &fa
->value
[i
]);
1132 if (ds
->length
> start_len
) {
1137 /* Appends to 'b' a series of OXM TLVs corresponding to the series
1138 * of enum mf_field_id and value tuples in 'fa_'.
1140 * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow
1141 * version in use as 'version'.
1143 * This function can cause 'b''s data to be reallocated.
1145 * Returns the number of bytes appended to 'b'. May return zero. */
1147 oxm_put_field_array(struct ofpbuf
*b
, const struct field_array
*fa
,
1148 enum ofp_version version
)
1150 size_t start_len
= b
->size
;
1153 /* Field arrays are only used with the group selection method
1154 * property and group properties are only available in OpenFlow 1.5+.
1155 * So the following assertion should never fail.
1157 * If support for older OpenFlow versions is desired then some care
1158 * will need to be taken of different TLVs that handle the same
1159 * flow fields. In particular:
1160 * - VLAN_TCI, VLAN_VID and MFF_VLAN_PCP
1161 * - IP_DSCP_MASK and DSCP_SHIFTED
1164 ovs_assert(version
>= OFP15_VERSION
);
1166 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1167 if (bitmap_is_set(fa
->used
.bm
, i
)) {
1168 nxm_put_unmasked(b
, i
, version
, &fa
->value
[i
],
1169 mf_from_id(i
)->n_bytes
);
1173 return b
->size
- start_len
;
1177 nx_put_header__(struct ofpbuf
*b
, uint64_t header
, bool masked
)
1179 uint64_t masked_header
= masked
? nxm_make_wild_header(header
) : header
;
1180 ovs_be64 network_header
= htonll(masked_header
);
1182 ofpbuf_put(b
, &network_header
, nxm_header_len(header
));
1186 nx_put_header(struct ofpbuf
*b
, enum mf_field_id field
,
1187 enum ofp_version version
, bool masked
)
1189 nx_put_header__(b
, mf_oxm_header(field
, version
), masked
);
1193 nx_put_entry(struct ofpbuf
*b
,
1194 enum mf_field_id field
, enum ofp_version version
,
1195 const union mf_value
*value
, const union mf_value
*mask
)
1197 int n_bytes
= mf_from_id(field
)->n_bytes
;
1198 bool masked
= mask
&& !is_all_ones(mask
, n_bytes
);
1200 nx_put_header(b
, field
, version
, masked
);
1201 ofpbuf_put(b
, value
, n_bytes
);
1203 ofpbuf_put(b
, mask
, n_bytes
);
1207 /* nx_match_to_string() and helpers. */
1209 static void format_nxm_field_name(struct ds
*, uint64_t header
);
1212 nx_match_to_string(const uint8_t *p
, unsigned int match_len
)
1218 return xstrdup("<any>");
1221 ofpbuf_use_const(&b
, p
, match_len
);
1224 union mf_value value
;
1225 union mf_value mask
;
1230 error
= nx_pull_entry__(&b
, true, &header
, NULL
, &value
, &mask
);
1234 value_len
= MIN(sizeof value
, nxm_field_bytes(header
));
1237 ds_put_cstr(&s
, ", ");
1240 format_nxm_field_name(&s
, header
);
1241 ds_put_char(&s
, '(');
1243 for (int i
= 0; i
< value_len
; i
++) {
1244 ds_put_format(&s
, "%02x", ((const uint8_t *) &value
)[i
]);
1246 if (nxm_hasmask(header
)) {
1247 ds_put_char(&s
, '/');
1248 for (int i
= 0; i
< value_len
; i
++) {
1249 ds_put_format(&s
, "%02x", ((const uint8_t *) &mask
)[i
]);
1252 ds_put_char(&s
, ')');
1257 ds_put_cstr(&s
, ", ");
1260 ds_put_format(&s
, "<%u invalid bytes>", b
.size
);
1263 return ds_steal_cstr(&s
);
1267 oxm_match_to_string(const struct ofpbuf
*p
, unsigned int match_len
)
1269 const struct ofp11_match_header
*omh
= p
->data
;
1270 uint16_t match_len_
;
1275 if (match_len
< sizeof *omh
) {
1276 ds_put_format(&s
, "<match too short: %u>", match_len
);
1280 if (omh
->type
!= htons(OFPMT_OXM
)) {
1281 ds_put_format(&s
, "<bad match type field: %u>", ntohs(omh
->type
));
1285 match_len_
= ntohs(omh
->length
);
1286 if (match_len_
< sizeof *omh
) {
1287 ds_put_format(&s
, "<match length field too short: %u>", match_len_
);
1291 if (match_len_
!= match_len
) {
1292 ds_put_format(&s
, "<match length field incorrect: %u != %u>",
1293 match_len_
, match_len
);
1297 return nx_match_to_string(ofpbuf_at(p
, sizeof *omh
, 0),
1298 match_len
- sizeof *omh
);
1301 return ds_steal_cstr(&s
);
1305 nx_format_field_name(enum mf_field_id id
, enum ofp_version version
,
1308 format_nxm_field_name(s
, mf_oxm_header(id
, version
));
1312 format_nxm_field_name(struct ds
*s
, uint64_t header
)
1314 const struct nxm_field
*f
= nxm_field_by_header(header
);
1316 ds_put_cstr(s
, f
->name
);
1317 if (nxm_hasmask(header
)) {
1318 ds_put_cstr(s
, "_W");
1320 } else if (header
== NXM_NX_COOKIE
) {
1321 ds_put_cstr(s
, "NXM_NX_COOKIE");
1322 } else if (header
== NXM_NX_COOKIE_W
) {
1323 ds_put_cstr(s
, "NXM_NX_COOKIE_W");
1325 ds_put_format(s
, "%d:%d", nxm_class(header
), nxm_field(header
));
1330 streq_len(const char *a
, size_t a_len
, const char *b
)
1332 return strlen(b
) == a_len
&& !memcmp(a
, b
, a_len
);
1336 parse_nxm_field_name(const char *name
, int name_len
)
1338 const struct nxm_field
*f
;
1341 f
= mf_parse_subfield_name(name
, name_len
, &wild
);
1345 } else if (mf_from_id(f
->id
)->maskable
!= MFM_NONE
) {
1346 return nxm_make_wild_header(f
->header
);
1350 if (streq_len(name
, name_len
, "NXM_NX_COOKIE")) {
1351 return NXM_NX_COOKIE
;
1352 } else if (streq_len(name
, name_len
, "NXM_NX_COOKIE_W")) {
1353 return NXM_NX_COOKIE_W
;
1356 /* Check whether it's a field header value as hex.
1357 * (This isn't ordinarily useful except for testing error behavior.) */
1358 if (name_len
== 8) {
1362 header
= hexits_value(name
, name_len
, &ok
) << 32;
1366 } else if (name_len
== 16) {
1370 header
= hexits_value(name
, name_len
, &ok
);
1371 if (ok
&& is_experimenter_oxm(header
)) {
1379 /* nx_match_from_string(). */
1382 nx_match_from_string_raw(const char *s
, struct ofpbuf
*b
)
1384 const char *full_s
= s
;
1385 const size_t start_len
= b
->size
;
1387 if (!strcmp(s
, "<any>")) {
1388 /* Ensure that 'b->data' isn't actually null. */
1389 ofpbuf_prealloc_tailroom(b
, 1);
1393 for (s
+= strspn(s
, ", "); *s
; s
+= strspn(s
, ", ")) {
1400 name_len
= strcspn(s
, "(");
1401 if (s
[name_len
] != '(') {
1402 ovs_fatal(0, "%s: missing ( at end of nx_match", full_s
);
1405 header
= parse_nxm_field_name(name
, name_len
);
1407 ovs_fatal(0, "%s: unknown field `%.*s'", full_s
, name_len
, s
);
1412 nx_put_header__(b
, header
, false);
1413 s
= ofpbuf_put_hex(b
, s
, &n
);
1414 if (n
!= nxm_field_bytes(header
)) {
1415 ovs_fatal(0, "%.2s: hex digits expected", s
);
1417 if (nxm_hasmask(header
)) {
1418 s
+= strspn(s
, " ");
1420 ovs_fatal(0, "%s: missing / in masked field %.*s",
1421 full_s
, name_len
, name
);
1423 s
= ofpbuf_put_hex(b
, s
+ 1, &n
);
1424 if (n
!= nxm_field_bytes(header
)) {
1425 ovs_fatal(0, "%.2s: hex digits expected", s
);
1429 s
+= strspn(s
, " ");
1431 ovs_fatal(0, "%s: missing ) following field %.*s",
1432 full_s
, name_len
, name
);
1437 return b
->size
- start_len
;
1441 nx_match_from_string(const char *s
, struct ofpbuf
*b
)
1443 int match_len
= nx_match_from_string_raw(s
, b
);
1444 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1449 oxm_match_from_string(const char *s
, struct ofpbuf
*b
)
1452 struct ofp11_match_header
*omh
;
1453 size_t start_len
= b
->size
;
1455 ofpbuf_put_uninit(b
, sizeof *omh
);
1456 match_len
= nx_match_from_string_raw(s
, b
) + sizeof *omh
;
1457 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1459 omh
= ofpbuf_at(b
, start_len
, sizeof *omh
);
1460 omh
->type
= htons(OFPMT_OXM
);
1461 omh
->length
= htons(match_len
);
1466 /* Parses 's' as a "move" action, in the form described in ovs-ofctl(8), into
1469 * Returns NULL if successful, otherwise a malloc()'d string describing the
1470 * error. The caller is responsible for freeing the returned string. */
1471 char * OVS_WARN_UNUSED_RESULT
1472 nxm_parse_reg_move(struct ofpact_reg_move
*move
, const char *s
)
1474 const char *full_s
= s
;
1477 error
= mf_parse_subfield__(&move
->src
, &s
);
1481 if (strncmp(s
, "->", 2)) {
1482 return xasprintf("%s: missing `->' following source", full_s
);
1485 error
= mf_parse_subfield(&move
->dst
, s
);
1490 if (move
->src
.n_bits
!= move
->dst
.n_bits
) {
1491 return xasprintf("%s: source field is %d bits wide but destination is "
1492 "%d bits wide", full_s
,
1493 move
->src
.n_bits
, move
->dst
.n_bits
);
1498 /* nxm_format_reg_move(). */
1501 nxm_format_reg_move(const struct ofpact_reg_move
*move
, struct ds
*s
)
1503 ds_put_format(s
, "move:");
1504 mf_format_subfield(&move
->src
, s
);
1505 ds_put_cstr(s
, "->");
1506 mf_format_subfield(&move
->dst
, s
);
1511 nxm_reg_move_check(const struct ofpact_reg_move
*move
, const struct flow
*flow
)
1515 error
= mf_check_src(&move
->src
, flow
);
1520 return mf_check_dst(&move
->dst
, flow
);
1523 /* nxm_execute_reg_move(). */
1526 nxm_execute_reg_move(const struct ofpact_reg_move
*move
,
1527 struct flow
*flow
, struct flow_wildcards
*wc
)
1529 union mf_value src_value
;
1530 union mf_value dst_value
;
1532 mf_mask_field_and_prereqs(move
->dst
.field
, &wc
->masks
);
1533 mf_mask_field_and_prereqs(move
->src
.field
, &wc
->masks
);
1535 /* A flow may wildcard nw_frag. Do nothing if setting a transport
1536 * header field on a packet that does not have them. */
1537 if (mf_are_prereqs_ok(move
->dst
.field
, flow
)
1538 && mf_are_prereqs_ok(move
->src
.field
, flow
)) {
1540 mf_get_value(move
->dst
.field
, flow
, &dst_value
);
1541 mf_get_value(move
->src
.field
, flow
, &src_value
);
1542 bitwise_copy(&src_value
, move
->src
.field
->n_bytes
, move
->src
.ofs
,
1543 &dst_value
, move
->dst
.field
->n_bytes
, move
->dst
.ofs
,
1545 mf_set_flow_value(move
->dst
.field
, &dst_value
, flow
);
1550 nxm_reg_load(const struct mf_subfield
*dst
, uint64_t src_data
,
1551 struct flow
*flow
, struct flow_wildcards
*wc
)
1553 union mf_subvalue src_subvalue
;
1554 union mf_subvalue mask_value
;
1555 ovs_be64 src_data_be
= htonll(src_data
);
1557 memset(&mask_value
, 0xff, sizeof mask_value
);
1558 mf_write_subfield_flow(dst
, &mask_value
, &wc
->masks
);
1560 bitwise_copy(&src_data_be
, sizeof src_data_be
, 0,
1561 &src_subvalue
, sizeof src_subvalue
, 0,
1562 sizeof src_data_be
* 8);
1563 mf_write_subfield_flow(dst
, &src_subvalue
, flow
);
1566 /* nxm_parse_stack_action, works for both push() and pop(). */
1568 /* Parses 's' as a "push" or "pop" action, in the form described in
1569 * ovs-ofctl(8), into '*stack_action'.
1571 * Returns NULL if successful, otherwise a malloc()'d string describing the
1572 * error. The caller is responsible for freeing the returned string. */
1573 char * OVS_WARN_UNUSED_RESULT
1574 nxm_parse_stack_action(struct ofpact_stack
*stack_action
, const char *s
)
1578 error
= mf_parse_subfield__(&stack_action
->subfield
, &s
);
1584 return xasprintf("%s: trailing garbage following push or pop", s
);
1591 nxm_format_stack_push(const struct ofpact_stack
*push
, struct ds
*s
)
1593 ds_put_cstr(s
, "push:");
1594 mf_format_subfield(&push
->subfield
, s
);
1598 nxm_format_stack_pop(const struct ofpact_stack
*pop
, struct ds
*s
)
1600 ds_put_cstr(s
, "pop:");
1601 mf_format_subfield(&pop
->subfield
, s
);
1605 nxm_stack_push_check(const struct ofpact_stack
*push
,
1606 const struct flow
*flow
)
1608 return mf_check_src(&push
->subfield
, flow
);
1612 nxm_stack_pop_check(const struct ofpact_stack
*pop
,
1613 const struct flow
*flow
)
1615 return mf_check_dst(&pop
->subfield
, flow
);
1618 /* nxm_execute_stack_push(), nxm_execute_stack_pop(). */
1620 nx_stack_push(struct ofpbuf
*stack
, union mf_subvalue
*v
)
1622 ofpbuf_put(stack
, v
, sizeof *v
);
1625 static union mf_subvalue
*
1626 nx_stack_pop(struct ofpbuf
*stack
)
1628 union mf_subvalue
*v
= NULL
;
1632 stack
->size
-= sizeof *v
;
1633 v
= (union mf_subvalue
*) ofpbuf_tail(stack
);
1640 nxm_execute_stack_push(const struct ofpact_stack
*push
,
1641 const struct flow
*flow
, struct flow_wildcards
*wc
,
1642 struct ofpbuf
*stack
)
1644 union mf_subvalue mask_value
;
1645 union mf_subvalue dst_value
;
1647 memset(&mask_value
, 0xff, sizeof mask_value
);
1648 mf_write_subfield_flow(&push
->subfield
, &mask_value
, &wc
->masks
);
1650 mf_read_subfield(&push
->subfield
, flow
, &dst_value
);
1651 nx_stack_push(stack
, &dst_value
);
1655 nxm_execute_stack_pop(const struct ofpact_stack
*pop
,
1656 struct flow
*flow
, struct flow_wildcards
*wc
,
1657 struct ofpbuf
*stack
)
1659 union mf_subvalue
*src_value
;
1661 src_value
= nx_stack_pop(stack
);
1663 /* Only pop if stack is not empty. Otherwise, give warning. */
1665 union mf_subvalue mask_value
;
1667 memset(&mask_value
, 0xff, sizeof mask_value
);
1668 mf_write_subfield_flow(&pop
->subfield
, &mask_value
, &wc
->masks
);
1669 mf_write_subfield_flow(&pop
->subfield
, src_value
, flow
);
1671 if (!VLOG_DROP_WARN(&rl
)) {
1672 char *flow_str
= flow_to_string(flow
);
1673 VLOG_WARN_RL(&rl
, "Failed to pop from an empty stack. On flow\n"
1680 /* Formats 'sf' into 's' in a format normally acceptable to
1681 * mf_parse_subfield(). (It won't be acceptable if sf->field is NULL or if
1682 * sf->field has no NXM name.) */
1684 mf_format_subfield(const struct mf_subfield
*sf
, struct ds
*s
)
1687 ds_put_cstr(s
, "<unknown>");
1689 const struct nxm_field
*f
= nxm_field_by_mf_id(sf
->field
->id
, 0);
1690 ds_put_cstr(s
, f
? f
->name
: sf
->field
->name
);
1693 if (sf
->field
&& sf
->ofs
== 0 && sf
->n_bits
== sf
->field
->n_bits
) {
1694 ds_put_cstr(s
, "[]");
1695 } else if (sf
->n_bits
== 1) {
1696 ds_put_format(s
, "[%d]", sf
->ofs
);
1698 ds_put_format(s
, "[%d..%d]", sf
->ofs
, sf
->ofs
+ sf
->n_bits
- 1);
1702 static const struct nxm_field
*
1703 mf_parse_subfield_name(const char *name
, int name_len
, bool *wild
)
1705 *wild
= name_len
> 2 && !memcmp(&name
[name_len
- 2], "_W", 2);
1710 return nxm_field_by_name(name
, name_len
);
1713 /* Parses a subfield from the beginning of '*sp' into 'sf'. If successful,
1714 * returns NULL and advances '*sp' to the first byte following the parsed
1715 * string. On failure, returns a malloc()'d error message, does not modify
1716 * '*sp', and does not properly initialize 'sf'.
1718 * The syntax parsed from '*sp' takes the form "header[start..end]" where
1719 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1720 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1721 * may both be omitted (the [] are still required) to indicate an entire
1723 char * OVS_WARN_UNUSED_RESULT
1724 mf_parse_subfield__(struct mf_subfield
*sf
, const char **sp
)
1726 const struct mf_field
*field
;
1727 const struct nxm_field
*f
;
1736 name_len
= strcspn(s
, "[");
1737 if (s
[name_len
] != '[') {
1738 return xasprintf("%s: missing [ looking for field name", *sp
);
1741 f
= mf_parse_subfield_name(name
, name_len
, &wild
);
1743 return xasprintf("%s: unknown field `%.*s'", *sp
, name_len
, s
);
1745 field
= mf_from_id(f
->id
);
1748 if (ovs_scan(s
, "[%d..%d]", &start
, &end
)) {
1749 /* Nothing to do. */
1750 } else if (ovs_scan(s
, "[%d]", &start
)) {
1752 } else if (!strncmp(s
, "[]", 2)) {
1754 end
= field
->n_bits
- 1;
1756 return xasprintf("%s: syntax error expecting [] or [<bit>] or "
1757 "[<start>..<end>]", *sp
);
1759 s
= strchr(s
, ']') + 1;
1762 return xasprintf("%s: starting bit %d is after ending bit %d",
1764 } else if (start
>= field
->n_bits
) {
1765 return xasprintf("%s: starting bit %d is not valid because field is "
1766 "only %d bits wide", *sp
, start
, field
->n_bits
);
1767 } else if (end
>= field
->n_bits
){
1768 return xasprintf("%s: ending bit %d is not valid because field is "
1769 "only %d bits wide", *sp
, end
, field
->n_bits
);
1774 sf
->n_bits
= end
- start
+ 1;
1780 /* Parses a subfield from the entirety of 's' into 'sf'. Returns NULL if
1781 * successful, otherwise a malloc()'d string describing the error. The caller
1782 * is responsible for freeing the returned string.
1784 * The syntax parsed from 's' takes the form "header[start..end]" where
1785 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1786 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1787 * may both be omitted (the [] are still required) to indicate an entire
1789 char * OVS_WARN_UNUSED_RESULT
1790 mf_parse_subfield(struct mf_subfield
*sf
, const char *s
)
1792 char *error
= mf_parse_subfield__(sf
, &s
);
1793 if (!error
&& s
[0]) {
1794 error
= xstrdup("unexpected input following field syntax");
1799 /* Returns an bitmap in which each bit corresponds to the like-numbered field
1800 * in the OFPXMC12_OPENFLOW_BASIC OXM class, in which the bit values are taken
1801 * from the 'fields' bitmap. Only fields defined in OpenFlow 'version' are
1804 * This is useful for encoding OpenFlow 1.2 table stats messages. */
1806 oxm_bitmap_from_mf_bitmap(const struct mf_bitmap
*fields
,
1807 enum ofp_version version
)
1809 uint64_t oxm_bitmap
= 0;
1812 BITMAP_FOR_EACH_1 (i
, MFF_N_IDS
, fields
->bm
) {
1813 uint64_t oxm
= mf_oxm_header(i
, version
);
1814 uint32_t class = nxm_class(oxm
);
1815 int field
= nxm_field(oxm
);
1817 if (class == OFPXMC12_OPENFLOW_BASIC
&& field
< 64) {
1818 oxm_bitmap
|= UINT64_C(1) << field
;
1821 return htonll(oxm_bitmap
);
1824 /* Opposite conversion from oxm_bitmap_from_mf_bitmap().
1826 * This is useful for decoding OpenFlow 1.2 table stats messages. */
1828 oxm_bitmap_to_mf_bitmap(ovs_be64 oxm_bitmap
, enum ofp_version version
)
1830 struct mf_bitmap fields
= MF_BITMAP_INITIALIZER
;
1832 for (enum mf_field_id id
= 0; id
< MFF_N_IDS
; id
++) {
1833 uint64_t oxm
= mf_oxm_header(id
, version
);
1834 if (oxm
&& version
>= nxm_field_by_header(oxm
)->version
) {
1835 uint32_t class = nxm_class(oxm
);
1836 int field
= nxm_field(oxm
);
1838 if (class == OFPXMC12_OPENFLOW_BASIC
1840 && oxm_bitmap
& htonll(UINT64_C(1) << field
)) {
1841 bitmap_set1(fields
.bm
, id
);
1848 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1849 * modified with a "set_field" action. */
1851 oxm_writable_fields(void)
1853 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1856 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1857 if (mf_oxm_header(i
, 0) && mf_from_id(i
)->writable
) {
1858 bitmap_set1(b
.bm
, i
);
1864 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1865 * matched in a flow table. */
1867 oxm_matchable_fields(void)
1869 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1872 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1873 if (mf_oxm_header(i
, 0)) {
1874 bitmap_set1(b
.bm
, i
);
1880 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1881 * matched in a flow table with an arbitrary bitmask. */
1883 oxm_maskable_fields(void)
1885 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1888 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1889 if (mf_oxm_header(i
, 0) && mf_from_id(i
)->maskable
== MFM_FULLY
) {
1890 bitmap_set1(b
.bm
, i
);
1896 struct nxm_field_index
{
1897 struct hmap_node header_node
; /* In nxm_header_map. */
1898 struct hmap_node name_node
; /* In nxm_name_map. */
1899 struct ovs_list mf_node
; /* In mf_mf_map[nf.id]. */
1900 const struct nxm_field nf
;
1903 #include "nx-match.inc"
1905 static struct hmap nxm_header_map
;
1906 static struct hmap nxm_name_map
;
1907 static struct ovs_list nxm_mf_map
[MFF_N_IDS
];
1912 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
1913 if (ovsthread_once_start(&once
)) {
1914 hmap_init(&nxm_header_map
);
1915 hmap_init(&nxm_name_map
);
1916 for (int i
= 0; i
< MFF_N_IDS
; i
++) {
1917 list_init(&nxm_mf_map
[i
]);
1919 for (struct nxm_field_index
*nfi
= all_nxm_fields
;
1920 nfi
< &all_nxm_fields
[ARRAY_SIZE(all_nxm_fields
)]; nfi
++) {
1921 hmap_insert(&nxm_header_map
, &nfi
->header_node
,
1922 hash_uint64(nxm_no_len(nfi
->nf
.header
)));
1923 hmap_insert(&nxm_name_map
, &nfi
->name_node
,
1924 hash_string(nfi
->nf
.name
, 0));
1925 list_push_back(&nxm_mf_map
[nfi
->nf
.id
], &nfi
->mf_node
);
1927 ovsthread_once_done(&once
);
1931 static const struct nxm_field
*
1932 nxm_field_by_header(uint64_t header
)
1934 const struct nxm_field_index
*nfi
;
1935 uint64_t header_no_len
;
1938 if (nxm_hasmask(header
)) {
1939 header
= nxm_make_exact_header(header
);
1942 header_no_len
= nxm_no_len(header
);
1944 HMAP_FOR_EACH_IN_BUCKET (nfi
, header_node
, hash_uint64(header_no_len
),
1946 if (header_no_len
== nxm_no_len(nfi
->nf
.header
)) {
1947 if (nxm_length(header
) == nxm_length(nfi
->nf
.header
) ||
1948 mf_from_id(nfi
->nf
.id
)->variable_len
) {
1958 static const struct nxm_field
*
1959 nxm_field_by_name(const char *name
, size_t len
)
1961 const struct nxm_field_index
*nfi
;
1964 HMAP_FOR_EACH_WITH_HASH (nfi
, name_node
, hash_bytes(name
, len
, 0),
1966 if (strlen(nfi
->nf
.name
) == len
&& !memcmp(nfi
->nf
.name
, name
, len
)) {
1973 static const struct nxm_field
*
1974 nxm_field_by_mf_id(enum mf_field_id id
, enum ofp_version version
)
1976 const struct nxm_field_index
*nfi
;
1977 const struct nxm_field
*f
;
1982 LIST_FOR_EACH (nfi
, mf_node
, &nxm_mf_map
[id
]) {
1983 if (!f
|| version
>= nfi
->nf
.version
) {