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; }
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
== 30);
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
.conj_id
) {
833 nxm_put_32(b
, MFF_CONJ_ID
, oxm
, htonl(flow
->conj_id
));
836 if (match
->wc
.masks
.in_port
.ofp_port
) {
837 ofp_port_t in_port
= flow
->in_port
.ofp_port
;
839 nxm_put_32(b
, MFF_IN_PORT_OXM
, oxm
,
840 ofputil_port_to_ofp11(in_port
));
842 nxm_put_16(b
, MFF_IN_PORT
, oxm
,
843 htons(ofp_to_u16(in_port
)));
846 if (match
->wc
.masks
.actset_output
) {
847 nxm_put_32(b
, MFF_ACTSET_OUTPUT
, oxm
,
848 ofputil_port_to_ofp11(flow
->actset_output
));
852 nxm_put_eth_masked(b
, MFF_ETH_SRC
, oxm
,
853 flow
->dl_src
, match
->wc
.masks
.dl_src
);
854 nxm_put_eth_masked(b
, MFF_ETH_DST
, oxm
,
855 flow
->dl_dst
, match
->wc
.masks
.dl_dst
);
856 nxm_put_16m(b
, MFF_ETH_TYPE
, oxm
,
857 ofputil_dl_type_to_openflow(flow
->dl_type
),
858 match
->wc
.masks
.dl_type
);
862 ovs_be16 VID_CFI_MASK
= htons(VLAN_VID_MASK
| VLAN_CFI
);
863 ovs_be16 vid
= flow
->vlan_tci
& VID_CFI_MASK
;
864 ovs_be16 mask
= match
->wc
.masks
.vlan_tci
& VID_CFI_MASK
;
866 if (mask
== htons(VLAN_VID_MASK
| VLAN_CFI
)) {
867 nxm_put_16(b
, MFF_VLAN_VID
, oxm
, vid
);
869 nxm_put_16m(b
, MFF_VLAN_VID
, oxm
, vid
, mask
);
872 if (vid
&& vlan_tci_to_pcp(match
->wc
.masks
.vlan_tci
)) {
873 nxm_put_8(b
, MFF_VLAN_PCP
, oxm
,
874 vlan_tci_to_pcp(flow
->vlan_tci
));
878 nxm_put_16m(b
, MFF_VLAN_TCI
, oxm
, flow
->vlan_tci
,
879 match
->wc
.masks
.vlan_tci
);
883 if (eth_type_mpls(flow
->dl_type
)) {
884 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_TC_MASK
)) {
885 nxm_put_8(b
, MFF_MPLS_TC
, oxm
,
886 mpls_lse_to_tc(flow
->mpls_lse
[0]));
889 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_BOS_MASK
)) {
890 nxm_put_8(b
, MFF_MPLS_BOS
, oxm
,
891 mpls_lse_to_bos(flow
->mpls_lse
[0]));
894 if (match
->wc
.masks
.mpls_lse
[0] & htonl(MPLS_LABEL_MASK
)) {
895 nxm_put_32(b
, MFF_MPLS_LABEL
, oxm
,
896 htonl(mpls_lse_to_label(flow
->mpls_lse
[0])));
901 if (is_ip_any(flow
)) {
902 nxm_put_ip(b
, match
, oxm
);
903 } else if (flow
->dl_type
== htons(ETH_TYPE_ARP
) ||
904 flow
->dl_type
== htons(ETH_TYPE_RARP
)) {
906 if (match
->wc
.masks
.nw_proto
) {
907 nxm_put_16(b
, MFF_ARP_OP
, oxm
,
908 htons(flow
->nw_proto
));
910 nxm_put_32m(b
, MFF_ARP_SPA
, oxm
,
911 flow
->nw_src
, match
->wc
.masks
.nw_src
);
912 nxm_put_32m(b
, MFF_ARP_TPA
, oxm
,
913 flow
->nw_dst
, match
->wc
.masks
.nw_dst
);
914 nxm_put_eth_masked(b
, MFF_ARP_SHA
, oxm
,
915 flow
->arp_sha
, match
->wc
.masks
.arp_sha
);
916 nxm_put_eth_masked(b
, MFF_ARP_THA
, oxm
,
917 flow
->arp_tha
, match
->wc
.masks
.arp_tha
);
921 nxm_put_64m(b
, MFF_TUN_ID
, oxm
,
922 flow
->tunnel
.tun_id
, match
->wc
.masks
.tunnel
.tun_id
);
924 /* Other tunnel metadata. */
925 nxm_put_32m(b
, MFF_TUN_SRC
, oxm
,
926 flow
->tunnel
.ip_src
, match
->wc
.masks
.tunnel
.ip_src
);
927 nxm_put_32m(b
, MFF_TUN_DST
, oxm
,
928 flow
->tunnel
.ip_dst
, match
->wc
.masks
.tunnel
.ip_dst
);
931 if (oxm
< OFP15_VERSION
) {
932 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
933 nxm_put_32m(b
, MFF_REG0
+ i
, oxm
,
934 htonl(flow
->regs
[i
]), htonl(match
->wc
.masks
.regs
[i
]));
937 for (i
= 0; i
< FLOW_N_XREGS
; i
++) {
938 nxm_put_64m(b
, MFF_XREG0
+ i
, oxm
,
939 htonll(flow_get_xreg(flow
, i
)),
940 htonll(flow_get_xreg(&match
->wc
.masks
, i
)));
945 nxm_put_32m(b
, MFF_PKT_MARK
, oxm
, htonl(flow
->pkt_mark
),
946 htonl(match
->wc
.masks
.pkt_mark
));
948 /* OpenFlow 1.1+ Metadata. */
949 nxm_put_64m(b
, MFF_METADATA
, oxm
,
950 flow
->metadata
, match
->wc
.masks
.metadata
);
954 bool masked
= cookie_mask
!= OVS_BE64_MAX
;
956 cookie
&= cookie_mask
;
957 nx_put_header__(b
, NXM_NX_COOKIE
, masked
);
958 ofpbuf_put(b
, &cookie
, sizeof cookie
);
960 ofpbuf_put(b
, &cookie_mask
, sizeof cookie_mask
);
964 match_len
= ofpbuf_size(b
) - start_len
;
968 /* Appends to 'b' the nx_match format that expresses 'match', plus enough zero
969 * bytes to pad the nx_match out to a multiple of 8. For Flow Mod and Flow
970 * Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied.
971 * Otherwise, 'cookie_mask' should be zero.
973 * This function can cause 'b''s data to be reallocated.
975 * Returns the number of bytes appended to 'b', excluding padding. The return
976 * value can be zero if it appended nothing at all to 'b' (which happens if
977 * 'cr' is a catch-all rule that matches every packet). */
979 nx_put_match(struct ofpbuf
*b
, const struct match
*match
,
980 ovs_be64 cookie
, ovs_be64 cookie_mask
)
982 int match_len
= nx_put_raw(b
, 0, match
, cookie
, cookie_mask
);
984 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
988 /* Appends to 'b' an struct ofp11_match_header followed by the OXM format that
989 * expresses 'cr', plus enough zero bytes to pad the data appended out to a
992 * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow
993 * version in use as 'version'.
995 * This function can cause 'b''s data to be reallocated.
997 * Returns the number of bytes appended to 'b', excluding the padding. Never
1000 oxm_put_match(struct ofpbuf
*b
, const struct match
*match
,
1001 enum ofp_version version
)
1004 struct ofp11_match_header
*omh
;
1005 size_t start_len
= ofpbuf_size(b
);
1006 ovs_be64 cookie
= htonll(0), cookie_mask
= htonll(0);
1008 ofpbuf_put_uninit(b
, sizeof *omh
);
1009 match_len
= (nx_put_raw(b
, version
, match
, cookie
, cookie_mask
)
1011 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1013 omh
= ofpbuf_at(b
, start_len
, sizeof *omh
);
1014 omh
->type
= htons(OFPMT_OXM
);
1015 omh
->length
= htons(match_len
);
1021 nx_put_header__(struct ofpbuf
*b
, uint64_t header
, bool masked
)
1023 uint64_t masked_header
= masked
? nxm_make_wild_header(header
) : header
;
1024 ovs_be64 network_header
= htonll(masked_header
);
1026 ofpbuf_put(b
, &network_header
, nxm_header_len(header
));
1030 nx_put_header(struct ofpbuf
*b
, enum mf_field_id field
,
1031 enum ofp_version version
, bool masked
)
1033 nx_put_header__(b
, mf_oxm_header(field
, version
), masked
);
1037 nx_put_entry(struct ofpbuf
*b
,
1038 enum mf_field_id field
, enum ofp_version version
,
1039 const union mf_value
*value
, const union mf_value
*mask
)
1041 int n_bytes
= mf_from_id(field
)->n_bytes
;
1042 bool masked
= mask
&& !is_all_ones(mask
, n_bytes
);
1044 nx_put_header(b
, field
, version
, masked
);
1045 ofpbuf_put(b
, value
, n_bytes
);
1047 ofpbuf_put(b
, mask
, n_bytes
);
1051 /* nx_match_to_string() and helpers. */
1053 static void format_nxm_field_name(struct ds
*, uint64_t header
);
1056 nx_match_to_string(const uint8_t *p
, unsigned int match_len
)
1062 return xstrdup("<any>");
1065 ofpbuf_use_const(&b
, p
, match_len
);
1067 while (ofpbuf_size(&b
)) {
1068 union mf_value value
;
1069 union mf_value mask
;
1074 error
= nx_pull_entry__(&b
, true, &header
, NULL
, &value
, &mask
);
1078 value_len
= MIN(sizeof value
, nxm_field_bytes(header
));
1081 ds_put_cstr(&s
, ", ");
1084 format_nxm_field_name(&s
, header
);
1085 ds_put_char(&s
, '(');
1087 for (int i
= 0; i
< value_len
; i
++) {
1088 ds_put_format(&s
, "%02x", ((const uint8_t *) &value
)[i
]);
1090 if (nxm_hasmask(header
)) {
1091 ds_put_char(&s
, '/');
1092 for (int i
= 0; i
< value_len
; i
++) {
1093 ds_put_format(&s
, "%02x", ((const uint8_t *) &mask
)[i
]);
1096 ds_put_char(&s
, ')');
1099 if (ofpbuf_size(&b
)) {
1101 ds_put_cstr(&s
, ", ");
1104 ds_put_format(&s
, "<%u invalid bytes>", ofpbuf_size(&b
));
1107 return ds_steal_cstr(&s
);
1111 oxm_match_to_string(const struct ofpbuf
*p
, unsigned int match_len
)
1113 const struct ofp11_match_header
*omh
= ofpbuf_data(p
);
1114 uint16_t match_len_
;
1119 if (match_len
< sizeof *omh
) {
1120 ds_put_format(&s
, "<match too short: %u>", match_len
);
1124 if (omh
->type
!= htons(OFPMT_OXM
)) {
1125 ds_put_format(&s
, "<bad match type field: %u>", ntohs(omh
->type
));
1129 match_len_
= ntohs(omh
->length
);
1130 if (match_len_
< sizeof *omh
) {
1131 ds_put_format(&s
, "<match length field too short: %u>", match_len_
);
1135 if (match_len_
!= match_len
) {
1136 ds_put_format(&s
, "<match length field incorrect: %u != %u>",
1137 match_len_
, match_len
);
1141 return nx_match_to_string(ofpbuf_at(p
, sizeof *omh
, 0),
1142 match_len
- sizeof *omh
);
1145 return ds_steal_cstr(&s
);
1149 nx_format_field_name(enum mf_field_id id
, enum ofp_version version
,
1152 format_nxm_field_name(s
, mf_oxm_header(id
, version
));
1156 format_nxm_field_name(struct ds
*s
, uint64_t header
)
1158 const struct nxm_field
*f
= nxm_field_by_header(header
);
1160 ds_put_cstr(s
, f
->name
);
1161 if (nxm_hasmask(header
)) {
1162 ds_put_cstr(s
, "_W");
1164 } else if (header
== NXM_NX_COOKIE
) {
1165 ds_put_cstr(s
, "NXM_NX_COOKIE");
1166 } else if (header
== NXM_NX_COOKIE_W
) {
1167 ds_put_cstr(s
, "NXM_NX_COOKIE_W");
1169 ds_put_format(s
, "%d:%d", nxm_class(header
), nxm_field(header
));
1174 streq_len(const char *a
, size_t a_len
, const char *b
)
1176 return strlen(b
) == a_len
&& !memcmp(a
, b
, a_len
);
1180 parse_nxm_field_name(const char *name
, int name_len
)
1182 const struct nxm_field
*f
;
1185 f
= mf_parse_subfield_name(name
, name_len
, &wild
);
1189 } else if (mf_from_id(f
->id
)->maskable
!= MFM_NONE
) {
1190 return nxm_make_wild_header(f
->header
);
1194 if (streq_len(name
, name_len
, "NXM_NX_COOKIE")) {
1195 return NXM_NX_COOKIE
;
1196 } else if (streq_len(name
, name_len
, "NXM_NX_COOKIE_W")) {
1197 return NXM_NX_COOKIE_W
;
1200 /* Check whether it's a field header value as hex.
1201 * (This isn't ordinarily useful except for testing error behavior.) */
1202 if (name_len
== 8) {
1206 header
= hexits_value(name
, name_len
, &ok
) << 32;
1210 } else if (name_len
== 16) {
1214 header
= hexits_value(name
, name_len
, &ok
);
1215 if (ok
&& is_experimenter_oxm(header
)) {
1223 /* nx_match_from_string(). */
1226 nx_match_from_string_raw(const char *s
, struct ofpbuf
*b
)
1228 const char *full_s
= s
;
1229 const size_t start_len
= ofpbuf_size(b
);
1231 if (!strcmp(s
, "<any>")) {
1232 /* Ensure that 'ofpbuf_data(b)' isn't actually null. */
1233 ofpbuf_prealloc_tailroom(b
, 1);
1237 for (s
+= strspn(s
, ", "); *s
; s
+= strspn(s
, ", ")) {
1244 name_len
= strcspn(s
, "(");
1245 if (s
[name_len
] != '(') {
1246 ovs_fatal(0, "%s: missing ( at end of nx_match", full_s
);
1249 header
= parse_nxm_field_name(name
, name_len
);
1251 ovs_fatal(0, "%s: unknown field `%.*s'", full_s
, name_len
, s
);
1256 nx_put_header__(b
, header
, false);
1257 s
= ofpbuf_put_hex(b
, s
, &n
);
1258 if (n
!= nxm_field_bytes(header
)) {
1259 ovs_fatal(0, "%.2s: hex digits expected", s
);
1261 if (nxm_hasmask(header
)) {
1262 s
+= strspn(s
, " ");
1264 ovs_fatal(0, "%s: missing / in masked field %.*s",
1265 full_s
, name_len
, name
);
1267 s
= ofpbuf_put_hex(b
, s
+ 1, &n
);
1268 if (n
!= nxm_field_bytes(header
)) {
1269 ovs_fatal(0, "%.2s: hex digits expected", s
);
1273 s
+= strspn(s
, " ");
1275 ovs_fatal(0, "%s: missing ) following field %.*s",
1276 full_s
, name_len
, name
);
1281 return ofpbuf_size(b
) - start_len
;
1285 nx_match_from_string(const char *s
, struct ofpbuf
*b
)
1287 int match_len
= nx_match_from_string_raw(s
, b
);
1288 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1293 oxm_match_from_string(const char *s
, struct ofpbuf
*b
)
1296 struct ofp11_match_header
*omh
;
1297 size_t start_len
= ofpbuf_size(b
);
1299 ofpbuf_put_uninit(b
, sizeof *omh
);
1300 match_len
= nx_match_from_string_raw(s
, b
) + sizeof *omh
;
1301 ofpbuf_put_zeros(b
, PAD_SIZE(match_len
, 8));
1303 omh
= ofpbuf_at(b
, start_len
, sizeof *omh
);
1304 omh
->type
= htons(OFPMT_OXM
);
1305 omh
->length
= htons(match_len
);
1310 /* Parses 's' as a "move" action, in the form described in ovs-ofctl(8), into
1313 * Returns NULL if successful, otherwise a malloc()'d string describing the
1314 * error. The caller is responsible for freeing the returned string. */
1315 char * OVS_WARN_UNUSED_RESULT
1316 nxm_parse_reg_move(struct ofpact_reg_move
*move
, const char *s
)
1318 const char *full_s
= s
;
1321 error
= mf_parse_subfield__(&move
->src
, &s
);
1325 if (strncmp(s
, "->", 2)) {
1326 return xasprintf("%s: missing `->' following source", full_s
);
1329 error
= mf_parse_subfield(&move
->dst
, s
);
1334 if (move
->src
.n_bits
!= move
->dst
.n_bits
) {
1335 return xasprintf("%s: source field is %d bits wide but destination is "
1336 "%d bits wide", full_s
,
1337 move
->src
.n_bits
, move
->dst
.n_bits
);
1342 /* nxm_format_reg_move(). */
1345 nxm_format_reg_move(const struct ofpact_reg_move
*move
, struct ds
*s
)
1347 ds_put_format(s
, "move:");
1348 mf_format_subfield(&move
->src
, s
);
1349 ds_put_cstr(s
, "->");
1350 mf_format_subfield(&move
->dst
, s
);
1355 nxm_reg_move_check(const struct ofpact_reg_move
*move
, const struct flow
*flow
)
1359 error
= mf_check_src(&move
->src
, flow
);
1364 return mf_check_dst(&move
->dst
, flow
);
1367 /* nxm_execute_reg_move(). */
1370 nxm_execute_reg_move(const struct ofpact_reg_move
*move
,
1371 struct flow
*flow
, struct flow_wildcards
*wc
)
1373 union mf_value src_value
;
1374 union mf_value dst_value
;
1376 mf_mask_field_and_prereqs(move
->dst
.field
, &wc
->masks
);
1377 mf_mask_field_and_prereqs(move
->src
.field
, &wc
->masks
);
1379 /* A flow may wildcard nw_frag. Do nothing if setting a transport
1380 * header field on a packet that does not have them. */
1381 if (mf_are_prereqs_ok(move
->dst
.field
, flow
)
1382 && mf_are_prereqs_ok(move
->src
.field
, flow
)) {
1384 mf_get_value(move
->dst
.field
, flow
, &dst_value
);
1385 mf_get_value(move
->src
.field
, flow
, &src_value
);
1386 bitwise_copy(&src_value
, move
->src
.field
->n_bytes
, move
->src
.ofs
,
1387 &dst_value
, move
->dst
.field
->n_bytes
, move
->dst
.ofs
,
1389 mf_set_flow_value(move
->dst
.field
, &dst_value
, flow
);
1394 nxm_reg_load(const struct mf_subfield
*dst
, uint64_t src_data
,
1395 struct flow
*flow
, struct flow_wildcards
*wc
)
1397 union mf_subvalue src_subvalue
;
1398 union mf_subvalue mask_value
;
1399 ovs_be64 src_data_be
= htonll(src_data
);
1401 memset(&mask_value
, 0xff, sizeof mask_value
);
1402 mf_write_subfield_flow(dst
, &mask_value
, &wc
->masks
);
1404 bitwise_copy(&src_data_be
, sizeof src_data_be
, 0,
1405 &src_subvalue
, sizeof src_subvalue
, 0,
1406 sizeof src_data_be
* 8);
1407 mf_write_subfield_flow(dst
, &src_subvalue
, flow
);
1410 /* nxm_parse_stack_action, works for both push() and pop(). */
1412 /* Parses 's' as a "push" or "pop" action, in the form described in
1413 * ovs-ofctl(8), into '*stack_action'.
1415 * Returns NULL if successful, otherwise a malloc()'d string describing the
1416 * error. The caller is responsible for freeing the returned string. */
1417 char * OVS_WARN_UNUSED_RESULT
1418 nxm_parse_stack_action(struct ofpact_stack
*stack_action
, const char *s
)
1422 error
= mf_parse_subfield__(&stack_action
->subfield
, &s
);
1428 return xasprintf("%s: trailing garbage following push or pop", s
);
1435 nxm_format_stack_push(const struct ofpact_stack
*push
, struct ds
*s
)
1437 ds_put_cstr(s
, "push:");
1438 mf_format_subfield(&push
->subfield
, s
);
1442 nxm_format_stack_pop(const struct ofpact_stack
*pop
, struct ds
*s
)
1444 ds_put_cstr(s
, "pop:");
1445 mf_format_subfield(&pop
->subfield
, s
);
1449 nxm_stack_push_check(const struct ofpact_stack
*push
,
1450 const struct flow
*flow
)
1452 return mf_check_src(&push
->subfield
, flow
);
1456 nxm_stack_pop_check(const struct ofpact_stack
*pop
,
1457 const struct flow
*flow
)
1459 return mf_check_dst(&pop
->subfield
, flow
);
1462 /* nxm_execute_stack_push(), nxm_execute_stack_pop(). */
1464 nx_stack_push(struct ofpbuf
*stack
, union mf_subvalue
*v
)
1466 ofpbuf_put(stack
, v
, sizeof *v
);
1469 static union mf_subvalue
*
1470 nx_stack_pop(struct ofpbuf
*stack
)
1472 union mf_subvalue
*v
= NULL
;
1474 if (ofpbuf_size(stack
)) {
1476 ofpbuf_set_size(stack
, ofpbuf_size(stack
) - sizeof *v
);
1477 v
= (union mf_subvalue
*) ofpbuf_tail(stack
);
1484 nxm_execute_stack_push(const struct ofpact_stack
*push
,
1485 const struct flow
*flow
, struct flow_wildcards
*wc
,
1486 struct ofpbuf
*stack
)
1488 union mf_subvalue mask_value
;
1489 union mf_subvalue dst_value
;
1491 memset(&mask_value
, 0xff, sizeof mask_value
);
1492 mf_write_subfield_flow(&push
->subfield
, &mask_value
, &wc
->masks
);
1494 mf_read_subfield(&push
->subfield
, flow
, &dst_value
);
1495 nx_stack_push(stack
, &dst_value
);
1499 nxm_execute_stack_pop(const struct ofpact_stack
*pop
,
1500 struct flow
*flow
, struct flow_wildcards
*wc
,
1501 struct ofpbuf
*stack
)
1503 union mf_subvalue
*src_value
;
1505 src_value
= nx_stack_pop(stack
);
1507 /* Only pop if stack is not empty. Otherwise, give warning. */
1509 union mf_subvalue mask_value
;
1511 memset(&mask_value
, 0xff, sizeof mask_value
);
1512 mf_write_subfield_flow(&pop
->subfield
, &mask_value
, &wc
->masks
);
1513 mf_write_subfield_flow(&pop
->subfield
, src_value
, flow
);
1515 if (!VLOG_DROP_WARN(&rl
)) {
1516 char *flow_str
= flow_to_string(flow
);
1517 VLOG_WARN_RL(&rl
, "Failed to pop from an empty stack. On flow \n"
1524 /* Formats 'sf' into 's' in a format normally acceptable to
1525 * mf_parse_subfield(). (It won't be acceptable if sf->field is NULL or if
1526 * sf->field has no NXM name.) */
1528 mf_format_subfield(const struct mf_subfield
*sf
, struct ds
*s
)
1531 ds_put_cstr(s
, "<unknown>");
1533 const struct nxm_field
*f
= nxm_field_by_mf_id(sf
->field
->id
, 0);
1534 ds_put_cstr(s
, f
? f
->name
: sf
->field
->name
);
1537 if (sf
->field
&& sf
->ofs
== 0 && sf
->n_bits
== sf
->field
->n_bits
) {
1538 ds_put_cstr(s
, "[]");
1539 } else if (sf
->n_bits
== 1) {
1540 ds_put_format(s
, "[%d]", sf
->ofs
);
1542 ds_put_format(s
, "[%d..%d]", sf
->ofs
, sf
->ofs
+ sf
->n_bits
- 1);
1546 static const struct nxm_field
*
1547 mf_parse_subfield_name(const char *name
, int name_len
, bool *wild
)
1549 *wild
= name_len
> 2 && !memcmp(&name
[name_len
- 2], "_W", 2);
1554 return nxm_field_by_name(name
, name_len
);
1557 /* Parses a subfield from the beginning of '*sp' into 'sf'. If successful,
1558 * returns NULL and advances '*sp' to the first byte following the parsed
1559 * string. On failure, returns a malloc()'d error message, does not modify
1560 * '*sp', and does not properly initialize 'sf'.
1562 * The syntax parsed from '*sp' takes the form "header[start..end]" where
1563 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1564 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1565 * may both be omitted (the [] are still required) to indicate an entire
1567 char * OVS_WARN_UNUSED_RESULT
1568 mf_parse_subfield__(struct mf_subfield
*sf
, const char **sp
)
1570 const struct mf_field
*field
;
1571 const struct nxm_field
*f
;
1580 name_len
= strcspn(s
, "[");
1581 if (s
[name_len
] != '[') {
1582 return xasprintf("%s: missing [ looking for field name", *sp
);
1585 f
= mf_parse_subfield_name(name
, name_len
, &wild
);
1587 return xasprintf("%s: unknown field `%.*s'", *sp
, name_len
, s
);
1589 field
= mf_from_id(f
->id
);
1592 if (ovs_scan(s
, "[%d..%d]", &start
, &end
)) {
1593 /* Nothing to do. */
1594 } else if (ovs_scan(s
, "[%d]", &start
)) {
1596 } else if (!strncmp(s
, "[]", 2)) {
1598 end
= field
->n_bits
- 1;
1600 return xasprintf("%s: syntax error expecting [] or [<bit>] or "
1601 "[<start>..<end>]", *sp
);
1603 s
= strchr(s
, ']') + 1;
1606 return xasprintf("%s: starting bit %d is after ending bit %d",
1608 } else if (start
>= field
->n_bits
) {
1609 return xasprintf("%s: starting bit %d is not valid because field is "
1610 "only %d bits wide", *sp
, start
, field
->n_bits
);
1611 } else if (end
>= field
->n_bits
){
1612 return xasprintf("%s: ending bit %d is not valid because field is "
1613 "only %d bits wide", *sp
, end
, field
->n_bits
);
1618 sf
->n_bits
= end
- start
+ 1;
1624 /* Parses a subfield from the entirety of 's' into 'sf'. Returns NULL if
1625 * successful, otherwise a malloc()'d string describing the error. The caller
1626 * is responsible for freeing the returned string.
1628 * The syntax parsed from 's' takes the form "header[start..end]" where
1629 * 'header' is the name of an NXM field and 'start' and 'end' are (inclusive)
1630 * bit indexes. "..end" may be omitted to indicate a single bit. "start..end"
1631 * may both be omitted (the [] are still required) to indicate an entire
1633 char * OVS_WARN_UNUSED_RESULT
1634 mf_parse_subfield(struct mf_subfield
*sf
, const char *s
)
1636 char *error
= mf_parse_subfield__(sf
, &s
);
1637 if (!error
&& s
[0]) {
1638 error
= xstrdup("unexpected input following field syntax");
1643 /* Returns an bitmap in which each bit corresponds to the like-numbered field
1644 * in the OFPXMC12_OPENFLOW_BASIC OXM class, in which the bit values are taken
1645 * from the 'fields' bitmap. Only fields defined in OpenFlow 'version' are
1648 * This is useful for encoding OpenFlow 1.2 table stats messages. */
1650 oxm_bitmap_from_mf_bitmap(const struct mf_bitmap
*fields
,
1651 enum ofp_version version
)
1653 uint64_t oxm_bitmap
= 0;
1656 BITMAP_FOR_EACH_1 (i
, MFF_N_IDS
, fields
->bm
) {
1657 uint64_t oxm
= mf_oxm_header(i
, version
);
1658 uint32_t class = nxm_class(oxm
);
1659 int field
= nxm_field(oxm
);
1661 if (class == OFPXMC12_OPENFLOW_BASIC
&& field
< 64) {
1662 oxm_bitmap
|= UINT64_C(1) << field
;
1665 return htonll(oxm_bitmap
);
1668 /* Opposite conversion from oxm_bitmap_from_mf_bitmap().
1670 * This is useful for decoding OpenFlow 1.2 table stats messages. */
1672 oxm_bitmap_to_mf_bitmap(ovs_be64 oxm_bitmap
, enum ofp_version version
)
1674 struct mf_bitmap fields
= MF_BITMAP_INITIALIZER
;
1676 for (enum mf_field_id id
= 0; id
< MFF_N_IDS
; id
++) {
1677 uint64_t oxm
= mf_oxm_header(id
, version
);
1678 if (oxm
&& version
>= nxm_field_by_header(oxm
)->version
) {
1679 uint32_t class = nxm_class(oxm
);
1680 int field
= nxm_field(oxm
);
1682 if (class == OFPXMC12_OPENFLOW_BASIC
1684 && oxm_bitmap
& htonll(UINT64_C(1) << field
)) {
1685 bitmap_set1(fields
.bm
, id
);
1692 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1693 * modified with a "set_field" action. */
1695 oxm_writable_fields(void)
1697 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1700 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1701 if (mf_oxm_header(i
, 0) && mf_from_id(i
)->writable
) {
1702 bitmap_set1(b
.bm
, i
);
1708 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1709 * matched in a flow table. */
1711 oxm_matchable_fields(void)
1713 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1716 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1717 if (mf_oxm_header(i
, 0)) {
1718 bitmap_set1(b
.bm
, i
);
1724 /* Returns a bitmap of fields that can be encoded in OXM and that can be
1725 * matched in a flow table with an arbitrary bitmask. */
1727 oxm_maskable_fields(void)
1729 struct mf_bitmap b
= MF_BITMAP_INITIALIZER
;
1732 for (i
= 0; i
< MFF_N_IDS
; i
++) {
1733 if (mf_oxm_header(i
, 0) && mf_from_id(i
)->maskable
== MFM_FULLY
) {
1734 bitmap_set1(b
.bm
, i
);
1740 struct nxm_field_index
{
1741 struct hmap_node header_node
; /* In nxm_header_map. */
1742 struct hmap_node name_node
; /* In nxm_name_map. */
1743 struct ovs_list mf_node
; /* In mf_mf_map[nf.id]. */
1744 const struct nxm_field nf
;
1747 #include "nx-match.inc"
1749 static struct hmap nxm_header_map
;
1750 static struct hmap nxm_name_map
;
1751 static struct ovs_list nxm_mf_map
[MFF_N_IDS
];
1756 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
1757 if (ovsthread_once_start(&once
)) {
1758 hmap_init(&nxm_header_map
);
1759 hmap_init(&nxm_name_map
);
1760 for (int i
= 0; i
< MFF_N_IDS
; i
++) {
1761 list_init(&nxm_mf_map
[i
]);
1763 for (struct nxm_field_index
*nfi
= all_nxm_fields
;
1764 nfi
< &all_nxm_fields
[ARRAY_SIZE(all_nxm_fields
)]; nfi
++) {
1765 hmap_insert(&nxm_header_map
, &nfi
->header_node
,
1766 hash_int(nfi
->nf
.header
, 0));
1767 hmap_insert(&nxm_name_map
, &nfi
->name_node
,
1768 hash_string(nfi
->nf
.name
, 0));
1769 list_push_back(&nxm_mf_map
[nfi
->nf
.id
], &nfi
->mf_node
);
1771 ovsthread_once_done(&once
);
1775 static const struct nxm_field
*
1776 nxm_field_by_header(uint64_t header
)
1778 const struct nxm_field_index
*nfi
;
1781 if (nxm_hasmask(header
)) {
1782 header
= nxm_make_exact_header(header
);
1785 HMAP_FOR_EACH_IN_BUCKET (nfi
, header_node
, hash_int(header
, 0),
1787 if (header
== nfi
->nf
.header
) {
1794 static const struct nxm_field
*
1795 nxm_field_by_name(const char *name
, size_t len
)
1797 const struct nxm_field_index
*nfi
;
1800 HMAP_FOR_EACH_WITH_HASH (nfi
, name_node
, hash_bytes(name
, len
, 0),
1802 if (strlen(nfi
->nf
.name
) == len
&& !memcmp(nfi
->nf
.name
, name
, len
)) {
1809 static const struct nxm_field
*
1810 nxm_field_by_mf_id(enum mf_field_id id
, enum ofp_version version
)
1812 const struct nxm_field_index
*nfi
;
1813 const struct nxm_field
*f
;
1818 LIST_FOR_EACH (nfi
, mf_node
, &nxm_mf_map
[id
]) {
1819 if (!f
|| version
>= nfi
->nf
.version
) {