2 * Copyright (c) 2010, 2011, 2012, 2013, 2014 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"
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; }
102 is_experimenter_oxm(uint64_t header
)
104 return nxm_class(header
) == OFPXMC12_EXPERIMENTER
;
107 /* The OXM header "length" field is somewhat tricky:
109 * - For a standard OXM header, the length is the number of bytes of the
110 * payload, and the payload consists of just the value (and mask, if
113 * - For an experimenter OXM header, the length is the number of bytes in
114 * the payload plus 4 (the length of the experimenter ID). That is, the
115 * experimenter ID is included in oxm_length.
117 * This function returns the length of the experimenter ID field in 'header'.
118 * That is, for an experimenter OXM (when an experimenter ID is present), it
119 * returns 4, and for a standard OXM (when no experimenter ID is present), it
122 nxm_experimenter_len(uint64_t header
)
124 return is_experimenter_oxm(header
) ? 4 : 0;
127 /* Returns the number of bytes that follow the header for an NXM/OXM entry
128 * with the given 'header'. */
130 nxm_payload_len(uint64_t header
)
132 return nxm_length(header
) - nxm_experimenter_len(header
);
135 /* Returns the number of bytes in the header for an NXM/OXM entry with the
138 nxm_header_len(uint64_t header
)
140 return 4 + nxm_experimenter_len(header
);
143 #define NXM_HEADER(VENDOR, CLASS, FIELD, HASMASK, LENGTH) \
144 (((uint64_t) (CLASS) << 48) | \
145 ((uint64_t) (FIELD) << 41) | \
146 ((uint64_t) (HASMASK) << 40) | \
147 ((uint64_t) (LENGTH) << 32) | \
150 #define NXM_HEADER_FMT "%#"PRIx32":%d:%d:%d:%d"
151 #define NXM_HEADER_ARGS(HEADER) \
152 nxm_vendor(HEADER), nxm_class(HEADER), nxm_field(HEADER), \
153 nxm_hasmask(HEADER), nxm_length(HEADER)
155 /* Functions for turning the "hasmask" bit on or off. (This also requires
156 * adjusting the length.) */
158 nxm_make_exact_header(uint64_t header
)
160 int new_len
= nxm_payload_len(header
) / 2 + nxm_experimenter_len(header
);
161 return NXM_HEADER(nxm_vendor(header
), nxm_class(header
),
162 nxm_field(header
), 0, new_len
);
165 nxm_make_wild_header(uint64_t header
)
167 int new_len
= nxm_payload_len(header
) * 2 + nxm_experimenter_len(header
);
168 return NXM_HEADER(nxm_vendor(header
), nxm_class(header
),
169 nxm_field(header
), 1, new_len
);
174 * This may be used to gain the OpenFlow 1.1-like ability to restrict
175 * certain NXM-based Flow Mod and Flow Stats Request messages to flows
176 * with specific cookies. See the "nx_flow_mod" and "nx_flow_stats_request"
177 * structure definitions for more details. This match is otherwise not
179 #define NXM_NX_COOKIE NXM_HEADER (0, 0x0001, 30, 0, 8)
180 #define NXM_NX_COOKIE_W nxm_make_wild_header(NXM_NX_COOKIE)
184 enum ofp_version version
;
185 const char *name
; /* e.g. "NXM_OF_IN_PORT". */
190 static const struct nxm_field
*nxm_field_by_header(uint64_t header
);
191 static const struct nxm_field
*nxm_field_by_name(const char *name
, size_t len
);
192 static const struct nxm_field
*nxm_field_by_mf_id(enum mf_field_id
,
195 static void nx_put_header__(struct ofpbuf
*, uint64_t header
, bool masked
);
197 /* Rate limit for nx_match parse errors. These always indicate a bug in the
198 * peer and so there's not much point in showing a lot of them. */
199 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
201 static const struct nxm_field
*
202 mf_parse_subfield_name(const char *name
, int name_len
, bool *wild
);
204 /* Returns the preferred OXM header to use for field 'id' in OpenFlow version
205 * 'version'. Specify 0 for 'version' if an NXM legacy header should be
206 * preferred over any standardized OXM header. Returns 0 if field 'id' cannot
207 * be expressed in NXM or OXM. */
209 mf_oxm_header(enum mf_field_id id
, enum ofp_version version
)
211 const struct nxm_field
*f
= nxm_field_by_mf_id(id
, version
);
212 return f
? f
->header
: 0;
215 /* Returns the 32-bit OXM or NXM header to use for field 'id', preferring an
216 * NXM legacy header over any standardized OXM header. Returns 0 if field 'id'
217 * cannot be expressed with a 32-bit NXM or OXM header.
219 * Whenever possible, use nx_pull_header() instead of this function, because
220 * this function cannot support 64-bit experimenter OXM headers. */
222 mf_nxm_header(enum mf_field_id id
)
224 uint64_t oxm
= mf_oxm_header(id
, 0);
225 return is_experimenter_oxm(oxm
) ? 0 : oxm
>> 32;
228 static const struct mf_field
*
229 mf_from_oxm_header(uint64_t header
)
231 const struct nxm_field
*f
= nxm_field_by_header(header
);
232 return f
? mf_from_id(f
->id
) : NULL
;
235 /* Returns the "struct mf_field" that corresponds to NXM or OXM header
236 * 'header', or NULL if 'header' doesn't correspond to any known field. */
237 const struct mf_field
*
238 mf_from_nxm_header(uint32_t header
)
240 return mf_from_oxm_header((uint64_t) header
<< 32);
243 /* Returns the width of the data for a field with the given 'header', in
246 nxm_field_bytes(uint64_t header
)
248 unsigned int length
= nxm_payload_len(header
);
249 return nxm_hasmask(header
) ? length
/ 2 : length
;
252 /* nx_pull_match() and helpers. */
254 /* Given NXM/OXM value 'value' and mask 'mask' associated with 'header', checks
255 * for any 1-bit in the value where there is a 0-bit in the mask. Returns 0 if
256 * none, otherwise an error code. */
258 is_mask_consistent(uint64_t header
, const uint8_t *value
, const uint8_t *mask
)
260 unsigned int width
= nxm_field_bytes(header
);
263 for (i
= 0; i
< width
; i
++) {
264 if (value
[i
] & ~mask
[i
]) {
265 if (!VLOG_DROP_WARN(&rl
)) {
266 VLOG_WARN_RL(&rl
, "Rejecting NXM/OXM entry "NXM_HEADER_FMT
" "
267 "with 1-bits in value for bits wildcarded by the "
268 "mask.", NXM_HEADER_ARGS(header
));
277 is_cookie_pseudoheader(uint64_t header
)
279 return header
== NXM_NX_COOKIE
|| header
== NXM_NX_COOKIE_W
;
283 nx_pull_header__(struct ofpbuf
*b
, bool allow_cookie
, uint64_t *header
,
284 const struct mf_field
**field
)
286 if (ofpbuf_size(b
) < 4) {
290 *header
= ((uint64_t) ntohl(get_unaligned_be32(ofpbuf_data(b
)))) << 32;
291 if (is_experimenter_oxm(*header
)) {
292 if (ofpbuf_size(b
) < 8) {
295 *header
= ntohll(get_unaligned_be64(ofpbuf_data(b
)));
297 if (nxm_length(*header
) <= nxm_experimenter_len(*header
)) {
298 VLOG_WARN_RL(&rl
, "OXM header "NXM_HEADER_FMT
" has invalid length %d "
300 NXM_HEADER_ARGS(*header
), nxm_length(*header
),
301 nxm_header_len(*header
) + 1);
304 ofpbuf_pull(b
, nxm_header_len(*header
));
307 *field
= mf_from_oxm_header(*header
);
308 if (!*field
&& !(allow_cookie
&& is_cookie_pseudoheader(*header
))) {
309 VLOG_DBG_RL(&rl
, "OXM header "NXM_HEADER_FMT
" is unknown",
310 NXM_HEADER_ARGS(*header
));
311 return OFPERR_OFPBMC_BAD_FIELD
;
318 VLOG_DBG_RL(&rl
, "encountered partial (%"PRIu32
"-byte) OXM entry",
323 return OFPERR_OFPBMC_BAD_LEN
;
327 nx_pull_entry__(struct ofpbuf
*b
, bool allow_cookie
, uint64_t *header
,
328 const struct mf_field
**field
,
329 union mf_value
*value
, union mf_value
*mask
)
331 enum ofperr header_error
;
332 unsigned int payload_len
;
333 const uint8_t *payload
;
336 header_error
= nx_pull_header__(b
, allow_cookie
, header
, field
);
337 if (header_error
&& header_error
!= OFPERR_OFPBMC_BAD_FIELD
) {
341 payload_len
= nxm_payload_len(*header
);
342 payload
= ofpbuf_try_pull(b
, payload_len
);
344 VLOG_DBG_RL(&rl
, "OXM header "NXM_HEADER_FMT
" calls for %u-byte "
345 "payload but only %"PRIu32
" bytes follow OXM header",
346 NXM_HEADER_ARGS(*header
), payload_len
, ofpbuf_size(b
));
347 return OFPERR_OFPBMC_BAD_LEN
;
350 width
= nxm_field_bytes(*header
);
351 if (nxm_hasmask(*header
)
352 && !is_mask_consistent(*header
, payload
, payload
+ width
)) {
353 return OFPERR_OFPBMC_BAD_WILDCARDS
;
356 memcpy(value
, payload
, MIN(width
, sizeof *value
));
358 if (nxm_hasmask(*header
)) {
359 memcpy(mask
, payload
+ width
, MIN(width
, sizeof *mask
));
361 memset(mask
, 0xff, MIN(width
, sizeof *mask
));
363 } else if (nxm_hasmask(*header
)) {
364 VLOG_DBG_RL(&rl
, "OXM header "NXM_HEADER_FMT
" includes mask but "
365 "masked OXMs are not allowed here",
366 NXM_HEADER_ARGS(*header
));
367 return OFPERR_OFPBMC_BAD_MASK
;
373 /* Attempts to pull an NXM or OXM header, value, and mask (if present) from the
374 * beginning of 'b'. If successful, stores a pointer to the "struct mf_field"
375 * corresponding to the pulled header in '*field', the value into '*value',
376 * and the mask into '*mask', and returns 0. On error, returns an OpenFlow
377 * error; in this case, some bytes might have been pulled off 'b' anyhow, and
378 * the output parameters might have been modified.
380 * If a NULL 'mask' is supplied, masked OXM or NXM entries are treated as
381 * errors (with OFPERR_OFPBMC_BAD_MASK).
384 nx_pull_entry(struct ofpbuf
*b
, const struct mf_field
**field
,
385 union mf_value
*value
, union mf_value
*mask
)
389 return nx_pull_entry__(b
, false, &header
, field
, value
, mask
);
392 /* Attempts to pull an NXM or OXM header from the beginning of 'b'. If
393 * successful, stores a pointer to the "struct mf_field" corresponding to the
394 * pulled header in '*field', stores the header's hasmask bit in '*masked'
395 * (true if hasmask=1, false if hasmask=0), and returns 0. On error, returns
396 * an OpenFlow error; in this case, some bytes might have been pulled off 'b'
397 * anyhow, and the output parameters might have been modified.
399 * If NULL 'masked' is supplied, masked OXM or NXM headers are treated as
400 * errors (with OFPERR_OFPBMC_BAD_MASK).
403 nx_pull_header(struct ofpbuf
*b
, const struct mf_field
**field
, bool *masked
)
408 error
= nx_pull_header__(b
, false, &header
, field
);
410 *masked
= !error
&& nxm_hasmask(header
);
411 } else if (!error
&& nxm_hasmask(header
)) {
412 error
= OFPERR_OFPBMC_BAD_MASK
;
418 nx_pull_match_entry(struct ofpbuf
*b
, bool allow_cookie
,
419 const struct mf_field
**field
,
420 union mf_value
*value
, union mf_value
*mask
)
425 error
= nx_pull_entry__(b
, allow_cookie
, &header
, field
, value
, mask
);
429 if (field
&& *field
) {
430 if (!mf_is_mask_valid(*field
, mask
)) {
431 VLOG_DBG_RL(&rl
, "bad mask for field %s", (*field
)->name
);
432 return OFPERR_OFPBMC_BAD_MASK
;
434 if (!mf_is_value_valid(*field
, value
)) {
435 VLOG_DBG_RL(&rl
, "bad value for field %s", (*field
)->name
);
436 return OFPERR_OFPBMC_BAD_VALUE
;
443 nx_pull_raw(const uint8_t *p
, unsigned int match_len
, bool strict
,
444 struct match
*match
, ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
448 ovs_assert((cookie
!= NULL
) == (cookie_mask
!= NULL
));
450 match_init_catchall(match
);
452 *cookie
= *cookie_mask
= htonll(0);
455 ofpbuf_use_const(&b
, p
, match_len
);
456 while (ofpbuf_size(&b
)) {
457 const uint8_t *pos
= ofpbuf_data(&b
);
458 const struct mf_field
*field
;
459 union mf_value value
;
463 error
= nx_pull_match_entry(&b
, cookie
!= NULL
, &field
, &value
, &mask
);
465 if (error
== OFPERR_OFPBMC_BAD_FIELD
&& !strict
) {
470 error
= OFPERR_OFPBMC_BAD_FIELD
;
471 } else if (*cookie_mask
) {
472 error
= OFPERR_OFPBMC_DUP_FIELD
;
474 *cookie
= value
.be64
;
475 *cookie_mask
= mask
.be64
;
477 } else if (!mf_are_prereqs_ok(field
, &match
->flow
)) {
478 error
= OFPERR_OFPBMC_BAD_PREREQ
;
479 } else if (!mf_is_all_wild(field
, &match
->wc
)) {
480 error
= OFPERR_OFPBMC_DUP_FIELD
;
482 mf_set(field
, &value
, &mask
, match
);
486 VLOG_DBG_RL(&rl
, "error parsing OXM at offset %"PRIdPTR
" "
487 "within match (%s)", pos
-
488 p
, ofperr_to_string(error
));
497 nx_pull_match__(struct ofpbuf
*b
, unsigned int match_len
, bool strict
,
499 ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
504 p
= ofpbuf_try_pull(b
, ROUND_UP(match_len
, 8));
506 VLOG_DBG_RL(&rl
, "nx_match length %u, rounded up to a "
507 "multiple of 8, is longer than space in message (max "
508 "length %"PRIu32
")", match_len
, ofpbuf_size(b
));
509 return OFPERR_OFPBMC_BAD_LEN
;
513 return nx_pull_raw(p
, match_len
, strict
, match
, cookie
, cookie_mask
);
516 /* Parses the nx_match formatted match description in 'b' with length
517 * 'match_len'. Stores the results in 'match'. If 'cookie' and 'cookie_mask'
518 * are valid pointers, then stores the cookie and mask in them if 'b' contains
519 * a "NXM_NX_COOKIE*" match. Otherwise, stores 0 in both.
521 * Fails with an error upon encountering an unknown NXM header.
523 * Returns 0 if successful, otherwise an OpenFlow error code. */
525 nx_pull_match(struct ofpbuf
*b
, unsigned int match_len
, struct match
*match
,
526 ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
528 return nx_pull_match__(b
, match_len
, true, match
, cookie
, cookie_mask
);
531 /* Behaves the same as nx_pull_match(), but skips over unknown NXM headers,
532 * instead of failing with an error. */
534 nx_pull_match_loose(struct ofpbuf
*b
, unsigned int match_len
,
536 ovs_be64
*cookie
, ovs_be64
*cookie_mask
)
538 return nx_pull_match__(b
, match_len
, false, match
, cookie
, cookie_mask
);
542 oxm_pull_match__(struct ofpbuf
*b
, bool strict
, struct match
*match
)
544 struct ofp11_match_header
*omh
= ofpbuf_data(b
);
548 if (ofpbuf_size(b
) < sizeof *omh
) {
549 return OFPERR_OFPBMC_BAD_LEN
;
552 match_len
= ntohs(omh
->length
);
553 if (match_len
< sizeof *omh
) {
554 return OFPERR_OFPBMC_BAD_LEN
;
557 if (omh
->type
!= htons(OFPMT_OXM
)) {
558 return OFPERR_OFPBMC_BAD_TYPE
;
561 p
= ofpbuf_try_pull(b
, ROUND_UP(match_len
, 8));
563 VLOG_DBG_RL(&rl
, "oxm length %u, rounded up to a "
564 "multiple of 8, is longer than space in message (max "
565 "length %"PRIu32
")", match_len
, ofpbuf_size(b
));
566 return OFPERR_OFPBMC_BAD_LEN
;
569 return nx_pull_raw(p
+ sizeof *omh
, match_len
- sizeof *omh
,
570 strict
, match
, NULL
, NULL
);
573 /* Parses the oxm formatted match description preceded by a struct
574 * ofp11_match_header in 'b'. Stores the result in 'match'.
576 * Fails with an error when encountering unknown OXM headers.
578 * Returns 0 if successful, otherwise an OpenFlow error code. */
580 oxm_pull_match(struct ofpbuf
*b
, struct match
*match
)
582 return oxm_pull_match__(b
, true, match
);
585 /* Behaves the same as oxm_pull_match() with one exception. Skips over unknown
586 * OXM headers instead of failing with an error when they are encountered. */
588 oxm_pull_match_loose(struct ofpbuf
*b
, struct match
*match
)
590 return oxm_pull_match__(b
, false, match
);
593 /* nx_put_match() and helpers.
595 * 'put' functions whose names end in 'w' add a wildcarded field.
596 * 'put' functions whose names end in 'm' add a field that might be wildcarded.
597 * Other 'put' functions add exact-match fields.
601 nxm_put_unmasked(struct ofpbuf
*b
, enum mf_field_id field
,
602 enum ofp_version version
, const void *value
, size_t n_bytes
)
604 nx_put_header(b
, field
, version
, false);
605 ofpbuf_put(b
, value
, n_bytes
);
609 nxm_put(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
610 const void *value
, const void *mask
, size_t n_bytes
)
612 if (!is_all_zeros(mask
, n_bytes
)) {
613 bool masked
= !is_all_ones(mask
, n_bytes
);
614 nx_put_header(b
, field
, version
, masked
);
615 ofpbuf_put(b
, value
, n_bytes
);
617 ofpbuf_put(b
, mask
, n_bytes
);
623 nxm_put_8m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
624 uint8_t value
, uint8_t mask
)
626 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
630 nxm_put_8(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
633 nxm_put_unmasked(b
, field
, version
, &value
, sizeof value
);
637 nxm_put_16m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
638 ovs_be16 value
, ovs_be16 mask
)
640 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
644 nxm_put_16(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
647 nxm_put_unmasked(b
, field
, version
, &value
, sizeof value
);
651 nxm_put_32m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
652 ovs_be32 value
, ovs_be32 mask
)
654 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
658 nxm_put_32(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
661 nxm_put_unmasked(b
, field
, version
, &value
, sizeof value
);
665 nxm_put_64m(struct ofpbuf
*b
, enum mf_field_id field
, enum ofp_version version
,
666 ovs_be64 value
, ovs_be64 mask
)
668 nxm_put(b
, field
, version
, &value
, &mask
, sizeof value
);
672 nxm_put_eth_masked(struct ofpbuf
*b
,
673 enum mf_field_id field
, enum ofp_version version
,
674 const uint8_t value
[ETH_ADDR_LEN
],
675 const uint8_t mask
[ETH_ADDR_LEN
])
677 nxm_put(b
, field
, version
, value
, mask
, ETH_ADDR_LEN
);
681 nxm_put_ipv6(struct ofpbuf
*b
,
682 enum mf_field_id field
, enum ofp_version version
,
683 const struct in6_addr
*value
, const struct in6_addr
*mask
)
685 nxm_put(b
, field
, version
, value
->s6_addr
, mask
->s6_addr
,
686 sizeof value
->s6_addr
);
690 nxm_put_frag(struct ofpbuf
*b
, const struct match
*match
,
691 enum ofp_version version
)
693 uint8_t nw_frag
= match
->flow
.nw_frag
& FLOW_NW_FRAG_MASK
;
694 uint8_t nw_frag_mask
= match
->wc
.masks
.nw_frag
& FLOW_NW_FRAG_MASK
;
696 nxm_put_8m(b
, MFF_IP_FRAG
, version
, nw_frag
,
697 nw_frag_mask
== FLOW_NW_FRAG_MASK
? UINT8_MAX
: nw_frag_mask
);
700 /* Appends to 'b' a set of OXM or NXM matches for the IPv4 or IPv6 fields in
703 nxm_put_ip(struct ofpbuf
*b
, const struct match
*match
, enum ofp_version oxm
)
705 const struct flow
*flow
= &match
->flow
;
707 if (flow
->dl_type
== htons(ETH_TYPE_IP
)) {
708 nxm_put_32m(b
, MFF_IPV4_SRC
, oxm
,
709 flow
->nw_src
, match
->wc
.masks
.nw_src
);
710 nxm_put_32m(b
, MFF_IPV4_DST
, oxm
,
711 flow
->nw_dst
, match
->wc
.masks
.nw_dst
);
713 nxm_put_ipv6(b
, MFF_IPV6_SRC
, oxm
,
714 &flow
->ipv6_src
, &match
->wc
.masks
.ipv6_src
);
715 nxm_put_ipv6(b
, MFF_IPV6_DST
, oxm
,
716 &flow
->ipv6_dst
, &match
->wc
.masks
.ipv6_dst
);
719 nxm_put_frag(b
, match
, oxm
);
721 if (match
->wc
.masks
.nw_tos
& IP_DSCP_MASK
) {
723 nxm_put_8(b
, MFF_IP_DSCP_SHIFTED
, oxm
,
726 nxm_put_8(b
, MFF_IP_DSCP
, oxm
,
727 flow
->nw_tos
& IP_DSCP_MASK
);
731 if (match
->wc
.masks
.nw_tos
& IP_ECN_MASK
) {
732 nxm_put_8(b
, MFF_IP_ECN
, oxm
,
733 flow
->nw_tos
& IP_ECN_MASK
);
736 if (!oxm
&& match
->wc
.masks
.nw_ttl
) {
737 nxm_put_8(b
, MFF_IP_TTL
, oxm
, flow
->nw_ttl
);
740 nxm_put_32m(b
, MFF_IPV6_LABEL
, oxm
,
741 flow
->ipv6_label
, match
->wc
.masks
.ipv6_label
);
743 if (match
->wc
.masks
.nw_proto
) {
744 nxm_put_8(b
, MFF_IP_PROTO
, oxm
, flow
->nw_proto
);
746 if (flow
->nw_proto
== IPPROTO_TCP
) {
747 nxm_put_16m(b
, MFF_TCP_SRC
, oxm
,
748 flow
->tp_src
, match
->wc
.masks
.tp_src
);
749 nxm_put_16m(b
, MFF_TCP_DST
, oxm
,
750 flow
->tp_dst
, match
->wc
.masks
.tp_dst
);
751 nxm_put_16m(b
, MFF_TCP_FLAGS
, oxm
,
752 flow
->tcp_flags
, match
->wc
.masks
.tcp_flags
);
753 } else if (flow
->nw_proto
== IPPROTO_UDP
) {
754 nxm_put_16m(b
, MFF_UDP_SRC
, oxm
,
755 flow
->tp_src
, match
->wc
.masks
.tp_src
);
756 nxm_put_16m(b
, MFF_UDP_DST
, oxm
,
757 flow
->tp_dst
, match
->wc
.masks
.tp_dst
);
758 } else if (flow
->nw_proto
== IPPROTO_SCTP
) {
759 nxm_put_16m(b
, MFF_SCTP_SRC
, oxm
, flow
->tp_src
,
760 match
->wc
.masks
.tp_src
);
761 nxm_put_16m(b
, MFF_SCTP_DST
, oxm
, flow
->tp_dst
,
762 match
->wc
.masks
.tp_dst
);
763 } else if (is_icmpv4(flow
)) {
764 if (match
->wc
.masks
.tp_src
) {
765 nxm_put_8(b
, MFF_ICMPV4_TYPE
, oxm
,
766 ntohs(flow
->tp_src
));
768 if (match
->wc
.masks
.tp_dst
) {
769 nxm_put_8(b
, MFF_ICMPV4_CODE
, oxm
,
770 ntohs(flow
->tp_dst
));
772 } else if (is_icmpv6(flow
)) {
773 if (match
->wc
.masks
.tp_src
) {
774 nxm_put_8(b
, MFF_ICMPV6_TYPE
, oxm
,
775 ntohs(flow
->tp_src
));
777 if (match
->wc
.masks
.tp_dst
) {
778 nxm_put_8(b
, MFF_ICMPV6_CODE
, oxm
,
779 ntohs(flow
->tp_dst
));
781 if (flow
->tp_src
== htons(ND_NEIGHBOR_SOLICIT
) ||
782 flow
->tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
783 nxm_put_ipv6(b
, MFF_ND_TARGET
, oxm
,
784 &flow
->nd_target
, &match
->wc
.masks
.nd_target
);
785 if (flow
->tp_src
== htons(ND_NEIGHBOR_SOLICIT
)) {
786 nxm_put_eth_masked(b
, MFF_ND_SLL
, oxm
,
787 flow
->arp_sha
, match
->wc
.masks
.arp_sha
);
789 if (flow
->tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
790 nxm_put_eth_masked(b
, MFF_ND_TLL
, oxm
,
791 flow
->arp_tha
, match
->wc
.masks
.arp_tha
);
798 /* Appends to 'b' the nx_match format that expresses 'match'. For Flow Mod and
799 * Flow Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
800 * Otherwise, 'cookie_mask' should be zero.
802 * Specify 'oxm' as 0 to express the match in NXM format; otherwise, specify
803 * 'oxm' as the OpenFlow version number for the OXM format to use.
805 * This function can cause 'b''s data to be reallocated.
807 * Returns the number of bytes appended to 'b', excluding padding.
809 * If 'match' is a catch-all rule that matches every packet, then this function
810 * appends nothing to 'b' and returns 0. */
812 nx_put_raw(struct ofpbuf
*b
, enum ofp_version oxm
, const struct match
*match
,
813 ovs_be64 cookie
, ovs_be64 cookie_mask
)
815 const struct flow
*flow
= &match
->flow
;
816 const size_t start_len
= ofpbuf_size(b
);
820 BUILD_ASSERT_DECL(FLOW_WC_SEQ
== 28);
823 if (match
->wc
.masks
.dp_hash
) {
824 nxm_put_32m(b
, MFF_DP_HASH
, oxm
,
825 htonl(flow
->dp_hash
), htonl(match
->wc
.masks
.dp_hash
));
828 if (match
->wc
.masks
.recirc_id
) {
829 nxm_put_32(b
, MFF_RECIRC_ID
, oxm
, htonl(flow
->recirc_id
));
832 if (match
->wc
.masks
.in_port
.ofp_port
) {
833 ofp_port_t in_port
= flow
->in_port
.ofp_port
;
835 nxm_put_32(b
, MFF_IN_PORT_OXM
, oxm
,
836 ofputil_port_to_ofp11(in_port
));
838 nxm_put_16(b
, MFF_IN_PORT
, oxm
,
839 htons(ofp_to_u16(in_port
)));
842 if (match
->wc
.masks
.actset_output
) {
843 nxm_put_32(b
, MFF_ACTSET_OUTPUT
, oxm
,
844 ofputil_port_to_ofp11(flow
->actset_output
));
848 nxm_put_eth_masked(b
, MFF_ETH_SRC
, oxm
,
849 flow
->dl_src
, match
->wc
.masks
.dl_src
);
850 nxm_put_eth_masked(b
, MFF_ETH_DST
, oxm
,
851 flow
->dl_dst
, match
->wc
.masks
.dl_dst
);
852 nxm_put_16m(b
, MFF_ETH_TYPE
, oxm
,
853 ofputil_dl_type_to_openflow(flow
->dl_type
),
854 match
->wc
.masks
.dl_type
);
858 ovs_be16 VID_CFI_MASK
= htons(VLAN_VID_MASK
| VLAN_CFI
);
859 ovs_be16 vid
= flow
->vlan_tci
& VID_CFI_MASK
;
860 ovs_be16 mask
= match
->wc
.masks
.vlan_tci
& VID_CFI_MASK
;
862 if (mask
== htons(VLAN_VID_MASK
| VLAN_CFI
)) {
863 nxm_put_16(b
, MFF_VLAN_VID
, oxm
, vid
);
865 nxm_put_16m(b
, MFF_VLAN_VID
, oxm
, vid
, mask
);
868 if (vid
&& vlan_tci_to_pcp(match
->wc
.masks
.vlan_tci
)) {
869 nxm_put_8(b
, MFF_VLAN_PCP
, oxm
,
870 vlan_tci_to_pcp(flow
->vlan_tci
));
874 nxm_put_16m(b
, MFF_VLAN_TCI
, oxm
, flow
->vlan_tci
,
875 match
->wc
.masks
.vlan_tci
);
879 if (eth_type_mpls(flow
->dl_type
)) {
880 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_TC_MASK
)) {
881 nxm_put_8(b
, MFF_MPLS_TC
, oxm
,
882 mpls_lse_to_tc(flow
->mpls_lse
[0]));
885 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_BOS_MASK
)) {
886 nxm_put_8(b
, MFF_MPLS_BOS
, oxm
,
887 mpls_lse_to_bos(flow
->mpls_lse
[0]));
890 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_LABEL_MASK
)) {
891 nxm_put_32(b
, MFF_MPLS_LABEL
, oxm
,
892 htonl(mpls_lse_to_label(flow
->mpls_lse
[0])));
897 if (is_ip_any(flow
)) {
898 nxm_put_ip(b
, match
, oxm
);
899 } else if (flow
->dl_type
== htons(ETH_TYPE_ARP
) ||
900 flow
->dl_type
== htons(ETH_TYPE_RARP
)) {
902 if (match
->wc
.masks
.nw_proto
) {
903 nxm_put_16(b
, MFF_ARP_OP
, oxm
,
904 htons(flow
->nw_proto
));
906 nxm_put_32m(b
, MFF_ARP_SPA
, oxm
,
907 flow
->nw_src
, match
->wc
.masks
.nw_src
);
908 nxm_put_32m(b
, MFF_ARP_TPA
, oxm
,
909 flow
->nw_dst
, match
->wc
.masks
.nw_dst
);
910 nxm_put_eth_masked(b
, MFF_ARP_SHA
, oxm
,
911 flow
->arp_sha
, match
->wc
.masks
.arp_sha
);
912 nxm_put_eth_masked(b
, MFF_ARP_THA
, oxm
,
913 flow
->arp_tha
, match
->wc
.masks
.arp_tha
);
917 nxm_put_64m(b
, MFF_TUN_ID
, oxm
,
918 flow
->tunnel
.tun_id
, match
->wc
.masks
.tunnel
.tun_id
);
920 /* Other tunnel metadata. */
921 nxm_put_32m(b
, MFF_TUN_SRC
, oxm
,
922 flow
->tunnel
.ip_src
, match
->wc
.masks
.tunnel
.ip_src
);
923 nxm_put_32m(b
, MFF_TUN_DST
, oxm
,
924 flow
->tunnel
.ip_dst
, match
->wc
.masks
.tunnel
.ip_dst
);
927 if (oxm
< OFP15_VERSION
) {
928 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
929 nxm_put_32m(b
, MFF_REG0
+ i
, oxm
,
930 htonl(flow
->regs
[i
]), htonl(match
->wc
.masks
.regs
[i
]));
933 for (i
= 0; i
< FLOW_N_XREGS
; i
++) {
934 nxm_put_64m(b
, MFF_XREG0
+ i
, oxm
,
935 htonll(flow_get_xreg(flow
, i
)),
936 htonll(flow_get_xreg(&match
->wc
.masks
, i
)));
941 nxm_put_32m(b
, MFF_PKT_MARK
, oxm
, htonl(flow
->pkt_mark
),
942 htonl(match
->wc
.masks
.pkt_mark
));
944 /* OpenFlow 1.1+ Metadata. */
945 nxm_put_64m(b
, MFF_METADATA
, oxm
,
946 flow
->metadata
, match
->wc
.masks
.metadata
);
950 bool masked
= cookie_mask
!= OVS_BE64_MAX
;
952 cookie
&= cookie_mask
;
953 nx_put_header__(b
, NXM_NX_COOKIE
, masked
);
954 ofpbuf_put(b
, &cookie
, sizeof cookie
);
956 ofpbuf_put(b
, &cookie_mask
, sizeof cookie_mask
);
960 match_len
= ofpbuf_size(b
) - start_len
;
964 /* Appends to 'b' the nx_match format that expresses 'match', plus enough zero
965 * bytes to pad the nx_match out to a multiple of 8. For Flow Mod and Flow
966 * Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
967 * Otherwise, 'cookie_mask' should be zero.
969 * This function can cause 'b''s data to be reallocated.
971 * Returns the number of bytes appended to 'b', excluding padding. The return
972 * value can be zero if it appended nothing at all to 'b' (which happens if
973 * 'cr' is a catch-all rule that matches every packet). */
975 nx_put_match(struct ofpbuf
*b
, const struct match
*match
,
976 ovs_be64 cookie
, ovs_be64 cookie_mask
)
978 int match_len
= nx_put_raw(b
, 0, match
, cookie
, cookie_mask
);
980 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
984 /* Appends to 'b' an struct ofp11_match_header followed by the OXM format that
985 * expresses 'cr', plus enough zero bytes to pad the data appended out to a
988 * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow
989 * version in use as 'version'.
991 * This function can cause 'b''s data to be reallocated.
993 * Returns the number of bytes appended to 'b', excluding the padding. Never
996 oxm_put_match(struct ofpbuf
*b
, const struct match
*match
,
997 enum ofp_version version
)
1000 struct ofp11_match_header
*omh
;
1001 size_t start_len
= ofpbuf_size(b
);
1002 ovs_be64 cookie
= htonll(0), cookie_mask
= htonll(0);
1004 ofpbuf_put_uninit(b
, sizeof *omh
);
1005 match_len
= (nx_put_raw(b
, version
, match
, cookie
, cookie_mask
)
1007 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1009 omh
= ofpbuf_at(b
, start_len
, sizeof *omh
);
1010 omh
->type
= htons(OFPMT_OXM
);
1011 omh
->length
= htons(match_len
);
1017 nx_put_header__(struct ofpbuf
*b
, uint64_t header
, bool masked
)
1019 uint64_t masked_header
= masked
? nxm_make_wild_header(header
) : header
;
1020 ovs_be64 network_header
= htonll(masked_header
);
1022 ofpbuf_put(b
, &network_header
, nxm_header_len(header
));
1026 nx_put_header(struct ofpbuf
*b
, enum mf_field_id field
,
1027 enum ofp_version version
, bool masked
)
1029 nx_put_header__(b
, mf_oxm_header(field
, version
), masked
);
1033 nx_put_entry(struct ofpbuf
*b
,
1034 enum mf_field_id field
, enum ofp_version version
,
1035 const union mf_value
*value
, const union mf_value
*mask
)
1037 int n_bytes
= mf_from_id(field
)->n_bytes
;
1038 bool masked
= mask
&& !is_all_ones(mask
, n_bytes
);
1040 nx_put_header(b
, field
, version
, masked
);
1041 ofpbuf_put(b
, value
, n_bytes
);
1043 ofpbuf_put(b
, mask
, n_bytes
);
1047 /* nx_match_to_string() and helpers. */
1049 static void format_nxm_field_name(struct ds
*, uint64_t header
);
1052 nx_match_to_string(const uint8_t *p
, unsigned int match_len
)
1058 return xstrdup("<any>");
1061 ofpbuf_use_const(&b
, p
, match_len
);
1063 while (ofpbuf_size(&b
)) {
1064 union mf_value value
;
1065 union mf_value mask
;
1070 error
= nx_pull_entry__(&b
, true, &header
, NULL
, &value
, &mask
);
1074 value_len
= MIN(sizeof value
, nxm_field_bytes(header
));
1077 ds_put_cstr(&s
, ", ");
1080 format_nxm_field_name(&s
, header
);
1081 ds_put_char(&s
, '(');
1083 for (int i
= 0; i
< value_len
; i
++) {
1084 ds_put_format(&s
, "%02x", ((const uint8_t *) &value
)[i
]);
1086 if (nxm_hasmask(header
)) {
1087 ds_put_char(&s
, '/');
1088 for (int i
= 0; i
< value_len
; i
++) {
1089 ds_put_format(&s
, "%02x", ((const uint8_t *) &mask
)[i
]);
1092 ds_put_char(&s
, ')');
1095 if (ofpbuf_size(&b
)) {
1097 ds_put_cstr(&s
, ", ");
1100 ds_put_format(&s
, "<%u invalid bytes>", ofpbuf_size(&b
));
1103 return ds_steal_cstr(&s
);
1107 oxm_match_to_string(const struct ofpbuf
*p
, unsigned int match_len
)
1109 const struct ofp11_match_header
*omh
= ofpbuf_data(p
);
1110 uint16_t match_len_
;
1115 if (match_len
< sizeof *omh
) {
1116 ds_put_format(&s
, "<match too short: %u>", match_len
);
1120 if (omh
->type
!= htons(OFPMT_OXM
)) {
1121 ds_put_format(&s
, "<bad match type field: %u>", ntohs(omh
->type
));
1125 match_len_
= ntohs(omh
->length
);
1126 if (match_len_
< sizeof *omh
) {
1127 ds_put_format(&s
, "<match length field too short: %u>", match_len_
);
1131 if (match_len_
!= match_len
) {
1132 ds_put_format(&s
, "<match length field incorrect: %u != %u>",
1133 match_len_
, match_len
);
1137 return nx_match_to_string(ofpbuf_at(p
, sizeof *omh
, 0),
1138 match_len
- sizeof *omh
);
1141 return ds_steal_cstr(&s
);
1145 nx_format_field_name(enum mf_field_id id
, enum ofp_version version
,
1148 format_nxm_field_name(s
, mf_oxm_header(id
, version
));
1152 format_nxm_field_name(struct ds
*s
, uint64_t header
)
1154 const struct nxm_field
*f
= nxm_field_by_header(header
);
1156 ds_put_cstr(s
, f
->name
);
1157 if (nxm_hasmask(header
)) {
1158 ds_put_cstr(s
, "_W");
1160 } else if (header
== NXM_NX_COOKIE
) {
1161 ds_put_cstr(s
, "NXM_NX_COOKIE");
1162 } else if (header
== NXM_NX_COOKIE_W
) {
1163 ds_put_cstr(s
, "NXM_NX_COOKIE_W");
1165 ds_put_format(s
, "%d:%d", nxm_class(header
), nxm_field(header
));
1170 streq_len(const char *a
, size_t a_len
, const char *b
)
1172 return strlen(b
) == a_len
&& !memcmp(a
, b
, a_len
);
1176 parse_nxm_field_name(const char *name
, int name_len
)
1178 const struct nxm_field
*f
;
1181 f
= mf_parse_subfield_name(name
, name_len
, &wild
);
1185 } else if (mf_from_id(f
->id
)->maskable
!= MFM_NONE
) {
1186 return nxm_make_wild_header(f
->header
);
1190 if (streq_len(name
, name_len
, "NXM_NX_COOKIE")) {
1191 return NXM_NX_COOKIE
;
1192 } else if (streq_len(name
, name_len
, "NXM_NX_COOKIE_W")) {
1193 return NXM_NX_COOKIE_W
;
1196 /* Check whether it's a field header value as hex.
1197 * (This isn't ordinarily useful except for testing error behavior.) */
1198 if (name_len
== 8) {
1202 header
= hexits_value(name
, name_len
, &ok
) << 32;
1206 } else if (name_len
== 16) {
1210 header
= hexits_value(name
, name_len
, &ok
);
1211 if (ok
&& is_experimenter_oxm(header
)) {
1219 /* nx_match_from_string(). */
1222 nx_match_from_string_raw(const char *s
, struct ofpbuf
*b
)
1224 const char *full_s
= s
;
1225 const size_t start_len
= ofpbuf_size(b
);
1227 if (!strcmp(s
, "<any>")) {
1228 /* Ensure that 'ofpbuf_data(b)' isn't actually null. */
1229 ofpbuf_prealloc_tailroom(b
, 1);
1233 for (s
+= strspn(s
, ", "); *s
; s
+= strspn(s
, ", ")) {
1240 name_len
= strcspn(s
, "(");
1241 if (s
[name_len
] != '(') {
1242 ovs_fatal(0, "%s: missing ( at end of nx_match", full_s
);
1245 header
= parse_nxm_field_name(name
, name_len
);
1247 ovs_fatal(0, "%s: unknown field `%.*s'", full_s
, name_len
, s
);
1252 nx_put_header__(b
, header
, false);
1253 s
= ofpbuf_put_hex(b
, s
, &n
);
1254 if (n
!= nxm_field_bytes(header
)) {
1255 ovs_fatal(0, "%.2s: hex digits expected", s
);
1257 if (nxm_hasmask(header
)) {
1258 s
+= strspn(s
, " ");
1260 ovs_fatal(0, "%s: missing / in masked field %.*s",
1261 full_s
, name_len
, name
);
1263 s
= ofpbuf_put_hex(b
, s
+ 1, &n
);
1264 if (n
!= nxm_field_bytes(header
)) {
1265 ovs_fatal(0, "%.2s: hex digits expected", s
);
1269 s
+= strspn(s
, " ");
1271 ovs_fatal(0, "%s: missing ) following field %.*s",
1272 full_s
, name_len
, name
);
1277 return ofpbuf_size(b
) - start_len
;
1281 nx_match_from_string(const char *s
, struct ofpbuf
*b
)
1283 int match_len
= nx_match_from_string_raw(s
, b
);
1284 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1289 oxm_match_from_string(const char *s
, struct ofpbuf
*b
)
1292 struct ofp11_match_header
*omh
;
1293 size_t start_len
= ofpbuf_size(b
);
1295 ofpbuf_put_uninit(b
, sizeof *omh
);
1296 match_len
= nx_match_from_string_raw(s
, b
) + sizeof *omh
;
1297 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1299 omh
= ofpbuf_at(b
, start_len
, sizeof *omh
);
1300 omh
->type
= htons(OFPMT_OXM
);
1301 omh
->length
= htons(match_len
);
1306 /* Parses 's' as a "move" action, in the form described in ovs-ofctl(8), into
1309 * Returns NULL if successful, otherwise a malloc()'d string describing the
1310 * error. The caller is responsible for freeing the returned string. */
1311 char * WARN_UNUSED_RESULT
1312 nxm_parse_reg_move(struct ofpact_reg_move
*move
, const char *s
)
1314 const char *full_s
= s
;
1317 error
= mf_parse_subfield__(&move
->src
, &s
);
1321 if (strncmp(s
, "->", 2)) {
1322 return xasprintf("%s: missing `->' following source", full_s
);
1325 error
= mf_parse_subfield(&move
->dst
, s
);
1330 if (move
->src
.n_bits
!= move
->dst
.n_bits
) {
1331 return xasprintf("%s: source field is %d bits wide but destination is "
1332 "%d bits wide", full_s
,
1333 move
->src
.n_bits
, move
->dst
.n_bits
);
1338 /* nxm_format_reg_move(). */
1341 nxm_format_reg_move(const struct ofpact_reg_move
*move
, struct ds
*s
)
1343 ds_put_format(s
, "move:");
1344 mf_format_subfield(&move
->src
, s
);
1345 ds_put_cstr(s
, "->");
1346 mf_format_subfield(&move
->dst
, s
);
1351 nxm_reg_move_check(const struct ofpact_reg_move
*move
, const struct flow
*flow
)
1355 error
= mf_check_src(&move
->src
, flow
);
1360 return mf_check_dst(&move
->dst
, flow
);
1363 /* nxm_execute_reg_move(). */
1366 nxm_execute_reg_move(const struct ofpact_reg_move
*move
,
1367 struct flow
*flow
, struct flow_wildcards
*wc
)
1369 union mf_value src_value
;
1370 union mf_value dst_value
;
1372 mf_mask_field_and_prereqs(move
->dst
.field
, &wc
->masks
);
1373 mf_mask_field_and_prereqs(move
->src
.field
, &wc
->masks
);
1375 /* A flow may wildcard nw_frag. Do nothing if setting a transport
1376 * header field on a packet that does not have them. */
1377 if (mf_are_prereqs_ok(move
->dst
.field
, flow
)
1378 && mf_are_prereqs_ok(move
->src
.field
, flow
)) {
1380 mf_get_value(move
->dst
.field
, flow
, &dst_value
);
1381 mf_get_value(move
->src
.field
, flow
, &src_value
);
1382 bitwise_copy(&src_value
, move
->src
.field
->n_bytes
, move
->src
.ofs
,
1383 &dst_value
, move
->dst
.field
->n_bytes
, move
->dst
.ofs
,
1385 mf_set_flow_value(move
->dst
.field
, &dst_value
, flow
);
1390 nxm_reg_load(const struct mf_subfield
*dst
, uint64_t src_data
,
1391 struct flow
*flow
, struct flow_wildcards
*wc
)
1393 union mf_subvalue src_subvalue
;
1394 union mf_subvalue mask_value
;
1395 ovs_be64 src_data_be
= htonll(src_data
);
1397 memset(&mask_value
, 0xff, sizeof mask_value
);
1398 mf_write_subfield_flow(dst
, &mask_value
, &wc
->masks
);
1400 bitwise_copy(&src_data_be
, sizeof src_data_be
, 0,
1401 &src_subvalue
, sizeof src_subvalue
, 0,
1402 sizeof src_data_be
* 8);
1403 mf_write_subfield_flow(dst
, &src_subvalue
, flow
);
1406 /* nxm_parse_stack_action, works for both push() and pop(). */
1408 /* Parses 's' as a "push" or "pop" action, in the form described in
1409 * ovs-ofctl(8), into '*stack_action'.
1411 * Returns NULL if successful, otherwise a malloc()'d string describing the
1412 * error. The caller is responsible for freeing the returned string. */
1413 char * WARN_UNUSED_RESULT
1414 nxm_parse_stack_action(struct ofpact_stack
*stack_action
, const char *s
)
1418 error
= mf_parse_subfield__(&stack_action
->subfield
, &s
);
1424 return xasprintf("%s: trailing garbage following push or pop", s
);
1431 nxm_format_stack_push(const struct ofpact_stack
*push
, struct ds
*s
)
1433 ds_put_cstr(s
, "push:");
1434 mf_format_subfield(&push
->subfield
, s
);
1438 nxm_format_stack_pop(const struct ofpact_stack
*pop
, struct ds
*s
)
1440 ds_put_cstr(s
, "pop:");
1441 mf_format_subfield(&pop
->subfield
, s
);
1445 nxm_stack_push_check(const struct ofpact_stack
*push
,
1446 const struct flow
*flow
)
1448 return mf_check_src(&push
->subfield
, flow
);
1452 nxm_stack_pop_check(const struct ofpact_stack
*pop
,
1453 const struct flow
*flow
)
1455 return mf_check_dst(&pop
->subfield
, flow
);
1458 /* nxm_execute_stack_push(), nxm_execute_stack_pop(). */
1460 nx_stack_push(struct ofpbuf
*stack
, union mf_subvalue
*v
)
1462 ofpbuf_put(stack
, v
, sizeof *v
);
1465 static union mf_subvalue
*
1466 nx_stack_pop(struct ofpbuf
*stack
)
1468 union mf_subvalue
*v
= NULL
;
1470 if (ofpbuf_size(stack
)) {
1472 ofpbuf_set_size(stack
, ofpbuf_size(stack
) - sizeof *v
);
1473 v
= (union mf_subvalue
*) ofpbuf_tail(stack
);
1480 nxm_execute_stack_push(const struct ofpact_stack
*push
,
1481 const struct flow
*flow
, struct flow_wildcards
*wc
,
1482 struct ofpbuf
*stack
)
1484 union mf_subvalue mask_value
;
1485 union mf_subvalue dst_value
;
1487 memset(&mask_value
, 0xff, sizeof mask_value
);
1488 mf_write_subfield_flow(&push
->subfield
, &mask_value
, &wc
->masks
);
1490 mf_read_subfield(&push
->subfield
, flow
, &dst_value
);
1491 nx_stack_push(stack
, &dst_value
);
1495 nxm_execute_stack_pop(const struct ofpact_stack
*pop
,
1496 struct flow
*flow
, struct flow_wildcards
*wc
,
1497 struct ofpbuf
*stack
)
1499 union mf_subvalue
*src_value
;
1501 src_value
= nx_stack_pop(stack
);
1503 /* Only pop if stack is not empty. Otherwise, give warning. */
1505 union mf_subvalue mask_value
;
1507 memset(&mask_value
, 0xff, sizeof mask_value
);
1508 mf_write_subfield_flow(&pop
->subfield
, &mask_value
, &wc
->masks
);
1509 mf_write_subfield_flow(&pop
->subfield
, src_value
, flow
);
1511 if (!VLOG_DROP_WARN(&rl
)) {
1512 char *flow_str
= flow_to_string(flow
);
1513 VLOG_WARN_RL(&rl
, "Failed to pop from an empty stack. On flow \n"
1520 /* Formats 'sf' into 's' in a format normally acceptable to
1521 * mf_parse_subfield(). (It won't be acceptable if sf->field is NULL or if
1522 * sf->field has no NXM name.) */
1524 mf_format_subfield(const struct mf_subfield
*sf
, struct ds
*s
)
1527 ds_put_cstr(s
, "<unknown>");
1529 const struct nxm_field
*f
= nxm_field_by_mf_id(sf
->field
->id
, 0);
1530 ds_put_cstr(s
, f
? f
->name
: sf
->field
->name
);
1533 if (sf
->field
&& sf
->ofs
== 0 && sf
->n_bits
== sf
->field
->n_bits
) {
1534 ds_put_cstr(s
, "[]");
1535 } else if (sf
->n_bits
== 1) {
1536 ds_put_format(s
, "[%d]", sf
->ofs
);
1538 ds_put_format(s
, "[%d..%d]", sf
->ofs
, sf
->ofs
+ sf
->n_bits
- 1);
1542 static const struct nxm_field
*
1543 mf_parse_subfield_name(const char *name
, int name_len
, bool *wild
)
1545 *wild
= name_len
> 2 && !memcmp(&name
[name_len
- 2], "_W", 2);
1550 return nxm_field_by_name(name
, name_len
);
1553 /* Parses a subfield from the beginning of '*sp' into 'sf'. If successful,
1554 * returns NULL and advances '*sp' to the first byte following the parsed
1555 * string. On failure, returns a malloc()'d error message, does not modify
1556 * '*sp', and does not properly initialize 'sf'.
1558 * The syntax parsed from '*sp' takes the form "header[start..end]" where
1559 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1560 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1561 * may both be omitted (the [] are still required) to indicate an entire
1563 char * WARN_UNUSED_RESULT
1564 mf_parse_subfield__(struct mf_subfield
*sf
, const char **sp
)
1566 const struct mf_field
*field
;
1567 const struct nxm_field
*f
;
1576 name_len
= strcspn(s
, "[");
1577 if (s
[name_len
] != '[') {
1578 return xasprintf("%s: missing [ looking for field name", *sp
);
1581 f
= mf_parse_subfield_name(name
, name_len
, &wild
);
1583 return xasprintf("%s: unknown field `%.*s'", *sp
, name_len
, s
);
1585 field
= mf_from_id(f
->id
);
1588 if (ovs_scan(s
, "[%d..%d]", &start
, &end
)) {
1589 /* Nothing to do. */
1590 } else if (ovs_scan(s
, "[%d]", &start
)) {
1592 } else if (!strncmp(s
, "[]", 2)) {
1594 end
= field
->n_bits
- 1;
1596 return xasprintf("%s: syntax error expecting [] or [<bit>] or "
1597 "[<start>..<end>]", *sp
);
1599 s
= strchr(s
, ']') + 1;
1602 return xasprintf("%s: starting bit %d is after ending bit %d",
1604 } else if (start
>= field
->n_bits
) {
1605 return xasprintf("%s: starting bit %d is not valid because field is "
1606 "only %d bits wide", *sp
, start
, field
->n_bits
);
1607 } else if (end
>= field
->n_bits
){
1608 return xasprintf("%s: ending bit %d is not valid because field is "
1609 "only %d bits wide", *sp
, end
, field
->n_bits
);
1614 sf
->n_bits
= end
- start
+ 1;
1620 /* Parses a subfield from the entirety of 's' into 'sf'. Returns NULL if
1621 * successful, otherwise a malloc()'d string describing the error. The caller
1622 * is responsible for freeing the returned string.
1624 * The syntax parsed from 's' takes the form "header[start..end]" where
1625 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1626 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1627 * may both be omitted (the [] are still required) to indicate an entire
1629 char * WARN_UNUSED_RESULT
1630 mf_parse_subfield(struct mf_subfield
*sf
, const char *s
)
1632 char *error
= mf_parse_subfield__(sf
, &s
);
1633 if (!error
&& s
[0]) {
1634 error
= xstrdup("unexpected input following field syntax");
1639 /* Returns an bitmap in which each bit corresponds to the like-numbered field
1640 * in the OFPXMC12_OPENFLOW_BASIC OXM class, in which the bit values are taken
1641 * from the 'fields' bitmap. Only fields defined in OpenFlow 'version' are
1644 * This is useful for encoding OpenFlow 1.2 table stats messages. */
1646 oxm_bitmap_from_mf_bitmap(const struct mf_bitmap
*fields
,
1647 enum ofp_version version
)
1649 uint64_t oxm_bitmap
= 0;
1652 BITMAP_FOR_EACH_1 (i
, MFF_N_IDS
, fields
->bm
) {
1653 uint64_t oxm
= mf_oxm_header(i
, version
);
1654 uint32_t class = nxm_class(oxm
);
1655 int field
= nxm_field(oxm
);
1657 if (class == OFPXMC12_OPENFLOW_BASIC
&& field
< 64) {
1658 oxm_bitmap
|= UINT64_C(1) << field
;
1661 return htonll(oxm_bitmap
);
1664 /* Opposite conversion from oxm_bitmap_from_mf_bitmap().
1666 * This is useful for decoding OpenFlow 1.2 table stats messages. */
1668 oxm_bitmap_to_mf_bitmap(ovs_be64 oxm_bitmap
, enum ofp_version version
)
1670 struct mf_bitmap fields
= MF_BITMAP_INITIALIZER
;
1672 for (enum mf_field_id id
= 0; id
< MFF_N_IDS
; id
++) {
1673 uint64_t oxm
= mf_oxm_header(id
, version
);
1674 if (oxm
&& version
>= nxm_field_by_header(oxm
)->version
) {
1675 uint32_t class = nxm_class(oxm
);
1676 int field
= nxm_field(oxm
);
1678 if (class == OFPXMC12_OPENFLOW_BASIC
1680 && oxm_bitmap
& htonll(UINT64_C(1) << field
)) {
1681 bitmap_set1(fields
.bm
, id
);
1688 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1689 * modified with a "set_field" action. */
1691 oxm_writable_fields(void)
1693 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1696 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1697 if (mf_oxm_header(i
, 0) && mf_from_id(i
)->writable
) {
1698 bitmap_set1(b
.bm
, i
);
1704 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1705 * matched in a flow table. */
1707 oxm_matchable_fields(void)
1709 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1712 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1713 if (mf_oxm_header(i
, 0)) {
1714 bitmap_set1(b
.bm
, i
);
1720 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1721 * matched in a flow table with an arbitrary bitmask. */
1723 oxm_maskable_fields(void)
1725 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1728 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1729 if (mf_oxm_header(i
, 0) && mf_from_id(i
)->maskable
== MFM_FULLY
) {
1730 bitmap_set1(b
.bm
, i
);
1736 struct nxm_field_index
{
1737 struct hmap_node header_node
; /* In nxm_header_map. */
1738 struct hmap_node name_node
; /* In nxm_name_map. */
1739 struct list mf_node
; /* In mf_mf_map[nf.id]. */
1740 const struct nxm_field nf
;
1743 #include "nx-match.inc"
1745 static struct hmap nxm_header_map
;
1746 static struct hmap nxm_name_map
;
1747 static struct list nxm_mf_map
[MFF_N_IDS
];
1752 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
1753 if (ovsthread_once_start(&once
)) {
1754 hmap_init(&nxm_header_map
);
1755 hmap_init(&nxm_name_map
);
1756 for (int i
= 0; i
< MFF_N_IDS
; i
++) {
1757 list_init(&nxm_mf_map
[i
]);
1759 for (struct nxm_field_index
*nfi
= all_nxm_fields
;
1760 nfi
< &all_nxm_fields
[ARRAY_SIZE(all_nxm_fields
)]; nfi
++) {
1761 hmap_insert(&nxm_header_map
, &nfi
->header_node
,
1762 hash_int(nfi
->nf
.header
, 0));
1763 hmap_insert(&nxm_name_map
, &nfi
->name_node
,
1764 hash_string(nfi
->nf
.name
, 0));
1765 list_push_back(&nxm_mf_map
[nfi
->nf
.id
], &nfi
->mf_node
);
1767 ovsthread_once_done(&once
);
1771 static const struct nxm_field
*
1772 nxm_field_by_header(uint64_t header
)
1774 const struct nxm_field_index
*nfi
;
1777 if (nxm_hasmask(header
)) {
1778 header
= nxm_make_exact_header(header
);
1781 HMAP_FOR_EACH_IN_BUCKET (nfi
, header_node
, hash_int(header
, 0),
1783 if (header
== nfi
->nf
.header
) {
1790 static const struct nxm_field
*
1791 nxm_field_by_name(const char *name
, size_t len
)
1793 const struct nxm_field_index
*nfi
;
1796 HMAP_FOR_EACH_WITH_HASH (nfi
, name_node
, hash_bytes(name
, len
, 0),
1798 if (strlen(nfi
->nf
.name
) == len
&& !memcmp(nfi
->nf
.name
, name
, len
)) {
1805 static const struct nxm_field
*
1806 nxm_field_by_mf_id(enum mf_field_id id
, enum ofp_version version
)
1808 const struct nxm_field_index
*nfi
;
1809 const struct nxm_field
*f
;
1814 LIST_FOR_EACH (nfi
, mf_node
, &nxm_mf_map
[id
]) {
1815 if (!f
|| version
>= nfi
->nf
.version
) {