2 * Copyright (c) 2009, 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.
20 #include "byte-order.h"
21 #include "dynamic-string.h"
25 /* Converts the flow in 'flow' into a match in 'match', with the given
28 match_init(struct match
*match
,
29 const struct flow
*flow
, const struct flow_wildcards
*wc
)
33 match_zero_wildcarded_fields(match
);
36 /* Converts a flow into a match. It sets the wildcard masks based on
37 * the packet contents. It will not set the mask for fields that do not
38 * make sense for the packet type. */
40 match_wc_init(struct match
*match
, const struct flow
*flow
)
42 struct flow_wildcards
*wc
;
47 memset(&wc
->masks
, 0x0, sizeof wc
->masks
);
49 memset(&wc
->masks
.dl_type
, 0xff, sizeof wc
->masks
.dl_type
);
52 memset(&wc
->masks
.nw_proto
, 0xff, sizeof wc
->masks
.nw_proto
);
55 if (flow
->skb_priority
) {
56 memset(&wc
->masks
.skb_priority
, 0xff, sizeof wc
->masks
.skb_priority
);
60 memset(&wc
->masks
.pkt_mark
, 0xff, sizeof wc
->masks
.pkt_mark
);
63 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
65 memset(&wc
->masks
.regs
[i
], 0xff, sizeof wc
->masks
.regs
[i
]);
69 if (flow
->tunnel
.ip_dst
) {
70 if (flow
->tunnel
.flags
& FLOW_TNL_F_KEY
) {
71 memset(&wc
->masks
.tunnel
.tun_id
, 0xff, sizeof wc
->masks
.tunnel
.tun_id
);
73 memset(&wc
->masks
.tunnel
.ip_src
, 0xff, sizeof wc
->masks
.tunnel
.ip_src
);
74 memset(&wc
->masks
.tunnel
.ip_dst
, 0xff, sizeof wc
->masks
.tunnel
.ip_dst
);
75 memset(&wc
->masks
.tunnel
.flags
, 0xff, sizeof wc
->masks
.tunnel
.flags
);
76 memset(&wc
->masks
.tunnel
.ip_tos
, 0xff, sizeof wc
->masks
.tunnel
.ip_tos
);
77 memset(&wc
->masks
.tunnel
.ip_ttl
, 0xff, sizeof wc
->masks
.tunnel
.ip_ttl
);
78 } else if (flow
->tunnel
.tun_id
) {
79 memset(&wc
->masks
.tunnel
.tun_id
, 0xff, sizeof wc
->masks
.tunnel
.tun_id
);
82 memset(&wc
->masks
.metadata
, 0xff, sizeof wc
->masks
.metadata
);
83 memset(&wc
->masks
.in_port
, 0xff, sizeof wc
->masks
.in_port
);
84 memset(&wc
->masks
.vlan_tci
, 0xff, sizeof wc
->masks
.vlan_tci
);
85 memset(&wc
->masks
.dl_src
, 0xff, sizeof wc
->masks
.dl_src
);
86 memset(&wc
->masks
.dl_dst
, 0xff, sizeof wc
->masks
.dl_dst
);
88 if (flow
->dl_type
== htons(ETH_TYPE_IPV6
)) {
89 memset(&wc
->masks
.ipv6_src
, 0xff, sizeof wc
->masks
.ipv6_src
);
90 memset(&wc
->masks
.ipv6_dst
, 0xff, sizeof wc
->masks
.ipv6_dst
);
91 memset(&wc
->masks
.ipv6_label
, 0xff, sizeof wc
->masks
.ipv6_label
);
92 } else if (flow
->dl_type
== htons(ETH_TYPE_IP
) ||
93 (flow
->dl_type
== htons(ETH_TYPE_ARP
)) ||
94 (flow
->dl_type
== htons(ETH_TYPE_RARP
))) {
95 memset(&wc
->masks
.nw_src
, 0xff, sizeof wc
->masks
.nw_src
);
96 memset(&wc
->masks
.nw_dst
, 0xff, sizeof wc
->masks
.nw_dst
);
97 } else if (eth_type_mpls(flow
->dl_type
)) {
100 for (i
= 0; i
< FLOW_MAX_MPLS_LABELS
; i
++) {
101 wc
->masks
.mpls_lse
[i
] = OVS_BE32_MAX
;
102 if (flow
->mpls_lse
[i
] & htonl(MPLS_BOS_MASK
)) {
108 if (flow
->dl_type
== htons(ETH_TYPE_ARP
) ||
109 flow
->dl_type
== htons(ETH_TYPE_RARP
)) {
110 memset(&wc
->masks
.arp_sha
, 0xff, sizeof wc
->masks
.arp_sha
);
111 memset(&wc
->masks
.arp_tha
, 0xff, sizeof wc
->masks
.arp_tha
);
114 if (is_ip_any(flow
)) {
115 memset(&wc
->masks
.nw_tos
, 0xff, sizeof wc
->masks
.nw_tos
);
116 memset(&wc
->masks
.nw_ttl
, 0xff, sizeof wc
->masks
.nw_ttl
);
119 memset(&wc
->masks
.nw_frag
, 0xff, sizeof wc
->masks
.nw_frag
);
120 if (flow
->nw_frag
& FLOW_NW_FRAG_LATER
) {
121 /* No transport layer header in later fragments. */
126 if (flow
->nw_proto
== IPPROTO_ICMP
||
127 flow
->nw_proto
== IPPROTO_ICMPV6
||
128 (flow
->tp_src
|| flow
->tp_dst
)) {
129 memset(&wc
->masks
.tp_src
, 0xff, sizeof wc
->masks
.tp_src
);
130 memset(&wc
->masks
.tp_dst
, 0xff, sizeof wc
->masks
.tp_dst
);
132 if (flow
->nw_proto
== IPPROTO_TCP
) {
133 memset(&wc
->masks
.tcp_flags
, 0xff, sizeof wc
->masks
.tcp_flags
);
136 if (flow
->nw_proto
== IPPROTO_ICMPV6
) {
137 memset(&wc
->masks
.arp_sha
, 0xff, sizeof wc
->masks
.arp_sha
);
138 memset(&wc
->masks
.arp_tha
, 0xff, sizeof wc
->masks
.arp_tha
);
145 /* Initializes 'match' as a "catch-all" match that matches every packet. */
147 match_init_catchall(struct match
*match
)
149 memset(&match
->flow
, 0, sizeof match
->flow
);
150 flow_wildcards_init_catchall(&match
->wc
);
153 /* For each bit or field wildcarded in 'match', sets the corresponding bit or
154 * field in 'flow' to all-0-bits. It is important to maintain this invariant
155 * in a match that might be inserted into a classifier.
157 * It is never necessary to call this function directly for a match that is
158 * initialized or modified only by match_*() functions. It is useful to
159 * restore the invariant in a match whose 'wc' member is modified by hand.
162 match_zero_wildcarded_fields(struct match
*match
)
164 flow_zero_wildcards(&match
->flow
, &match
->wc
);
168 match_set_dp_hash(struct match
*match
, uint32_t value
)
170 match_set_dp_hash_masked(match
, value
, UINT32_MAX
);
174 match_set_dp_hash_masked(struct match
*match
, uint32_t value
, uint32_t mask
)
176 match
->wc
.masks
.dp_hash
= mask
;
177 match
->flow
.dp_hash
= value
& mask
;
181 match_set_recirc_id(struct match
*match
, uint32_t value
)
183 match
->flow
.recirc_id
= value
;
184 match
->wc
.masks
.recirc_id
= UINT32_MAX
;
188 match_set_reg(struct match
*match
, unsigned int reg_idx
, uint32_t value
)
190 match_set_reg_masked(match
, reg_idx
, value
, UINT32_MAX
);
194 match_set_reg_masked(struct match
*match
, unsigned int reg_idx
,
195 uint32_t value
, uint32_t mask
)
197 ovs_assert(reg_idx
< FLOW_N_REGS
);
198 flow_wildcards_set_reg_mask(&match
->wc
, reg_idx
, mask
);
199 match
->flow
.regs
[reg_idx
] = value
& mask
;
203 match_set_metadata(struct match
*match
, ovs_be64 metadata
)
205 match_set_metadata_masked(match
, metadata
, OVS_BE64_MAX
);
209 match_set_metadata_masked(struct match
*match
,
210 ovs_be64 metadata
, ovs_be64 mask
)
212 match
->wc
.masks
.metadata
= mask
;
213 match
->flow
.metadata
= metadata
& mask
;
217 match_set_tun_id(struct match
*match
, ovs_be64 tun_id
)
219 match_set_tun_id_masked(match
, tun_id
, OVS_BE64_MAX
);
223 match_set_tun_id_masked(struct match
*match
, ovs_be64 tun_id
, ovs_be64 mask
)
225 match
->wc
.masks
.tunnel
.tun_id
= mask
;
226 match
->flow
.tunnel
.tun_id
= tun_id
& mask
;
230 match_set_tun_src(struct match
*match
, ovs_be32 src
)
232 match_set_tun_src_masked(match
, src
, OVS_BE32_MAX
);
236 match_set_tun_src_masked(struct match
*match
, ovs_be32 src
, ovs_be32 mask
)
238 match
->wc
.masks
.tunnel
.ip_src
= mask
;
239 match
->flow
.tunnel
.ip_src
= src
& mask
;
243 match_set_tun_dst(struct match
*match
, ovs_be32 dst
)
245 match_set_tun_dst_masked(match
, dst
, OVS_BE32_MAX
);
249 match_set_tun_dst_masked(struct match
*match
, ovs_be32 dst
, ovs_be32 mask
)
251 match
->wc
.masks
.tunnel
.ip_dst
= mask
;
252 match
->flow
.tunnel
.ip_dst
= dst
& mask
;
256 match_set_tun_ttl(struct match
*match
, uint8_t ttl
)
258 match_set_tun_ttl_masked(match
, ttl
, UINT8_MAX
);
262 match_set_tun_ttl_masked(struct match
*match
, uint8_t ttl
, uint8_t mask
)
264 match
->wc
.masks
.tunnel
.ip_ttl
= mask
;
265 match
->flow
.tunnel
.ip_ttl
= ttl
& mask
;
269 match_set_tun_tos(struct match
*match
, uint8_t tos
)
271 match_set_tun_tos_masked(match
, tos
, UINT8_MAX
);
275 match_set_tun_tos_masked(struct match
*match
, uint8_t tos
, uint8_t mask
)
277 match
->wc
.masks
.tunnel
.ip_tos
= mask
;
278 match
->flow
.tunnel
.ip_tos
= tos
& mask
;
282 match_set_tun_flags(struct match
*match
, uint16_t flags
)
284 match_set_tun_flags_masked(match
, flags
, UINT16_MAX
);
288 match_set_tun_flags_masked(struct match
*match
, uint16_t flags
, uint16_t mask
)
290 match
->wc
.masks
.tunnel
.flags
= mask
;
291 match
->flow
.tunnel
.flags
= flags
& mask
;
295 match_set_in_port(struct match
*match
, ofp_port_t ofp_port
)
297 match
->wc
.masks
.in_port
.ofp_port
= u16_to_ofp(UINT16_MAX
);
298 match
->flow
.in_port
.ofp_port
= ofp_port
;
302 match_set_skb_priority(struct match
*match
, uint32_t skb_priority
)
304 match
->wc
.masks
.skb_priority
= UINT32_MAX
;
305 match
->flow
.skb_priority
= skb_priority
;
309 match_set_pkt_mark(struct match
*match
, uint32_t pkt_mark
)
311 match_set_pkt_mark_masked(match
, pkt_mark
, UINT32_MAX
);
315 match_set_pkt_mark_masked(struct match
*match
, uint32_t pkt_mark
, uint32_t mask
)
317 match
->flow
.pkt_mark
= pkt_mark
& mask
;
318 match
->wc
.masks
.pkt_mark
= mask
;
322 match_set_dl_type(struct match
*match
, ovs_be16 dl_type
)
324 match
->wc
.masks
.dl_type
= OVS_BE16_MAX
;
325 match
->flow
.dl_type
= dl_type
;
328 /* Modifies 'value_src' so that the Ethernet address must match 'value_dst'
329 * exactly. 'mask_dst' is set to all 1s. */
331 set_eth(const uint8_t value_src
[ETH_ADDR_LEN
],
332 uint8_t value_dst
[ETH_ADDR_LEN
],
333 uint8_t mask_dst
[ETH_ADDR_LEN
])
335 memcpy(value_dst
, value_src
, ETH_ADDR_LEN
);
336 memset(mask_dst
, 0xff, ETH_ADDR_LEN
);
339 /* Modifies 'value_src' so that the Ethernet address must match 'value_src'
340 * after each byte is ANDed with the appropriate byte in 'mask_src'.
341 * 'mask_dst' is set to 'mask_src' */
343 set_eth_masked(const uint8_t value_src
[ETH_ADDR_LEN
],
344 const uint8_t mask_src
[ETH_ADDR_LEN
],
345 uint8_t value_dst
[ETH_ADDR_LEN
],
346 uint8_t mask_dst
[ETH_ADDR_LEN
])
350 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
351 value_dst
[i
] = value_src
[i
] & mask_src
[i
];
352 mask_dst
[i
] = mask_src
[i
];
356 /* Modifies 'rule' so that the source Ethernet address must match 'dl_src'
359 match_set_dl_src(struct match
*match
, const uint8_t dl_src
[ETH_ADDR_LEN
])
361 set_eth(dl_src
, match
->flow
.dl_src
, match
->wc
.masks
.dl_src
);
364 /* Modifies 'rule' so that the source Ethernet address must match 'dl_src'
365 * after each byte is ANDed with the appropriate byte in 'mask'. */
367 match_set_dl_src_masked(struct match
*match
,
368 const uint8_t dl_src
[ETH_ADDR_LEN
],
369 const uint8_t mask
[ETH_ADDR_LEN
])
371 set_eth_masked(dl_src
, mask
, match
->flow
.dl_src
, match
->wc
.masks
.dl_src
);
374 /* Modifies 'match' so that the Ethernet address must match 'dl_dst'
377 match_set_dl_dst(struct match
*match
, const uint8_t dl_dst
[ETH_ADDR_LEN
])
379 set_eth(dl_dst
, match
->flow
.dl_dst
, match
->wc
.masks
.dl_dst
);
382 /* Modifies 'match' so that the Ethernet address must match 'dl_dst' after each
383 * byte is ANDed with the appropriate byte in 'mask'.
385 * This function will assert-fail if 'mask' is invalid. Only 'mask' values
386 * accepted by flow_wildcards_is_dl_dst_mask_valid() are allowed. */
388 match_set_dl_dst_masked(struct match
*match
,
389 const uint8_t dl_dst
[ETH_ADDR_LEN
],
390 const uint8_t mask
[ETH_ADDR_LEN
])
392 set_eth_masked(dl_dst
, mask
, match
->flow
.dl_dst
, match
->wc
.masks
.dl_dst
);
396 match_set_dl_tci(struct match
*match
, ovs_be16 tci
)
398 match_set_dl_tci_masked(match
, tci
, htons(0xffff));
402 match_set_dl_tci_masked(struct match
*match
, ovs_be16 tci
, ovs_be16 mask
)
404 match
->flow
.vlan_tci
= tci
& mask
;
405 match
->wc
.masks
.vlan_tci
= mask
;
408 /* Modifies 'match' so that the VLAN VID is wildcarded. If the PCP is already
409 * wildcarded, then 'match' will match a packet regardless of whether it has an
410 * 802.1Q header or not. */
412 match_set_any_vid(struct match
*match
)
414 if (match
->wc
.masks
.vlan_tci
& htons(VLAN_PCP_MASK
)) {
415 match
->wc
.masks
.vlan_tci
&= ~htons(VLAN_VID_MASK
);
416 match
->flow
.vlan_tci
&= ~htons(VLAN_VID_MASK
);
418 match_set_dl_tci_masked(match
, htons(0), htons(0));
422 /* Modifies 'match' depending on 'dl_vlan':
424 * - If 'dl_vlan' is htons(OFP_VLAN_NONE), makes 'match' match only packets
425 * without an 802.1Q header.
427 * - Otherwise, makes 'match' match only packets with an 802.1Q header whose
428 * VID equals the low 12 bits of 'dl_vlan'.
431 match_set_dl_vlan(struct match
*match
, ovs_be16 dl_vlan
)
433 flow_set_dl_vlan(&match
->flow
, dl_vlan
);
434 if (dl_vlan
== htons(OFP10_VLAN_NONE
)) {
435 match
->wc
.masks
.vlan_tci
= OVS_BE16_MAX
;
437 match
->wc
.masks
.vlan_tci
|= htons(VLAN_VID_MASK
| VLAN_CFI
);
441 /* Sets the VLAN VID that 'match' matches to 'vid', which is interpreted as an
442 * OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
445 match_set_vlan_vid(struct match
*match
, ovs_be16 vid
)
447 match_set_vlan_vid_masked(match
, vid
, htons(VLAN_VID_MASK
| VLAN_CFI
));
451 /* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
452 * OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
453 * plus CFI), with the corresponding 'mask'. */
455 match_set_vlan_vid_masked(struct match
*match
, ovs_be16 vid
, ovs_be16 mask
)
457 ovs_be16 pcp_mask
= htons(VLAN_PCP_MASK
);
458 ovs_be16 vid_mask
= htons(VLAN_VID_MASK
| VLAN_CFI
);
461 flow_set_vlan_vid(&match
->flow
, vid
& mask
);
462 match
->wc
.masks
.vlan_tci
= mask
| (match
->wc
.masks
.vlan_tci
& pcp_mask
);
465 /* Modifies 'match' so that the VLAN PCP is wildcarded. If the VID is already
466 * wildcarded, then 'match' will match a packet regardless of whether it has an
467 * 802.1Q header or not. */
469 match_set_any_pcp(struct match
*match
)
471 if (match
->wc
.masks
.vlan_tci
& htons(VLAN_VID_MASK
)) {
472 match
->wc
.masks
.vlan_tci
&= ~htons(VLAN_PCP_MASK
);
473 match
->flow
.vlan_tci
&= ~htons(VLAN_PCP_MASK
);
475 match_set_dl_tci_masked(match
, htons(0), htons(0));
479 /* Modifies 'match' so that it matches only packets with an 802.1Q header whose
480 * PCP equals the low 3 bits of 'dl_vlan_pcp'. */
482 match_set_dl_vlan_pcp(struct match
*match
, uint8_t dl_vlan_pcp
)
484 flow_set_vlan_pcp(&match
->flow
, dl_vlan_pcp
);
485 match
->wc
.masks
.vlan_tci
|= htons(VLAN_CFI
| VLAN_PCP_MASK
);
488 /* Modifies 'match' so that the MPLS label 'idx' matches 'lse' exactly. */
490 match_set_mpls_lse(struct match
*match
, int idx
, ovs_be32 lse
)
492 match
->wc
.masks
.mpls_lse
[idx
] = OVS_BE32_MAX
;
493 match
->flow
.mpls_lse
[idx
] = lse
;
496 /* Modifies 'match' so that the MPLS label is wildcarded. */
498 match_set_any_mpls_label(struct match
*match
, int idx
)
500 match
->wc
.masks
.mpls_lse
[idx
] &= ~htonl(MPLS_LABEL_MASK
);
501 flow_set_mpls_label(&match
->flow
, idx
, htonl(0));
504 /* Modifies 'match' so that it matches only packets with an MPLS header whose
505 * label equals the low 20 bits of 'mpls_label'. */
507 match_set_mpls_label(struct match
*match
, int idx
, ovs_be32 mpls_label
)
509 match
->wc
.masks
.mpls_lse
[idx
] |= htonl(MPLS_LABEL_MASK
);
510 flow_set_mpls_label(&match
->flow
, idx
, mpls_label
);
513 /* Modifies 'match' so that the MPLS TC is wildcarded. */
515 match_set_any_mpls_tc(struct match
*match
, int idx
)
517 match
->wc
.masks
.mpls_lse
[idx
] &= ~htonl(MPLS_TC_MASK
);
518 flow_set_mpls_tc(&match
->flow
, idx
, 0);
521 /* Modifies 'match' so that it matches only packets with an MPLS header whose
522 * Traffic Class equals the low 3 bits of 'mpls_tc'. */
524 match_set_mpls_tc(struct match
*match
, int idx
, uint8_t mpls_tc
)
526 match
->wc
.masks
.mpls_lse
[idx
] |= htonl(MPLS_TC_MASK
);
527 flow_set_mpls_tc(&match
->flow
, idx
, mpls_tc
);
530 /* Modifies 'match' so that the MPLS stack flag is wildcarded. */
532 match_set_any_mpls_bos(struct match
*match
, int idx
)
534 match
->wc
.masks
.mpls_lse
[idx
] &= ~htonl(MPLS_BOS_MASK
);
535 flow_set_mpls_bos(&match
->flow
, idx
, 0);
538 /* Modifies 'match' so that it matches only packets with an MPLS header whose
539 * Stack Flag equals the lower bit of 'mpls_bos' */
541 match_set_mpls_bos(struct match
*match
, int idx
, uint8_t mpls_bos
)
543 match
->wc
.masks
.mpls_lse
[idx
] |= htonl(MPLS_BOS_MASK
);
544 flow_set_mpls_bos(&match
->flow
, idx
, mpls_bos
);
547 /* Modifies 'match' so that the MPLS LSE is wildcarded. */
549 match_set_any_mpls_lse(struct match
*match
, int idx
)
551 match
->wc
.masks
.mpls_lse
[idx
] = htonl(0);
552 flow_set_mpls_lse(&match
->flow
, idx
, htonl(0));
556 match_set_tp_src(struct match
*match
, ovs_be16 tp_src
)
558 match_set_tp_src_masked(match
, tp_src
, OVS_BE16_MAX
);
562 match_set_tp_src_masked(struct match
*match
, ovs_be16 port
, ovs_be16 mask
)
564 match
->flow
.tp_src
= port
& mask
;
565 match
->wc
.masks
.tp_src
= mask
;
569 match_set_tp_dst(struct match
*match
, ovs_be16 tp_dst
)
571 match_set_tp_dst_masked(match
, tp_dst
, OVS_BE16_MAX
);
575 match_set_tp_dst_masked(struct match
*match
, ovs_be16 port
, ovs_be16 mask
)
577 match
->flow
.tp_dst
= port
& mask
;
578 match
->wc
.masks
.tp_dst
= mask
;
582 match_set_tcp_flags(struct match
*match
, ovs_be16 flags
)
584 match_set_tcp_flags_masked(match
, flags
, OVS_BE16_MAX
);
588 match_set_tcp_flags_masked(struct match
*match
, ovs_be16 flags
, ovs_be16 mask
)
590 match
->flow
.tcp_flags
= flags
& mask
;
591 match
->wc
.masks
.tcp_flags
= mask
;
595 match_set_nw_proto(struct match
*match
, uint8_t nw_proto
)
597 match
->flow
.nw_proto
= nw_proto
;
598 match
->wc
.masks
.nw_proto
= UINT8_MAX
;
602 match_set_nw_src(struct match
*match
, ovs_be32 nw_src
)
604 match
->flow
.nw_src
= nw_src
;
605 match
->wc
.masks
.nw_src
= OVS_BE32_MAX
;
609 match_set_nw_src_masked(struct match
*match
,
610 ovs_be32 nw_src
, ovs_be32 mask
)
612 match
->flow
.nw_src
= nw_src
& mask
;
613 match
->wc
.masks
.nw_src
= mask
;
617 match_set_nw_dst(struct match
*match
, ovs_be32 nw_dst
)
619 match
->flow
.nw_dst
= nw_dst
;
620 match
->wc
.masks
.nw_dst
= OVS_BE32_MAX
;
624 match_set_nw_dst_masked(struct match
*match
, ovs_be32 ip
, ovs_be32 mask
)
626 match
->flow
.nw_dst
= ip
& mask
;
627 match
->wc
.masks
.nw_dst
= mask
;
631 match_set_nw_dscp(struct match
*match
, uint8_t nw_dscp
)
633 match
->wc
.masks
.nw_tos
|= IP_DSCP_MASK
;
634 match
->flow
.nw_tos
&= ~IP_DSCP_MASK
;
635 match
->flow
.nw_tos
|= nw_dscp
& IP_DSCP_MASK
;
639 match_set_nw_ecn(struct match
*match
, uint8_t nw_ecn
)
641 match
->wc
.masks
.nw_tos
|= IP_ECN_MASK
;
642 match
->flow
.nw_tos
&= ~IP_ECN_MASK
;
643 match
->flow
.nw_tos
|= nw_ecn
& IP_ECN_MASK
;
647 match_set_nw_ttl(struct match
*match
, uint8_t nw_ttl
)
649 match
->wc
.masks
.nw_ttl
= UINT8_MAX
;
650 match
->flow
.nw_ttl
= nw_ttl
;
654 match_set_nw_frag(struct match
*match
, uint8_t nw_frag
)
656 match
->wc
.masks
.nw_frag
|= FLOW_NW_FRAG_MASK
;
657 match
->flow
.nw_frag
= nw_frag
;
661 match_set_nw_frag_masked(struct match
*match
,
662 uint8_t nw_frag
, uint8_t mask
)
664 match
->flow
.nw_frag
= nw_frag
& mask
;
665 match
->wc
.masks
.nw_frag
= mask
;
669 match_set_icmp_type(struct match
*match
, uint8_t icmp_type
)
671 match_set_tp_src(match
, htons(icmp_type
));
675 match_set_icmp_code(struct match
*match
, uint8_t icmp_code
)
677 match_set_tp_dst(match
, htons(icmp_code
));
681 match_set_arp_sha(struct match
*match
, const uint8_t sha
[ETH_ADDR_LEN
])
683 memcpy(match
->flow
.arp_sha
, sha
, ETH_ADDR_LEN
);
684 memset(match
->wc
.masks
.arp_sha
, UINT8_MAX
, ETH_ADDR_LEN
);
688 match_set_arp_sha_masked(struct match
*match
,
689 const uint8_t arp_sha
[ETH_ADDR_LEN
],
690 const uint8_t mask
[ETH_ADDR_LEN
])
692 set_eth_masked(arp_sha
, mask
,
693 match
->flow
.arp_sha
, match
->wc
.masks
.arp_sha
);
697 match_set_arp_tha(struct match
*match
, const uint8_t tha
[ETH_ADDR_LEN
])
699 memcpy(match
->flow
.arp_tha
, tha
, ETH_ADDR_LEN
);
700 memset(match
->wc
.masks
.arp_tha
, UINT8_MAX
, ETH_ADDR_LEN
);
704 match_set_arp_tha_masked(struct match
*match
,
705 const uint8_t arp_tha
[ETH_ADDR_LEN
],
706 const uint8_t mask
[ETH_ADDR_LEN
])
708 set_eth_masked(arp_tha
, mask
,
709 match
->flow
.arp_tha
, match
->wc
.masks
.arp_tha
);
713 match_set_ipv6_src(struct match
*match
, const struct in6_addr
*src
)
715 match
->flow
.ipv6_src
= *src
;
716 match
->wc
.masks
.ipv6_src
= in6addr_exact
;
720 match_set_ipv6_src_masked(struct match
*match
, const struct in6_addr
*src
,
721 const struct in6_addr
*mask
)
723 match
->flow
.ipv6_src
= ipv6_addr_bitand(src
, mask
);
724 match
->wc
.masks
.ipv6_src
= *mask
;
728 match_set_ipv6_dst(struct match
*match
, const struct in6_addr
*dst
)
730 match
->flow
.ipv6_dst
= *dst
;
731 match
->wc
.masks
.ipv6_dst
= in6addr_exact
;
735 match_set_ipv6_dst_masked(struct match
*match
, const struct in6_addr
*dst
,
736 const struct in6_addr
*mask
)
738 match
->flow
.ipv6_dst
= ipv6_addr_bitand(dst
, mask
);
739 match
->wc
.masks
.ipv6_dst
= *mask
;
743 match_set_ipv6_label(struct match
*match
, ovs_be32 ipv6_label
)
745 match
->wc
.masks
.ipv6_label
= OVS_BE32_MAX
;
746 match
->flow
.ipv6_label
= ipv6_label
;
751 match_set_ipv6_label_masked(struct match
*match
, ovs_be32 ipv6_label
,
754 match
->flow
.ipv6_label
= ipv6_label
& mask
;
755 match
->wc
.masks
.ipv6_label
= mask
;
759 match_set_nd_target(struct match
*match
, const struct in6_addr
*target
)
761 match
->flow
.nd_target
= *target
;
762 match
->wc
.masks
.nd_target
= in6addr_exact
;
766 match_set_nd_target_masked(struct match
*match
,
767 const struct in6_addr
*target
,
768 const struct in6_addr
*mask
)
770 match
->flow
.nd_target
= ipv6_addr_bitand(target
, mask
);
771 match
->wc
.masks
.nd_target
= *mask
;
774 /* Returns true if 'a' and 'b' wildcard the same fields and have the same
775 * values for fixed fields, otherwise false. */
777 match_equal(const struct match
*a
, const struct match
*b
)
779 return (flow_wildcards_equal(&a
->wc
, &b
->wc
)
780 && flow_equal(&a
->flow
, &b
->flow
));
783 /* Returns a hash value for the flow and wildcards in 'match', starting from
786 match_hash(const struct match
*match
, uint32_t basis
)
788 return flow_wildcards_hash(&match
->wc
, flow_hash(&match
->flow
, basis
));
792 match_has_default_recirc_id(const struct match
*m
)
794 return m
->flow
.recirc_id
== 0 && (m
->wc
.masks
.recirc_id
== UINT32_MAX
||
795 m
->wc
.masks
.recirc_id
== 0);
799 match_has_default_dp_hash(const struct match
*m
)
801 return ((m
->flow
.dp_hash
| m
->wc
.masks
.dp_hash
) == 0);
804 /* Return true if the hidden fields of the match are set to the default values.
805 * The default values equals to those set up by match_init_hidden_fields(). */
807 match_has_default_hidden_fields(const struct match
*m
)
809 return match_has_default_recirc_id(m
) && match_has_default_dp_hash(m
);
813 match_init_hidden_fields(struct match
*m
)
815 match_set_recirc_id(m
, 0);
816 match_set_dp_hash_masked(m
, 0, 0);
820 format_eth_masked(struct ds
*s
, const char *name
, const uint8_t eth
[6],
821 const uint8_t mask
[6])
823 if (!eth_addr_is_zero(mask
)) {
824 ds_put_format(s
, "%s=", name
);
825 eth_format_masked(eth
, mask
, s
);
831 format_ip_netmask(struct ds
*s
, const char *name
, ovs_be32 ip
,
835 ds_put_format(s
, "%s=", name
);
836 ip_format_masked(ip
, netmask
, s
);
842 format_ipv6_netmask(struct ds
*s
, const char *name
,
843 const struct in6_addr
*addr
,
844 const struct in6_addr
*netmask
)
846 if (!ipv6_mask_is_any(netmask
)) {
847 ds_put_format(s
, "%s=", name
);
848 print_ipv6_masked(s
, addr
, netmask
);
854 format_be16_masked(struct ds
*s
, const char *name
,
855 ovs_be16 value
, ovs_be16 mask
)
857 if (mask
!= htons(0)) {
858 ds_put_format(s
, "%s=", name
);
859 if (mask
== OVS_BE16_MAX
) {
860 ds_put_format(s
, "%"PRIu16
, ntohs(value
));
862 ds_put_format(s
, "0x%"PRIx16
"/0x%"PRIx16
,
863 ntohs(value
), ntohs(mask
));
870 format_be32_masked(struct ds
*s
, const char *name
,
871 ovs_be32 value
, ovs_be32 mask
)
873 if (mask
!= htonl(0)) {
874 ds_put_format(s
, "%s=", name
);
875 if (mask
== OVS_BE32_MAX
) {
876 ds_put_format(s
, "%"PRIu32
, ntohl(value
));
878 ds_put_format(s
, "0x%"PRIx32
"/0x%"PRIx32
,
879 ntohl(value
), ntohl(mask
));
886 format_uint32_masked(struct ds
*s
, const char *name
,
887 uint32_t value
, uint32_t mask
)
890 ds_put_format(s
, "%s=%#"PRIx32
, name
, value
);
891 if (mask
!= UINT32_MAX
) {
892 ds_put_format(s
, "/%#"PRIx32
, mask
);
899 format_be64_masked(struct ds
*s
, const char *name
,
900 ovs_be64 value
, ovs_be64 mask
)
902 if (mask
!= htonll(0)) {
903 ds_put_format(s
, "%s=%#"PRIx64
, name
, ntohll(value
));
904 if (mask
!= OVS_BE64_MAX
) {
905 ds_put_format(s
, "/%#"PRIx64
, ntohll(mask
));
912 format_flow_tunnel(struct ds
*s
, const struct match
*match
)
914 const struct flow_wildcards
*wc
= &match
->wc
;
915 const struct flow_tnl
*tnl
= &match
->flow
.tunnel
;
917 format_be64_masked(s
, "tun_id", tnl
->tun_id
, wc
->masks
.tunnel
.tun_id
);
918 format_ip_netmask(s
, "tun_src", tnl
->ip_src
, wc
->masks
.tunnel
.ip_src
);
919 format_ip_netmask(s
, "tun_dst", tnl
->ip_dst
, wc
->masks
.tunnel
.ip_dst
);
921 if (wc
->masks
.tunnel
.ip_tos
) {
922 ds_put_format(s
, "tun_tos=%"PRIx8
",", tnl
->ip_tos
);
924 if (wc
->masks
.tunnel
.ip_ttl
) {
925 ds_put_format(s
, "tun_ttl=%"PRIu8
",", tnl
->ip_ttl
);
927 if (wc
->masks
.tunnel
.flags
) {
928 format_flags(s
, flow_tun_flag_to_string
, tnl
->flags
, '|');
933 /* Appends a string representation of 'match' to 's'. If 'priority' is
934 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
936 match_format(const struct match
*match
, struct ds
*s
, unsigned int priority
)
938 const struct flow_wildcards
*wc
= &match
->wc
;
939 size_t start_len
= s
->length
;
940 const struct flow
*f
= &match
->flow
;
941 bool skip_type
= false;
942 bool skip_proto
= false;
946 BUILD_ASSERT_DECL(FLOW_WC_SEQ
== 26);
948 if (priority
!= OFP_DEFAULT_PRIORITY
) {
949 ds_put_format(s
, "priority=%u,", priority
);
952 format_uint32_masked(s
, "pkt_mark", f
->pkt_mark
, wc
->masks
.pkt_mark
);
954 if (wc
->masks
.recirc_id
) {
955 format_uint32_masked(s
, "recirc_id", f
->recirc_id
,
956 wc
->masks
.recirc_id
);
959 if (f
->dp_hash
&& wc
->masks
.dp_hash
) {
960 format_uint32_masked(s
, "dp_hash", f
->dp_hash
,
964 if (wc
->masks
.skb_priority
) {
965 ds_put_format(s
, "skb_priority=%#"PRIx32
",", f
->skb_priority
);
968 if (wc
->masks
.dl_type
) {
970 if (f
->dl_type
== htons(ETH_TYPE_IP
)) {
971 if (wc
->masks
.nw_proto
) {
973 if (f
->nw_proto
== IPPROTO_ICMP
) {
974 ds_put_cstr(s
, "icmp,");
975 } else if (f
->nw_proto
== IPPROTO_TCP
) {
976 ds_put_cstr(s
, "tcp,");
977 } else if (f
->nw_proto
== IPPROTO_UDP
) {
978 ds_put_cstr(s
, "udp,");
979 } else if (f
->nw_proto
== IPPROTO_SCTP
) {
980 ds_put_cstr(s
, "sctp,");
982 ds_put_cstr(s
, "ip,");
986 ds_put_cstr(s
, "ip,");
988 } else if (f
->dl_type
== htons(ETH_TYPE_IPV6
)) {
989 if (wc
->masks
.nw_proto
) {
991 if (f
->nw_proto
== IPPROTO_ICMPV6
) {
992 ds_put_cstr(s
, "icmp6,");
993 } else if (f
->nw_proto
== IPPROTO_TCP
) {
994 ds_put_cstr(s
, "tcp6,");
995 } else if (f
->nw_proto
== IPPROTO_UDP
) {
996 ds_put_cstr(s
, "udp6,");
997 } else if (f
->nw_proto
== IPPROTO_SCTP
) {
998 ds_put_cstr(s
, "sctp6,");
1000 ds_put_cstr(s
, "ipv6,");
1004 ds_put_cstr(s
, "ipv6,");
1006 } else if (f
->dl_type
== htons(ETH_TYPE_ARP
)) {
1007 ds_put_cstr(s
, "arp,");
1008 } else if (f
->dl_type
== htons(ETH_TYPE_RARP
)) {
1009 ds_put_cstr(s
, "rarp,");
1010 } else if (f
->dl_type
== htons(ETH_TYPE_MPLS
)) {
1011 ds_put_cstr(s
, "mpls,");
1012 } else if (f
->dl_type
== htons(ETH_TYPE_MPLS_MCAST
)) {
1013 ds_put_cstr(s
, "mplsm,");
1018 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
1019 #define REGNAME_LEN 20
1020 char regname
[REGNAME_LEN
];
1021 if (snprintf(regname
, REGNAME_LEN
, "reg%d", i
) >= REGNAME_LEN
) {
1022 strcpy(regname
, "reg?");
1024 format_uint32_masked(s
, regname
, f
->regs
[i
], wc
->masks
.regs
[i
]);
1027 format_flow_tunnel(s
, match
);
1029 format_be64_masked(s
, "metadata", f
->metadata
, wc
->masks
.metadata
);
1031 if (wc
->masks
.in_port
.ofp_port
) {
1032 ds_put_cstr(s
, "in_port=");
1033 ofputil_format_port(f
->in_port
.ofp_port
, s
);
1034 ds_put_char(s
, ',');
1036 if (wc
->masks
.vlan_tci
) {
1037 ovs_be16 vid_mask
= wc
->masks
.vlan_tci
& htons(VLAN_VID_MASK
);
1038 ovs_be16 pcp_mask
= wc
->masks
.vlan_tci
& htons(VLAN_PCP_MASK
);
1039 ovs_be16 cfi
= wc
->masks
.vlan_tci
& htons(VLAN_CFI
);
1041 if (cfi
&& f
->vlan_tci
& htons(VLAN_CFI
)
1042 && (!vid_mask
|| vid_mask
== htons(VLAN_VID_MASK
))
1043 && (!pcp_mask
|| pcp_mask
== htons(VLAN_PCP_MASK
))
1044 && (vid_mask
|| pcp_mask
)) {
1046 ds_put_format(s
, "dl_vlan=%"PRIu16
",",
1047 vlan_tci_to_vid(f
->vlan_tci
));
1050 ds_put_format(s
, "dl_vlan_pcp=%d,",
1051 vlan_tci_to_pcp(f
->vlan_tci
));
1053 } else if (wc
->masks
.vlan_tci
== htons(0xffff)) {
1054 ds_put_format(s
, "vlan_tci=0x%04"PRIx16
",", ntohs(f
->vlan_tci
));
1056 ds_put_format(s
, "vlan_tci=0x%04"PRIx16
"/0x%04"PRIx16
",",
1057 ntohs(f
->vlan_tci
), ntohs(wc
->masks
.vlan_tci
));
1060 format_eth_masked(s
, "dl_src", f
->dl_src
, wc
->masks
.dl_src
);
1061 format_eth_masked(s
, "dl_dst", f
->dl_dst
, wc
->masks
.dl_dst
);
1062 if (!skip_type
&& wc
->masks
.dl_type
) {
1063 ds_put_format(s
, "dl_type=0x%04"PRIx16
",", ntohs(f
->dl_type
));
1065 if (f
->dl_type
== htons(ETH_TYPE_IPV6
)) {
1066 format_ipv6_netmask(s
, "ipv6_src", &f
->ipv6_src
, &wc
->masks
.ipv6_src
);
1067 format_ipv6_netmask(s
, "ipv6_dst", &f
->ipv6_dst
, &wc
->masks
.ipv6_dst
);
1068 if (wc
->masks
.ipv6_label
) {
1069 if (wc
->masks
.ipv6_label
== OVS_BE32_MAX
) {
1070 ds_put_format(s
, "ipv6_label=0x%05"PRIx32
",",
1071 ntohl(f
->ipv6_label
));
1073 ds_put_format(s
, "ipv6_label=0x%05"PRIx32
"/0x%05"PRIx32
",",
1074 ntohl(f
->ipv6_label
),
1075 ntohl(wc
->masks
.ipv6_label
));
1078 } else if (f
->dl_type
== htons(ETH_TYPE_ARP
) ||
1079 f
->dl_type
== htons(ETH_TYPE_RARP
)) {
1080 format_ip_netmask(s
, "arp_spa", f
->nw_src
, wc
->masks
.nw_src
);
1081 format_ip_netmask(s
, "arp_tpa", f
->nw_dst
, wc
->masks
.nw_dst
);
1083 format_ip_netmask(s
, "nw_src", f
->nw_src
, wc
->masks
.nw_src
);
1084 format_ip_netmask(s
, "nw_dst", f
->nw_dst
, wc
->masks
.nw_dst
);
1086 if (!skip_proto
&& wc
->masks
.nw_proto
) {
1087 if (f
->dl_type
== htons(ETH_TYPE_ARP
) ||
1088 f
->dl_type
== htons(ETH_TYPE_RARP
)) {
1089 ds_put_format(s
, "arp_op=%"PRIu8
",", f
->nw_proto
);
1091 ds_put_format(s
, "nw_proto=%"PRIu8
",", f
->nw_proto
);
1094 if (f
->dl_type
== htons(ETH_TYPE_ARP
) ||
1095 f
->dl_type
== htons(ETH_TYPE_RARP
)) {
1096 format_eth_masked(s
, "arp_sha", f
->arp_sha
, wc
->masks
.arp_sha
);
1097 format_eth_masked(s
, "arp_tha", f
->arp_tha
, wc
->masks
.arp_tha
);
1099 if (wc
->masks
.nw_tos
& IP_DSCP_MASK
) {
1100 ds_put_format(s
, "nw_tos=%"PRIu8
",", f
->nw_tos
& IP_DSCP_MASK
);
1102 if (wc
->masks
.nw_tos
& IP_ECN_MASK
) {
1103 ds_put_format(s
, "nw_ecn=%"PRIu8
",", f
->nw_tos
& IP_ECN_MASK
);
1105 if (wc
->masks
.nw_ttl
) {
1106 ds_put_format(s
, "nw_ttl=%"PRIu8
",", f
->nw_ttl
);
1108 if (wc
->masks
.mpls_lse
[0] & htonl(MPLS_LABEL_MASK
)) {
1109 ds_put_format(s
, "mpls_label=%"PRIu32
",",
1110 mpls_lse_to_label(f
->mpls_lse
[0]));
1112 if (wc
->masks
.mpls_lse
[0] & htonl(MPLS_TC_MASK
)) {
1113 ds_put_format(s
, "mpls_tc=%"PRIu8
",",
1114 mpls_lse_to_tc(f
->mpls_lse
[0]));
1116 if (wc
->masks
.mpls_lse
[0] & htonl(MPLS_TTL_MASK
)) {
1117 ds_put_format(s
, "mpls_ttl=%"PRIu8
",",
1118 mpls_lse_to_ttl(f
->mpls_lse
[0]));
1120 if (wc
->masks
.mpls_lse
[0] & htonl(MPLS_BOS_MASK
)) {
1121 ds_put_format(s
, "mpls_bos=%"PRIu8
",",
1122 mpls_lse_to_bos(f
->mpls_lse
[0]));
1124 format_be32_masked(s
, "mpls_lse1", f
->mpls_lse
[1], wc
->masks
.mpls_lse
[1]);
1125 format_be32_masked(s
, "mpls_lse2", f
->mpls_lse
[2], wc
->masks
.mpls_lse
[2]);
1127 switch (wc
->masks
.nw_frag
) {
1128 case FLOW_NW_FRAG_ANY
| FLOW_NW_FRAG_LATER
:
1129 ds_put_format(s
, "nw_frag=%s,",
1130 f
->nw_frag
& FLOW_NW_FRAG_ANY
1131 ? (f
->nw_frag
& FLOW_NW_FRAG_LATER
? "later" : "first")
1132 : (f
->nw_frag
& FLOW_NW_FRAG_LATER
? "<error>" : "no"));
1135 case FLOW_NW_FRAG_ANY
:
1136 ds_put_format(s
, "nw_frag=%s,",
1137 f
->nw_frag
& FLOW_NW_FRAG_ANY
? "yes" : "no");
1140 case FLOW_NW_FRAG_LATER
:
1141 ds_put_format(s
, "nw_frag=%s,",
1142 f
->nw_frag
& FLOW_NW_FRAG_LATER
? "later" : "not_later");
1145 if (f
->dl_type
== htons(ETH_TYPE_IP
) &&
1146 f
->nw_proto
== IPPROTO_ICMP
) {
1147 format_be16_masked(s
, "icmp_type", f
->tp_src
, wc
->masks
.tp_src
);
1148 format_be16_masked(s
, "icmp_code", f
->tp_dst
, wc
->masks
.tp_dst
);
1149 } else if (f
->dl_type
== htons(ETH_TYPE_IPV6
) &&
1150 f
->nw_proto
== IPPROTO_ICMPV6
) {
1151 format_be16_masked(s
, "icmp_type", f
->tp_src
, wc
->masks
.tp_src
);
1152 format_be16_masked(s
, "icmp_code", f
->tp_dst
, wc
->masks
.tp_dst
);
1153 format_ipv6_netmask(s
, "nd_target", &f
->nd_target
,
1154 &wc
->masks
.nd_target
);
1155 format_eth_masked(s
, "nd_sll", f
->arp_sha
, wc
->masks
.arp_sha
);
1156 format_eth_masked(s
, "nd_tll", f
->arp_tha
, wc
->masks
.arp_tha
);
1158 format_be16_masked(s
, "tp_src", f
->tp_src
, wc
->masks
.tp_src
);
1159 format_be16_masked(s
, "tp_dst", f
->tp_dst
, wc
->masks
.tp_dst
);
1161 if (is_ip_any(f
) && f
->nw_proto
== IPPROTO_TCP
&& wc
->masks
.tcp_flags
) {
1162 uint16_t mask
= TCP_FLAGS(wc
->masks
.tcp_flags
);
1163 if (mask
== TCP_FLAGS(OVS_BE16_MAX
)) {
1164 ds_put_format(s
, "tcp_flags=0x%03"PRIx16
",", ntohs(f
->tcp_flags
));
1166 format_flags_masked(s
, "tcp_flags", packet_tcp_flag_to_string
,
1167 ntohs(f
->tcp_flags
), mask
);
1171 if (s
->length
> start_len
&& ds_last(s
) == ',') {
1176 /* Converts 'match' to a string and returns the string. If 'priority' is
1177 * different from OFP_DEFAULT_PRIORITY, includes it in the string. The caller
1178 * must free the string (with free()). */
1180 match_to_string(const struct match
*match
, unsigned int priority
)
1182 struct ds s
= DS_EMPTY_INITIALIZER
;
1183 match_format(match
, &s
, priority
);
1184 return ds_steal_cstr(&s
);
1188 match_print(const struct match
*match
)
1190 char *s
= match_to_string(match
, OFP_DEFAULT_PRIORITY
);
1195 /* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst'
1196 * with minimatch_destroy(). */
1198 minimatch_init(struct minimatch
*dst
, const struct match
*src
)
1200 minimask_init(&dst
->mask
, &src
->wc
);
1201 miniflow_init_with_minimask(&dst
->flow
, &src
->flow
, &dst
->mask
);
1204 /* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst'
1205 * with minimatch_destroy(). */
1207 minimatch_clone(struct minimatch
*dst
, const struct minimatch
*src
)
1209 miniflow_clone(&dst
->flow
, &src
->flow
);
1210 minimask_clone(&dst
->mask
, &src
->mask
);
1213 /* Initializes 'dst' with the data in 'src', destroying 'src'. The caller must
1214 * eventually free 'dst' with minimatch_destroy(). */
1216 minimatch_move(struct minimatch
*dst
, struct minimatch
*src
)
1218 miniflow_move(&dst
->flow
, &src
->flow
);
1219 minimask_move(&dst
->mask
, &src
->mask
);
1222 /* Frees any memory owned by 'match'. Does not free the storage in which
1223 * 'match' itself resides; the caller is responsible for that. */
1225 minimatch_destroy(struct minimatch
*match
)
1227 miniflow_destroy(&match
->flow
);
1228 minimask_destroy(&match
->mask
);
1231 /* Initializes 'dst' as a copy of 'src'. */
1233 minimatch_expand(const struct minimatch
*src
, struct match
*dst
)
1235 miniflow_expand(&src
->flow
, &dst
->flow
);
1236 minimask_expand(&src
->mask
, &dst
->wc
);
1239 /* Returns true if 'a' and 'b' match the same packets, false otherwise. */
1241 minimatch_equal(const struct minimatch
*a
, const struct minimatch
*b
)
1243 return (miniflow_equal(&a
->flow
, &b
->flow
)
1244 && minimask_equal(&a
->mask
, &b
->mask
));
1247 /* Returns a hash value for 'match', given 'basis'. */
1249 minimatch_hash(const struct minimatch
*match
, uint32_t basis
)
1251 return miniflow_hash(&match
->flow
, minimask_hash(&match
->mask
, basis
));
1254 /* Returns true if 'target' satisifies 'match', that is, if each bit for which
1255 * 'match' specifies a particular value has the correct value in 'target'.
1257 * This function is equivalent to miniflow_equal_flow_in_minimask(&match->flow,
1258 * target, &match->mask) but it is faster because of the invariant that
1259 * match->flow.map and match->mask.map are the same. */
1261 minimatch_matches_flow(const struct minimatch
*match
,
1262 const struct flow
*target
)
1264 const uint32_t *target_u32
= (const uint32_t *) target
;
1265 const uint32_t *flowp
= match
->flow
.values
;
1266 const uint32_t *maskp
= match
->mask
.masks
.values
;
1269 for (map
= match
->flow
.map
; map
; map
= zero_rightmost_1bit(map
)) {
1270 if ((*flowp
++ ^ target_u32
[raw_ctz(map
)]) & *maskp
++) {
1278 /* Returns a hash value for the bits of range [start, end) in 'minimatch',
1281 * The hash values returned by this function are the same as those returned by
1282 * flow_hash_in_minimask_range(), only the form of the arguments differ. */
1284 minimatch_hash_range(const struct minimatch
*match
, uint8_t start
, uint8_t end
,
1287 unsigned int offset
;
1288 const uint32_t *p
, *q
;
1289 uint32_t hash
= *basis
;
1292 n
= count_1bits(miniflow_get_map_in_range(&match
->mask
.masks
, start
, end
,
1294 q
= match
->mask
.masks
.values
+ offset
;
1295 p
= match
->flow
.values
+ offset
;
1297 for (i
= 0; i
< n
; i
++) {
1298 hash
= mhash_add(hash
, p
[i
] & q
[i
]);
1300 *basis
= hash
; /* Allow continuation from the unfinished value. */
1301 return mhash_finish(hash
, (offset
+ n
) * 4);
1304 /* Appends a string representation of 'match' to 's'. If 'priority' is
1305 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
1307 minimatch_format(const struct minimatch
*match
, struct ds
*s
,
1308 unsigned int priority
)
1310 struct match megamatch
;
1312 minimatch_expand(match
, &megamatch
);
1313 match_format(&megamatch
, s
, priority
);
1316 /* Converts 'match' to a string and returns the string. If 'priority' is
1317 * different from OFP_DEFAULT_PRIORITY, includes it in the string. The caller
1318 * must free the string (with free()). */
1320 minimatch_to_string(const struct minimatch
*match
, unsigned int priority
)
1322 struct match megamatch
;
1324 minimatch_expand(match
, &megamatch
);
1325 return match_to_string(&megamatch
, priority
);